From 070b9079226d4f3e3e7c9f4eb81f2e02e7d99572 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 16 Jan 2012 19:39:58 -0800 Subject: regulator: Add devm_regulator_get() Add a resource managed regulator_get() to simplify regulator usage in drivers. This allows driver authors to "get and forget" about their regulators by automatically calling regulator_put() when the driver is detached. [Fixed up a couple of coding style issues -- broonie] Signed-off-by: Stephen Boyd Signed-off-by: Mark Brown diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index 10c64c8..016fd2b 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -267,3 +267,6 @@ IOMAP pcim_iounmap() pcim_iomap_table() : array of mapped addresses indexed by BAR pcim_iomap_regions() : do request_region() and iomap() on multiple BARs + +REGULATOR + devm_regulator_get() diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index ca86f39..214640d 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1320,6 +1320,40 @@ struct regulator *regulator_get(struct device *dev, const char *id) } EXPORT_SYMBOL_GPL(regulator_get); +static void devm_regulator_release(struct device *dev, void *res) +{ + regulator_put(*(struct regulator **)res); +} + +/** + * devm_regulator_get - Resource managed regulator_get() + * @dev: device for regulator "consumer" + * @id: Supply name or regulator ID. + * + * Managed regulator_get(). Regulators returned from this function are + * automatically regulator_put() on driver detach. See regulator_get() for more + * information. + */ +struct regulator *devm_regulator_get(struct device *dev, const char *id) +{ + struct regulator **ptr, *regulator; + + ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + regulator = regulator_get(dev, id); + if (!IS_ERR(regulator)) { + *ptr = regulator; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return regulator; +} +EXPORT_SYMBOL_GPL(devm_regulator_get); + /** * regulator_get_exclusive - obtain exclusive access to a regulator. * @dev: device for regulator "consumer" diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index f2698a0..bcfe106 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -132,6 +132,8 @@ struct regulator_bulk_data { /* regulator get and put */ struct regulator *__must_check regulator_get(struct device *dev, const char *id); +struct regulator *__must_check devm_regulator_get(struct device *dev, + const char *id); struct regulator *__must_check regulator_get_exclusive(struct device *dev, const char *id); void regulator_put(struct regulator *regulator); @@ -200,6 +202,13 @@ static inline struct regulator *__must_check regulator_get(struct device *dev, */ return NULL; } + +static inline struct regulator *__must_check +devm_regulator_get(struct device *dev, const char *id) +{ + return NULL; +} + static inline void regulator_put(struct regulator *regulator) { } -- cgit v0.10.2 From 0d6df67583bb40fdc365210740bcce0bd27420f7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 11:12:45 +0000 Subject: ASoC: Make WM8978 I2C usage unconditional The driver only supports I2C. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 85d514d..0b1f7ad 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -1001,7 +1001,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8978 = { .reg_cache_default = wm8978_reg, }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -1043,27 +1042,22 @@ static struct i2c_driver wm8978_i2c_driver = { .remove = __devexit_p(wm8978_i2c_remove), .id_table = wm8978_i2c_id, }; -#endif static int __init wm8978_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&wm8978_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register WM8978 I2C driver: %d\n", ret); } -#endif return ret; } module_init(wm8978_modinit); static void __exit wm8978_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) i2c_del_driver(&wm8978_i2c_driver); -#endif } module_exit(wm8978_exit); -- cgit v0.10.2 From ad6cdec507d877189c9813655dfa30579256a2fc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 11:13:15 +0000 Subject: ASoC: Remove unused control type from wm8978 driver Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 0b1f7ad..2ba8f8c 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -50,7 +50,6 @@ static const u16 wm8978_reg[WM8978_CACHEREGNUM] = { /* codec private data */ struct wm8978_priv { - enum snd_soc_control_type control_type; unsigned int f_pllout; unsigned int f_mclk; unsigned int f_256fs; -- cgit v0.10.2 From 803b37885d355438192516d73ba3565e744a8b90 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 11:15:43 +0000 Subject: ASoC: Convert wm8978 to table based DAPM and control init Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 2ba8f8c..36468f8 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -302,7 +302,7 @@ static const struct snd_soc_dapm_widget wm8978_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("RSPK"), }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route wm8978_dapm_routes[] = { /* Output mixer */ {"Right Output Mixer", "PCM Playback Switch", "Right DAC"}, {"Right Output Mixer", "Aux Playback Switch", "RAUX"}, @@ -351,18 +351,6 @@ static const struct snd_soc_dapm_route audio_map[] = { {"Left Input Mixer", "MicP Switch", "LMICP"}, }; -static int wm8978_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, wm8978_dapm_widgets, - ARRAY_SIZE(wm8978_dapm_widgets)); - /* set up the WM8978 audio map */ - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - - return 0; -} - /* PLL divisors */ struct wm8978_pll_div { u32 k; @@ -975,10 +963,6 @@ static int wm8978_probe(struct snd_soc_codec *codec) wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_controls(codec, wm8978_snd_controls, - ARRAY_SIZE(wm8978_snd_controls)); - wm8978_add_widgets(codec); - return 0; } @@ -998,6 +982,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8978 = { .reg_cache_size = ARRAY_SIZE(wm8978_reg), .reg_word_size = sizeof(u16), .reg_cache_default = wm8978_reg, + + .controls = wm8978_snd_controls, + .num_controls = ARRAY_SIZE(wm8978_snd_controls), + .dapm_widgets = wm8978_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8978_dapm_widgets), + .dapm_routes = wm8978_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8978_dapm_routes), }; static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, -- cgit v0.10.2 From 623105dc97010f851f8fd22b7ce80b77d860b5f4 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 11:16:53 +0000 Subject: ASoC: Convert wm8978 to devm_kzalloc() Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 36468f8..051f5d0 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -997,7 +997,8 @@ static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, struct wm8978_priv *wm8978; int ret; - wm8978 = kzalloc(sizeof(struct wm8978_priv), GFP_KERNEL); + wm8978 = devm_kzalloc(&i2c->dev, sizeof(struct wm8978_priv), + GFP_KERNEL); if (wm8978 == NULL) return -ENOMEM; @@ -1005,15 +1006,14 @@ static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8978, &wm8978_dai, 1); - if (ret < 0) - kfree(wm8978); + return ret; } static __devexit int wm8978_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); + return 0; } -- cgit v0.10.2 From f98692ea6dda68c7eda6d53a3bc850702c3b8fde Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 11:32:09 +0000 Subject: ASoC: Use standard cache sync for WM8978 Saves a bit of code and supports further refactoring. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 051f5d0..0ab339c 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -891,16 +891,9 @@ static int wm8978_suspend(struct snd_soc_codec *codec) static int wm8978_resume(struct snd_soc_codec *codec) { struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec); - int i; - u16 *cache = codec->reg_cache; /* Sync reg_cache with the hardware */ - for (i = 0; i < ARRAY_SIZE(wm8978_reg); i++) { - if (i == WM8978_RESET) - continue; - if (cache[i] != wm8978_reg[i]) - snd_soc_write(codec, i, cache[i]); - } + snd_soc_cache_sync(codec); wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY); -- cgit v0.10.2 From ee60d0155d653888de75b642182b0300c21ce07a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 11:39:39 +0000 Subject: ASoC: Convert wm8978 to direct regmap API usage Helps push the register cache code down out of ASoC and improves resume times by using the more efficient regmap cache sync code. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 0ab339c..5ff8734d 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -29,27 +30,74 @@ #include "wm8978.h" -/* wm8978 register cache. Note that register 0 is not included in the cache. */ -static const u16 wm8978_reg[WM8978_CACHEREGNUM] = { - 0x0000, 0x0000, 0x0000, 0x0000, /* 0x00...0x03 */ - 0x0050, 0x0000, 0x0140, 0x0000, /* 0x04...0x07 */ - 0x0000, 0x0000, 0x0000, 0x00ff, /* 0x08...0x0b */ - 0x00ff, 0x0000, 0x0100, 0x00ff, /* 0x0c...0x0f */ - 0x00ff, 0x0000, 0x012c, 0x002c, /* 0x10...0x13 */ - 0x002c, 0x002c, 0x002c, 0x0000, /* 0x14...0x17 */ - 0x0032, 0x0000, 0x0000, 0x0000, /* 0x18...0x1b */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 0x1c...0x1f */ - 0x0038, 0x000b, 0x0032, 0x0000, /* 0x20...0x23 */ - 0x0008, 0x000c, 0x0093, 0x00e9, /* 0x24...0x27 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 0x28...0x2b */ - 0x0033, 0x0010, 0x0010, 0x0100, /* 0x2c...0x2f */ - 0x0100, 0x0002, 0x0001, 0x0001, /* 0x30...0x33 */ - 0x0039, 0x0039, 0x0039, 0x0039, /* 0x34...0x37 */ - 0x0001, 0x0001, /* 0x38...0x3b */ +static const struct reg_default wm8978_reg_defaults[] = { + { 1, 0x0000 }, + { 2, 0x0000 }, + { 3, 0x0000 }, + { 4, 0x0050 }, + { 5, 0x0000 }, + { 6, 0x0140 }, + { 7, 0x0000 }, + { 8, 0x0000 }, + { 9, 0x0000 }, + { 10, 0x0000 }, + { 11, 0x00ff }, + { 12, 0x00ff }, + { 13, 0x0000 }, + { 14, 0x0100 }, + { 15, 0x00ff }, + { 16, 0x00ff }, + { 17, 0x0000 }, + { 18, 0x012c }, + { 19, 0x002c }, + { 20, 0x002c }, + { 21, 0x002c }, + { 22, 0x002c }, + { 23, 0x0000 }, + { 24, 0x0032 }, + { 25, 0x0000 }, + { 26, 0x0000 }, + { 27, 0x0000 }, + { 28, 0x0000 }, + { 29, 0x0000 }, + { 30, 0x0000 }, + { 31, 0x0000 }, + { 32, 0x0038 }, + { 33, 0x000b }, + { 34, 0x0032 }, + { 35, 0x0000 }, + { 36, 0x0008 }, + { 37, 0x000c }, + { 38, 0x0093 }, + { 39, 0x00e9 }, + { 40, 0x0000 }, + { 41, 0x0000 }, + { 42, 0x0000 }, + { 43, 0x0000 }, + { 44, 0x0033 }, + { 45, 0x0010 }, + { 46, 0x0010 }, + { 47, 0x0100 }, + { 48, 0x0100 }, + { 49, 0x0002 }, + { 50, 0x0001 }, + { 51, 0x0001 }, + { 52, 0x0039 }, + { 53, 0x0039 }, + { 54, 0x0039 }, + { 55, 0x0039 }, + { 56, 0x0001 }, + { 57, 0x0001 }, }; +static bool wm8978_volatile(struct device *dev, unsigned int reg) +{ + return reg == WM8978_RESET; +} + /* codec private data */ struct wm8978_priv { + struct regmap *regmap; unsigned int f_pllout; unsigned int f_mclk; unsigned int f_256fs; @@ -881,10 +929,14 @@ static struct snd_soc_dai_driver wm8978_dai = { static int wm8978_suspend(struct snd_soc_codec *codec) { + struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec); + wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF); /* Also switch PLL off */ snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 0); + regcache_mark_dirty(wm8978->regmap); + return 0; } @@ -893,7 +945,7 @@ static int wm8978_resume(struct snd_soc_codec *codec) struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec); /* Sync reg_cache with the hardware */ - snd_soc_cache_sync(codec); + regcache_sync(wm8978->regmap); wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY); @@ -933,7 +985,8 @@ static int wm8978_probe(struct snd_soc_codec *codec) * default hardware setting */ wm8978->sysclk = WM8978_PLL; - ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C); + codec->control_data = wm8978->regmap; + ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); if (ret < 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; @@ -972,9 +1025,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8978 = { .suspend = wm8978_suspend, .resume = wm8978_resume, .set_bias_level = wm8978_set_bias_level, - .reg_cache_size = ARRAY_SIZE(wm8978_reg), - .reg_word_size = sizeof(u16), - .reg_cache_default = wm8978_reg, .controls = wm8978_snd_controls, .num_controls = ARRAY_SIZE(wm8978_snd_controls), @@ -984,6 +1034,18 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8978 = { .num_dapm_routes = ARRAY_SIZE(wm8978_dapm_routes), }; +static const struct regmap_config wm8978_regmap_config = { + .reg_bits = 7, + .val_bits = 9, + + .max_register = WM8978_MAX_REGISTER, + .volatile_reg = wm8978_volatile, + + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wm8978_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8978_reg_defaults), +}; + static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -995,6 +1057,13 @@ static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, if (wm8978 == NULL) return -ENOMEM; + wm8978->regmap = regmap_init_i2c(i2c, &wm8978_regmap_config); + if (IS_ERR(wm8978->regmap)) { + ret = PTR_ERR(wm8978->regmap); + dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); + return ret; + } + i2c_set_clientdata(i2c, wm8978); ret = snd_soc_register_codec(&i2c->dev, @@ -1005,7 +1074,10 @@ static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, static __devexit int wm8978_i2c_remove(struct i2c_client *client) { + struct wm8978_priv *wm8978 = i2c_get_clientdata(client); + snd_soc_unregister_codec(&client->dev); + regmap_exit(wm8978->regmap); return 0; } diff --git a/sound/soc/codecs/wm8978.h b/sound/soc/codecs/wm8978.h index c75525b..6ae4349 100644 --- a/sound/soc/codecs/wm8978.h +++ b/sound/soc/codecs/wm8978.h @@ -67,6 +67,8 @@ #define WM8978_OUT3_MIXER_CONTROL 0x38 #define WM8978_OUT4_MIXER_CONTROL 0x39 +#define WM8978_MAX_REGISTER 0x39 + #define WM8978_CACHEREGNUM 58 /* Clock divider Id's */ -- cgit v0.10.2 From 008f8d4f9955b5f20be06ed99434cc2f8b025e06 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 11:44:03 +0000 Subject: ASoC: Push wm8978 reset down into the I2C probe Ensures that we get control of the CODEC earlier and don't try to probe the card at all if register I/O isn't working. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 5ff8734d..72d5fdc 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -1000,13 +1000,6 @@ static int wm8978_probe(struct snd_soc_codec *codec) for (i = 0; i < ARRAY_SIZE(update_reg); i++) snd_soc_update_bits(codec, update_reg[i], 0x100, 0x100); - /* Reset the codec */ - ret = snd_soc_write(codec, WM8978_RESET, 0); - if (ret < 0) { - dev_err(codec->dev, "Failed to issue reset\n"); - return ret; - } - wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; @@ -1066,9 +1059,24 @@ static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, wm8978); + /* Reset the codec */ + ret = regmap_write(wm8978->regmap, WM8978_RESET, 0); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret); + goto err; + } + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8978, &wm8978_dai, 1); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); + goto err; + } + return 0; + +err: + regmap_exit(wm8978->regmap); return ret; } -- cgit v0.10.2 From ec2c0fec11f072222b63eb160da6be01773bfe65 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 Dec 2011 21:20:59 +0800 Subject: ASoC: Convert WM9090 to use regmap directly Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index 41ebe0d..4be5551 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -33,116 +34,51 @@ #include "wm9090.h" -static const u16 wm9090_reg_defaults[] = { - 0x9093, /* R0 - Software Reset */ - 0x0006, /* R1 - Power Management (1) */ - 0x6000, /* R2 - Power Management (2) */ - 0x0000, /* R3 - Power Management (3) */ - 0x0000, /* R4 */ - 0x0000, /* R5 */ - 0x01C0, /* R6 - Clocking 1 */ - 0x0000, /* R7 */ - 0x0000, /* R8 */ - 0x0000, /* R9 */ - 0x0000, /* R10 */ - 0x0000, /* R11 */ - 0x0000, /* R12 */ - 0x0000, /* R13 */ - 0x0000, /* R14 */ - 0x0000, /* R15 */ - 0x0000, /* R16 */ - 0x0000, /* R17 */ - 0x0000, /* R18 */ - 0x0000, /* R19 */ - 0x0000, /* R20 */ - 0x0000, /* R21 */ - 0x0003, /* R22 - IN1 Line Control */ - 0x0003, /* R23 - IN2 Line Control */ - 0x0083, /* R24 - IN1 Line Input A Volume */ - 0x0083, /* R25 - IN1 Line Input B Volume */ - 0x0083, /* R26 - IN2 Line Input A Volume */ - 0x0083, /* R27 - IN2 Line Input B Volume */ - 0x002D, /* R28 - Left Output Volume */ - 0x002D, /* R29 - Right Output Volume */ - 0x0000, /* R30 */ - 0x0000, /* R31 */ - 0x0000, /* R32 */ - 0x0000, /* R33 */ - 0x0100, /* R34 - SPKMIXL Attenuation */ - 0x0000, /* R35 */ - 0x0010, /* R36 - SPKOUT Mixers */ - 0x0140, /* R37 - ClassD3 */ - 0x0039, /* R38 - Speaker Volume Left */ - 0x0000, /* R39 */ - 0x0000, /* R40 */ - 0x0000, /* R41 */ - 0x0000, /* R42 */ - 0x0000, /* R43 */ - 0x0000, /* R44 */ - 0x0000, /* R45 - Output Mixer1 */ - 0x0000, /* R46 - Output Mixer2 */ - 0x0100, /* R47 - Output Mixer3 */ - 0x0100, /* R48 - Output Mixer4 */ - 0x0000, /* R49 */ - 0x0000, /* R50 */ - 0x0000, /* R51 */ - 0x0000, /* R52 */ - 0x0000, /* R53 */ - 0x0000, /* R54 - Speaker Mixer */ - 0x0000, /* R55 */ - 0x0000, /* R56 */ - 0x000D, /* R57 - AntiPOP2 */ - 0x0000, /* R58 */ - 0x0000, /* R59 */ - 0x0000, /* R60 */ - 0x0000, /* R61 */ - 0x0000, /* R62 */ - 0x0000, /* R63 */ - 0x0000, /* R64 */ - 0x0000, /* R65 */ - 0x0000, /* R66 */ - 0x0000, /* R67 */ - 0x0000, /* R68 */ - 0x0000, /* R69 */ - 0x0000, /* R70 - Write Sequencer 0 */ - 0x0000, /* R71 - Write Sequencer 1 */ - 0x0000, /* R72 - Write Sequencer 2 */ - 0x0000, /* R73 - Write Sequencer 3 */ - 0x0000, /* R74 - Write Sequencer 4 */ - 0x0000, /* R75 - Write Sequencer 5 */ - 0x1F25, /* R76 - Charge Pump 1 */ - 0x0000, /* R77 */ - 0x0000, /* R78 */ - 0x0000, /* R79 */ - 0x0000, /* R80 */ - 0x0000, /* R81 */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 - DC Servo 0 */ - 0x054A, /* R85 - DC Servo 1 */ - 0x0000, /* R86 */ - 0x0000, /* R87 - DC Servo 3 */ - 0x0000, /* R88 - DC Servo Readback 0 */ - 0x0000, /* R89 - DC Servo Readback 1 */ - 0x0000, /* R90 - DC Servo Readback 2 */ - 0x0000, /* R91 */ - 0x0000, /* R92 */ - 0x0000, /* R93 */ - 0x0000, /* R94 */ - 0x0000, /* R95 */ - 0x0100, /* R96 - Analogue HP 0 */ - 0x0000, /* R97 */ - 0x8640, /* R98 - AGC Control 0 */ - 0xC000, /* R99 - AGC Control 1 */ - 0x0200, /* R100 - AGC Control 2 */ +static const struct reg_default wm9090_reg_defaults[] = { + { 1, 0x0006 }, /* R1 - Power Management (1) */ + { 2, 0x6000 }, /* R2 - Power Management (2) */ + { 3, 0x0000 }, /* R3 - Power Management (3) */ + { 6, 0x01C0 }, /* R6 - Clocking 1 */ + { 22, 0x0003 }, /* R22 - IN1 Line Control */ + { 23, 0x0003 }, /* R23 - IN2 Line Control */ + { 24, 0x0083 }, /* R24 - IN1 Line Input A Volume */ + { 25, 0x0083 }, /* R25 - IN1 Line Input B Volume */ + { 26, 0x0083 }, /* R26 - IN2 Line Input A Volume */ + { 27, 0x0083 }, /* R27 - IN2 Line Input B Volume */ + { 28, 0x002D }, /* R28 - Left Output Volume */ + { 29, 0x002D }, /* R29 - Right Output Volume */ + { 34, 0x0100 }, /* R34 - SPKMIXL Attenuation */ + { 35, 0x0010 }, /* R36 - SPKOUT Mixers */ + { 37, 0x0140 }, /* R37 - ClassD3 */ + { 38, 0x0039 }, /* R38 - Speaker Volume Left */ + { 45, 0x0000 }, /* R45 - Output Mixer1 */ + { 46, 0x0000 }, /* R46 - Output Mixer2 */ + { 47, 0x0100 }, /* R47 - Output Mixer3 */ + { 48, 0x0100 }, /* R48 - Output Mixer4 */ + { 54, 0x0000 }, /* R54 - Speaker Mixer */ + { 57, 0x000D }, /* R57 - AntiPOP2 */ + { 70, 0x0000 }, /* R70 - Write Sequencer 0 */ + { 71, 0x0000 }, /* R71 - Write Sequencer 1 */ + { 72, 0x0000 }, /* R72 - Write Sequencer 2 */ + { 73, 0x0000 }, /* R73 - Write Sequencer 3 */ + { 74, 0x0000 }, /* R74 - Write Sequencer 4 */ + { 75, 0x0000 }, /* R75 - Write Sequencer 5 */ + { 76, 0x1F25 }, /* R76 - Charge Pump 1 */ + { 85, 0x054A }, /* R85 - DC Servo 1 */ + { 87, 0x0000 }, /* R87 - DC Servo 3 */ + { 96, 0x0100 }, /* R96 - Analogue HP 0 */ + { 98, 0x8640 }, /* R98 - AGC Control 0 */ + { 99, 0xC000 }, /* R99 - AGC Control 1 */ + { 100, 0x0200 }, /* R100 - AGC Control 2 */ }; /* This struct is used to save the context */ struct wm9090_priv { struct wm9090_platform_data pdata; + struct regmap *regmap; }; -static int wm9090_volatile(struct snd_soc_codec *codec, unsigned int reg) +static bool wm9090_volatile(struct device *dev, unsigned int reg) { switch (reg) { case WM9090_SOFTWARE_RESET: @@ -150,10 +86,60 @@ static int wm9090_volatile(struct snd_soc_codec *codec, unsigned int reg) case WM9090_DC_SERVO_READBACK_0: case WM9090_DC_SERVO_READBACK_1: case WM9090_DC_SERVO_READBACK_2: - return 1; + return true; default: - return 0; + return false; + } +} + +static bool wm9090_readable(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WM9090_SOFTWARE_RESET: + case WM9090_POWER_MANAGEMENT_1: + case WM9090_POWER_MANAGEMENT_2: + case WM9090_POWER_MANAGEMENT_3: + case WM9090_CLOCKING_1: + case WM9090_IN1_LINE_CONTROL: + case WM9090_IN2_LINE_CONTROL: + case WM9090_IN1_LINE_INPUT_A_VOLUME: + case WM9090_IN1_LINE_INPUT_B_VOLUME: + case WM9090_IN2_LINE_INPUT_A_VOLUME: + case WM9090_IN2_LINE_INPUT_B_VOLUME: + case WM9090_LEFT_OUTPUT_VOLUME: + case WM9090_RIGHT_OUTPUT_VOLUME: + case WM9090_SPKMIXL_ATTENUATION: + case WM9090_SPKOUT_MIXERS: + case WM9090_CLASSD3: + case WM9090_SPEAKER_VOLUME_LEFT: + case WM9090_OUTPUT_MIXER1: + case WM9090_OUTPUT_MIXER2: + case WM9090_OUTPUT_MIXER3: + case WM9090_OUTPUT_MIXER4: + case WM9090_SPEAKER_MIXER: + case WM9090_ANTIPOP2: + case WM9090_WRITE_SEQUENCER_0: + case WM9090_WRITE_SEQUENCER_1: + case WM9090_WRITE_SEQUENCER_2: + case WM9090_WRITE_SEQUENCER_3: + case WM9090_WRITE_SEQUENCER_4: + case WM9090_WRITE_SEQUENCER_5: + case WM9090_CHARGE_PUMP_1: + case WM9090_DC_SERVO_0: + case WM9090_DC_SERVO_1: + case WM9090_DC_SERVO_3: + case WM9090_DC_SERVO_READBACK_0: + case WM9090_DC_SERVO_READBACK_1: + case WM9090_DC_SERVO_READBACK_2: + case WM9090_ANALOGUE_HP_0: + case WM9090_AGC_CONTROL_0: + case WM9090_AGC_CONTROL_1: + case WM9090_AGC_CONTROL_2: + return true; + + default: + return false; } } @@ -492,8 +478,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec) static int wm9090_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - u16 *reg_cache = codec->reg_cache; - int i, ret; + struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec); switch (level) { case SND_SOC_BIAS_ON: @@ -513,7 +498,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_STANDBY: if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Restore the register cache */ - snd_soc_cache_sync(codec); + regcache_sync(wm9090->regmap); } /* We keep VMID off during standby since the combination of @@ -537,9 +522,11 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec, static int wm9090_probe(struct snd_soc_codec *codec) { + struct wm9090_priv *wm9090 = dev_get_drvdata(codec->dev); int ret; - ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); + codec->control_data = wm9090->regmap; + ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); if (ret != 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; @@ -548,7 +535,7 @@ static int wm9090_probe(struct snd_soc_codec *codec) ret = snd_soc_read(codec, WM9090_SOFTWARE_RESET); if (ret < 0) return ret; - if (ret != wm9090_reg_defaults[WM9090_SOFTWARE_RESET]) { + if (ret != 0x9093) { dev_err(codec->dev, "Device is not a WM9090, ID=%x\n", ret); return -EINVAL; } @@ -624,12 +611,22 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9090 = { .suspend = wm9090_suspend, .resume = wm9090_resume, .set_bias_level = wm9090_set_bias_level, - .reg_cache_size = (WM9090_MAX_REGISTER + 1), - .reg_word_size = sizeof(u16), - .reg_cache_default = wm9090_reg_defaults, - .volatile_register = wm9090_volatile, }; +static const struct regmap_config wm9090_regmap = { + .reg_bits = 8, + .val_bits = 16, + + .max_register = WM9090_MAX_REGISTER, + .volatile_reg = wm9090_volatile, + .readable_reg = wm9090_readable, + + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wm9090_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm9090_reg_defaults), +}; + + static int wm9090_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -642,6 +639,13 @@ static int wm9090_i2c_probe(struct i2c_client *i2c, return -ENOMEM; } + wm9090->regmap = regmap_init_i2c(i2c, &wm9090_regmap); + if (IS_ERR(wm9090->regmap)) { + ret = PTR_ERR(wm9090->regmap); + dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); + return ret; + } + if (i2c->dev.platform_data) memcpy(&wm9090->pdata, i2c->dev.platform_data, sizeof(wm9090->pdata)); @@ -650,6 +654,15 @@ static int wm9090_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm9090, NULL, 0); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); + goto err; + } + + return 0; + +err: + regmap_exit(wm9090->regmap); return ret; } @@ -658,6 +671,7 @@ static int __devexit wm9090_i2c_remove(struct i2c_client *i2c) struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c); snd_soc_unregister_codec(&i2c->dev); + regmap_exit(wm9090->regmap); return 0; } -- cgit v0.10.2 From 391d9e4e5ce50bf14400ed04d13821e7b56e84f7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 Dec 2011 21:43:01 +0800 Subject: ASoC: Move WM9090 device identification and reset to I2C probe Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index 4be5551..a2b9208 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c @@ -532,18 +532,6 @@ static int wm9090_probe(struct snd_soc_codec *codec) return ret; } - ret = snd_soc_read(codec, WM9090_SOFTWARE_RESET); - if (ret < 0) - return ret; - if (ret != 0x9093) { - dev_err(codec->dev, "Device is not a WM9090, ID=%x\n", ret); - return -EINVAL; - } - - ret = snd_soc_write(codec, WM9090_SOFTWARE_RESET, 0); - if (ret < 0) - return ret; - /* Configure some defaults; they will be written out when we * bring the bias up. */ @@ -631,6 +619,7 @@ static int wm9090_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct wm9090_priv *wm9090; + unsigned int reg; int ret; wm9090 = devm_kzalloc(&i2c->dev, sizeof(*wm9090), GFP_KERNEL); @@ -646,6 +635,19 @@ static int wm9090_i2c_probe(struct i2c_client *i2c, return ret; } + ret = regmap_read(wm9090->regmap, WM9090_SOFTWARE_RESET, ®); + if (ret < 0) + goto err; + if (reg != 0x9093) { + dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", ret); + ret = -ENODEV; + goto err; + } + + ret = regmap_write(wm9090->regmap, WM9090_SOFTWARE_RESET, 0); + if (ret < 0) + goto err; + if (i2c->dev.platform_data) memcpy(&wm9090->pdata, i2c->dev.platform_data, sizeof(wm9090->pdata)); -- cgit v0.10.2 From d0ad0af0432f7b4fe439a6a46e7a31f8dd5d3d55 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 14 Dec 2011 11:53:06 +0800 Subject: ASoC: Convert wm8993 to direct regmap API usage Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 7c7fd92..5321302 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -40,134 +41,112 @@ static const char *wm8993_supply_names[WM8993_NUM_SUPPLIES] = { "SPKVDD", }; -static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = { - 0x8993, /* R0 - Software Reset */ - 0x0000, /* R1 - Power Management (1) */ - 0x6000, /* R2 - Power Management (2) */ - 0x0000, /* R3 - Power Management (3) */ - 0x4050, /* R4 - Audio Interface (1) */ - 0x4000, /* R5 - Audio Interface (2) */ - 0x01C8, /* R6 - Clocking 1 */ - 0x0000, /* R7 - Clocking 2 */ - 0x0000, /* R8 - Audio Interface (3) */ - 0x0040, /* R9 - Audio Interface (4) */ - 0x0004, /* R10 - DAC CTRL */ - 0x00C0, /* R11 - Left DAC Digital Volume */ - 0x00C0, /* R12 - Right DAC Digital Volume */ - 0x0000, /* R13 - Digital Side Tone */ - 0x0300, /* R14 - ADC CTRL */ - 0x00C0, /* R15 - Left ADC Digital Volume */ - 0x00C0, /* R16 - Right ADC Digital Volume */ - 0x0000, /* R17 */ - 0x0000, /* R18 - GPIO CTRL 1 */ - 0x0010, /* R19 - GPIO1 */ - 0x0000, /* R20 - IRQ_DEBOUNCE */ - 0x0000, /* R21 */ - 0x8000, /* R22 - GPIOCTRL 2 */ - 0x0800, /* R23 - GPIO_POL */ - 0x008B, /* R24 - Left Line Input 1&2 Volume */ - 0x008B, /* R25 - Left Line Input 3&4 Volume */ - 0x008B, /* R26 - Right Line Input 1&2 Volume */ - 0x008B, /* R27 - Right Line Input 3&4 Volume */ - 0x006D, /* R28 - Left Output Volume */ - 0x006D, /* R29 - Right Output Volume */ - 0x0066, /* R30 - Line Outputs Volume */ - 0x0020, /* R31 - HPOUT2 Volume */ - 0x0079, /* R32 - Left OPGA Volume */ - 0x0079, /* R33 - Right OPGA Volume */ - 0x0003, /* R34 - SPKMIXL Attenuation */ - 0x0003, /* R35 - SPKMIXR Attenuation */ - 0x0011, /* R36 - SPKOUT Mixers */ - 0x0100, /* R37 - SPKOUT Boost */ - 0x0079, /* R38 - Speaker Volume Left */ - 0x0079, /* R39 - Speaker Volume Right */ - 0x0000, /* R40 - Input Mixer2 */ - 0x0000, /* R41 - Input Mixer3 */ - 0x0000, /* R42 - Input Mixer4 */ - 0x0000, /* R43 - Input Mixer5 */ - 0x0000, /* R44 - Input Mixer6 */ - 0x0000, /* R45 - Output Mixer1 */ - 0x0000, /* R46 - Output Mixer2 */ - 0x0000, /* R47 - Output Mixer3 */ - 0x0000, /* R48 - Output Mixer4 */ - 0x0000, /* R49 - Output Mixer5 */ - 0x0000, /* R50 - Output Mixer6 */ - 0x0000, /* R51 - HPOUT2 Mixer */ - 0x0000, /* R52 - Line Mixer1 */ - 0x0000, /* R53 - Line Mixer2 */ - 0x0000, /* R54 - Speaker Mixer */ - 0x0000, /* R55 - Additional Control */ - 0x0000, /* R56 - AntiPOP1 */ - 0x0000, /* R57 - AntiPOP2 */ - 0x0000, /* R58 - MICBIAS */ - 0x0000, /* R59 */ - 0x0000, /* R60 - FLL Control 1 */ - 0x0000, /* R61 - FLL Control 2 */ - 0x0000, /* R62 - FLL Control 3 */ - 0x2EE0, /* R63 - FLL Control 4 */ - 0x0002, /* R64 - FLL Control 5 */ - 0x2287, /* R65 - Clocking 3 */ - 0x025F, /* R66 - Clocking 4 */ - 0x0000, /* R67 - MW Slave Control */ - 0x0000, /* R68 */ - 0x0002, /* R69 - Bus Control 1 */ - 0x0000, /* R70 - Write Sequencer 0 */ - 0x0000, /* R71 - Write Sequencer 1 */ - 0x0000, /* R72 - Write Sequencer 2 */ - 0x0000, /* R73 - Write Sequencer 3 */ - 0x0000, /* R74 - Write Sequencer 4 */ - 0x0000, /* R75 - Write Sequencer 5 */ - 0x1F25, /* R76 - Charge Pump 1 */ - 0x0000, /* R77 */ - 0x0000, /* R78 */ - 0x0000, /* R79 */ - 0x0000, /* R80 */ - 0x0000, /* R81 - Class W 0 */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 - DC Servo 0 */ - 0x054A, /* R85 - DC Servo 1 */ - 0x0000, /* R86 */ - 0x0000, /* R87 - DC Servo 3 */ - 0x0000, /* R88 - DC Servo Readback 0 */ - 0x0000, /* R89 - DC Servo Readback 1 */ - 0x0000, /* R90 - DC Servo Readback 2 */ - 0x0000, /* R91 */ - 0x0000, /* R92 */ - 0x0000, /* R93 */ - 0x0000, /* R94 */ - 0x0000, /* R95 */ - 0x0100, /* R96 - Analogue HP 0 */ - 0x0000, /* R97 */ - 0x0000, /* R98 - EQ1 */ - 0x000C, /* R99 - EQ2 */ - 0x000C, /* R100 - EQ3 */ - 0x000C, /* R101 - EQ4 */ - 0x000C, /* R102 - EQ5 */ - 0x000C, /* R103 - EQ6 */ - 0x0FCA, /* R104 - EQ7 */ - 0x0400, /* R105 - EQ8 */ - 0x00D8, /* R106 - EQ9 */ - 0x1EB5, /* R107 - EQ10 */ - 0xF145, /* R108 - EQ11 */ - 0x0B75, /* R109 - EQ12 */ - 0x01C5, /* R110 - EQ13 */ - 0x1C58, /* R111 - EQ14 */ - 0xF373, /* R112 - EQ15 */ - 0x0A54, /* R113 - EQ16 */ - 0x0558, /* R114 - EQ17 */ - 0x168E, /* R115 - EQ18 */ - 0xF829, /* R116 - EQ19 */ - 0x07AD, /* R117 - EQ20 */ - 0x1103, /* R118 - EQ21 */ - 0x0564, /* R119 - EQ22 */ - 0x0559, /* R120 - EQ23 */ - 0x4000, /* R121 - EQ24 */ - 0x0000, /* R122 - Digital Pulls */ - 0x0F08, /* R123 - DRC Control 1 */ - 0x0000, /* R124 - DRC Control 2 */ - 0x0080, /* R125 - DRC Control 3 */ - 0x0000, /* R126 - DRC Control 4 */ +static struct reg_default wm8993_reg_defaults[] = { + { 1, 0x0000 }, /* R1 - Power Management (1) */ + { 2, 0x6000 }, /* R2 - Power Management (2) */ + { 3, 0x0000 }, /* R3 - Power Management (3) */ + { 4, 0x4050 }, /* R4 - Audio Interface (1) */ + { 5, 0x4000 }, /* R5 - Audio Interface (2) */ + { 6, 0x01C8 }, /* R6 - Clocking 1 */ + { 7, 0x0000 }, /* R7 - Clocking 2 */ + { 8, 0x0000 }, /* R8 - Audio Interface (3) */ + { 9, 0x0040 }, /* R9 - Audio Interface (4) */ + { 10, 0x0004 }, /* R10 - DAC CTRL */ + { 11, 0x00C0 }, /* R11 - Left DAC Digital Volume */ + { 12, 0x00C0 }, /* R12 - Right DAC Digital Volume */ + { 13, 0x0000 }, /* R13 - Digital Side Tone */ + { 14, 0x0300 }, /* R14 - ADC CTRL */ + { 15, 0x00C0 }, /* R15 - Left ADC Digital Volume */ + { 16, 0x00C0 }, /* R16 - Right ADC Digital Volume */ + { 18, 0x0000 }, /* R18 - GPIO CTRL 1 */ + { 19, 0x0010 }, /* R19 - GPIO1 */ + { 20, 0x0000 }, /* R20 - IRQ_DEBOUNCE */ + { 21, 0x8000 }, /* R22 - GPIOCTRL 2 */ + { 22, 0x0800 }, /* R23 - GPIO_POL */ + { 24, 0x008B }, /* R24 - Left Line Input 1&2 Volume */ + { 25, 0x008B }, /* R25 - Left Line Input 3&4 Volume */ + { 26, 0x008B }, /* R26 - Right Line Input 1&2 Volume */ + { 27, 0x008B }, /* R27 - Right Line Input 3&4 Volume */ + { 28, 0x006D }, /* R28 - Left Output Volume */ + { 29, 0x006D }, /* R29 - Right Output Volume */ + { 30, 0x0066 }, /* R30 - Line Outputs Volume */ + { 31, 0x0020 }, /* R31 - HPOUT2 Volume */ + { 32, 0x0079 }, /* R32 - Left OPGA Volume */ + { 33, 0x0079 }, /* R33 - Right OPGA Volume */ + { 34, 0x0003 }, /* R34 - SPKMIXL Attenuation */ + { 35, 0x0003 }, /* R35 - SPKMIXR Attenuation */ + { 36, 0x0011 }, /* R36 - SPKOUT Mixers */ + { 37, 0x0100 }, /* R37 - SPKOUT Boost */ + { 38, 0x0079 }, /* R38 - Speaker Volume Left */ + { 39, 0x0079 }, /* R39 - Speaker Volume Right */ + { 40, 0x0000 }, /* R40 - Input Mixer2 */ + { 41, 0x0000 }, /* R41 - Input Mixer3 */ + { 42, 0x0000 }, /* R42 - Input Mixer4 */ + { 43, 0x0000 }, /* R43 - Input Mixer5 */ + { 44, 0x0000 }, /* R44 - Input Mixer6 */ + { 45, 0x0000 }, /* R45 - Output Mixer1 */ + { 46, 0x0000 }, /* R46 - Output Mixer2 */ + { 47, 0x0000 }, /* R47 - Output Mixer3 */ + { 48, 0x0000 }, /* R48 - Output Mixer4 */ + { 49, 0x0000 }, /* R49 - Output Mixer5 */ + { 50, 0x0000 }, /* R50 - Output Mixer6 */ + { 51, 0x0000 }, /* R51 - HPOUT2 Mixer */ + { 52, 0x0000 }, /* R52 - Line Mixer1 */ + { 53, 0x0000 }, /* R53 - Line Mixer2 */ + { 54, 0x0000 }, /* R54 - Speaker Mixer */ + { 55, 0x0000 }, /* R55 - Additional Control */ + { 56, 0x0000 }, /* R56 - AntiPOP1 */ + { 57, 0x0000 }, /* R57 - AntiPOP2 */ + { 58, 0x0000 }, /* R58 - MICBIAS */ + { 60, 0x0000 }, /* R60 - FLL Control 1 */ + { 61, 0x0000 }, /* R61 - FLL Control 2 */ + { 62, 0x0000 }, /* R62 - FLL Control 3 */ + { 63, 0x2EE0 }, /* R63 - FLL Control 4 */ + { 64, 0x0002 }, /* R64 - FLL Control 5 */ + { 65, 0x2287 }, /* R65 - Clocking 3 */ + { 66, 0x025F }, /* R66 - Clocking 4 */ + { 67, 0x0000 }, /* R67 - MW Slave Control */ + { 69, 0x0002 }, /* R69 - Bus Control 1 */ + { 70, 0x0000 }, /* R70 - Write Sequencer 0 */ + { 71, 0x0000 }, /* R71 - Write Sequencer 1 */ + { 72, 0x0000 }, /* R72 - Write Sequencer 2 */ + { 73, 0x0000 }, /* R73 - Write Sequencer 3 */ + { 74, 0x0000 }, /* R74 - Write Sequencer 4 */ + { 75, 0x0000 }, /* R75 - Write Sequencer 5 */ + { 76, 0x1F25 }, /* R76 - Charge Pump 1 */ + { 81, 0x0000 }, /* R81 - Class W 0 */ + { 85, 0x054A }, /* R85 - DC Servo 1 */ + { 87, 0x0000 }, /* R87 - DC Servo 3 */ + { 96, 0x0100 }, /* R96 - Analogue HP 0 */ + { 98, 0x0000 }, /* R98 - EQ1 */ + { 99, 0x000C }, /* R99 - EQ2 */ + { 100, 0x000C }, /* R100 - EQ3 */ + { 101, 0x000C }, /* R101 - EQ4 */ + { 102, 0x000C }, /* R102 - EQ5 */ + { 103, 0x000C }, /* R103 - EQ6 */ + { 104, 0x0FCA }, /* R104 - EQ7 */ + { 105, 0x0400 }, /* R105 - EQ8 */ + { 106, 0x00D8 }, /* R106 - EQ9 */ + { 107, 0x1EB5 }, /* R107 - EQ10 */ + { 108, 0xF145 }, /* R108 - EQ11 */ + { 109, 0x0B75 }, /* R109 - EQ12 */ + { 110, 0x01C5 }, /* R110 - EQ13 */ + { 111, 0x1C58 }, /* R111 - EQ14 */ + { 112, 0xF373 }, /* R112 - EQ15 */ + { 113, 0x0A54 }, /* R113 - EQ16 */ + { 114, 0x0558 }, /* R114 - EQ17 */ + { 115, 0x168E }, /* R115 - EQ18 */ + { 116, 0xF829 }, /* R116 - EQ19 */ + { 117, 0x07AD }, /* R117 - EQ20 */ + { 118, 0x1103 }, /* R118 - EQ21 */ + { 119, 0x0564 }, /* R119 - EQ22 */ + { 120, 0x0559 }, /* R120 - EQ23 */ + { 121, 0x4000 }, /* R121 - EQ24 */ + { 122, 0x0000 }, /* R122 - Digital Pulls */ + { 123, 0x0F08 }, /* R123 - DRC Control 1 */ + { 124, 0x0000 }, /* R124 - DRC Control 2 */ + { 125, 0x0080 }, /* R125 - DRC Control 3 */ + { 126, 0x0000 }, /* R126 - DRC Control 4 */ }; static struct { @@ -225,9 +204,9 @@ static struct { struct wm8993_priv { struct wm_hubs_data hubs_data; + struct regmap *regmap; struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES]; struct wm8993_platform_data pdata; - enum snd_soc_control_type control_type; int master; int sysclk_source; int tdm_slots; @@ -242,7 +221,7 @@ struct wm8993_priv { int fll_src; }; -static int wm8993_volatile(struct snd_soc_codec *codec, unsigned int reg) +static bool wm8993_volatile(struct device *dev, unsigned int reg) { switch (reg) { case WM8993_SOFTWARE_RESET: @@ -250,9 +229,128 @@ static int wm8993_volatile(struct snd_soc_codec *codec, unsigned int reg) case WM8993_DC_SERVO_READBACK_0: case WM8993_DC_SERVO_READBACK_1: case WM8993_DC_SERVO_READBACK_2: - return 1; + return true; default: - return 0; + return false; + } +} + +static bool wm8993_readable(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WM8993_SOFTWARE_RESET: + case WM8993_POWER_MANAGEMENT_1: + case WM8993_POWER_MANAGEMENT_2: + case WM8993_POWER_MANAGEMENT_3: + case WM8993_AUDIO_INTERFACE_1: + case WM8993_AUDIO_INTERFACE_2: + case WM8993_CLOCKING_1: + case WM8993_CLOCKING_2: + case WM8993_AUDIO_INTERFACE_3: + case WM8993_AUDIO_INTERFACE_4: + case WM8993_DAC_CTRL: + case WM8993_LEFT_DAC_DIGITAL_VOLUME: + case WM8993_RIGHT_DAC_DIGITAL_VOLUME: + case WM8993_DIGITAL_SIDE_TONE: + case WM8993_ADC_CTRL: + case WM8993_LEFT_ADC_DIGITAL_VOLUME: + case WM8993_RIGHT_ADC_DIGITAL_VOLUME: + case WM8993_GPIO_CTRL_1: + case WM8993_GPIO1: + case WM8993_IRQ_DEBOUNCE: + case WM8993_GPIOCTRL_2: + case WM8993_GPIO_POL: + case WM8993_LEFT_LINE_INPUT_1_2_VOLUME: + case WM8993_LEFT_LINE_INPUT_3_4_VOLUME: + case WM8993_RIGHT_LINE_INPUT_1_2_VOLUME: + case WM8993_RIGHT_LINE_INPUT_3_4_VOLUME: + case WM8993_LEFT_OUTPUT_VOLUME: + case WM8993_RIGHT_OUTPUT_VOLUME: + case WM8993_LINE_OUTPUTS_VOLUME: + case WM8993_HPOUT2_VOLUME: + case WM8993_LEFT_OPGA_VOLUME: + case WM8993_RIGHT_OPGA_VOLUME: + case WM8993_SPKMIXL_ATTENUATION: + case WM8993_SPKMIXR_ATTENUATION: + case WM8993_SPKOUT_MIXERS: + case WM8993_SPKOUT_BOOST: + case WM8993_SPEAKER_VOLUME_LEFT: + case WM8993_SPEAKER_VOLUME_RIGHT: + case WM8993_INPUT_MIXER2: + case WM8993_INPUT_MIXER3: + case WM8993_INPUT_MIXER4: + case WM8993_INPUT_MIXER5: + case WM8993_INPUT_MIXER6: + case WM8993_OUTPUT_MIXER1: + case WM8993_OUTPUT_MIXER2: + case WM8993_OUTPUT_MIXER3: + case WM8993_OUTPUT_MIXER4: + case WM8993_OUTPUT_MIXER5: + case WM8993_OUTPUT_MIXER6: + case WM8993_HPOUT2_MIXER: + case WM8993_LINE_MIXER1: + case WM8993_LINE_MIXER2: + case WM8993_SPEAKER_MIXER: + case WM8993_ADDITIONAL_CONTROL: + case WM8993_ANTIPOP1: + case WM8993_ANTIPOP2: + case WM8993_MICBIAS: + case WM8993_FLL_CONTROL_1: + case WM8993_FLL_CONTROL_2: + case WM8993_FLL_CONTROL_3: + case WM8993_FLL_CONTROL_4: + case WM8993_FLL_CONTROL_5: + case WM8993_CLOCKING_3: + case WM8993_CLOCKING_4: + case WM8993_MW_SLAVE_CONTROL: + case WM8993_BUS_CONTROL_1: + case WM8993_WRITE_SEQUENCER_0: + case WM8993_WRITE_SEQUENCER_1: + case WM8993_WRITE_SEQUENCER_2: + case WM8993_WRITE_SEQUENCER_3: + case WM8993_WRITE_SEQUENCER_4: + case WM8993_WRITE_SEQUENCER_5: + case WM8993_CHARGE_PUMP_1: + case WM8993_CLASS_W_0: + case WM8993_DC_SERVO_0: + case WM8993_DC_SERVO_1: + case WM8993_DC_SERVO_3: + case WM8993_DC_SERVO_READBACK_0: + case WM8993_DC_SERVO_READBACK_1: + case WM8993_DC_SERVO_READBACK_2: + case WM8993_ANALOGUE_HP_0: + case WM8993_EQ1: + case WM8993_EQ2: + case WM8993_EQ3: + case WM8993_EQ4: + case WM8993_EQ5: + case WM8993_EQ6: + case WM8993_EQ7: + case WM8993_EQ8: + case WM8993_EQ9: + case WM8993_EQ10: + case WM8993_EQ11: + case WM8993_EQ12: + case WM8993_EQ13: + case WM8993_EQ14: + case WM8993_EQ15: + case WM8993_EQ16: + case WM8993_EQ17: + case WM8993_EQ18: + case WM8993_EQ19: + case WM8993_EQ20: + case WM8993_EQ21: + case WM8993_EQ22: + case WM8993_EQ23: + case WM8993_EQ24: + case WM8993_DIGITAL_PULLS: + case WM8993_DRC_CONTROL_1: + case WM8993_DRC_CONTROL_2: + case WM8993_DRC_CONTROL_3: + case WM8993_DRC_CONTROL_4: + return true; + default: + return false; } } @@ -963,7 +1061,8 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, if (ret != 0) return ret; - snd_soc_cache_sync(codec); + regcache_cache_only(wm8993->regmap, false); + regcache_sync(wm8993->regmap); /* Tune DC servo configuration */ snd_soc_write(codec, 0x44, 3); @@ -1024,14 +1123,8 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, WM8993_VMID_RAMP_MASK | WM8993_BIAS_SRC, 0); -#ifdef CONFIG_REGULATOR - /* Post 2.6.34 we will be able to get a callback when - * the regulators are disabled which we can use but - * for now just assume that the power will be cut if - * the regulator API is in use. - */ - codec->cache_sync = 1; -#endif + regcache_cache_only(wm8993->regmap, true); + regcache_mark_dirty(wm8993->regmap); regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); @@ -1425,7 +1518,8 @@ static int wm8993_probe(struct snd_soc_codec *codec) wm8993->hubs_data.dcs_codes_r = -2; wm8993->hubs_data.series_startup = 1; - ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); + codec->control_data = wm8993->regmap; + ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); if (ret != 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; @@ -1449,7 +1543,7 @@ static int wm8993_probe(struct snd_soc_codec *codec) } val = snd_soc_read(codec, WM8993_SOFTWARE_RESET); - if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) { + if (val != 0x8993) { dev_err(codec->dev, "Invalid ID register value %x\n", val); ret = -EINVAL; goto err_enable; @@ -1459,7 +1553,7 @@ static int wm8993_probe(struct snd_soc_codec *codec) if (ret != 0) goto err_enable; - codec->cache_only = 1; + regcache_cache_only(wm8993->regmap, true); /* By default we're using the output mixers */ wm8993->class_w_users = 2; @@ -1578,16 +1672,25 @@ static int wm8993_resume(struct snd_soc_codec *codec) #define wm8993_resume NULL #endif +static const struct regmap_config wm8993_regmap = { + .reg_bits = 8, + .val_bits = 16, + + .max_register = WM8993_MAX_REGISTER, + .volatile_reg = wm8993_volatile, + .readable_reg = wm8993_readable, + + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wm8993_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8993_reg_defaults), +}; + static struct snd_soc_codec_driver soc_codec_dev_wm8993 = { .probe = wm8993_probe, .remove = wm8993_remove, .suspend = wm8993_suspend, .resume = wm8993_resume, .set_bias_level = wm8993_set_bias_level, - .reg_cache_size = ARRAY_SIZE(wm8993_reg_defaults), - .reg_word_size = sizeof(u16), - .reg_cache_default = wm8993_reg_defaults, - .volatile_register = wm8993_volatile, }; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) @@ -1602,17 +1705,36 @@ static __devinit int wm8993_i2c_probe(struct i2c_client *i2c, if (wm8993 == NULL) return -ENOMEM; + wm8993->regmap = regmap_init_i2c(i2c, &wm8993_regmap); + if (IS_ERR(wm8993->regmap)) { + ret = PTR_ERR(wm8993->regmap); + dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); + return ret; + } + i2c_set_clientdata(i2c, wm8993); ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8993, &wm8993_dai, 1); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); + goto err; + } + + return ret; + +err: + regmap_exit(wm8993->regmap); return ret; } static __devexit int wm8993_i2c_remove(struct i2c_client *client) { + struct wm8993_priv *wm8993 = i2c_get_clientdata(client); + snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); + regmap_exit(wm8993->regmap); + return 0; } -- cgit v0.10.2 From bfea3abb804f5ab97c5da3da7c6386664531d698 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 14 Dec 2011 12:31:14 +0800 Subject: ASoC: Move WM8993 resource acquisition and device reset to bus probe Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 5321302..e7ae9fd 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -1511,7 +1511,7 @@ static int wm8993_probe(struct snd_soc_codec *codec) { struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); struct snd_soc_dapm_context *dapm = &codec->dapm; - int ret, i, val; + int ret; wm8993->hubs_data.hp_startup_mode = 1; wm8993->hubs_data.dcs_codes_l = -2; @@ -1525,36 +1525,6 @@ static int wm8993_probe(struct snd_soc_codec *codec) return ret; } - for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++) - wm8993->supplies[i].supply = wm8993_supply_names[i]; - - ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8993->supplies), - wm8993->supplies); - if (ret != 0) { - dev_err(codec->dev, "Failed to request supplies: %d\n", ret); - return ret; - } - - ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), - wm8993->supplies); - if (ret != 0) { - dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); - goto err_get; - } - - val = snd_soc_read(codec, WM8993_SOFTWARE_RESET); - if (val != 0x8993) { - dev_err(codec->dev, "Invalid ID register value %x\n", val); - ret = -EINVAL; - goto err_enable; - } - - ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff); - if (ret != 0) - goto err_enable; - - regcache_cache_only(wm8993->regmap, true); - /* By default we're using the output mixers */ wm8993->class_w_users = 2; @@ -1583,7 +1553,7 @@ static int wm8993_probe(struct snd_soc_codec *codec) ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); if (ret != 0) - goto err_enable; + return ret; snd_soc_add_controls(codec, wm8993_snd_controls, ARRAY_SIZE(wm8993_snd_controls)); @@ -1605,11 +1575,6 @@ static int wm8993_probe(struct snd_soc_codec *codec) return 0; -err_enable: - regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); -err_get: - regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); - return ret; } static int wm8993_remove(struct snd_soc_codec *codec) @@ -1698,7 +1663,8 @@ static __devinit int wm8993_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct wm8993_priv *wm8993; - int ret; + unsigned int reg; + int ret, i; wm8993 = devm_kzalloc(&i2c->dev, sizeof(struct wm8993_priv), GFP_KERNEL); @@ -1714,15 +1680,56 @@ static __devinit int wm8993_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, wm8993); + for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++) + wm8993->supplies[i].supply = wm8993_supply_names[i]; + + ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8993->supplies), + wm8993->supplies); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); + goto err; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), + wm8993->supplies); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); + goto err_get; + } + + ret = regmap_read(wm8993->regmap, WM8993_SOFTWARE_RESET, ®); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); + goto err_enable; + } + + if (reg != 0x8993) { + dev_err(&i2c->dev, "Invalid ID register value %x\n", reg); + ret = -EINVAL; + goto err_enable; + } + + ret = regmap_write(wm8993->regmap, WM8993_SOFTWARE_RESET, 0xffff); + if (ret != 0) + goto err_enable; + + regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); + + regcache_cache_only(wm8993->regmap, true); + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8993, &wm8993_dai, 1); if (ret != 0) { dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); - goto err; + goto err_enable; } - return ret; + return 0; +err_enable: + regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); +err_get: + regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); err: regmap_exit(wm8993->regmap); return ret; @@ -1734,6 +1741,8 @@ static __devexit int wm8993_i2c_remove(struct i2c_client *client) snd_soc_unregister_codec(&client->dev); regmap_exit(wm8993->regmap); + regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); + regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); return 0; } -- cgit v0.10.2 From d3398ff05907167f463e119421b053ce043741d1 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 21 Nov 2011 16:32:03 +0000 Subject: ASoC: Convert WM8753 to direct regmap API usage Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index b114c19..21ed75d 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -65,28 +66,86 @@ static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec, * We can't read the WM8753 register space when we * are using 2 wire for device control, so we cache them instead. */ -static const u16 wm8753_reg[] = { - 0x0000, 0x0008, 0x0000, 0x000a, - 0x000a, 0x0033, 0x0000, 0x0007, - 0x00ff, 0x00ff, 0x000f, 0x000f, - 0x007b, 0x0000, 0x0032, 0x0000, - 0x00c3, 0x00c3, 0x00c0, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, - 0x0055, 0x0005, 0x0050, 0x0055, - 0x0050, 0x0055, 0x0050, 0x0055, - 0x0079, 0x0079, 0x0079, 0x0079, - 0x0079, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0097, 0x0097, 0x0000, - 0x0004, 0x0000, 0x0083, 0x0024, - 0x01ba, 0x0000, 0x0083, 0x0024, - 0x01ba, 0x0000, 0x0000, 0x0000 +static const struct reg_default wm8753_reg_defaults[] = { + { 0x00, 0x0000 }, + { 0x01, 0x0008 }, + { 0x02, 0x0000 }, + { 0x03, 0x000a }, + { 0x04, 0x000a }, + { 0x05, 0x0033 }, + { 0x06, 0x0000 }, + { 0x07, 0x0007 }, + { 0x08, 0x00ff }, + { 0x09, 0x00ff }, + { 0x0a, 0x000f }, + { 0x0b, 0x000f }, + { 0x0c, 0x007b }, + { 0x0d, 0x0000 }, + { 0x0e, 0x0032 }, + { 0x0f, 0x0000 }, + { 0x10, 0x00c3 }, + { 0x11, 0x00c3 }, + { 0x12, 0x00c0 }, + { 0x13, 0x0000 }, + { 0x14, 0x0000 }, + { 0x15, 0x0000 }, + { 0x16, 0x0000 }, + { 0x17, 0x0000 }, + { 0x18, 0x0000 }, + { 0x19, 0x0000 }, + { 0x1a, 0x0000 }, + { 0x1b, 0x0000 }, + { 0x1c, 0x0000 }, + { 0x1d, 0x0000 }, + { 0x1e, 0x0000 }, + { 0x1f, 0x0000 }, + { 0x20, 0x0055 }, + { 0x21, 0x0005 }, + { 0x22, 0x0050 }, + { 0x23, 0x0055 }, + { 0x24, 0x0050 }, + { 0x25, 0x0055 }, + { 0x26, 0x0050 }, + { 0x27, 0x0055 }, + { 0x28, 0x0079 }, + { 0x29, 0x0079 }, + { 0x2a, 0x0079 }, + { 0x2b, 0x0079 }, + { 0x2c, 0x0079 }, + { 0x2d, 0x0000 }, + { 0x2e, 0x0000 }, + { 0x2f, 0x0000 }, + { 0x30, 0x0000 }, + { 0x31, 0x0097 }, + { 0x32, 0x0097 }, + { 0x33, 0x0000 }, + { 0x34, 0x0004 }, + { 0x35, 0x0000 }, + { 0x36, 0x0083 }, + { 0x37, 0x0024 }, + { 0x38, 0x01ba }, + { 0x39, 0x0000 }, + { 0x3a, 0x0083 }, + { 0x3b, 0x0024 }, + { 0x3c, 0x01ba }, + { 0x3d, 0x0000 }, + { 0x3e, 0x0000 }, + { 0x3f, 0x0000 }, }; +static bool wm8753_volatile(struct device *dev, unsigned int reg) +{ + return reg == WM8753_RESET; +} + +static bool wm8753_writeable(struct device *dev, unsigned int reg) +{ + return reg <= WM8753_ADCTL2; +} + /* codec private data */ struct wm8753_priv { - enum snd_soc_control_type control_type; + struct regmap *regmap; unsigned int sysclk; unsigned int pcmclk; @@ -1383,25 +1442,15 @@ static void wm8753_work(struct work_struct *work) static int wm8753_suspend(struct snd_soc_codec *codec) { wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); + codec->cache_sync = 1; return 0; } static int wm8753_resume(struct snd_soc_codec *codec) { - u16 *reg_cache = codec->reg_cache; - int i; - - /* Sync reg_cache with the hardware */ - for (i = 1; i < ARRAY_SIZE(wm8753_reg); i++) { - if (i == WM8753_RESET) - continue; - - /* No point in writing hardware default values back */ - if (reg_cache[i] == wm8753_reg[i]) - continue; + struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); - snd_soc_write(codec, i, reg_cache[i]); - } + regcache_sync(wm8753->regmap); wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY); @@ -1423,7 +1472,8 @@ static int wm8753_probe(struct snd_soc_codec *codec) INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work); - ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8753->control_type); + codec->control_data = wm8753->regmap; + ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); if (ret < 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; @@ -1473,9 +1523,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8753 = { .suspend = wm8753_suspend, .resume = wm8753_resume, .set_bias_level = wm8753_set_bias_level, - .reg_cache_size = ARRAY_SIZE(wm8753_reg), - .reg_word_size = sizeof(u16), - .reg_cache_default = wm8753_reg, .controls = wm8753_snd_controls, .num_controls = ARRAY_SIZE(wm8753_snd_controls), @@ -1491,6 +1538,19 @@ static const struct of_device_id wm8753_of_match[] = { }; MODULE_DEVICE_TABLE(of, wm8753_of_match); +static const struct regmap_config wm8753_regmap = { + .reg_bits = 7, + .val_bits = 9, + + .max_register = WM8753_ADCTL2, + .writeable_reg = wm8753_writeable, + .volatile_reg = wm8753_volatile, + + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wm8753_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8753_reg_defaults), +}; + #if defined(CONFIG_SPI_MASTER) static int __devinit wm8753_spi_probe(struct spi_device *spi) { @@ -1501,20 +1561,36 @@ static int __devinit wm8753_spi_probe(struct spi_device *spi) if (wm8753 == NULL) return -ENOMEM; - wm8753->control_type = SND_SOC_SPI; spi_set_drvdata(spi, wm8753); - ret = snd_soc_register_codec(&spi->dev, - &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai)); - if (ret < 0) - kfree(wm8753); + wm8753->regmap = regmap_init_spi(spi, &wm8753_regmap); + if (IS_ERR(wm8753->regmap)) { + ret = PTR_ERR(wm8753->regmap); + dev_err(&spi->dev, "Failed to allocate register map: %d\n", + ret); + goto err; + } + + ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8753, + wm8753_dai, ARRAY_SIZE(wm8753_dai)); + if (ret != 0) { + dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret); + goto err_regmap; + } +err_regmap: + regmap_exit(wm8753->regmap); +err: + kfree(wm8753); return ret; } static int __devexit wm8753_spi_remove(struct spi_device *spi) { + struct wm8753_priv *wm8753 = spi_get_drvdata(spi); + snd_soc_unregister_codec(&spi->dev); - kfree(spi_get_drvdata(spi)); + regmap_exit(wm8753->regmap); + kfree(wm8753); return 0; } @@ -1541,19 +1617,35 @@ static __devinit int wm8753_i2c_probe(struct i2c_client *i2c, return -ENOMEM; i2c_set_clientdata(i2c, wm8753); - wm8753->control_type = SND_SOC_I2C; - ret = snd_soc_register_codec(&i2c->dev, - &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai)); - if (ret < 0) - kfree(wm8753); + wm8753->regmap = regmap_init_i2c(i2c, &wm8753_regmap); + if (IS_ERR(wm8753->regmap)) { + ret = PTR_ERR(wm8753->regmap); + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + ret); + goto err; + } + + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8753, + wm8753_dai, ARRAY_SIZE(wm8753_dai)); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); + goto err_regmap; + } +err_regmap: + regmap_exit(wm8753->regmap); +err: + kfree(wm8753); return ret; } static __devexit int wm8753_i2c_remove(struct i2c_client *client) { + struct wm8753_priv *wm8753 = i2c_get_clientdata(client); + snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); + regmap_exit(wm8753->regmap); + kfree(wm8753); return 0; } -- cgit v0.10.2 From 542cc361de509798b311999ada07ebf2bd5673cf Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 10:59:39 +0000 Subject: ASoC: Make WM8971 I2C usage unconditional The driver only supports I2C so no need to worry about SPI only systems. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index 4af8936..a1db150 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c @@ -688,7 +688,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8971 = { .reg_cache_default = wm8971_reg, }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static __devinit int wm8971_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -731,27 +730,22 @@ static struct i2c_driver wm8971_i2c_driver = { .remove = __devexit_p(wm8971_i2c_remove), .id_table = wm8971_i2c_id, }; -#endif static int __init wm8971_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&wm8971_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register WM8971 I2C driver: %d\n", ret); } -#endif return ret; } module_init(wm8971_modinit); static void __exit wm8971_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) i2c_del_driver(&wm8971_i2c_driver); -#endif } module_exit(wm8971_exit); -- cgit v0.10.2 From c4850644ceaeb4fb6be3bd3305afc995a0f46a6c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 11:03:08 +0000 Subject: ASoC: Convert wm8971 to table based DAPM and control init Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index a1db150..3a5d67c 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c @@ -252,7 +252,7 @@ static const struct snd_soc_dapm_widget wm8971_dapm_widgets[] = { SND_SOC_DAPM_INPUT("MIC"), }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route wm8971_dapm_routes[] = { /* left mixer */ {"Left Mixer", "Playback Switch", "Left DAC"}, {"Left Mixer", "Left Bypass Switch", "Left Line Mux"}, @@ -329,17 +329,6 @@ static const struct snd_soc_dapm_route audio_map[] = { {"Right ADC", NULL, "Right ADC Mux"}, }; -static int wm8971_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, wm8971_dapm_widgets, - ARRAY_SIZE(wm8971_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - - return 0; -} - struct _coeff_div { u32 mclk; u32 rate; @@ -659,10 +648,6 @@ static int wm8971_probe(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WM8971_LINVOL, 0x0100, 0x0100); snd_soc_update_bits(codec, WM8971_RINVOL, 0x0100, 0x0100); - snd_soc_add_controls(codec, wm8971_snd_controls, - ARRAY_SIZE(wm8971_snd_controls)); - wm8971_add_widgets(codec); - return ret; } @@ -686,6 +671,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8971 = { .reg_cache_size = ARRAY_SIZE(wm8971_reg), .reg_word_size = sizeof(u16), .reg_cache_default = wm8971_reg, + + .controls = wm8971_snd_controls, + .num_controls = ARRAY_SIZE(wm8971_snd_controls), + .dapm_widgets = wm8971_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8971_dapm_widgets), + .dapm_routes = wm8971_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8971_dapm_routes), }; static __devinit int wm8971_i2c_probe(struct i2c_client *i2c, -- cgit v0.10.2 From 028b0a0a92daa36bd9e0f6d01954fe67c969a095 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 11:04:04 +0000 Subject: ASoC: Convert wm8971 to devm_kzalloc() Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index 3a5d67c..28fe59e 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c @@ -686,7 +686,8 @@ static __devinit int wm8971_i2c_probe(struct i2c_client *i2c, struct wm8971_priv *wm8971; int ret; - wm8971 = kzalloc(sizeof(struct wm8971_priv), GFP_KERNEL); + wm8971 = devm_kzalloc(&i2c->dev, sizeof(struct wm8971_priv), + GFP_KERNEL); if (wm8971 == NULL) return -ENOMEM; @@ -695,15 +696,13 @@ static __devinit int wm8971_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8971, &wm8971_dai, 1); - if (ret < 0) - kfree(wm8971); + return ret; } static __devexit int wm8971_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } -- cgit v0.10.2 From 7a389651bd88f884b46ddcada78730d294ccf1eb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 11:08:21 +0000 Subject: ASoC: Make wm8974 I2C usage unconditional The driver only supports I2C at present. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index 4a6a7b5..80c264e 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -636,7 +636,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8974 = { .reg_cache_default = wm8974_reg, }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static __devinit int wm8974_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -678,27 +677,22 @@ static struct i2c_driver wm8974_i2c_driver = { .remove = __devexit_p(wm8974_i2c_remove), .id_table = wm8974_i2c_id, }; -#endif static int __init wm8974_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&wm8974_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register wm8974 I2C driver: %d\n", ret); } -#endif return ret; } module_init(wm8974_modinit); static void __exit wm8974_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) i2c_del_driver(&wm8974_i2c_driver); -#endif } module_exit(wm8974_exit); -- cgit v0.10.2 From a2bd691c64383ab290732d771a7404e26c0b9d53 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 11:10:27 +0000 Subject: ASoC: Convert wm8974 to table based DAPM and control init Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index 80c264e..1e7a87a 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -235,7 +235,7 @@ SND_SOC_DAPM_OUTPUT("SPKOUTP"), SND_SOC_DAPM_OUTPUT("SPKOUTN"), }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route wm8974_dapm_routes[] = { /* Mono output mixer */ {"Mono Mixer", "PCM Playback Switch", "DAC"}, {"Mono Mixer", "Aux Playback Switch", "Aux Input"}, @@ -269,17 +269,6 @@ static const struct snd_soc_dapm_route audio_map[] = { {"Aux Input", NULL, "AUX"}, }; -static int wm8974_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, wm8974_dapm_widgets, - ARRAY_SIZE(wm8974_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - - return 0; -} - struct pll_ { unsigned int pre_div:1; unsigned int n:4; @@ -611,9 +600,6 @@ static int wm8974_probe(struct snd_soc_codec *codec) } wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_controls(codec, wm8974_snd_controls, - ARRAY_SIZE(wm8974_snd_controls)); - wm8974_add_widgets(codec); return ret; } @@ -634,6 +620,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8974 = { .reg_cache_size = ARRAY_SIZE(wm8974_reg), .reg_word_size = sizeof(u16), .reg_cache_default = wm8974_reg, + + .controls = wm8974_snd_controls, + .num_controls = ARRAY_SIZE(wm8974_snd_controls), + .dapm_widgets = wm8974_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8974_dapm_widgets), + .dapm_routes = wm8974_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8974_dapm_routes), }; static __devinit int wm8974_i2c_probe(struct i2c_client *i2c, -- cgit v0.10.2 From c2562a8e3b5f871ad0b73caf98bb7541e8724efc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 11:11:25 +0000 Subject: ASoC: Remove wm8974 private data It's only ever referenced when being allocated and freed. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index 1e7a87a..d93c03f 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -48,10 +48,6 @@ static const u16 wm8974_reg[WM8974_CACHEREGNUM] = { #define WM8974_POWER1_BIASEN 0x08 #define WM8974_POWER1_BUFIOEN 0x04 -struct wm8974_priv { - enum snd_soc_control_type control_type; -}; - #define wm8974_reset(c) snd_soc_write(c, WM8974_RESET, 0) static const char *wm8974_companding[] = {"Off", "NC", "u-law", "A-law" }; @@ -632,26 +628,18 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8974 = { static __devinit int wm8974_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { - struct wm8974_priv *wm8974; int ret; - wm8974 = kzalloc(sizeof(struct wm8974_priv), GFP_KERNEL); - if (wm8974 == NULL) - return -ENOMEM; - - i2c_set_clientdata(i2c, wm8974); - ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8974, &wm8974_dai, 1); - if (ret < 0) - kfree(wm8974); + return ret; } static __devexit int wm8974_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); + return 0; } -- cgit v0.10.2 From e055cd67fda76dd8efdcdd4038f5adfe0f8e85a0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 19:13:37 +0000 Subject: ASoC: Use standard cache sync for wm8804 Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index d54a3ca..4d79cef 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -482,24 +482,6 @@ static int wm8804_set_clkdiv(struct snd_soc_dai *dai, return 0; } -static void wm8804_sync_cache(struct snd_soc_codec *codec) -{ - short i; - u8 *cache; - - if (!codec->cache_sync) - return; - - codec->cache_only = 0; - cache = codec->reg_cache; - for (i = 0; i < codec->driver->reg_cache_size; i++) { - if (i == WM8804_RST_DEVID1 || cache[i] == wm8804_reg_defs[i]) - continue; - snd_soc_write(codec, i, cache[i]); - } - codec->cache_sync = 0; -} - static int wm8804_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { @@ -524,7 +506,7 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec, ret); return ret; } - wm8804_sync_cache(codec); + snd_soc_cache_sync(codec); } /* power down the OSC and the PLL */ snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0x9); -- cgit v0.10.2 From f649f1a8aadeb9ba146359daf51cc5ed137b394e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 19:19:18 +0000 Subject: ASoC: Convert wm8804 to devm_kzalloc() Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 4d79cef..a9f1eb3 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -713,7 +713,7 @@ static int __devinit wm8804_spi_probe(struct spi_device *spi) struct wm8804_priv *wm8804; int ret; - wm8804 = kzalloc(sizeof *wm8804, GFP_KERNEL); + wm8804 = devm_kzalloc(&spi->dev, sizeof *wm8804, GFP_KERNEL); if (!wm8804) return -ENOMEM; @@ -722,15 +722,13 @@ static int __devinit wm8804_spi_probe(struct spi_device *spi) ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8804, &wm8804_dai, 1); - if (ret < 0) - kfree(wm8804); + return ret; } static int __devexit wm8804_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); - kfree(spi_get_drvdata(spi)); return 0; } @@ -752,7 +750,7 @@ static __devinit int wm8804_i2c_probe(struct i2c_client *i2c, struct wm8804_priv *wm8804; int ret; - wm8804 = kzalloc(sizeof *wm8804, GFP_KERNEL); + wm8804 = devm_kzalloc(&i2c->dev, sizeof *wm8804, GFP_KERNEL); if (!wm8804) return -ENOMEM; @@ -761,15 +759,14 @@ static __devinit int wm8804_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8804, &wm8804_dai, 1); - if (ret < 0) - kfree(wm8804); + return ret; } static __devexit int wm8804_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); + return 0; } -- cgit v0.10.2 From 891271c28f06881332c6131158ea13f328401aa7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 19:58:06 +0000 Subject: ASoC: Convert wm8804 to direct regmap API usage The register map for this device is actually fairly sparse so the rbtree should be beneficial. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index a9f1eb3..8abe375 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -35,45 +36,33 @@ static const char *wm8804_supply_names[WM8804_NUM_SUPPLIES] = { "DVDD" }; -static const u8 wm8804_reg_defs[] = { - 0x05, /* R0 - RST/DEVID1 */ - 0x88, /* R1 - DEVID2 */ - 0x04, /* R2 - DEVREV */ - 0x21, /* R3 - PLL1 */ - 0xFD, /* R4 - PLL2 */ - 0x36, /* R5 - PLL3 */ - 0x07, /* R6 - PLL4 */ - 0x16, /* R7 - PLL5 */ - 0x18, /* R8 - PLL6 */ - 0xFF, /* R9 - SPDMODE */ - 0x00, /* R10 - INTMASK */ - 0x00, /* R11 - INTSTAT */ - 0x00, /* R12 - SPDSTAT */ - 0x00, /* R13 - RXCHAN1 */ - 0x00, /* R14 - RXCHAN2 */ - 0x00, /* R15 - RXCHAN3 */ - 0x00, /* R16 - RXCHAN4 */ - 0x00, /* R17 - RXCHAN5 */ - 0x00, /* R18 - SPDTX1 */ - 0x00, /* R19 - SPDTX2 */ - 0x00, /* R20 - SPDTX3 */ - 0x71, /* R21 - SPDTX4 */ - 0x0B, /* R22 - SPDTX5 */ - 0x70, /* R23 - GPO0 */ - 0x57, /* R24 - GPO1 */ - 0x00, /* R25 */ - 0x42, /* R26 - GPO2 */ - 0x06, /* R27 - AIFTX */ - 0x06, /* R28 - AIFRX */ - 0x80, /* R29 - SPDRX1 */ - 0x07, /* R30 - PWRDN */ +static const struct reg_default wm8804_reg_defaults[] = { + { 3, 0x21 }, /* R3 - PLL1 */ + { 4, 0xFD }, /* R4 - PLL2 */ + { 5, 0x36 }, /* R5 - PLL3 */ + { 6, 0x07 }, /* R6 - PLL4 */ + { 7, 0x16 }, /* R7 - PLL5 */ + { 8, 0x18 }, /* R8 - PLL6 */ + { 9, 0xFF }, /* R9 - SPDMODE */ + { 10, 0x00 }, /* R10 - INTMASK */ + { 18, 0x00 }, /* R18 - SPDTX1 */ + { 19, 0x00 }, /* R19 - SPDTX2 */ + { 20, 0x00 }, /* R20 - SPDTX3 */ + { 21, 0x71 }, /* R21 - SPDTX4 */ + { 22, 0x0B }, /* R22 - SPDTX5 */ + { 23, 0x70 }, /* R23 - GPO0 */ + { 24, 0x57 }, /* R24 - GPO1 */ + { 26, 0x42 }, /* R26 - GPO2 */ + { 27, 0x06 }, /* R27 - AIFTX */ + { 28, 0x06 }, /* R28 - AIFRX */ + { 29, 0x80 }, /* R29 - SPDRX1 */ + { 30, 0x07 }, /* R30 - PWRDN */ }; struct wm8804_priv { - enum snd_soc_control_type control_type; + struct regmap *regmap; struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES]; struct notifier_block disable_nb[WM8804_NUM_SUPPLIES]; - struct snd_soc_codec *codec; }; static int txsrc_get(struct snd_kcontrol *kcontrol, @@ -94,7 +83,7 @@ static int wm8804_regulator_event_##n(struct notifier_block *nb, \ struct wm8804_priv *wm8804 = container_of(nb, struct wm8804_priv, \ disable_nb[n]); \ if (event & REGULATOR_EVENT_DISABLE) { \ - wm8804->codec->cache_sync = 1; \ + regcache_mark_dirty(wm8804->regmap); \ } \ return 0; \ } @@ -176,7 +165,7 @@ static int txsrc_put(struct snd_kcontrol *kcontrol, return 0; } -static int wm8804_volatile(struct snd_soc_codec *codec, unsigned int reg) +static bool wm8804_volatile(struct device *dev, unsigned int reg) { switch (reg) { case WM8804_RST_DEVID1: @@ -189,12 +178,10 @@ static int wm8804_volatile(struct snd_soc_codec *codec, unsigned int reg) case WM8804_RXCHAN3: case WM8804_RXCHAN4: case WM8804_RXCHAN5: - return 1; + return true; default: - break; + return false; } - - return 0; } static int wm8804_reset(struct snd_soc_codec *codec) @@ -506,7 +493,7 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec, ret); return ret; } - snd_soc_cache_sync(codec); + regcache_sync(wm8804->regmap); } /* power down the OSC and the PLL */ snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0x9); @@ -561,11 +548,11 @@ static int wm8804_probe(struct snd_soc_codec *codec) int i, id1, id2, ret; wm8804 = snd_soc_codec_get_drvdata(codec); - wm8804->codec = codec; codec->dapm.idle_bias_off = 1; + codec->control_data = wm8804->regmap; - ret = snd_soc_codec_set_cache_io(codec, 8, 8, wm8804->control_type); + ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); if (ret < 0) { dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); return ret; @@ -618,8 +605,7 @@ static int wm8804_probe(struct snd_soc_codec *codec) id2 = (id2 << 8) | id1; - if (id2 != ((wm8804_reg_defs[WM8804_DEVID2] << 8) - | wm8804_reg_defs[WM8804_RST_DEVID1])) { + if (id2 != 0x8805) { dev_err(codec->dev, "Invalid device ID: %#x\n", id2); ret = -EINVAL; goto err_reg_enable; @@ -692,10 +678,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8804 = { .suspend = wm8804_suspend, .resume = wm8804_resume, .set_bias_level = wm8804_set_bias_level, - .reg_cache_size = ARRAY_SIZE(wm8804_reg_defs), - .reg_word_size = sizeof(u8), - .reg_cache_default = wm8804_reg_defs, - .volatile_register = wm8804_volatile, .controls = wm8804_snd_controls, .num_controls = ARRAY_SIZE(wm8804_snd_controls), @@ -707,6 +689,18 @@ static const struct of_device_id wm8804_of_match[] = { }; MODULE_DEVICE_TABLE(of, wm8804_of_match); +static struct regmap_config wm8804_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = WM8804_MAX_REGISTER, + .volatile_reg = wm8804_volatile, + + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wm8804_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8804_reg_defaults), +}; + #if defined(CONFIG_SPI_MASTER) static int __devinit wm8804_spi_probe(struct spi_device *spi) { @@ -717,7 +711,12 @@ static int __devinit wm8804_spi_probe(struct spi_device *spi) if (!wm8804) return -ENOMEM; - wm8804->control_type = SND_SOC_SPI; + wm8804->regmap = regmap_init_spi(spi, &wm8804_regmap_config); + if (IS_ERR(wm8804->regmap)) { + ret = PTR_ERR(wm8804->regmap); + return ret; + } + spi_set_drvdata(spi, wm8804); ret = snd_soc_register_codec(&spi->dev, @@ -728,7 +727,9 @@ static int __devinit wm8804_spi_probe(struct spi_device *spi) static int __devexit wm8804_spi_remove(struct spi_device *spi) { + struct wm8804_priv *wm8804 = spi_get_drvdata(spi); snd_soc_unregister_codec(&spi->dev); + regmap_exit(wm8804->regmap); return 0; } @@ -754,18 +755,26 @@ static __devinit int wm8804_i2c_probe(struct i2c_client *i2c, if (!wm8804) return -ENOMEM; - wm8804->control_type = SND_SOC_I2C; i2c_set_clientdata(i2c, wm8804); ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8804, &wm8804_dai, 1); + if (ret != 0) + goto err; + return 0; + +err: + regmap_exit(wm8804->regmap); return ret; } -static __devexit int wm8804_i2c_remove(struct i2c_client *client) +static __devexit int wm8804_i2c_remove(struct i2c_client *i2c) { - snd_soc_unregister_codec(&client->dev); + struct wm8804_priv *wm8804 = i2c_get_clientdata(i2c); + + snd_soc_unregister_codec(&i2c->dev); + regmap_exit(wm8804->regmap); return 0; } -- cgit v0.10.2 From 429440c947e72b6f6f317fa4346ddebf9d5e5413 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 20:03:23 +0000 Subject: ASoC: Make WM8904 I2C usage unconditional Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index f31c754..1ad9373 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -2525,7 +2525,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8904 = { .volatile_register = wm8904_volatile_register, }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -2571,27 +2570,22 @@ static struct i2c_driver wm8904_i2c_driver = { .remove = __devexit_p(wm8904_i2c_remove), .id_table = wm8904_i2c_id, }; -#endif static int __init wm8904_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&wm8904_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register wm8904 I2C driver: %d\n", ret); } -#endif return ret; } module_init(wm8904_modinit); static void __exit wm8904_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) i2c_del_driver(&wm8904_i2c_driver); -#endif } module_exit(wm8904_exit); -- cgit v0.10.2 From 93e26d4e44e65ef803ea35cfd0fe14fd8af49cb0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 20:05:00 +0000 Subject: ASoC: Convert wm8904 to devm_kzalloc() Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 1ad9373..98d4f81 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -2531,7 +2531,8 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, struct wm8904_priv *wm8904; int ret; - wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL); + wm8904 = devm_kzalloc(&i2c->dev, sizeof(struct wm8904_priv), + GFP_KERNEL); if (wm8904 == NULL) return -ENOMEM; @@ -2541,15 +2542,13 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8904, &wm8904_dai, 1); - if (ret < 0) - kfree(wm8904); + return ret; } static __devexit int wm8904_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } -- cgit v0.10.2 From 274eb8f9d8780903ccd40e007928f26c3a8c6e15 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 21:07:04 +0000 Subject: ASoC: Use standard cache sync for WM8904 Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 98d4f81..673a2fe5 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -2088,32 +2088,6 @@ static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute) return 0; } -static void wm8904_sync_cache(struct snd_soc_codec *codec) -{ - u16 *reg_cache = codec->reg_cache; - int i; - - if (!codec->cache_sync) - return; - - codec->cache_only = 0; - - /* Sync back cached values if they're different from the - * hardware default. - */ - for (i = 1; i < codec->driver->reg_cache_size; i++) { - if (!wm8904_access[i].writable) - continue; - - if (reg_cache[i] == wm8904_reg[i]) - continue; - - snd_soc_write(codec, i, reg_cache[i]); - } - - codec->cache_sync = 0; -} - static int wm8904_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { @@ -2146,7 +2120,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec, return ret; } - wm8904_sync_cache(codec); + snd_soc_cache_sync(codec); /* Enable bias */ snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, -- cgit v0.10.2 From 84d0d83180a8db564483f5e2ff58a7661d78858b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 21:12:51 +0000 Subject: ASoC: Convert WM8904 to direct regmap API usage The device has a very sparse register map so should benefit from using a rbtree cache. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 673a2fe5..f2a740d 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,7 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = { /* codec private data */ struct wm8904_priv { + struct regmap *regmap; enum wm8904_type devtype; @@ -86,517 +88,229 @@ struct wm8904_priv { int dcs_state[WM8904_NUM_DCS_CHANNELS]; }; -static const u16 wm8904_reg[WM8904_MAX_REGISTER + 1] = { - 0x8904, /* R0 - SW Reset and ID */ - 0x0000, /* R1 - Revision */ - 0x0000, /* R2 */ - 0x0000, /* R3 */ - 0x0018, /* R4 - Bias Control 0 */ - 0x0000, /* R5 - VMID Control 0 */ - 0x0000, /* R6 - Mic Bias Control 0 */ - 0x0000, /* R7 - Mic Bias Control 1 */ - 0x0001, /* R8 - Analogue DAC 0 */ - 0x9696, /* R9 - mic Filter Control */ - 0x0001, /* R10 - Analogue ADC 0 */ - 0x0000, /* R11 */ - 0x0000, /* R12 - Power Management 0 */ - 0x0000, /* R13 */ - 0x0000, /* R14 - Power Management 2 */ - 0x0000, /* R15 - Power Management 3 */ - 0x0000, /* R16 */ - 0x0000, /* R17 */ - 0x0000, /* R18 - Power Management 6 */ - 0x0000, /* R19 */ - 0x945E, /* R20 - Clock Rates 0 */ - 0x0C05, /* R21 - Clock Rates 1 */ - 0x0006, /* R22 - Clock Rates 2 */ - 0x0000, /* R23 */ - 0x0050, /* R24 - Audio Interface 0 */ - 0x000A, /* R25 - Audio Interface 1 */ - 0x00E4, /* R26 - Audio Interface 2 */ - 0x0040, /* R27 - Audio Interface 3 */ - 0x0000, /* R28 */ - 0x0000, /* R29 */ - 0x00C0, /* R30 - DAC Digital Volume Left */ - 0x00C0, /* R31 - DAC Digital Volume Right */ - 0x0000, /* R32 - DAC Digital 0 */ - 0x0008, /* R33 - DAC Digital 1 */ - 0x0000, /* R34 */ - 0x0000, /* R35 */ - 0x00C0, /* R36 - ADC Digital Volume Left */ - 0x00C0, /* R37 - ADC Digital Volume Right */ - 0x0010, /* R38 - ADC Digital 0 */ - 0x0000, /* R39 - Digital Microphone 0 */ - 0x01AF, /* R40 - DRC 0 */ - 0x3248, /* R41 - DRC 1 */ - 0x0000, /* R42 - DRC 2 */ - 0x0000, /* R43 - DRC 3 */ - 0x0085, /* R44 - Analogue Left Input 0 */ - 0x0085, /* R45 - Analogue Right Input 0 */ - 0x0044, /* R46 - Analogue Left Input 1 */ - 0x0044, /* R47 - Analogue Right Input 1 */ - 0x0000, /* R48 */ - 0x0000, /* R49 */ - 0x0000, /* R50 */ - 0x0000, /* R51 */ - 0x0000, /* R52 */ - 0x0000, /* R53 */ - 0x0000, /* R54 */ - 0x0000, /* R55 */ - 0x0000, /* R56 */ - 0x002D, /* R57 - Analogue OUT1 Left */ - 0x002D, /* R58 - Analogue OUT1 Right */ - 0x0039, /* R59 - Analogue OUT2 Left */ - 0x0039, /* R60 - Analogue OUT2 Right */ - 0x0000, /* R61 - Analogue OUT12 ZC */ - 0x0000, /* R62 */ - 0x0000, /* R63 */ - 0x0000, /* R64 */ - 0x0000, /* R65 */ - 0x0000, /* R66 */ - 0x0000, /* R67 - DC Servo 0 */ - 0x0000, /* R68 - DC Servo 1 */ - 0xAAAA, /* R69 - DC Servo 2 */ - 0x0000, /* R70 */ - 0xAAAA, /* R71 - DC Servo 4 */ - 0xAAAA, /* R72 - DC Servo 5 */ - 0x0000, /* R73 - DC Servo 6 */ - 0x0000, /* R74 - DC Servo 7 */ - 0x0000, /* R75 - DC Servo 8 */ - 0x0000, /* R76 - DC Servo 9 */ - 0x0000, /* R77 - DC Servo Readback 0 */ - 0x0000, /* R78 */ - 0x0000, /* R79 */ - 0x0000, /* R80 */ - 0x0000, /* R81 */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 */ - 0x0000, /* R85 */ - 0x0000, /* R86 */ - 0x0000, /* R87 */ - 0x0000, /* R88 */ - 0x0000, /* R89 */ - 0x0000, /* R90 - Analogue HP 0 */ - 0x0000, /* R91 */ - 0x0000, /* R92 */ - 0x0000, /* R93 */ - 0x0000, /* R94 - Analogue Lineout 0 */ - 0x0000, /* R95 */ - 0x0000, /* R96 */ - 0x0000, /* R97 */ - 0x0000, /* R98 - Charge Pump 0 */ - 0x0000, /* R99 */ - 0x0000, /* R100 */ - 0x0000, /* R101 */ - 0x0000, /* R102 */ - 0x0000, /* R103 */ - 0x0004, /* R104 - Class W 0 */ - 0x0000, /* R105 */ - 0x0000, /* R106 */ - 0x0000, /* R107 */ - 0x0000, /* R108 - Write Sequencer 0 */ - 0x0000, /* R109 - Write Sequencer 1 */ - 0x0000, /* R110 - Write Sequencer 2 */ - 0x0000, /* R111 - Write Sequencer 3 */ - 0x0000, /* R112 - Write Sequencer 4 */ - 0x0000, /* R113 */ - 0x0000, /* R114 */ - 0x0000, /* R115 */ - 0x0000, /* R116 - FLL Control 1 */ - 0x0007, /* R117 - FLL Control 2 */ - 0x0000, /* R118 - FLL Control 3 */ - 0x2EE0, /* R119 - FLL Control 4 */ - 0x0004, /* R120 - FLL Control 5 */ - 0x0014, /* R121 - GPIO Control 1 */ - 0x0010, /* R122 - GPIO Control 2 */ - 0x0010, /* R123 - GPIO Control 3 */ - 0x0000, /* R124 - GPIO Control 4 */ - 0x0000, /* R125 */ - 0x0000, /* R126 - Digital Pulls */ - 0x0000, /* R127 - Interrupt Status */ - 0xFFFF, /* R128 - Interrupt Status Mask */ - 0x0000, /* R129 - Interrupt Polarity */ - 0x0000, /* R130 - Interrupt Debounce */ - 0x0000, /* R131 */ - 0x0000, /* R132 */ - 0x0000, /* R133 */ - 0x0000, /* R134 - EQ1 */ - 0x000C, /* R135 - EQ2 */ - 0x000C, /* R136 - EQ3 */ - 0x000C, /* R137 - EQ4 */ - 0x000C, /* R138 - EQ5 */ - 0x000C, /* R139 - EQ6 */ - 0x0FCA, /* R140 - EQ7 */ - 0x0400, /* R141 - EQ8 */ - 0x00D8, /* R142 - EQ9 */ - 0x1EB5, /* R143 - EQ10 */ - 0xF145, /* R144 - EQ11 */ - 0x0B75, /* R145 - EQ12 */ - 0x01C5, /* R146 - EQ13 */ - 0x1C58, /* R147 - EQ14 */ - 0xF373, /* R148 - EQ15 */ - 0x0A54, /* R149 - EQ16 */ - 0x0558, /* R150 - EQ17 */ - 0x168E, /* R151 - EQ18 */ - 0xF829, /* R152 - EQ19 */ - 0x07AD, /* R153 - EQ20 */ - 0x1103, /* R154 - EQ21 */ - 0x0564, /* R155 - EQ22 */ - 0x0559, /* R156 - EQ23 */ - 0x4000, /* R157 - EQ24 */ - 0x0000, /* R158 */ - 0x0000, /* R159 */ - 0x0000, /* R160 */ - 0x0000, /* R161 - Control Interface Test 1 */ - 0x0000, /* R162 */ - 0x0000, /* R163 */ - 0x0000, /* R164 */ - 0x0000, /* R165 */ - 0x0000, /* R166 */ - 0x0000, /* R167 */ - 0x0000, /* R168 */ - 0x0000, /* R169 */ - 0x0000, /* R170 */ - 0x0000, /* R171 */ - 0x0000, /* R172 */ - 0x0000, /* R173 */ - 0x0000, /* R174 */ - 0x0000, /* R175 */ - 0x0000, /* R176 */ - 0x0000, /* R177 */ - 0x0000, /* R178 */ - 0x0000, /* R179 */ - 0x0000, /* R180 */ - 0x0000, /* R181 */ - 0x0000, /* R182 */ - 0x0000, /* R183 */ - 0x0000, /* R184 */ - 0x0000, /* R185 */ - 0x0000, /* R186 */ - 0x0000, /* R187 */ - 0x0000, /* R188 */ - 0x0000, /* R189 */ - 0x0000, /* R190 */ - 0x0000, /* R191 */ - 0x0000, /* R192 */ - 0x0000, /* R193 */ - 0x0000, /* R194 */ - 0x0000, /* R195 */ - 0x0000, /* R196 */ - 0x0000, /* R197 */ - 0x0000, /* R198 */ - 0x0000, /* R199 */ - 0x0000, /* R200 */ - 0x0000, /* R201 */ - 0x0000, /* R202 */ - 0x0000, /* R203 */ - 0x0000, /* R204 - Analogue Output Bias 0 */ - 0x0000, /* R205 */ - 0x0000, /* R206 */ - 0x0000, /* R207 */ - 0x0000, /* R208 */ - 0x0000, /* R209 */ - 0x0000, /* R210 */ - 0x0000, /* R211 */ - 0x0000, /* R212 */ - 0x0000, /* R213 */ - 0x0000, /* R214 */ - 0x0000, /* R215 */ - 0x0000, /* R216 */ - 0x0000, /* R217 */ - 0x0000, /* R218 */ - 0x0000, /* R219 */ - 0x0000, /* R220 */ - 0x0000, /* R221 */ - 0x0000, /* R222 */ - 0x0000, /* R223 */ - 0x0000, /* R224 */ - 0x0000, /* R225 */ - 0x0000, /* R226 */ - 0x0000, /* R227 */ - 0x0000, /* R228 */ - 0x0000, /* R229 */ - 0x0000, /* R230 */ - 0x0000, /* R231 */ - 0x0000, /* R232 */ - 0x0000, /* R233 */ - 0x0000, /* R234 */ - 0x0000, /* R235 */ - 0x0000, /* R236 */ - 0x0000, /* R237 */ - 0x0000, /* R238 */ - 0x0000, /* R239 */ - 0x0000, /* R240 */ - 0x0000, /* R241 */ - 0x0000, /* R242 */ - 0x0000, /* R243 */ - 0x0000, /* R244 */ - 0x0000, /* R245 */ - 0x0000, /* R246 */ - 0x0000, /* R247 - FLL NCO Test 0 */ - 0x0019, /* R248 - FLL NCO Test 1 */ +static const struct reg_default wm8904_reg_defaults[] = { + { 4, 0x0018 }, /* R4 - Bias Control 0 */ + { 5, 0x0000 }, /* R5 - VMID Control 0 */ + { 6, 0x0000 }, /* R6 - Mic Bias Control 0 */ + { 7, 0x0000 }, /* R7 - Mic Bias Control 1 */ + { 8, 0x0001 }, /* R8 - Analogue DAC 0 */ + { 9, 0x9696 }, /* R9 - mic Filter Control */ + { 10, 0x0001 }, /* R10 - Analogue ADC 0 */ + { 12, 0x0000 }, /* R12 - Power Management 0 */ + { 14, 0x0000 }, /* R14 - Power Management 2 */ + { 15, 0x0000 }, /* R15 - Power Management 3 */ + { 18, 0x0000 }, /* R18 - Power Management 6 */ + { 19, 0x945E }, /* R20 - Clock Rates 0 */ + { 21, 0x0C05 }, /* R21 - Clock Rates 1 */ + { 22, 0x0006 }, /* R22 - Clock Rates 2 */ + { 24, 0x0050 }, /* R24 - Audio Interface 0 */ + { 25, 0x000A }, /* R25 - Audio Interface 1 */ + { 26, 0x00E4 }, /* R26 - Audio Interface 2 */ + { 27, 0x0040 }, /* R27 - Audio Interface 3 */ + { 30, 0x00C0 }, /* R30 - DAC Digital Volume Left */ + { 31, 0x00C0 }, /* R31 - DAC Digital Volume Right */ + { 32, 0x0000 }, /* R32 - DAC Digital 0 */ + { 33, 0x0008 }, /* R33 - DAC Digital 1 */ + { 36, 0x00C0 }, /* R36 - ADC Digital Volume Left */ + { 37, 0x00C0 }, /* R37 - ADC Digital Volume Right */ + { 38, 0x0010 }, /* R38 - ADC Digital 0 */ + { 39, 0x0000 }, /* R39 - Digital Microphone 0 */ + { 40, 0x01AF }, /* R40 - DRC 0 */ + { 41, 0x3248 }, /* R41 - DRC 1 */ + { 42, 0x0000 }, /* R42 - DRC 2 */ + { 43, 0x0000 }, /* R43 - DRC 3 */ + { 44, 0x0085 }, /* R44 - Analogue Left Input 0 */ + { 45, 0x0085 }, /* R45 - Analogue Right Input 0 */ + { 46, 0x0044 }, /* R46 - Analogue Left Input 1 */ + { 47, 0x0044 }, /* R47 - Analogue Right Input 1 */ + { 57, 0x002D }, /* R57 - Analogue OUT1 Left */ + { 58, 0x002D }, /* R58 - Analogue OUT1 Right */ + { 59, 0x0039 }, /* R59 - Analogue OUT2 Left */ + { 60, 0x0039 }, /* R60 - Analogue OUT2 Right */ + { 61, 0x0000 }, /* R61 - Analogue OUT12 ZC */ + { 67, 0x0000 }, /* R67 - DC Servo 0 */ + { 69, 0xAAAA }, /* R69 - DC Servo 2 */ + { 71, 0xAAAA }, /* R71 - DC Servo 4 */ + { 72, 0xAAAA }, /* R72 - DC Servo 5 */ + { 90, 0x0000 }, /* R90 - Analogue HP 0 */ + { 94, 0x0000 }, /* R94 - Analogue Lineout 0 */ + { 98, 0x0000 }, /* R98 - Charge Pump 0 */ + { 104, 0x0004 }, /* R104 - Class W 0 */ + { 108, 0x0000 }, /* R108 - Write Sequencer 0 */ + { 109, 0x0000 }, /* R109 - Write Sequencer 1 */ + { 110, 0x0000 }, /* R110 - Write Sequencer 2 */ + { 111, 0x0000 }, /* R111 - Write Sequencer 3 */ + { 112, 0x0000 }, /* R112 - Write Sequencer 4 */ + { 116, 0x0000 }, /* R116 - FLL Control 1 */ + { 117, 0x0007 }, /* R117 - FLL Control 2 */ + { 118, 0x0000 }, /* R118 - FLL Control 3 */ + { 119, 0x2EE0 }, /* R119 - FLL Control 4 */ + { 120, 0x0004 }, /* R120 - FLL Control 5 */ + { 121, 0x0014 }, /* R121 - GPIO Control 1 */ + { 122, 0x0010 }, /* R122 - GPIO Control 2 */ + { 123, 0x0010 }, /* R123 - GPIO Control 3 */ + { 124, 0x0000 }, /* R124 - GPIO Control 4 */ + { 126, 0x0000 }, /* R126 - Digital Pulls */ + { 128, 0xFFFF }, /* R128 - Interrupt Status Mask */ + { 129, 0x0000 }, /* R129 - Interrupt Polarity */ + { 130, 0x0000 }, /* R130 - Interrupt Debounce */ + { 134, 0x0000 }, /* R134 - EQ1 */ + { 135, 0x000C }, /* R135 - EQ2 */ + { 136, 0x000C }, /* R136 - EQ3 */ + { 137, 0x000C }, /* R137 - EQ4 */ + { 138, 0x000C }, /* R138 - EQ5 */ + { 139, 0x000C }, /* R139 - EQ6 */ + { 140, 0x0FCA }, /* R140 - EQ7 */ + { 141, 0x0400 }, /* R141 - EQ8 */ + { 142, 0x00D8 }, /* R142 - EQ9 */ + { 143, 0x1EB5 }, /* R143 - EQ10 */ + { 144, 0xF145 }, /* R144 - EQ11 */ + { 145, 0x0B75 }, /* R145 - EQ12 */ + { 146, 0x01C5 }, /* R146 - EQ13 */ + { 147, 0x1C58 }, /* R147 - EQ14 */ + { 148, 0xF373 }, /* R148 - EQ15 */ + { 149, 0x0A54 }, /* R149 - EQ16 */ + { 150, 0x0558 }, /* R150 - EQ17 */ + { 151, 0x168E }, /* R151 - EQ18 */ + { 152, 0xF829 }, /* R152 - EQ19 */ + { 153, 0x07AD }, /* R153 - EQ20 */ + { 154, 0x1103 }, /* R154 - EQ21 */ + { 155, 0x0564 }, /* R155 - EQ22 */ + { 156, 0x0559 }, /* R156 - EQ23 */ + { 157, 0x4000 }, /* R157 - EQ24 */ + { 161, 0x0000 }, /* R161 - Control Interface Test 1 */ + { 204, 0x0000 }, /* R204 - Analogue Output Bias 0 */ + { 247, 0x0000 }, /* R247 - FLL NCO Test 0 */ + { 248, 0x0019 }, /* R248 - FLL NCO Test 1 */ }; -static struct { - int readable; - int writable; - int vol; -} wm8904_access[] = { - { 0xFFFF, 0xFFFF, 1 }, /* R0 - SW Reset and ID */ - { 0x0000, 0x0000, 0 }, /* R1 - Revision */ - { 0x0000, 0x0000, 0 }, /* R2 */ - { 0x0000, 0x0000, 0 }, /* R3 */ - { 0x001F, 0x001F, 0 }, /* R4 - Bias Control 0 */ - { 0x0047, 0x0047, 0 }, /* R5 - VMID Control 0 */ - { 0x007F, 0x007F, 0 }, /* R6 - Mic Bias Control 0 */ - { 0xC007, 0xC007, 0 }, /* R7 - Mic Bias Control 1 */ - { 0x001E, 0x001E, 0 }, /* R8 - Analogue DAC 0 */ - { 0xFFFF, 0xFFFF, 0 }, /* R9 - mic Filter Control */ - { 0x0001, 0x0001, 0 }, /* R10 - Analogue ADC 0 */ - { 0x0000, 0x0000, 0 }, /* R11 */ - { 0x0003, 0x0003, 0 }, /* R12 - Power Management 0 */ - { 0x0000, 0x0000, 0 }, /* R13 */ - { 0x0003, 0x0003, 0 }, /* R14 - Power Management 2 */ - { 0x0003, 0x0003, 0 }, /* R15 - Power Management 3 */ - { 0x0000, 0x0000, 0 }, /* R16 */ - { 0x0000, 0x0000, 0 }, /* R17 */ - { 0x000F, 0x000F, 0 }, /* R18 - Power Management 6 */ - { 0x0000, 0x0000, 0 }, /* R19 */ - { 0x7001, 0x7001, 0 }, /* R20 - Clock Rates 0 */ - { 0x3C07, 0x3C07, 0 }, /* R21 - Clock Rates 1 */ - { 0xD00F, 0xD00F, 0 }, /* R22 - Clock Rates 2 */ - { 0x0000, 0x0000, 0 }, /* R23 */ - { 0x1FFF, 0x1FFF, 0 }, /* R24 - Audio Interface 0 */ - { 0x3DDF, 0x3DDF, 0 }, /* R25 - Audio Interface 1 */ - { 0x0F1F, 0x0F1F, 0 }, /* R26 - Audio Interface 2 */ - { 0x0FFF, 0x0FFF, 0 }, /* R27 - Audio Interface 3 */ - { 0x0000, 0x0000, 0 }, /* R28 */ - { 0x0000, 0x0000, 0 }, /* R29 */ - { 0x00FF, 0x01FF, 0 }, /* R30 - DAC Digital Volume Left */ - { 0x00FF, 0x01FF, 0 }, /* R31 - DAC Digital Volume Right */ - { 0x0FFF, 0x0FFF, 0 }, /* R32 - DAC Digital 0 */ - { 0x1E4E, 0x1E4E, 0 }, /* R33 - DAC Digital 1 */ - { 0x0000, 0x0000, 0 }, /* R34 */ - { 0x0000, 0x0000, 0 }, /* R35 */ - { 0x00FF, 0x01FF, 0 }, /* R36 - ADC Digital Volume Left */ - { 0x00FF, 0x01FF, 0 }, /* R37 - ADC Digital Volume Right */ - { 0x0073, 0x0073, 0 }, /* R38 - ADC Digital 0 */ - { 0x1800, 0x1800, 0 }, /* R39 - Digital Microphone 0 */ - { 0xDFEF, 0xDFEF, 0 }, /* R40 - DRC 0 */ - { 0xFFFF, 0xFFFF, 0 }, /* R41 - DRC 1 */ - { 0x003F, 0x003F, 0 }, /* R42 - DRC 2 */ - { 0x07FF, 0x07FF, 0 }, /* R43 - DRC 3 */ - { 0x009F, 0x009F, 0 }, /* R44 - Analogue Left Input 0 */ - { 0x009F, 0x009F, 0 }, /* R45 - Analogue Right Input 0 */ - { 0x007F, 0x007F, 0 }, /* R46 - Analogue Left Input 1 */ - { 0x007F, 0x007F, 0 }, /* R47 - Analogue Right Input 1 */ - { 0x0000, 0x0000, 0 }, /* R48 */ - { 0x0000, 0x0000, 0 }, /* R49 */ - { 0x0000, 0x0000, 0 }, /* R50 */ - { 0x0000, 0x0000, 0 }, /* R51 */ - { 0x0000, 0x0000, 0 }, /* R52 */ - { 0x0000, 0x0000, 0 }, /* R53 */ - { 0x0000, 0x0000, 0 }, /* R54 */ - { 0x0000, 0x0000, 0 }, /* R55 */ - { 0x0000, 0x0000, 0 }, /* R56 */ - { 0x017F, 0x01FF, 0 }, /* R57 - Analogue OUT1 Left */ - { 0x017F, 0x01FF, 0 }, /* R58 - Analogue OUT1 Right */ - { 0x017F, 0x01FF, 0 }, /* R59 - Analogue OUT2 Left */ - { 0x017F, 0x01FF, 0 }, /* R60 - Analogue OUT2 Right */ - { 0x000F, 0x000F, 0 }, /* R61 - Analogue OUT12 ZC */ - { 0x0000, 0x0000, 0 }, /* R62 */ - { 0x0000, 0x0000, 0 }, /* R63 */ - { 0x0000, 0x0000, 0 }, /* R64 */ - { 0x0000, 0x0000, 0 }, /* R65 */ - { 0x0000, 0x0000, 0 }, /* R66 */ - { 0x000F, 0x000F, 0 }, /* R67 - DC Servo 0 */ - { 0xFFFF, 0xFFFF, 1 }, /* R68 - DC Servo 1 */ - { 0x0F0F, 0x0F0F, 0 }, /* R69 - DC Servo 2 */ - { 0x0000, 0x0000, 0 }, /* R70 */ - { 0x007F, 0x007F, 0 }, /* R71 - DC Servo 4 */ - { 0x007F, 0x007F, 0 }, /* R72 - DC Servo 5 */ - { 0x00FF, 0x00FF, 1 }, /* R73 - DC Servo 6 */ - { 0x00FF, 0x00FF, 1 }, /* R74 - DC Servo 7 */ - { 0x00FF, 0x00FF, 1 }, /* R75 - DC Servo 8 */ - { 0x00FF, 0x00FF, 1 }, /* R76 - DC Servo 9 */ - { 0x0FFF, 0x0000, 1 }, /* R77 - DC Servo Readback 0 */ - { 0x0000, 0x0000, 0 }, /* R78 */ - { 0x0000, 0x0000, 0 }, /* R79 */ - { 0x0000, 0x0000, 0 }, /* R80 */ - { 0x0000, 0x0000, 0 }, /* R81 */ - { 0x0000, 0x0000, 0 }, /* R82 */ - { 0x0000, 0x0000, 0 }, /* R83 */ - { 0x0000, 0x0000, 0 }, /* R84 */ - { 0x0000, 0x0000, 0 }, /* R85 */ - { 0x0000, 0x0000, 0 }, /* R86 */ - { 0x0000, 0x0000, 0 }, /* R87 */ - { 0x0000, 0x0000, 0 }, /* R88 */ - { 0x0000, 0x0000, 0 }, /* R89 */ - { 0x00FF, 0x00FF, 0 }, /* R90 - Analogue HP 0 */ - { 0x0000, 0x0000, 0 }, /* R91 */ - { 0x0000, 0x0000, 0 }, /* R92 */ - { 0x0000, 0x0000, 0 }, /* R93 */ - { 0x00FF, 0x00FF, 0 }, /* R94 - Analogue Lineout 0 */ - { 0x0000, 0x0000, 0 }, /* R95 */ - { 0x0000, 0x0000, 0 }, /* R96 */ - { 0x0000, 0x0000, 0 }, /* R97 */ - { 0x0001, 0x0001, 0 }, /* R98 - Charge Pump 0 */ - { 0x0000, 0x0000, 0 }, /* R99 */ - { 0x0000, 0x0000, 0 }, /* R100 */ - { 0x0000, 0x0000, 0 }, /* R101 */ - { 0x0000, 0x0000, 0 }, /* R102 */ - { 0x0000, 0x0000, 0 }, /* R103 */ - { 0x0001, 0x0001, 0 }, /* R104 - Class W 0 */ - { 0x0000, 0x0000, 0 }, /* R105 */ - { 0x0000, 0x0000, 0 }, /* R106 */ - { 0x0000, 0x0000, 0 }, /* R107 */ - { 0x011F, 0x011F, 0 }, /* R108 - Write Sequencer 0 */ - { 0x7FFF, 0x7FFF, 0 }, /* R109 - Write Sequencer 1 */ - { 0x4FFF, 0x4FFF, 0 }, /* R110 - Write Sequencer 2 */ - { 0x003F, 0x033F, 0 }, /* R111 - Write Sequencer 3 */ - { 0x03F1, 0x0000, 0 }, /* R112 - Write Sequencer 4 */ - { 0x0000, 0x0000, 0 }, /* R113 */ - { 0x0000, 0x0000, 0 }, /* R114 */ - { 0x0000, 0x0000, 0 }, /* R115 */ - { 0x0007, 0x0007, 0 }, /* R116 - FLL Control 1 */ - { 0x3F77, 0x3F77, 0 }, /* R117 - FLL Control 2 */ - { 0xFFFF, 0xFFFF, 0 }, /* R118 - FLL Control 3 */ - { 0x7FEF, 0x7FEF, 0 }, /* R119 - FLL Control 4 */ - { 0x001B, 0x001B, 0 }, /* R120 - FLL Control 5 */ - { 0x003F, 0x003F, 0 }, /* R121 - GPIO Control 1 */ - { 0x003F, 0x003F, 0 }, /* R122 - GPIO Control 2 */ - { 0x003F, 0x003F, 0 }, /* R123 - GPIO Control 3 */ - { 0x038F, 0x038F, 0 }, /* R124 - GPIO Control 4 */ - { 0x0000, 0x0000, 0 }, /* R125 */ - { 0x00FF, 0x00FF, 0 }, /* R126 - Digital Pulls */ - { 0x07FF, 0x03FF, 1 }, /* R127 - Interrupt Status */ - { 0x03FF, 0x03FF, 0 }, /* R128 - Interrupt Status Mask */ - { 0x03FF, 0x03FF, 0 }, /* R129 - Interrupt Polarity */ - { 0x03FF, 0x03FF, 0 }, /* R130 - Interrupt Debounce */ - { 0x0000, 0x0000, 0 }, /* R131 */ - { 0x0000, 0x0000, 0 }, /* R132 */ - { 0x0000, 0x0000, 0 }, /* R133 */ - { 0x0001, 0x0001, 0 }, /* R134 - EQ1 */ - { 0x001F, 0x001F, 0 }, /* R135 - EQ2 */ - { 0x001F, 0x001F, 0 }, /* R136 - EQ3 */ - { 0x001F, 0x001F, 0 }, /* R137 - EQ4 */ - { 0x001F, 0x001F, 0 }, /* R138 - EQ5 */ - { 0x001F, 0x001F, 0 }, /* R139 - EQ6 */ - { 0xFFFF, 0xFFFF, 0 }, /* R140 - EQ7 */ - { 0xFFFF, 0xFFFF, 0 }, /* R141 - EQ8 */ - { 0xFFFF, 0xFFFF, 0 }, /* R142 - EQ9 */ - { 0xFFFF, 0xFFFF, 0 }, /* R143 - EQ10 */ - { 0xFFFF, 0xFFFF, 0 }, /* R144 - EQ11 */ - { 0xFFFF, 0xFFFF, 0 }, /* R145 - EQ12 */ - { 0xFFFF, 0xFFFF, 0 }, /* R146 - EQ13 */ - { 0xFFFF, 0xFFFF, 0 }, /* R147 - EQ14 */ - { 0xFFFF, 0xFFFF, 0 }, /* R148 - EQ15 */ - { 0xFFFF, 0xFFFF, 0 }, /* R149 - EQ16 */ - { 0xFFFF, 0xFFFF, 0 }, /* R150 - EQ17 */ - { 0xFFFF, 0xFFFF, 0 }, /* R151wm8523_dai - EQ18 */ - { 0xFFFF, 0xFFFF, 0 }, /* R152 - EQ19 */ - { 0xFFFF, 0xFFFF, 0 }, /* R153 - EQ20 */ - { 0xFFFF, 0xFFFF, 0 }, /* R154 - EQ21 */ - { 0xFFFF, 0xFFFF, 0 }, /* R155 - EQ22 */ - { 0xFFFF, 0xFFFF, 0 }, /* R156 - EQ23 */ - { 0xFFFF, 0xFFFF, 0 }, /* R157 - EQ24 */ - { 0x0000, 0x0000, 0 }, /* R158 */ - { 0x0000, 0x0000, 0 }, /* R159 */ - { 0x0000, 0x0000, 0 }, /* R160 */ - { 0x0002, 0x0002, 0 }, /* R161 - Control Interface Test 1 */ - { 0x0000, 0x0000, 0 }, /* R162 */ - { 0x0000, 0x0000, 0 }, /* R163 */ - { 0x0000, 0x0000, 0 }, /* R164 */ - { 0x0000, 0x0000, 0 }, /* R165 */ - { 0x0000, 0x0000, 0 }, /* R166 */ - { 0x0000, 0x0000, 0 }, /* R167 */ - { 0x0000, 0x0000, 0 }, /* R168 */ - { 0x0000, 0x0000, 0 }, /* R169 */ - { 0x0000, 0x0000, 0 }, /* R170 */ - { 0x0000, 0x0000, 0 }, /* R171 */ - { 0x0000, 0x0000, 0 }, /* R172 */ - { 0x0000, 0x0000, 0 }, /* R173 */ - { 0x0000, 0x0000, 0 }, /* R174 */ - { 0x0000, 0x0000, 0 }, /* R175 */ - { 0x0000, 0x0000, 0 }, /* R176 */ - { 0x0000, 0x0000, 0 }, /* R177 */ - { 0x0000, 0x0000, 0 }, /* R178 */ - { 0x0000, 0x0000, 0 }, /* R179 */ - { 0x0000, 0x0000, 0 }, /* R180 */ - { 0x0000, 0x0000, 0 }, /* R181 */ - { 0x0000, 0x0000, 0 }, /* R182 */ - { 0x0000, 0x0000, 0 }, /* R183 */ - { 0x0000, 0x0000, 0 }, /* R184 */ - { 0x0000, 0x0000, 0 }, /* R185 */ - { 0x0000, 0x0000, 0 }, /* R186 */ - { 0x0000, 0x0000, 0 }, /* R187 */ - { 0x0000, 0x0000, 0 }, /* R188 */ - { 0x0000, 0x0000, 0 }, /* R189 */ - { 0x0000, 0x0000, 0 }, /* R190 */ - { 0x0000, 0x0000, 0 }, /* R191 */ - { 0x0000, 0x0000, 0 }, /* R192 */ - { 0x0000, 0x0000, 0 }, /* R193 */ - { 0x0000, 0x0000, 0 }, /* R194 */ - { 0x0000, 0x0000, 0 }, /* R195 */ - { 0x0000, 0x0000, 0 }, /* R196 */ - { 0x0000, 0x0000, 0 }, /* R197 */ - { 0x0000, 0x0000, 0 }, /* R198 */ - { 0x0000, 0x0000, 0 }, /* R199 */ - { 0x0000, 0x0000, 0 }, /* R200 */ - { 0x0000, 0x0000, 0 }, /* R201 */ - { 0x0000, 0x0000, 0 }, /* R202 */ - { 0x0000, 0x0000, 0 }, /* R203 */ - { 0x0070, 0x0070, 0 }, /* R204 - Analogue Output Bias 0 */ - { 0x0000, 0x0000, 0 }, /* R205 */ - { 0x0000, 0x0000, 0 }, /* R206 */ - { 0x0000, 0x0000, 0 }, /* R207 */ - { 0x0000, 0x0000, 0 }, /* R208 */ - { 0x0000, 0x0000, 0 }, /* R209 */ - { 0x0000, 0x0000, 0 }, /* R210 */ - { 0x0000, 0x0000, 0 }, /* R211 */ - { 0x0000, 0x0000, 0 }, /* R212 */ - { 0x0000, 0x0000, 0 }, /* R213 */ - { 0x0000, 0x0000, 0 }, /* R214 */ - { 0x0000, 0x0000, 0 }, /* R215 */ - { 0x0000, 0x0000, 0 }, /* R216 */ - { 0x0000, 0x0000, 0 }, /* R217 */ - { 0x0000, 0x0000, 0 }, /* R218 */ - { 0x0000, 0x0000, 0 }, /* R219 */ - { 0x0000, 0x0000, 0 }, /* R220 */ - { 0x0000, 0x0000, 0 }, /* R221 */ - { 0x0000, 0x0000, 0 }, /* R222 */ - { 0x0000, 0x0000, 0 }, /* R223 */ - { 0x0000, 0x0000, 0 }, /* R224 */ - { 0x0000, 0x0000, 0 }, /* R225 */ - { 0x0000, 0x0000, 0 }, /* R226 */ - { 0x0000, 0x0000, 0 }, /* R227 */ - { 0x0000, 0x0000, 0 }, /* R228 */ - { 0x0000, 0x0000, 0 }, /* R229 */ - { 0x0000, 0x0000, 0 }, /* R230 */ - { 0x0000, 0x0000, 0 }, /* R231 */ - { 0x0000, 0x0000, 0 }, /* R232 */ - { 0x0000, 0x0000, 0 }, /* R233 */ - { 0x0000, 0x0000, 0 }, /* R234 */ - { 0x0000, 0x0000, 0 }, /* R235 */ - { 0x0000, 0x0000, 0 }, /* R236 */ - { 0x0000, 0x0000, 0 }, /* R237 */ - { 0x0000, 0x0000, 0 }, /* R238 */ - { 0x0000, 0x0000, 0 }, /* R239 */ - { 0x0000, 0x0000, 0 }, /* R240 */ - { 0x0000, 0x0000, 0 }, /* R241 */ - { 0x0000, 0x0000, 0 }, /* R242 */ - { 0x0000, 0x0000, 0 }, /* R243 */ - { 0x0000, 0x0000, 0 }, /* R244 */ - { 0x0000, 0x0000, 0 }, /* R245 */ - { 0x0000, 0x0000, 0 }, /* R246 */ - { 0x0001, 0x0001, 0 }, /* R247 - FLL NCO Test 0 */ - { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */ -}; +static bool wm8904_volatile_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WM8904_SW_RESET_AND_ID: + case WM8904_REVISION: + case WM8904_DC_SERVO_1: + case WM8904_DC_SERVO_6: + case WM8904_DC_SERVO_7: + case WM8904_DC_SERVO_8: + case WM8904_DC_SERVO_9: + case WM8904_DC_SERVO_READBACK_0: + case WM8904_INTERRUPT_STATUS: + return true; + default: + return false; + } +} -static int wm8904_volatile_register(struct snd_soc_codec *codec, unsigned int reg) +static bool wm8904_readable_register(struct device *dev, unsigned int reg) { - return wm8904_access[reg].vol; + switch (reg) { + case WM8904_SW_RESET_AND_ID: + case WM8904_REVISION: + case WM8904_BIAS_CONTROL_0: + case WM8904_VMID_CONTROL_0: + case WM8904_MIC_BIAS_CONTROL_0: + case WM8904_MIC_BIAS_CONTROL_1: + case WM8904_ANALOGUE_DAC_0: + case WM8904_MIC_FILTER_CONTROL: + case WM8904_ANALOGUE_ADC_0: + case WM8904_POWER_MANAGEMENT_0: + case WM8904_POWER_MANAGEMENT_2: + case WM8904_POWER_MANAGEMENT_3: + case WM8904_POWER_MANAGEMENT_6: + case WM8904_CLOCK_RATES_0: + case WM8904_CLOCK_RATES_1: + case WM8904_CLOCK_RATES_2: + case WM8904_AUDIO_INTERFACE_0: + case WM8904_AUDIO_INTERFACE_1: + case WM8904_AUDIO_INTERFACE_2: + case WM8904_AUDIO_INTERFACE_3: + case WM8904_DAC_DIGITAL_VOLUME_LEFT: + case WM8904_DAC_DIGITAL_VOLUME_RIGHT: + case WM8904_DAC_DIGITAL_0: + case WM8904_DAC_DIGITAL_1: + case WM8904_ADC_DIGITAL_VOLUME_LEFT: + case WM8904_ADC_DIGITAL_VOLUME_RIGHT: + case WM8904_ADC_DIGITAL_0: + case WM8904_DIGITAL_MICROPHONE_0: + case WM8904_DRC_0: + case WM8904_DRC_1: + case WM8904_DRC_2: + case WM8904_DRC_3: + case WM8904_ANALOGUE_LEFT_INPUT_0: + case WM8904_ANALOGUE_RIGHT_INPUT_0: + case WM8904_ANALOGUE_LEFT_INPUT_1: + case WM8904_ANALOGUE_RIGHT_INPUT_1: + case WM8904_ANALOGUE_OUT1_LEFT: + case WM8904_ANALOGUE_OUT1_RIGHT: + case WM8904_ANALOGUE_OUT2_LEFT: + case WM8904_ANALOGUE_OUT2_RIGHT: + case WM8904_ANALOGUE_OUT12_ZC: + case WM8904_DC_SERVO_0: + case WM8904_DC_SERVO_1: + case WM8904_DC_SERVO_2: + case WM8904_DC_SERVO_4: + case WM8904_DC_SERVO_5: + case WM8904_DC_SERVO_6: + case WM8904_DC_SERVO_7: + case WM8904_DC_SERVO_8: + case WM8904_DC_SERVO_9: + case WM8904_DC_SERVO_READBACK_0: + case WM8904_ANALOGUE_HP_0: + case WM8904_ANALOGUE_LINEOUT_0: + case WM8904_CHARGE_PUMP_0: + case WM8904_CLASS_W_0: + case WM8904_WRITE_SEQUENCER_0: + case WM8904_WRITE_SEQUENCER_1: + case WM8904_WRITE_SEQUENCER_2: + case WM8904_WRITE_SEQUENCER_3: + case WM8904_WRITE_SEQUENCER_4: + case WM8904_FLL_CONTROL_1: + case WM8904_FLL_CONTROL_2: + case WM8904_FLL_CONTROL_3: + case WM8904_FLL_CONTROL_4: + case WM8904_FLL_CONTROL_5: + case WM8904_GPIO_CONTROL_1: + case WM8904_GPIO_CONTROL_2: + case WM8904_GPIO_CONTROL_3: + case WM8904_GPIO_CONTROL_4: + case WM8904_DIGITAL_PULLS: + case WM8904_INTERRUPT_STATUS: + case WM8904_INTERRUPT_STATUS_MASK: + case WM8904_INTERRUPT_POLARITY: + case WM8904_INTERRUPT_DEBOUNCE: + case WM8904_EQ1: + case WM8904_EQ2: + case WM8904_EQ3: + case WM8904_EQ4: + case WM8904_EQ5: + case WM8904_EQ6: + case WM8904_EQ7: + case WM8904_EQ8: + case WM8904_EQ9: + case WM8904_EQ10: + case WM8904_EQ11: + case WM8904_EQ12: + case WM8904_EQ13: + case WM8904_EQ14: + case WM8904_EQ15: + case WM8904_EQ16: + case WM8904_EQ17: + case WM8904_EQ18: + case WM8904_EQ19: + case WM8904_EQ20: + case WM8904_EQ21: + case WM8904_EQ22: + case WM8904_EQ23: + case WM8904_EQ24: + case WM8904_CONTROL_INTERFACE_TEST_1: + case WM8904_ANALOGUE_OUTPUT_BIAS_0: + case WM8904_FLL_NCO_TEST_0: + case WM8904_FLL_NCO_TEST_1: + return true; + default: + return true; + } } static int wm8904_reset(struct snd_soc_codec *codec) @@ -2120,7 +1834,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec, return ret; } - snd_soc_cache_sync(codec); + regcache_sync(wm8904->regmap); /* Enable bias */ snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, @@ -2346,6 +2060,7 @@ static int wm8904_probe(struct snd_soc_codec *codec) codec->cache_sync = 1; codec->dapm.idle_bias_off = 1; + codec->control_data = wm8904->regmap; switch (wm8904->devtype) { case WM8904: @@ -2359,7 +2074,7 @@ static int wm8904_probe(struct snd_soc_codec *codec) return -EINVAL; } - ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); + ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); if (ret != 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; @@ -2387,7 +2102,7 @@ static int wm8904_probe(struct snd_soc_codec *codec) dev_err(codec->dev, "Failed to read ID register\n"); goto err_enable; } - if (ret != wm8904_reg[WM8904_SW_RESET_AND_ID]) { + if (ret != 0x8904) { dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret); ret = -EINVAL; goto err_enable; @@ -2493,10 +2208,19 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8904 = { .suspend = wm8904_suspend, .resume = wm8904_resume, .set_bias_level = wm8904_set_bias_level, - .reg_cache_size = ARRAY_SIZE(wm8904_reg), - .reg_word_size = sizeof(u16), - .reg_cache_default = wm8904_reg, - .volatile_register = wm8904_volatile_register, +}; + +static const struct regmap_config wm8904_regmap = { + .reg_bits = 8, + .val_bits = 16, + + .max_register = WM8904_MAX_REGISTER, + .volatile_reg = wm8904_volatile_register, + .readable_reg = wm8904_readable_register, + + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wm8904_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8904_reg_defaults), }; static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, @@ -2510,19 +2234,35 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, if (wm8904 == NULL) return -ENOMEM; + wm8904->regmap = regmap_init_i2c(i2c, &wm8904_regmap); + if (IS_ERR(wm8904->regmap)) { + ret = PTR_ERR(wm8904->regmap); + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + wm8904->devtype = id->driver_data; i2c_set_clientdata(i2c, wm8904); wm8904->pdata = i2c->dev.platform_data; ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8904, &wm8904_dai, 1); + if (ret != 0) + goto err; + + return 0; +err: + regmap_exit(wm8904->regmap); return ret; } static __devexit int wm8904_i2c_remove(struct i2c_client *client) { + struct wm8904_priv *wm8904 = i2c_get_clientdata(client); snd_soc_unregister_codec(&client->dev); + regmap_exit(wm8904->regmap); return 0; } -- cgit v0.10.2 From b5531205f51c6f5f073fd0c63cfa9659fa4d912b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 21:15:48 +0000 Subject: ASoC: Make I2C usage unconditional in WM8940 Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 14039ea..ffc123b 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -743,7 +743,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8940 = { .volatile_register = wm8940_volatile_register, }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static __devinit int wm8940_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -786,27 +785,22 @@ static struct i2c_driver wm8940_i2c_driver = { .remove = __devexit_p(wm8940_i2c_remove), .id_table = wm8940_i2c_id, }; -#endif static int __init wm8940_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&wm8940_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register wm8940 I2C driver: %d\n", ret); } -#endif return ret; } module_init(wm8940_modinit); static void __exit wm8940_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) i2c_del_driver(&wm8940_i2c_driver); -#endif } module_exit(wm8940_exit); -- cgit v0.10.2 From 42dad0d84a318d5245b8b311644388dae5f521c0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 21:16:59 +0000 Subject: ASoC: Convert WM8940 to devm_kzalloc() Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index ffc123b..ae1933e 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -749,7 +749,8 @@ static __devinit int wm8940_i2c_probe(struct i2c_client *i2c, struct wm8940_priv *wm8940; int ret; - wm8940 = kzalloc(sizeof(struct wm8940_priv), GFP_KERNEL); + wm8940 = devm_kzalloc(&i2c->dev, sizeof(struct wm8940_priv), + GFP_KERNEL); if (wm8940 == NULL) return -ENOMEM; @@ -758,15 +759,14 @@ static __devinit int wm8940_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8940, &wm8940_dai, 1); - if (ret < 0) - kfree(wm8940); + return ret; } static __devexit int wm8940_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); + return 0; } -- cgit v0.10.2 From 1e9c898df0ef659dacbc9ee037f825cc380854cf Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 21:21:49 +0000 Subject: ASoC: Make I2C usage unconditional in WM8955 Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 9245481..adcfdca 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -1001,7 +1001,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8955 = { .reg_cache_default = wm8955_reg, }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static __devinit int wm8955_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -1044,27 +1043,22 @@ static struct i2c_driver wm8955_i2c_driver = { .remove = __devexit_p(wm8955_i2c_remove), .id_table = wm8955_i2c_id, }; -#endif static int __init wm8955_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&wm8955_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register WM8955 I2C driver: %d\n", ret); } -#endif return ret; } module_init(wm8955_modinit); static void __exit wm8955_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) i2c_del_driver(&wm8955_i2c_driver); -#endif } module_exit(wm8955_exit); -- cgit v0.10.2 From ba5c88d02de255b51d399001115384f8847cb0df Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 21:23:04 +0000 Subject: ASoC: Convert WM8955 to devm_kzalloc() Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index adcfdca..cc6f669 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -1007,7 +1007,8 @@ static __devinit int wm8955_i2c_probe(struct i2c_client *i2c, struct wm8955_priv *wm8955; int ret; - wm8955 = kzalloc(sizeof(struct wm8955_priv), GFP_KERNEL); + wm8955 = devm_kzalloc(&i2c->dev, sizeof(struct wm8955_priv), + GFP_KERNEL); if (wm8955 == NULL) return -ENOMEM; @@ -1016,15 +1017,13 @@ static __devinit int wm8955_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8955, &wm8955_dai, 1); - if (ret < 0) - kfree(wm8955); + return ret; } static __devexit int wm8955_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } -- cgit v0.10.2 From 9887cb9e651da91c5bad2578d71e7ff8410e14b7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 21:39:44 +0000 Subject: ASoC: Use standard register cache sync for WM8955 Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index cc6f669..559c96b 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -795,18 +795,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec, return ret; } - /* Sync back cached values if they're - * different from the hardware default. - */ - for (i = 0; i < codec->driver->reg_cache_size; i++) { - if (i == WM8955_RESET) - continue; - - if (reg_cache[i] == wm8955_reg[i]) - continue; - - snd_soc_write(codec, i, reg_cache[i]); - } + snd_soc_cache_sync(codec); /* Enable VREF and VMID */ snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1, -- cgit v0.10.2 From 95860fdf0f565f96fc37561b6794177604f89097 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 21:42:36 +0000 Subject: ASoC: Convert WM8955 to direct regmap API usage Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 559c96b..11fb2dd 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -38,7 +39,7 @@ static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = { /* codec private data */ struct wm8955_priv { - enum snd_soc_control_type control_type; + struct regmap *regmap; unsigned int mclk_rate; @@ -48,69 +49,85 @@ struct wm8955_priv { struct regulator_bulk_data supplies[WM8955_NUM_SUPPLIES]; }; -static const u16 wm8955_reg[WM8955_MAX_REGISTER + 1] = { - 0x0000, /* R0 */ - 0x0000, /* R1 */ - 0x0079, /* R2 - LOUT1 volume */ - 0x0079, /* R3 - ROUT1 volume */ - 0x0000, /* R4 */ - 0x0008, /* R5 - DAC Control */ - 0x0000, /* R6 */ - 0x000A, /* R7 - Audio Interface */ - 0x0000, /* R8 - Sample Rate */ - 0x0000, /* R9 */ - 0x00FF, /* R10 - Left DAC volume */ - 0x00FF, /* R11 - Right DAC volume */ - 0x000F, /* R12 - Bass control */ - 0x000F, /* R13 - Treble control */ - 0x0000, /* R14 */ - 0x0000, /* R15 - Reset */ - 0x0000, /* R16 */ - 0x0000, /* R17 */ - 0x0000, /* R18 */ - 0x0000, /* R19 */ - 0x0000, /* R20 */ - 0x0000, /* R21 */ - 0x0000, /* R22 */ - 0x00C1, /* R23 - Additional control (1) */ - 0x0000, /* R24 - Additional control (2) */ - 0x0000, /* R25 - Power Management (1) */ - 0x0000, /* R26 - Power Management (2) */ - 0x0000, /* R27 - Additional Control (3) */ - 0x0000, /* R28 */ - 0x0000, /* R29 */ - 0x0000, /* R30 */ - 0x0000, /* R31 */ - 0x0000, /* R32 */ - 0x0000, /* R33 */ - 0x0050, /* R34 - Left out Mix (1) */ - 0x0050, /* R35 - Left out Mix (2) */ - 0x0050, /* R36 - Right out Mix (1) */ - 0x0050, /* R37 - Right Out Mix (2) */ - 0x0050, /* R38 - Mono out Mix (1) */ - 0x0050, /* R39 - Mono out Mix (2) */ - 0x0079, /* R40 - LOUT2 volume */ - 0x0079, /* R41 - ROUT2 volume */ - 0x0079, /* R42 - MONOOUT volume */ - 0x0000, /* R43 - Clocking / PLL */ - 0x0103, /* R44 - PLL Control 1 */ - 0x0024, /* R45 - PLL Control 2 */ - 0x01BA, /* R46 - PLL Control 3 */ - 0x0000, /* R47 */ - 0x0000, /* R48 */ - 0x0000, /* R49 */ - 0x0000, /* R50 */ - 0x0000, /* R51 */ - 0x0000, /* R52 */ - 0x0000, /* R53 */ - 0x0000, /* R54 */ - 0x0000, /* R55 */ - 0x0000, /* R56 */ - 0x0000, /* R57 */ - 0x0000, /* R58 */ - 0x0000, /* R59 - PLL Control 4 */ +static const struct reg_default wm8955_reg_defaults[] = { + { 2, 0x0079 }, /* R2 - LOUT1 volume */ + { 3, 0x0079 }, /* R3 - ROUT1 volume */ + { 5, 0x0008 }, /* R5 - DAC Control */ + { 7, 0x000A }, /* R7 - Audio Interface */ + { 8, 0x0000 }, /* R8 - Sample Rate */ + { 10, 0x00FF }, /* R10 - Left DAC volume */ + { 11, 0x00FF }, /* R11 - Right DAC volume */ + { 12, 0x000F }, /* R12 - Bass control */ + { 13, 0x000F }, /* R13 - Treble control */ + { 23, 0x00C1 }, /* R23 - Additional control (1) */ + { 24, 0x0000 }, /* R24 - Additional control (2) */ + { 25, 0x0000 }, /* R25 - Power Management (1) */ + { 26, 0x0000 }, /* R26 - Power Management (2) */ + { 27, 0x0000 }, /* R27 - Additional Control (3) */ + { 34, 0x0050 }, /* R34 - Left out Mix (1) */ + { 35, 0x0050 }, /* R35 - Left out Mix (2) */ + { 36, 0x0050 }, /* R36 - Right out Mix (1) */ + { 37, 0x0050 }, /* R37 - Right Out Mix (2) */ + { 38, 0x0050 }, /* R38 - Mono out Mix (1) */ + { 39, 0x0050 }, /* R39 - Mono out Mix (2) */ + { 40, 0x0079 }, /* R40 - LOUT2 volume */ + { 41, 0x0079 }, /* R41 - ROUT2 volume */ + { 42, 0x0079 }, /* R42 - MONOOUT volume */ + { 43, 0x0000 }, /* R43 - Clocking / PLL */ + { 44, 0x0103 }, /* R44 - PLL Control 1 */ + { 45, 0x0024 }, /* R45 - PLL Control 2 */ + { 46, 0x01BA }, /* R46 - PLL Control 3 */ + { 59, 0x0000 }, /* R59 - PLL Control 4 */ }; +static bool wm8955_writeable(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WM8955_LOUT1_VOLUME: + case WM8955_ROUT1_VOLUME: + case WM8955_DAC_CONTROL: + case WM8955_AUDIO_INTERFACE: + case WM8955_SAMPLE_RATE: + case WM8955_LEFT_DAC_VOLUME: + case WM8955_RIGHT_DAC_VOLUME: + case WM8955_BASS_CONTROL: + case WM8955_TREBLE_CONTROL: + case WM8955_RESET: + case WM8955_ADDITIONAL_CONTROL_1: + case WM8955_ADDITIONAL_CONTROL_2: + case WM8955_POWER_MANAGEMENT_1: + case WM8955_POWER_MANAGEMENT_2: + case WM8955_ADDITIONAL_CONTROL_3: + case WM8955_LEFT_OUT_MIX_1: + case WM8955_LEFT_OUT_MIX_2: + case WM8955_RIGHT_OUT_MIX_1: + case WM8955_RIGHT_OUT_MIX_2: + case WM8955_MONO_OUT_MIX_1: + case WM8955_MONO_OUT_MIX_2: + case WM8955_LOUT2_VOLUME: + case WM8955_ROUT2_VOLUME: + case WM8955_MONOOUT_VOLUME: + case WM8955_CLOCKING_PLL: + case WM8955_PLL_CONTROL_1: + case WM8955_PLL_CONTROL_2: + case WM8955_PLL_CONTROL_3: + case WM8955_PLL_CONTROL_4: + return true; + default: + return false; + } +} + +static bool wm8955_volatile(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WM8955_RESET: + return true; + default: + return false; + } +} + static int wm8955_reset(struct snd_soc_codec *codec) { return snd_soc_write(codec, WM8955_RESET, 0); @@ -765,8 +782,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); - u16 *reg_cache = codec->reg_cache; - int ret, i; + int ret; switch (level) { case SND_SOC_BIAS_ON: @@ -795,7 +811,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec, return ret; } - snd_soc_cache_sync(codec); + regcache_sync(wm8955->regmap); /* Enable VREF and VMID */ snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1, @@ -869,8 +885,12 @@ static struct snd_soc_dai_driver wm8955_dai = { #ifdef CONFIG_PM static int wm8955_suspend(struct snd_soc_codec *codec) { + struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); + wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF); + regcache_mark_dirty(wm8955->regmap); + return 0; } @@ -889,10 +909,11 @@ static int wm8955_probe(struct snd_soc_codec *codec) { struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); struct wm8955_pdata *pdata = dev_get_platdata(codec->dev); - u16 *reg_cache = codec->reg_cache; int ret, i; - ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8955->control_type); + codec->control_data = wm8955->regmap; + + ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); if (ret != 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; @@ -947,12 +968,12 @@ static int wm8955_probe(struct snd_soc_codec *codec) /* Set platform data values */ if (pdata) { if (pdata->out2_speaker) - reg_cache[WM8955_ADDITIONAL_CONTROL_2] - |= WM8955_ROUT2INV; + snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_2, + WM8955_ROUT2INV, WM8955_ROUT2INV); if (pdata->monoin_diff) - reg_cache[WM8955_MONO_OUT_MIX_1] - |= WM8955_DMEN; + snd_soc_update_bits(codec, WM8955_MONO_OUT_MIX_1, + WM8955_DMEN, WM8955_DMEN); } wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY); @@ -985,9 +1006,19 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8955 = { .suspend = wm8955_suspend, .resume = wm8955_resume, .set_bias_level = wm8955_set_bias_level, - .reg_cache_size = ARRAY_SIZE(wm8955_reg), - .reg_word_size = sizeof(u16), - .reg_cache_default = wm8955_reg, +}; + +static const struct regmap_config wm8955_regmap = { + .reg_bits = 7, + .val_bits = 9, + + .max_register = WM8955_MAX_REGISTER, + .volatile_reg = wm8955_volatile, + .writeable_reg = wm8955_writeable, + + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wm8955_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8955_reg_defaults), }; static __devinit int wm8955_i2c_probe(struct i2c_client *i2c, @@ -1001,18 +1032,35 @@ static __devinit int wm8955_i2c_probe(struct i2c_client *i2c, if (wm8955 == NULL) return -ENOMEM; + wm8955->regmap = regmap_init_i2c(i2c, &wm8955_regmap); + if (IS_ERR(wm8955->regmap)) { + ret = PTR_ERR(wm8955->regmap); + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + i2c_set_clientdata(i2c, wm8955); - wm8955->control_type = SND_SOC_I2C; ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8955, &wm8955_dai, 1); + if (ret != 0) + goto err; + + return ret; +err: + regmap_exit(wm8955->regmap); return ret; } static __devexit int wm8955_i2c_remove(struct i2c_client *client) { + struct wm8955_priv *wm8955 = i2c_get_clientdata(client); + snd_soc_unregister_codec(&client->dev); + regmap_exit(wm8955->regmap); + return 0; } -- cgit v0.10.2 From 3294c4c603a1c4ce00e5b8495e99dd3ba076f1e3 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 29 Dec 2011 21:45:27 +0000 Subject: ASoC: Convert WM8955 to table based DAPM and control init Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 11fb2dd..61fe974 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -544,7 +544,7 @@ SND_SOC_DAPM_OUTPUT("MONOOUT"), SND_SOC_DAPM_OUTPUT("OUT3"), }; -static const struct snd_soc_dapm_route wm8955_intercon[] = { +static const struct snd_soc_dapm_route wm8955_dapm_routes[] = { { "DACL", NULL, "SYSCLK" }, { "DACR", NULL, "SYSCLK" }, @@ -589,21 +589,6 @@ static const struct snd_soc_dapm_route wm8955_intercon[] = { { "OUT3", NULL, "OUT3 PGA" }, }; -static int wm8955_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_add_controls(codec, wm8955_snd_controls, - ARRAY_SIZE(wm8955_snd_controls)); - - snd_soc_dapm_new_controls(dapm, wm8955_dapm_widgets, - ARRAY_SIZE(wm8955_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, wm8955_intercon, - ARRAY_SIZE(wm8955_intercon)); - - return 0; -} - static int wm8955_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -981,7 +966,6 @@ static int wm8955_probe(struct snd_soc_codec *codec) /* Bias level configuration will have done an extra enable */ regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); - wm8955_add_widgets(codec); return 0; err_enable: @@ -1006,6 +990,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8955 = { .suspend = wm8955_suspend, .resume = wm8955_resume, .set_bias_level = wm8955_set_bias_level, + + .controls = wm8955_snd_controls, + .num_controls = ARRAY_SIZE(wm8955_snd_controls), + .dapm_widgets = wm8955_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8955_dapm_widgets), + .dapm_routes = wm8955_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8955_dapm_routes), }; static const struct regmap_config wm8955_regmap = { -- cgit v0.10.2 From 6296914ccefe6efefee811436dd7cfad6545f2eb Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Sun, 1 Jan 2012 02:14:24 +0100 Subject: ASoC: use proper defines for stream directions in pcm engines Signed-off-by: Joachim Eastwood Signed-off-by: Mark Brown diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index 4f59bba..96bb92d 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c @@ -311,23 +311,23 @@ static int fsl_dma_new(struct snd_soc_pcm_runtime *rtd) * should allocate a DMA buffer only for the streams that are valid. */ - if (pcm->streams[0].substream) { + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev, fsl_dma_hardware.buffer_bytes_max, - &pcm->streams[0].substream->dma_buffer); + &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer); if (ret) { dev_err(card->dev, "can't alloc playback dma buffer\n"); return ret; } } - if (pcm->streams[1].substream) { + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev, fsl_dma_hardware.buffer_bytes_max, - &pcm->streams[1].substream->dma_buffer); + &pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->dma_buffer); if (ret) { dev_err(card->dev, "can't alloc capture dma buffer\n"); - snd_dma_free_pages(&pcm->streams[0].substream->dma_buffer); + snd_dma_free_pages(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer); return ret; } } diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c index e7803d3..2112e22 100644 --- a/sound/soc/fsl/mpc5200_dma.c +++ b/sound/soc/fsl/mpc5200_dma.c @@ -316,16 +316,16 @@ static int psc_dma_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = 0xffffffff; - if (pcm->streams[0].substream) { + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev, - size, &pcm->streams[0].substream->dma_buffer); + size, &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer); if (rc) goto playback_alloc_err; } - if (pcm->streams[1].substream) { + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev, - size, &pcm->streams[1].substream->dma_buffer); + size, &pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->dma_buffer); if (rc) goto capture_alloc_err; } @@ -336,8 +336,8 @@ static int psc_dma_new(struct snd_soc_pcm_runtime *rtd) return 0; capture_alloc_err: - if (pcm->streams[0].substream) - snd_dma_free_pages(&pcm->streams[0].substream->dma_buffer); + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) + snd_dma_free_pages(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer); playback_alloc_err: dev_err(card->dev, "Cannot allocate buffer(s)\n"); diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c index 43c014f..716da86 100644 --- a/sound/soc/s6000/s6000-pcm.c +++ b/sound/soc/s6000/s6000-pcm.c @@ -435,7 +435,8 @@ static void s6000_pcm_free(struct snd_pcm *pcm) { struct snd_soc_pcm_runtime *runtime = pcm->private_data; struct s6000_pcm_dma_params *params = - snd_soc_dai_get_dma_data(runtime->cpu_dai, pcm->streams[0].substream); + snd_soc_dai_get_dma_data(runtime->cpu_dai, + pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream); free_irq(params->irq, pcm); snd_pcm_lib_preallocate_free_for_all(pcm); @@ -451,7 +452,7 @@ static int s6000_pcm_new(struct snd_soc_pcm_runtime *runtime) int res; params = snd_soc_dai_get_dma_data(runtime->cpu_dai, - pcm->streams[0].substream); + pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream); if (!card->dev->dma_mask) card->dev->dma_mask = &s6000_pcm_dmamask; -- cgit v0.10.2 From 350e16d5293b54e2ef105ebd777f43dbe5a15ffa Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Sun, 1 Jan 2012 02:43:03 +0100 Subject: ASoC: replace 0xffffffff with DMA_BIT_MASK macro Signed-off-by: Joachim Eastwood Signed-off-by: Mark Brown diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c index a21ff45..9b84f98 100644 --- a/sound/soc/atmel/atmel-pcm.c +++ b/sound/soc/atmel/atmel-pcm.c @@ -362,7 +362,7 @@ static struct snd_pcm_ops atmel_pcm_ops = { /*--------------------------------------------------------------------------*\ * ASoC platform driver \*--------------------------------------------------------------------------*/ -static u64 atmel_pcm_dmamask = 0xffffffff; +static u64 atmel_pcm_dmamask = DMA_BIT_MASK(32); static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) { @@ -373,7 +373,7 @@ static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->dma_mask) card->dev->dma_mask = &atmel_pcm_dmamask; if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = 0xffffffff; + card->dev->coherent_dma_mask = DMA_BIT_MASK(32); if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = atmel_pcm_preallocate_dma_buffer(pcm, diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index b26401f..97d77b2 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c @@ -826,7 +826,7 @@ static void davinci_pcm_free(struct snd_pcm *pcm) } } -static u64 davinci_pcm_dmamask = 0xffffffff; +static u64 davinci_pcm_dmamask = DMA_BIT_MASK(32); static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd) { @@ -837,7 +837,7 @@ static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->dma_mask) card->dev->dma_mask = &davinci_pcm_dmamask; if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = 0xffffffff; + card->dev->coherent_dma_mask = DMA_BIT_MASK(32); if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = davinci_pcm_preallocate_dma_buffer(pcm, diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c index de83904..32adca3 100644 --- a/sound/soc/ep93xx/ep93xx-pcm.c +++ b/sound/soc/ep93xx/ep93xx-pcm.c @@ -281,7 +281,7 @@ static void ep93xx_pcm_free_dma_buffers(struct snd_pcm *pcm) } } -static u64 ep93xx_pcm_dmamask = 0xffffffff; +static u64 ep93xx_pcm_dmamask = DMA_BIT_MASK(32); static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd) { @@ -292,7 +292,7 @@ static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->dma_mask) card->dev->dma_mask = &ep93xx_pcm_dmamask; if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = 0xffffffff; + card->dev->coherent_dma_mask = DMA_BIT_MASK(32); if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = ep93xx_pcm_preallocate_dma_buffer(pcm, diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c index 2112e22..33adbf1 100644 --- a/sound/soc/fsl/mpc5200_dma.c +++ b/sound/soc/fsl/mpc5200_dma.c @@ -298,7 +298,7 @@ static struct snd_pcm_ops psc_dma_ops = { .hw_params = psc_dma_hw_params, }; -static u64 psc_dma_dmamask = 0xffffffff; +static u64 psc_dma_dmamask = DMA_BIT_MASK(32); static int psc_dma_new(struct snd_soc_pcm_runtime *rtd) { struct snd_card *card = rtd->card->snd_card; @@ -314,7 +314,7 @@ static int psc_dma_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->dma_mask) card->dev->dma_mask = &psc_dma_dmamask; if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = 0xffffffff; + card->dev->coherent_dma_mask = DMA_BIT_MASK(32); if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev, diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c index d038540..b9f1659 100644 --- a/sound/soc/kirkwood/kirkwood-dma.c +++ b/sound/soc/kirkwood/kirkwood-dma.c @@ -55,7 +55,7 @@ static struct snd_pcm_hardware kirkwood_dma_snd_hw = { .fifo_size = 0, }; -static u64 kirkwood_dma_dmamask = 0xFFFFFFFFUL; +static u64 kirkwood_dma_dmamask = DMA_BIT_MASK(32); static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id) { @@ -324,7 +324,7 @@ static int kirkwood_dma_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->dma_mask) card->dev->dma_mask = &kirkwood_dma_dmamask; if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = 0xffffffff; + card->dev->coherent_dma_mask = DMA_BIT_MASK(32); if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = kirkwood_dma_preallocate_dma_buffer(pcm, diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index e4ba17c..ddc6cde 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c @@ -411,7 +411,7 @@ static int dma_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->dma_mask) card->dev->dma_mask = &dma_mask; if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = 0xffffffff; + card->dev->coherent_dma_mask = DMA_BIT_MASK(32); if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = preallocate_dma_buffer(pcm, diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index c224315..8b44571 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -336,7 +336,7 @@ static int tegra_pcm_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->dma_mask) card->dev->dma_mask = &tegra_dma_mask; if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = 0xffffffff; + card->dev->coherent_dma_mask = DMA_BIT_MASK(32); if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = tegra_pcm_preallocate_dma_buffer(pcm, -- cgit v0.10.2 From 3b09bb820dda209d5c81e329420ccf36dd30c8eb Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 9 Jan 2012 12:09:29 +0000 Subject: ASoC: core - Improve card registration error messaging for large DAI links. Print out the offending DAI link entry when a naming error occurs. Makes thing easier to debug for machines with a large number of DAI links. Signed-off-by: Liam Girdwood Signed-off-by: Mark Brown diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b5ecf6d..41c8e45 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2864,7 +2864,8 @@ int snd_soc_register_card(struct snd_soc_card *card) */ if (!!link->codec_name == !!link->codec_of_node) { dev_err(card->dev, - "Neither/both codec name/of_node are set\n"); + "Neither/both codec name/of_node are set for %s\n", + link->name); return -EINVAL; } @@ -2874,7 +2875,7 @@ int snd_soc_register_card(struct snd_soc_card *card) */ if (link->platform_name && link->platform_of_node) { dev_err(card->dev, - "Both platform name/of_node are set\n"); + "Both platform name/of_node are set for %s\n", link->name); return -EINVAL; } @@ -2884,7 +2885,8 @@ int snd_soc_register_card(struct snd_soc_card *card) */ if (!!link->cpu_dai_name == !!link->cpu_dai_of_node) { dev_err(card->dev, - "Neither/both cpu_dai name/of_node are set\n"); + "Neither/both cpu_dai name/of_node are set for %s\n", + link->name); return -EINVAL; } } -- cgit v0.10.2 From 9b85fc90634972634a229aaa1c94f8c9a50fddbc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 7 Jan 2012 18:02:57 -0800 Subject: ASoC: Optimise performance of WM8904 ADC 128fs OSR mode Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index f2a740d..14afc11 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -304,6 +304,7 @@ static bool wm8904_readable_register(struct device *dev, unsigned int reg) case WM8904_EQ23: case WM8904_EQ24: case WM8904_CONTROL_INTERFACE_TEST_1: + case WM8904_ADC_TEST_0: case WM8904_ANALOGUE_OUTPUT_BIAS_0: case WM8904_FLL_NCO_TEST_0: case WM8904_FLL_NCO_TEST_1: @@ -569,6 +570,29 @@ static const char *hpf_mode_text[] = { static const struct soc_enum hpf_mode = SOC_ENUM_SINGLE(WM8904_ADC_DIGITAL_0, 5, 4, hpf_mode_text); +static int wm8904_adc_osr_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + unsigned int val; + int ret; + + ret = snd_soc_put_volsw(kcontrol, ucontrol); + if (ret < 0) + return ret; + + if (ucontrol->value.integer.value[0]) + val = 0; + else + val = WM8904_ADC_128_OSR_TST_MODE | WM8904_ADC_BIASX1P5; + + snd_soc_update_bits(codec, WM8904_ADC_TEST_0, + WM8904_ADC_128_OSR_TST_MODE | WM8904_ADC_BIASX1P5, + val); + + return ret; +} + static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = { SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT, WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv), @@ -585,7 +609,12 @@ SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0, SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0), SOC_ENUM("High Pass Filter Mode", hpf_mode), -SOC_SINGLE("ADC 128x OSR Switch", WM8904_ANALOGUE_ADC_0, 0, 1, 0), +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "ADC 128x OSR Switch", + .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, + .put = wm8904_adc_osr_put, + .private_value = SOC_SINGLE_VALUE(WM8904_ANALOGUE_ADC_0, 0, 1, 0), +}, }; static const char *drc_path_text[] = { diff --git a/sound/soc/codecs/wm8904.h b/sound/soc/codecs/wm8904.h index 9e8c841..c29a0e8 100644 --- a/sound/soc/codecs/wm8904.h +++ b/sound/soc/codecs/wm8904.h @@ -123,6 +123,7 @@ #define WM8904_EQ23 0x9C #define WM8904_EQ24 0x9D #define WM8904_CONTROL_INTERFACE_TEST_1 0xA1 +#define WM8904_ADC_TEST_0 0xC6 #define WM8904_ANALOGUE_OUTPUT_BIAS_0 0xCC #define WM8904_FLL_NCO_TEST_0 0xF7 #define WM8904_FLL_NCO_TEST_1 0xF8 @@ -1557,6 +1558,16 @@ #define WM8904_USER_KEY_WIDTH 1 /* USER_KEY */ /* + * R198 (0xC6) - ADC Test 0 + */ +#define WM8904_ADC_128_OSR_TST_MODE 0x0004 /* ADC_128_OSR_TST_MODE */ +#define WM8904_ADC_128_OSR_TST_MODE_SHIFT 2 /* ADC_128_OSR_TST_MODE */ +#define WM8904_ADC_128_OSR_TST_MODE_WIDTH 1 /* ADC_128_OSR_TST_MODE */ +#define WM8904_ADC_BIASX1P5 0x0001 /* ADC_BIASX1P5 */ +#define WM8904_ADC_BIASX1P5_SHIFT 0 /* ADC_BIASX1P5 */ +#define WM8904_ADC_BIASX1P5_WIDTH 1 /* ADC_BIASX1P5 */ + +/* * R204 (0xCC) - Analogue Output Bias 0 */ #define WM8904_PGA_BIAS_MASK 0x0070 /* PGA_BIAS - [6:4] */ -- cgit v0.10.2 From 08656910bb80882aaad739faea6dac3a0818f71c Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 9 Jan 2012 12:10:16 +0000 Subject: ASoC: twl6040 - add method to query HS DC offset step size in mV Provide a method for mach drivers to query the HS DC offset step size in mV. Signed-off-by: Liam Girdwood Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 5b9c79b..284dd2e 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1052,6 +1052,19 @@ int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim) } EXPORT_SYMBOL_GPL(twl6040_get_trim_value); +int twl6040_get_hs_step_size(struct snd_soc_codec *codec) +{ + struct twl6040 *twl6040 = codec->control_data; + + if (twl6040_get_revid(twl6040) < TWL6040_REV_ES1_2) + /* For ES under ES_1.3 HS step is 2 mV */ + return 2; + else + /* For ES_1.3 HS step is 1 mV */ + return 1; +} +EXPORT_SYMBOL_GPL(twl6040_get_hs_step_size); + static const struct snd_kcontrol_new twl6040_snd_controls[] = { /* Capture gains */ SOC_DOUBLE_TLV("Capture Preamplifier Volume", diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h index ef273f1..0611406 100644 --- a/sound/soc/codecs/twl6040.h +++ b/sound/soc/codecs/twl6040.h @@ -39,5 +39,6 @@ void twl6040_hs_jack_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, int report); int twl6040_get_clk_id(struct snd_soc_codec *codec); int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim); +int twl6040_get_hs_step_size(struct snd_soc_codec *codec); #endif /* End of __TWL6040_H__ */ -- cgit v0.10.2 From 7aca69f9fe8f04ca37a01e2540960c53b24e3223 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 9 Jan 2012 12:36:24 +0000 Subject: ASoC: utils - Add support for a dummy codec driver. This is useful to create dummy codec devices where we need to have some DAI links without a real Codec. e.g. could be used to represent dumb FM, MODEM, etc This is also used by dynamic PCM for DAI links that have no codec. Signed-off-by: Liam Girdwood [Fixed the indentation -- broonie] Signed-off-by: Mark Brown diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 4220bb0..6005370 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c @@ -89,14 +89,32 @@ static struct snd_soc_platform_driver dummy_platform = { .ops = &dummy_dma_ops, }; +static struct snd_soc_codec_driver dummy_codec; +static struct snd_soc_dai_driver dummy_dai = { + .name = "snd-soc-dummy-dai", +}; + static __devinit int snd_soc_dummy_probe(struct platform_device *pdev) { - return snd_soc_register_platform(&pdev->dev, &dummy_platform); + int ret; + + ret = snd_soc_register_codec(&pdev->dev, &dummy_codec, &dummy_dai, 1); + if (ret < 0) + return ret; + + ret = snd_soc_register_platform(&pdev->dev, &dummy_platform); + if (ret < 0) { + snd_soc_unregister_codec(&pdev->dev); + return ret; + } + + return ret; } static __devexit int snd_soc_dummy_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); + snd_soc_unregister_codec(&pdev->dev); return 0; } -- cgit v0.10.2 From 2e932f29409ca6129578b10fa61b7cb9937b9f54 Mon Sep 17 00:00:00 2001 From: Manjunath Hadli Date: Tue, 10 Jan 2012 16:57:43 +0530 Subject: ASoC: CQ93VC: remove machine specific header file inclusion from codec driver remove unnecessary inclusion of machine specific header file mach/dm365.h from cq93vc.c voice codec driver which comes in the way of platform code consolidation. Signed-off-by: Manjunath Hadli Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 4854b47..06d2ea1 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c @@ -38,8 +38,6 @@ #include #include -#include - static inline unsigned int cq93vc_read(struct snd_soc_codec *codec, unsigned int reg) { -- cgit v0.10.2 From 291d64be3137b9bb709ce3bc72dbe2ca6b647466 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 10 Jan 2012 10:53:49 -0800 Subject: ASoC: Make WM8962 I2C usage unconditional We only support I2C so no need to ifdef. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 296de4e..63e908c 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -4155,7 +4155,6 @@ static const struct regmap_config wm8962_regmap = { .cache_type = REGCACHE_RBTREE, }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -4284,27 +4283,16 @@ static struct i2c_driver wm8962_i2c_driver = { .remove = __devexit_p(wm8962_i2c_remove), .id_table = wm8962_i2c_id, }; -#endif static int __init wm8962_modinit(void) { - int ret; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - ret = i2c_add_driver(&wm8962_i2c_driver); - if (ret != 0) { - printk(KERN_ERR "Failed to register WM8962 I2C driver: %d\n", - ret); - } -#endif - return 0; + return i2c_add_driver(&wm8962_i2c_driver); } module_init(wm8962_modinit); static void __exit wm8962_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) i2c_del_driver(&wm8962_i2c_driver); -#endif } module_exit(wm8962_exit); -- cgit v0.10.2 From 44fb864b8f696d3e8328b294e6515ad45aecfeb0 Mon Sep 17 00:00:00 2001 From: Ryan Mallon Date: Wed, 11 Jan 2012 14:14:31 +1100 Subject: ep93xx: Don't use system controller defines in audio drivers Both the Snapper CL15 and EDB93xx audio drivers set the same audio configuration in ep93xx_i2s_acquire. Remove the arguments to ep93xx_i2s_acquire so that the audio drivers no longer need the EP93XX_SYSCON defines exported. Cc: Hartley Sweeten Cc: Mika Westerberg Cc: Liam Girdwood Cc: Mark Brown Signed-off-by: Ryan Mallon Signed-off-by: Mark Brown diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 24203f9..b5c1dae 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -817,23 +817,12 @@ void __init ep93xx_register_i2s(void) #define EP93XX_I2SCLKDIV_MASK (EP93XX_SYSCON_I2SCLKDIV_ORIDE | \ EP93XX_SYSCON_I2SCLKDIV_SPOL) -int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config) +int ep93xx_i2s_acquire(void) { unsigned val; - /* Sanity check */ - if (i2s_pins & ~EP93XX_SYSCON_DEVCFG_I2S_MASK) - return -EINVAL; - if (i2s_config & ~EP93XX_I2SCLKDIV_MASK) - return -EINVAL; - - /* Must have only one of I2SONSSP/I2SONAC97 set */ - if ((i2s_pins & EP93XX_SYSCON_DEVCFG_I2SONSSP) == - (i2s_pins & EP93XX_SYSCON_DEVCFG_I2SONAC97)) - return -EINVAL; - - ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2S_MASK); - ep93xx_devcfg_set_bits(i2s_pins); + ep93xx_devcfg_set_clear(EP93XX_SYSCON_DEVCFG_I2SONAC97, + EP93XX_SYSCON_DEVCFG_I2S_MASK); /* * This is potentially racy with the clock api for i2s_mclk, sclk and @@ -843,7 +832,7 @@ int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config) */ val = __raw_readl(EP93XX_SYSCON_I2SCLKDIV); val &= ~EP93XX_I2SCLKDIV_MASK; - val |= i2s_config; + val |= EP93XX_SYSCON_I2SCLKDIV_ORIDE | EP93XX_SYSCON_I2SCLKDIV_SPOL; ep93xx_syscon_swlocked_write(val, EP93XX_SYSCON_I2SCLKDIV); return 0; diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h index d4c9349..ad63d4b 100644 --- a/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/arch/arm/mach-ep93xx/include/mach/platform.h @@ -59,7 +59,7 @@ void ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data); int ep93xx_keypad_acquire_gpio(struct platform_device *pdev); void ep93xx_keypad_release_gpio(struct platform_device *pdev); void ep93xx_register_i2s(void); -int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config); +int ep93xx_i2s_acquire(void); void ep93xx_i2s_release(void); void ep93xx_register_ac97(void); diff --git a/sound/soc/ep93xx/edb93xx.c b/sound/soc/ep93xx/edb93xx.c index bae5cbb..e01cb02 100644 --- a/sound/soc/ep93xx/edb93xx.c +++ b/sound/soc/ep93xx/edb93xx.c @@ -85,9 +85,7 @@ static int __devinit edb93xx_probe(struct platform_device *pdev) struct snd_soc_card *card = &snd_soc_edb93xx; int ret; - ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, - EP93XX_SYSCON_I2SCLKDIV_ORIDE | - EP93XX_SYSCON_I2SCLKDIV_SPOL); + ret = ep93xx_i2s_acquire(); if (ret) return ret; diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c index ccae34a..a193cea 100644 --- a/sound/soc/ep93xx/snappercl15.c +++ b/sound/soc/ep93xx/snappercl15.c @@ -103,9 +103,7 @@ static int __devinit snappercl15_probe(struct platform_device *pdev) struct snd_soc_card *card = &snd_soc_snappercl15; int ret; - ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, - EP93XX_SYSCON_I2SCLKDIV_ORIDE | - EP93XX_SYSCON_I2SCLKDIV_SPOL); + ret = ep93xx_i2s_acquire(); if (ret) return ret; -- cgit v0.10.2 From a6b44f1636f244c97eacb43720414ff356e17c6e Mon Sep 17 00:00:00 2001 From: Javier Martin Date: Wed, 11 Jan 2012 13:21:05 +0100 Subject: ASoC: Route Mic Bias in Visstrim_M10 board. Visstrim_M10 board uses an external microphone that can be enabled/disabled by the user Signed-off-by: Javier Martin Signed-off-by: Mark Brown diff --git a/sound/soc/imx/mx27vis-aic32x4.c b/sound/soc/imx/mx27vis-aic32x4.c index 3c2eed9..d37e23c 100644 --- a/sound/soc/imx/mx27vis-aic32x4.c +++ b/sound/soc/imx/mx27vis-aic32x4.c @@ -74,6 +74,24 @@ static struct snd_soc_ops mx27vis_aic32x4_snd_ops = { .hw_params = mx27vis_aic32x4_hw_params, }; +static const struct snd_kcontrol_new mx27vis_aic32x4_controls[] = { + SOC_DAPM_PIN_SWITCH("External Mic"), +}; + +static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = { + SND_SOC_DAPM_MIC("External Mic", NULL), +}; + +static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = { + {"Mic Bias", NULL, "External Mic"}, + {"IN1_R", NULL, "Mic Bias"}, + {"IN2_R", NULL, "Mic Bias"}, + {"IN3_R", NULL, "Mic Bias"}, + {"IN1_L", NULL, "Mic Bias"}, + {"IN2_L", NULL, "Mic Bias"}, + {"IN3_L", NULL, "Mic Bias"}, +}; + static struct snd_soc_dai_link mx27vis_aic32x4_dai = { .name = "tlv320aic32x4", .stream_name = "TLV320AIC32X4", @@ -89,6 +107,12 @@ static struct snd_soc_card mx27vis_aic32x4 = { .owner = THIS_MODULE, .dai_link = &mx27vis_aic32x4_dai, .num_links = 1, + .controls = mx27vis_aic32x4_controls, + .num_controls = ARRAY_SIZE(mx27vis_aic32x4_controls), + .dapm_widgets = aic32x4_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets), + .dapm_routes = aic32x4_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes), }; static struct platform_device *mx27vis_aic32x4_snd_device; -- cgit v0.10.2 From cef6d1d450ba217dc173a83a50d12de9aaa32bb6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 11 Jan 2012 20:13:19 -0800 Subject: ASoC: Convert WM8962 register access map to modern style Much more compact, both in terms of source and especially in terms of RAM used at runtime. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 63e908c..a20e2b7 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -797,1167 +797,660 @@ static struct reg_default wm8962_reg[] = { { 21139, 0x8580 }, /* R21139 - VSS_XTS32_0 */ }; -static const struct wm8962_reg_access { - u16 read; - u16 write; - u16 vol; -} wm8962_reg_access[WM8962_MAX_REGISTER + 1] = { - [0] = { 0x00FF, 0x01FF, 0x0000 }, /* R0 - Left Input volume */ - [1] = { 0xFEFF, 0x01FF, 0x0000 }, /* R1 - Right Input volume */ - [2] = { 0x00FF, 0x01FF, 0x0000 }, /* R2 - HPOUTL volume */ - [3] = { 0x00FF, 0x01FF, 0x0000 }, /* R3 - HPOUTR volume */ - [4] = { 0x07FE, 0x07FE, 0xFFFF }, /* R4 - Clocking1 */ - [5] = { 0x007F, 0x007F, 0x0000 }, /* R5 - ADC & DAC Control 1 */ - [6] = { 0x37ED, 0x37ED, 0x0000 }, /* R6 - ADC & DAC Control 2 */ - [7] = { 0x1FFF, 0x1FFF, 0x0000 }, /* R7 - Audio Interface 0 */ - [8] = { 0x0FEF, 0x0FEF, 0xFFFF }, /* R8 - Clocking2 */ - [9] = { 0x0B9F, 0x039F, 0x0000 }, /* R9 - Audio Interface 1 */ - [10] = { 0x00FF, 0x01FF, 0x0000 }, /* R10 - Left DAC volume */ - [11] = { 0x00FF, 0x01FF, 0x0000 }, /* R11 - Right DAC volume */ - [14] = { 0x07FF, 0x07FF, 0x0000 }, /* R14 - Audio Interface 2 */ - [15] = { 0xFFFF, 0xFFFF, 0xFFFF }, /* R15 - Software Reset */ - [17] = { 0x07FF, 0x07FF, 0x0000 }, /* R17 - ALC1 */ - [18] = { 0xF8FF, 0x00FF, 0xFFFF }, /* R18 - ALC2 */ - [19] = { 0x1DFF, 0x1DFF, 0x0000 }, /* R19 - ALC3 */ - [20] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20 - Noise Gate */ - [21] = { 0x00FF, 0x01FF, 0x0000 }, /* R21 - Left ADC volume */ - [22] = { 0x00FF, 0x01FF, 0x0000 }, /* R22 - Right ADC volume */ - [23] = { 0x0161, 0x0161, 0x0000 }, /* R23 - Additional control(1) */ - [24] = { 0x0008, 0x0008, 0x0000 }, /* R24 - Additional control(2) */ - [25] = { 0x07FE, 0x07FE, 0x0000 }, /* R25 - Pwr Mgmt (1) */ - [26] = { 0x01FB, 0x01FB, 0x0000 }, /* R26 - Pwr Mgmt (2) */ - [27] = { 0x0017, 0x0017, 0x0000 }, /* R27 - Additional Control (3) */ - [28] = { 0x001C, 0x001C, 0x0000 }, /* R28 - Anti-pop */ - - [30] = { 0xFFFE, 0xFFFE, 0x0000 }, /* R30 - Clocking 3 */ - [31] = { 0x000F, 0x000F, 0x0000 }, /* R31 - Input mixer control (1) */ - [32] = { 0x01FF, 0x01FF, 0x0000 }, /* R32 - Left input mixer volume */ - [33] = { 0x01FF, 0x01FF, 0x0000 }, /* R33 - Right input mixer volume */ - [34] = { 0x003F, 0x003F, 0x0000 }, /* R34 - Input mixer control (2) */ - [35] = { 0x003F, 0x003F, 0x0000 }, /* R35 - Input bias control */ - [37] = { 0x001F, 0x001F, 0x0000 }, /* R37 - Left input PGA control */ - [38] = { 0x001F, 0x001F, 0x0000 }, /* R38 - Right input PGA control */ - [40] = { 0x00FF, 0x01FF, 0x0000 }, /* R40 - SPKOUTL volume */ - [41] = { 0x00FF, 0x01FF, 0x0000 }, /* R41 - SPKOUTR volume */ - - [47] = { 0x000F, 0x0000, 0xFFFF }, /* R47 - Thermal Shutdown Status */ - [48] = { 0x7EC7, 0x7E07, 0xFFFF }, /* R48 - Additional Control (4) */ - [49] = { 0x00D3, 0x00D7, 0xFFFF }, /* R49 - Class D Control 1 */ - [51] = { 0x0047, 0x0047, 0x0000 }, /* R51 - Class D Control 2 */ - [56] = { 0x001E, 0x001E, 0x0000 }, /* R56 - Clocking 4 */ - [57] = { 0x02FC, 0x02FC, 0x0000 }, /* R57 - DAC DSP Mixing (1) */ - [58] = { 0x00FC, 0x00FC, 0x0000 }, /* R58 - DAC DSP Mixing (2) */ - [60] = { 0x00CC, 0x00CC, 0x0000 }, /* R60 - DC Servo 0 */ - [61] = { 0x00DD, 0x00DD, 0x0000 }, /* R61 - DC Servo 1 */ - [64] = { 0x3F80, 0x3F80, 0x0000 }, /* R64 - DC Servo 4 */ - [66] = { 0x0780, 0x0000, 0xFFFF }, /* R66 - DC Servo 6 */ - [68] = { 0x0007, 0x0007, 0x0000 }, /* R68 - Analogue PGA Bias */ - [69] = { 0x00FF, 0x00FF, 0x0000 }, /* R69 - Analogue HP 0 */ - [71] = { 0x01FF, 0x01FF, 0x0000 }, /* R71 - Analogue HP 2 */ - [72] = { 0x0001, 0x0001, 0x0000 }, /* R72 - Charge Pump 1 */ - [82] = { 0x0001, 0x0001, 0x0000 }, /* R82 - Charge Pump B */ - [87] = { 0x00A0, 0x00A0, 0x0000 }, /* R87 - Write Sequencer Control 1 */ - [90] = { 0x007F, 0x01FF, 0x0000 }, /* R90 - Write Sequencer Control 2 */ - [93] = { 0x03F9, 0x0000, 0x0000 }, /* R93 - Write Sequencer Control 3 */ - [94] = { 0x0070, 0x0070, 0x0000 }, /* R94 - Control Interface */ - [99] = { 0x000F, 0x000F, 0x0000 }, /* R99 - Mixer Enables */ - [100] = { 0x00BF, 0x00BF, 0x0000 }, /* R100 - Headphone Mixer (1) */ - [101] = { 0x00BF, 0x00BF, 0x0000 }, /* R101 - Headphone Mixer (2) */ - [102] = { 0x01FF, 0x01FF, 0x0000 }, /* R102 - Headphone Mixer (3) */ - [103] = { 0x01FF, 0x01FF, 0x0000 }, /* R103 - Headphone Mixer (4) */ - [105] = { 0x00BF, 0x00BF, 0x0000 }, /* R105 - Speaker Mixer (1) */ - [106] = { 0x00BF, 0x00BF, 0x0000 }, /* R106 - Speaker Mixer (2) */ - [107] = { 0x01FF, 0x01FF, 0x0000 }, /* R107 - Speaker Mixer (3) */ - [108] = { 0x01FF, 0x01FF, 0x0000 }, /* R108 - Speaker Mixer (4) */ - [109] = { 0x00F0, 0x00F0, 0x0000 }, /* R109 - Speaker Mixer (5) */ - [110] = { 0x00F7, 0x00F7, 0x0000 }, /* R110 - Beep Generator (1) */ - [115] = { 0x001F, 0x001F, 0x0000 }, /* R115 - Oscillator Trim (3) */ - [116] = { 0x001F, 0x001F, 0x0000 }, /* R116 - Oscillator Trim (4) */ - [119] = { 0x00FF, 0x00FF, 0x0000 }, /* R119 - Oscillator Trim (7) */ - [124] = { 0x0079, 0x0079, 0x0000 }, /* R124 - Analogue Clocking1 */ - [125] = { 0x00DF, 0x00DF, 0x0000 }, /* R125 - Analogue Clocking2 */ - [126] = { 0x000D, 0x000D, 0x0000 }, /* R126 - Analogue Clocking3 */ - [127] = { 0x0000, 0xFFFF, 0x0000 }, /* R127 - PLL Software Reset */ - [129] = { 0x00B0, 0x00B0, 0x0000 }, /* R129 - PLL2 */ - [131] = { 0x0003, 0x0003, 0x0000 }, /* R131 - PLL 4 */ - [136] = { 0x005F, 0x005F, 0x0000 }, /* R136 - PLL 9 */ - [137] = { 0x00FF, 0x00FF, 0x0000 }, /* R137 - PLL 10 */ - [138] = { 0x00FF, 0x00FF, 0x0000 }, /* R138 - PLL 11 */ - [139] = { 0x00FF, 0x00FF, 0x0000 }, /* R139 - PLL 12 */ - [140] = { 0x005F, 0x005F, 0x0000 }, /* R140 - PLL 13 */ - [141] = { 0x00FF, 0x00FF, 0x0000 }, /* R141 - PLL 14 */ - [142] = { 0x00FF, 0x00FF, 0x0000 }, /* R142 - PLL 15 */ - [143] = { 0x00FF, 0x00FF, 0x0000 }, /* R143 - PLL 16 */ - [155] = { 0x0067, 0x0067, 0x0000 }, /* R155 - FLL Control (1) */ - [156] = { 0x01FB, 0x01FB, 0x0000 }, /* R156 - FLL Control (2) */ - [157] = { 0x0007, 0x0007, 0x0000 }, /* R157 - FLL Control (3) */ - [159] = { 0x007F, 0x007F, 0x0000 }, /* R159 - FLL Control (5) */ - [160] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R160 - FLL Control (6) */ - [161] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R161 - FLL Control (7) */ - [162] = { 0x03FF, 0x03FF, 0x0000 }, /* R162 - FLL Control (8) */ - [252] = { 0x0005, 0x0005, 0x0000 }, /* R252 - General test 1 */ - [256] = { 0x000F, 0x000F, 0x0000 }, /* R256 - DF1 */ - [257] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R257 - DF2 */ - [258] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R258 - DF3 */ - [259] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R259 - DF4 */ - [260] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R260 - DF5 */ - [261] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R261 - DF6 */ - [262] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R262 - DF7 */ - [264] = { 0x0003, 0x0003, 0x0000 }, /* R264 - LHPF1 */ - [265] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R265 - LHPF2 */ - [268] = { 0x0077, 0x0077, 0x0000 }, /* R268 - THREED1 */ - [269] = { 0xFFFC, 0xFFFC, 0x0000 }, /* R269 - THREED2 */ - [270] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R270 - THREED3 */ - [271] = { 0xFFFC, 0xFFFC, 0x0000 }, /* R271 - THREED4 */ - [276] = { 0x7FFF, 0x7FFF, 0x0000 }, /* R276 - DRC 1 */ - [277] = { 0x1FFF, 0x1FFF, 0x0000 }, /* R277 - DRC 2 */ - [278] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R278 - DRC 3 */ - [279] = { 0x07FF, 0x07FF, 0x0000 }, /* R279 - DRC 4 */ - [280] = { 0x03FF, 0x03FF, 0x0000 }, /* R280 - DRC 5 */ - [285] = { 0x0003, 0x0003, 0x0000 }, /* R285 - Tloopback */ - [335] = { 0x0007, 0x0007, 0x0000 }, /* R335 - EQ1 */ - [336] = { 0xFFFE, 0xFFFE, 0x0000 }, /* R336 - EQ2 */ - [337] = { 0xFFC0, 0xFFC0, 0x0000 }, /* R337 - EQ3 */ - [338] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R338 - EQ4 */ - [339] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R339 - EQ5 */ - [340] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R340 - EQ6 */ - [341] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R341 - EQ7 */ - [342] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R342 - EQ8 */ - [343] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R343 - EQ9 */ - [344] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R344 - EQ10 */ - [345] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R345 - EQ11 */ - [346] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R346 - EQ12 */ - [347] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R347 - EQ13 */ - [348] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R348 - EQ14 */ - [349] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R349 - EQ15 */ - [350] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R350 - EQ16 */ - [351] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R351 - EQ17 */ - [352] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R352 - EQ18 */ - [353] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R353 - EQ19 */ - [354] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R354 - EQ20 */ - [355] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R355 - EQ21 */ - [356] = { 0xFFFE, 0xFFFE, 0x0000 }, /* R356 - EQ22 */ - [357] = { 0xFFC0, 0xFFC0, 0x0000 }, /* R357 - EQ23 */ - [358] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R358 - EQ24 */ - [359] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R359 - EQ25 */ - [360] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R360 - EQ26 */ - [361] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R361 - EQ27 */ - [362] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R362 - EQ28 */ - [363] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R363 - EQ29 */ - [364] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R364 - EQ30 */ - [365] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R365 - EQ31 */ - [366] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R366 - EQ32 */ - [367] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R367 - EQ33 */ - [368] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R368 - EQ34 */ - [369] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R369 - EQ35 */ - [370] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R370 - EQ36 */ - [371] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R371 - EQ37 */ - [372] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R372 - EQ38 */ - [373] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R373 - EQ39 */ - [374] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R374 - EQ40 */ - [375] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R375 - EQ41 */ - [513] = { 0x045F, 0x045F, 0x0000 }, /* R513 - GPIO 2 */ - [514] = { 0x045F, 0x045F, 0x0000 }, /* R514 - GPIO 3 */ - [516] = { 0xE75F, 0xE75F, 0x0000 }, /* R516 - GPIO 5 */ - [517] = { 0xE75F, 0xE75F, 0x0000 }, /* R517 - GPIO 6 */ - [560] = { 0x0030, 0x0030, 0xFFFF }, /* R560 - Interrupt Status 1 */ - [561] = { 0xFFED, 0xFFED, 0xFFFF }, /* R561 - Interrupt Status 2 */ - [568] = { 0x0030, 0x0030, 0x0000 }, /* R568 - Interrupt Status 1 Mask */ - [569] = { 0xFFED, 0xFFED, 0x0000 }, /* R569 - Interrupt Status 2 Mask */ - [576] = { 0x0001, 0x0001, 0x0000 }, /* R576 - Interrupt Control */ - [584] = { 0x002D, 0x002D, 0x0000 }, /* R584 - IRQ Debounce */ - [586] = { 0xC000, 0xC000, 0x0000 }, /* R586 - MICINT Source Pol */ - [768] = { 0x0001, 0x0001, 0x0000 }, /* R768 - DSP2 Power Management */ - [1037] = { 0x0000, 0x003F, 0xFFFF }, /* R1037 - DSP2_ExecControl */ - [4096] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4096 - Write Sequencer 0 */ - [4097] = { 0x00FF, 0x00FF, 0x0000 }, /* R4097 - Write Sequencer 1 */ - [4098] = { 0x070F, 0x070F, 0x0000 }, /* R4098 - Write Sequencer 2 */ - [4099] = { 0x010F, 0x010F, 0x0000 }, /* R4099 - Write Sequencer 3 */ - [4100] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4100 - Write Sequencer 4 */ - [4101] = { 0x00FF, 0x00FF, 0x0000 }, /* R4101 - Write Sequencer 5 */ - [4102] = { 0x070F, 0x070F, 0x0000 }, /* R4102 - Write Sequencer 6 */ - [4103] = { 0x010F, 0x010F, 0x0000 }, /* R4103 - Write Sequencer 7 */ - [4104] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4104 - Write Sequencer 8 */ - [4105] = { 0x00FF, 0x00FF, 0x0000 }, /* R4105 - Write Sequencer 9 */ - [4106] = { 0x070F, 0x070F, 0x0000 }, /* R4106 - Write Sequencer 10 */ - [4107] = { 0x010F, 0x010F, 0x0000 }, /* R4107 - Write Sequencer 11 */ - [4108] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4108 - Write Sequencer 12 */ - [4109] = { 0x00FF, 0x00FF, 0x0000 }, /* R4109 - Write Sequencer 13 */ - [4110] = { 0x070F, 0x070F, 0x0000 }, /* R4110 - Write Sequencer 14 */ - [4111] = { 0x010F, 0x010F, 0x0000 }, /* R4111 - Write Sequencer 15 */ - [4112] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4112 - Write Sequencer 16 */ - [4113] = { 0x00FF, 0x00FF, 0x0000 }, /* R4113 - Write Sequencer 17 */ - [4114] = { 0x070F, 0x070F, 0x0000 }, /* R4114 - Write Sequencer 18 */ - [4115] = { 0x010F, 0x010F, 0x0000 }, /* R4115 - Write Sequencer 19 */ - [4116] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4116 - Write Sequencer 20 */ - [4117] = { 0x00FF, 0x00FF, 0x0000 }, /* R4117 - Write Sequencer 21 */ - [4118] = { 0x070F, 0x070F, 0x0000 }, /* R4118 - Write Sequencer 22 */ - [4119] = { 0x010F, 0x010F, 0x0000 }, /* R4119 - Write Sequencer 23 */ - [4120] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4120 - Write Sequencer 24 */ - [4121] = { 0x00FF, 0x00FF, 0x0000 }, /* R4121 - Write Sequencer 25 */ - [4122] = { 0x070F, 0x070F, 0x0000 }, /* R4122 - Write Sequencer 26 */ - [4123] = { 0x010F, 0x010F, 0x0000 }, /* R4123 - Write Sequencer 27 */ - [4124] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4124 - Write Sequencer 28 */ - [4125] = { 0x00FF, 0x00FF, 0x0000 }, /* R4125 - Write Sequencer 29 */ - [4126] = { 0x070F, 0x070F, 0x0000 }, /* R4126 - Write Sequencer 30 */ - [4127] = { 0x010F, 0x010F, 0x0000 }, /* R4127 - Write Sequencer 31 */ - [4128] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4128 - Write Sequencer 32 */ - [4129] = { 0x00FF, 0x00FF, 0x0000 }, /* R4129 - Write Sequencer 33 */ - [4130] = { 0x070F, 0x070F, 0x0000 }, /* R4130 - Write Sequencer 34 */ - [4131] = { 0x010F, 0x010F, 0x0000 }, /* R4131 - Write Sequencer 35 */ - [4132] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4132 - Write Sequencer 36 */ - [4133] = { 0x00FF, 0x00FF, 0x0000 }, /* R4133 - Write Sequencer 37 */ - [4134] = { 0x070F, 0x070F, 0x0000 }, /* R4134 - Write Sequencer 38 */ - [4135] = { 0x010F, 0x010F, 0x0000 }, /* R4135 - Write Sequencer 39 */ - [4136] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4136 - Write Sequencer 40 */ - [4137] = { 0x00FF, 0x00FF, 0x0000 }, /* R4137 - Write Sequencer 41 */ - [4138] = { 0x070F, 0x070F, 0x0000 }, /* R4138 - Write Sequencer 42 */ - [4139] = { 0x010F, 0x010F, 0x0000 }, /* R4139 - Write Sequencer 43 */ - [4140] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4140 - Write Sequencer 44 */ - [4141] = { 0x00FF, 0x00FF, 0x0000 }, /* R4141 - Write Sequencer 45 */ - [4142] = { 0x070F, 0x070F, 0x0000 }, /* R4142 - Write Sequencer 46 */ - [4143] = { 0x010F, 0x010F, 0x0000 }, /* R4143 - Write Sequencer 47 */ - [4144] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4144 - Write Sequencer 48 */ - [4145] = { 0x00FF, 0x00FF, 0x0000 }, /* R4145 - Write Sequencer 49 */ - [4146] = { 0x070F, 0x070F, 0x0000 }, /* R4146 - Write Sequencer 50 */ - [4147] = { 0x010F, 0x010F, 0x0000 }, /* R4147 - Write Sequencer 51 */ - [4148] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4148 - Write Sequencer 52 */ - [4149] = { 0x00FF, 0x00FF, 0x0000 }, /* R4149 - Write Sequencer 53 */ - [4150] = { 0x070F, 0x070F, 0x0000 }, /* R4150 - Write Sequencer 54 */ - [4151] = { 0x010F, 0x010F, 0x0000 }, /* R4151 - Write Sequencer 55 */ - [4152] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4152 - Write Sequencer 56 */ - [4153] = { 0x00FF, 0x00FF, 0x0000 }, /* R4153 - Write Sequencer 57 */ - [4154] = { 0x070F, 0x070F, 0x0000 }, /* R4154 - Write Sequencer 58 */ - [4155] = { 0x010F, 0x010F, 0x0000 }, /* R4155 - Write Sequencer 59 */ - [4156] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4156 - Write Sequencer 60 */ - [4157] = { 0x00FF, 0x00FF, 0x0000 }, /* R4157 - Write Sequencer 61 */ - [4158] = { 0x070F, 0x070F, 0x0000 }, /* R4158 - Write Sequencer 62 */ - [4159] = { 0x010F, 0x010F, 0x0000 }, /* R4159 - Write Sequencer 63 */ - [4160] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4160 - Write Sequencer 64 */ - [4161] = { 0x00FF, 0x00FF, 0x0000 }, /* R4161 - Write Sequencer 65 */ - [4162] = { 0x070F, 0x070F, 0x0000 }, /* R4162 - Write Sequencer 66 */ - [4163] = { 0x010F, 0x010F, 0x0000 }, /* R4163 - Write Sequencer 67 */ - [4164] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4164 - Write Sequencer 68 */ - [4165] = { 0x00FF, 0x00FF, 0x0000 }, /* R4165 - Write Sequencer 69 */ - [4166] = { 0x070F, 0x070F, 0x0000 }, /* R4166 - Write Sequencer 70 */ - [4167] = { 0x010F, 0x010F, 0x0000 }, /* R4167 - Write Sequencer 71 */ - [4168] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4168 - Write Sequencer 72 */ - [4169] = { 0x00FF, 0x00FF, 0x0000 }, /* R4169 - Write Sequencer 73 */ - [4170] = { 0x070F, 0x070F, 0x0000 }, /* R4170 - Write Sequencer 74 */ - [4171] = { 0x010F, 0x010F, 0x0000 }, /* R4171 - Write Sequencer 75 */ - [4172] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4172 - Write Sequencer 76 */ - [4173] = { 0x00FF, 0x00FF, 0x0000 }, /* R4173 - Write Sequencer 77 */ - [4174] = { 0x070F, 0x070F, 0x0000 }, /* R4174 - Write Sequencer 78 */ - [4175] = { 0x010F, 0x010F, 0x0000 }, /* R4175 - Write Sequencer 79 */ - [4176] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4176 - Write Sequencer 80 */ - [4177] = { 0x00FF, 0x00FF, 0x0000 }, /* R4177 - Write Sequencer 81 */ - [4178] = { 0x070F, 0x070F, 0x0000 }, /* R4178 - Write Sequencer 82 */ - [4179] = { 0x010F, 0x010F, 0x0000 }, /* R4179 - Write Sequencer 83 */ - [4180] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4180 - Write Sequencer 84 */ - [4181] = { 0x00FF, 0x00FF, 0x0000 }, /* R4181 - Write Sequencer 85 */ - [4182] = { 0x070F, 0x070F, 0x0000 }, /* R4182 - Write Sequencer 86 */ - [4183] = { 0x010F, 0x010F, 0x0000 }, /* R4183 - Write Sequencer 87 */ - [4184] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4184 - Write Sequencer 88 */ - [4185] = { 0x00FF, 0x00FF, 0x0000 }, /* R4185 - Write Sequencer 89 */ - [4186] = { 0x070F, 0x070F, 0x0000 }, /* R4186 - Write Sequencer 90 */ - [4187] = { 0x010F, 0x010F, 0x0000 }, /* R4187 - Write Sequencer 91 */ - [4188] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4188 - Write Sequencer 92 */ - [4189] = { 0x00FF, 0x00FF, 0x0000 }, /* R4189 - Write Sequencer 93 */ - [4190] = { 0x070F, 0x070F, 0x0000 }, /* R4190 - Write Sequencer 94 */ - [4191] = { 0x010F, 0x010F, 0x0000 }, /* R4191 - Write Sequencer 95 */ - [4192] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4192 - Write Sequencer 96 */ - [4193] = { 0x00FF, 0x00FF, 0x0000 }, /* R4193 - Write Sequencer 97 */ - [4194] = { 0x070F, 0x070F, 0x0000 }, /* R4194 - Write Sequencer 98 */ - [4195] = { 0x010F, 0x010F, 0x0000 }, /* R4195 - Write Sequencer 99 */ - [4196] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4196 - Write Sequencer 100 */ - [4197] = { 0x00FF, 0x00FF, 0x0000 }, /* R4197 - Write Sequencer 101 */ - [4198] = { 0x070F, 0x070F, 0x0000 }, /* R4198 - Write Sequencer 102 */ - [4199] = { 0x010F, 0x010F, 0x0000 }, /* R4199 - Write Sequencer 103 */ - [4200] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4200 - Write Sequencer 104 */ - [4201] = { 0x00FF, 0x00FF, 0x0000 }, /* R4201 - Write Sequencer 105 */ - [4202] = { 0x070F, 0x070F, 0x0000 }, /* R4202 - Write Sequencer 106 */ - [4203] = { 0x010F, 0x010F, 0x0000 }, /* R4203 - Write Sequencer 107 */ - [4204] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4204 - Write Sequencer 108 */ - [4205] = { 0x00FF, 0x00FF, 0x0000 }, /* R4205 - Write Sequencer 109 */ - [4206] = { 0x070F, 0x070F, 0x0000 }, /* R4206 - Write Sequencer 110 */ - [4207] = { 0x010F, 0x010F, 0x0000 }, /* R4207 - Write Sequencer 111 */ - [4208] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4208 - Write Sequencer 112 */ - [4209] = { 0x00FF, 0x00FF, 0x0000 }, /* R4209 - Write Sequencer 113 */ - [4210] = { 0x070F, 0x070F, 0x0000 }, /* R4210 - Write Sequencer 114 */ - [4211] = { 0x010F, 0x010F, 0x0000 }, /* R4211 - Write Sequencer 115 */ - [4212] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4212 - Write Sequencer 116 */ - [4213] = { 0x00FF, 0x00FF, 0x0000 }, /* R4213 - Write Sequencer 117 */ - [4214] = { 0x070F, 0x070F, 0x0000 }, /* R4214 - Write Sequencer 118 */ - [4215] = { 0x010F, 0x010F, 0x0000 }, /* R4215 - Write Sequencer 119 */ - [4216] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4216 - Write Sequencer 120 */ - [4217] = { 0x00FF, 0x00FF, 0x0000 }, /* R4217 - Write Sequencer 121 */ - [4218] = { 0x070F, 0x070F, 0x0000 }, /* R4218 - Write Sequencer 122 */ - [4219] = { 0x010F, 0x010F, 0x0000 }, /* R4219 - Write Sequencer 123 */ - [4220] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4220 - Write Sequencer 124 */ - [4221] = { 0x00FF, 0x00FF, 0x0000 }, /* R4221 - Write Sequencer 125 */ - [4222] = { 0x070F, 0x070F, 0x0000 }, /* R4222 - Write Sequencer 126 */ - [4223] = { 0x010F, 0x010F, 0x0000 }, /* R4223 - Write Sequencer 127 */ - [4224] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4224 - Write Sequencer 128 */ - [4225] = { 0x00FF, 0x00FF, 0x0000 }, /* R4225 - Write Sequencer 129 */ - [4226] = { 0x070F, 0x070F, 0x0000 }, /* R4226 - Write Sequencer 130 */ - [4227] = { 0x010F, 0x010F, 0x0000 }, /* R4227 - Write Sequencer 131 */ - [4228] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4228 - Write Sequencer 132 */ - [4229] = { 0x00FF, 0x00FF, 0x0000 }, /* R4229 - Write Sequencer 133 */ - [4230] = { 0x070F, 0x070F, 0x0000 }, /* R4230 - Write Sequencer 134 */ - [4231] = { 0x010F, 0x010F, 0x0000 }, /* R4231 - Write Sequencer 135 */ - [4232] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4232 - Write Sequencer 136 */ - [4233] = { 0x00FF, 0x00FF, 0x0000 }, /* R4233 - Write Sequencer 137 */ - [4234] = { 0x070F, 0x070F, 0x0000 }, /* R4234 - Write Sequencer 138 */ - [4235] = { 0x010F, 0x010F, 0x0000 }, /* R4235 - Write Sequencer 139 */ - [4236] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4236 - Write Sequencer 140 */ - [4237] = { 0x00FF, 0x00FF, 0x0000 }, /* R4237 - Write Sequencer 141 */ - [4238] = { 0x070F, 0x070F, 0x0000 }, /* R4238 - Write Sequencer 142 */ - [4239] = { 0x010F, 0x010F, 0x0000 }, /* R4239 - Write Sequencer 143 */ - [4240] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4240 - Write Sequencer 144 */ - [4241] = { 0x00FF, 0x00FF, 0x0000 }, /* R4241 - Write Sequencer 145 */ - [4242] = { 0x070F, 0x070F, 0x0000 }, /* R4242 - Write Sequencer 146 */ - [4243] = { 0x010F, 0x010F, 0x0000 }, /* R4243 - Write Sequencer 147 */ - [4244] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4244 - Write Sequencer 148 */ - [4245] = { 0x00FF, 0x00FF, 0x0000 }, /* R4245 - Write Sequencer 149 */ - [4246] = { 0x070F, 0x070F, 0x0000 }, /* R4246 - Write Sequencer 150 */ - [4247] = { 0x010F, 0x010F, 0x0000 }, /* R4247 - Write Sequencer 151 */ - [4248] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4248 - Write Sequencer 152 */ - [4249] = { 0x00FF, 0x00FF, 0x0000 }, /* R4249 - Write Sequencer 153 */ - [4250] = { 0x070F, 0x070F, 0x0000 }, /* R4250 - Write Sequencer 154 */ - [4251] = { 0x010F, 0x010F, 0x0000 }, /* R4251 - Write Sequencer 155 */ - [4252] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4252 - Write Sequencer 156 */ - [4253] = { 0x00FF, 0x00FF, 0x0000 }, /* R4253 - Write Sequencer 157 */ - [4254] = { 0x070F, 0x070F, 0x0000 }, /* R4254 - Write Sequencer 158 */ - [4255] = { 0x010F, 0x010F, 0x0000 }, /* R4255 - Write Sequencer 159 */ - [4256] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4256 - Write Sequencer 160 */ - [4257] = { 0x00FF, 0x00FF, 0x0000 }, /* R4257 - Write Sequencer 161 */ - [4258] = { 0x070F, 0x070F, 0x0000 }, /* R4258 - Write Sequencer 162 */ - [4259] = { 0x010F, 0x010F, 0x0000 }, /* R4259 - Write Sequencer 163 */ - [4260] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4260 - Write Sequencer 164 */ - [4261] = { 0x00FF, 0x00FF, 0x0000 }, /* R4261 - Write Sequencer 165 */ - [4262] = { 0x070F, 0x070F, 0x0000 }, /* R4262 - Write Sequencer 166 */ - [4263] = { 0x010F, 0x010F, 0x0000 }, /* R4263 - Write Sequencer 167 */ - [4264] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4264 - Write Sequencer 168 */ - [4265] = { 0x00FF, 0x00FF, 0x0000 }, /* R4265 - Write Sequencer 169 */ - [4266] = { 0x070F, 0x070F, 0x0000 }, /* R4266 - Write Sequencer 170 */ - [4267] = { 0x010F, 0x010F, 0x0000 }, /* R4267 - Write Sequencer 171 */ - [4268] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4268 - Write Sequencer 172 */ - [4269] = { 0x00FF, 0x00FF, 0x0000 }, /* R4269 - Write Sequencer 173 */ - [4270] = { 0x070F, 0x070F, 0x0000 }, /* R4270 - Write Sequencer 174 */ - [4271] = { 0x010F, 0x010F, 0x0000 }, /* R4271 - Write Sequencer 175 */ - [4272] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4272 - Write Sequencer 176 */ - [4273] = { 0x00FF, 0x00FF, 0x0000 }, /* R4273 - Write Sequencer 177 */ - [4274] = { 0x070F, 0x070F, 0x0000 }, /* R4274 - Write Sequencer 178 */ - [4275] = { 0x010F, 0x010F, 0x0000 }, /* R4275 - Write Sequencer 179 */ - [4276] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4276 - Write Sequencer 180 */ - [4277] = { 0x00FF, 0x00FF, 0x0000 }, /* R4277 - Write Sequencer 181 */ - [4278] = { 0x070F, 0x070F, 0x0000 }, /* R4278 - Write Sequencer 182 */ - [4279] = { 0x010F, 0x010F, 0x0000 }, /* R4279 - Write Sequencer 183 */ - [4280] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4280 - Write Sequencer 184 */ - [4281] = { 0x00FF, 0x00FF, 0x0000 }, /* R4281 - Write Sequencer 185 */ - [4282] = { 0x070F, 0x070F, 0x0000 }, /* R4282 - Write Sequencer 186 */ - [4283] = { 0x010F, 0x010F, 0x0000 }, /* R4283 - Write Sequencer 187 */ - [4284] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4284 - Write Sequencer 188 */ - [4285] = { 0x00FF, 0x00FF, 0x0000 }, /* R4285 - Write Sequencer 189 */ - [4286] = { 0x070F, 0x070F, 0x0000 }, /* R4286 - Write Sequencer 190 */ - [4287] = { 0x010F, 0x010F, 0x0000 }, /* R4287 - Write Sequencer 191 */ - [4288] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4288 - Write Sequencer 192 */ - [4289] = { 0x00FF, 0x00FF, 0x0000 }, /* R4289 - Write Sequencer 193 */ - [4290] = { 0x070F, 0x070F, 0x0000 }, /* R4290 - Write Sequencer 194 */ - [4291] = { 0x010F, 0x010F, 0x0000 }, /* R4291 - Write Sequencer 195 */ - [4292] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4292 - Write Sequencer 196 */ - [4293] = { 0x00FF, 0x00FF, 0x0000 }, /* R4293 - Write Sequencer 197 */ - [4294] = { 0x070F, 0x070F, 0x0000 }, /* R4294 - Write Sequencer 198 */ - [4295] = { 0x010F, 0x010F, 0x0000 }, /* R4295 - Write Sequencer 199 */ - [4296] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4296 - Write Sequencer 200 */ - [4297] = { 0x00FF, 0x00FF, 0x0000 }, /* R4297 - Write Sequencer 201 */ - [4298] = { 0x070F, 0x070F, 0x0000 }, /* R4298 - Write Sequencer 202 */ - [4299] = { 0x010F, 0x010F, 0x0000 }, /* R4299 - Write Sequencer 203 */ - [4300] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4300 - Write Sequencer 204 */ - [4301] = { 0x00FF, 0x00FF, 0x0000 }, /* R4301 - Write Sequencer 205 */ - [4302] = { 0x070F, 0x070F, 0x0000 }, /* R4302 - Write Sequencer 206 */ - [4303] = { 0x010F, 0x010F, 0x0000 }, /* R4303 - Write Sequencer 207 */ - [4304] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4304 - Write Sequencer 208 */ - [4305] = { 0x00FF, 0x00FF, 0x0000 }, /* R4305 - Write Sequencer 209 */ - [4306] = { 0x070F, 0x070F, 0x0000 }, /* R4306 - Write Sequencer 210 */ - [4307] = { 0x010F, 0x010F, 0x0000 }, /* R4307 - Write Sequencer 211 */ - [4308] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4308 - Write Sequencer 212 */ - [4309] = { 0x00FF, 0x00FF, 0x0000 }, /* R4309 - Write Sequencer 213 */ - [4310] = { 0x070F, 0x070F, 0x0000 }, /* R4310 - Write Sequencer 214 */ - [4311] = { 0x010F, 0x010F, 0x0000 }, /* R4311 - Write Sequencer 215 */ - [4312] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4312 - Write Sequencer 216 */ - [4313] = { 0x00FF, 0x00FF, 0x0000 }, /* R4313 - Write Sequencer 217 */ - [4314] = { 0x070F, 0x070F, 0x0000 }, /* R4314 - Write Sequencer 218 */ - [4315] = { 0x010F, 0x010F, 0x0000 }, /* R4315 - Write Sequencer 219 */ - [4316] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4316 - Write Sequencer 220 */ - [4317] = { 0x00FF, 0x00FF, 0x0000 }, /* R4317 - Write Sequencer 221 */ - [4318] = { 0x070F, 0x070F, 0x0000 }, /* R4318 - Write Sequencer 222 */ - [4319] = { 0x010F, 0x010F, 0x0000 }, /* R4319 - Write Sequencer 223 */ - [4320] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4320 - Write Sequencer 224 */ - [4321] = { 0x00FF, 0x00FF, 0x0000 }, /* R4321 - Write Sequencer 225 */ - [4322] = { 0x070F, 0x070F, 0x0000 }, /* R4322 - Write Sequencer 226 */ - [4323] = { 0x010F, 0x010F, 0x0000 }, /* R4323 - Write Sequencer 227 */ - [4324] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4324 - Write Sequencer 228 */ - [4325] = { 0x00FF, 0x00FF, 0x0000 }, /* R4325 - Write Sequencer 229 */ - [4326] = { 0x070F, 0x070F, 0x0000 }, /* R4326 - Write Sequencer 230 */ - [4327] = { 0x010F, 0x010F, 0x0000 }, /* R4327 - Write Sequencer 231 */ - [4328] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4328 - Write Sequencer 232 */ - [4329] = { 0x00FF, 0x00FF, 0x0000 }, /* R4329 - Write Sequencer 233 */ - [4330] = { 0x070F, 0x070F, 0x0000 }, /* R4330 - Write Sequencer 234 */ - [4331] = { 0x010F, 0x010F, 0x0000 }, /* R4331 - Write Sequencer 235 */ - [4332] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4332 - Write Sequencer 236 */ - [4333] = { 0x00FF, 0x00FF, 0x0000 }, /* R4333 - Write Sequencer 237 */ - [4334] = { 0x070F, 0x070F, 0x0000 }, /* R4334 - Write Sequencer 238 */ - [4335] = { 0x010F, 0x010F, 0x0000 }, /* R4335 - Write Sequencer 239 */ - [4336] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4336 - Write Sequencer 240 */ - [4337] = { 0x00FF, 0x00FF, 0x0000 }, /* R4337 - Write Sequencer 241 */ - [4338] = { 0x070F, 0x070F, 0x0000 }, /* R4338 - Write Sequencer 242 */ - [4339] = { 0x010F, 0x010F, 0x0000 }, /* R4339 - Write Sequencer 243 */ - [4340] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4340 - Write Sequencer 244 */ - [4341] = { 0x00FF, 0x00FF, 0x0000 }, /* R4341 - Write Sequencer 245 */ - [4342] = { 0x070F, 0x070F, 0x0000 }, /* R4342 - Write Sequencer 246 */ - [4343] = { 0x010F, 0x010F, 0x0000 }, /* R4343 - Write Sequencer 247 */ - [4344] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4344 - Write Sequencer 248 */ - [4345] = { 0x00FF, 0x00FF, 0x0000 }, /* R4345 - Write Sequencer 249 */ - [4346] = { 0x070F, 0x070F, 0x0000 }, /* R4346 - Write Sequencer 250 */ - [4347] = { 0x010F, 0x010F, 0x0000 }, /* R4347 - Write Sequencer 251 */ - [4348] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4348 - Write Sequencer 252 */ - [4349] = { 0x00FF, 0x00FF, 0x0000 }, /* R4349 - Write Sequencer 253 */ - [4350] = { 0x070F, 0x070F, 0x0000 }, /* R4350 - Write Sequencer 254 */ - [4351] = { 0x010F, 0x010F, 0x0000 }, /* R4351 - Write Sequencer 255 */ - [4352] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4352 - Write Sequencer 256 */ - [4353] = { 0x00FF, 0x00FF, 0x0000 }, /* R4353 - Write Sequencer 257 */ - [4354] = { 0x070F, 0x070F, 0x0000 }, /* R4354 - Write Sequencer 258 */ - [4355] = { 0x010F, 0x010F, 0x0000 }, /* R4355 - Write Sequencer 259 */ - [4356] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4356 - Write Sequencer 260 */ - [4357] = { 0x00FF, 0x00FF, 0x0000 }, /* R4357 - Write Sequencer 261 */ - [4358] = { 0x070F, 0x070F, 0x0000 }, /* R4358 - Write Sequencer 262 */ - [4359] = { 0x010F, 0x010F, 0x0000 }, /* R4359 - Write Sequencer 263 */ - [4360] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4360 - Write Sequencer 264 */ - [4361] = { 0x00FF, 0x00FF, 0x0000 }, /* R4361 - Write Sequencer 265 */ - [4362] = { 0x070F, 0x070F, 0x0000 }, /* R4362 - Write Sequencer 266 */ - [4363] = { 0x010F, 0x010F, 0x0000 }, /* R4363 - Write Sequencer 267 */ - [4364] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4364 - Write Sequencer 268 */ - [4365] = { 0x00FF, 0x00FF, 0x0000 }, /* R4365 - Write Sequencer 269 */ - [4366] = { 0x070F, 0x070F, 0x0000 }, /* R4366 - Write Sequencer 270 */ - [4367] = { 0x010F, 0x010F, 0x0000 }, /* R4367 - Write Sequencer 271 */ - [4368] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4368 - Write Sequencer 272 */ - [4369] = { 0x00FF, 0x00FF, 0x0000 }, /* R4369 - Write Sequencer 273 */ - [4370] = { 0x070F, 0x070F, 0x0000 }, /* R4370 - Write Sequencer 274 */ - [4371] = { 0x010F, 0x010F, 0x0000 }, /* R4371 - Write Sequencer 275 */ - [4372] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4372 - Write Sequencer 276 */ - [4373] = { 0x00FF, 0x00FF, 0x0000 }, /* R4373 - Write Sequencer 277 */ - [4374] = { 0x070F, 0x070F, 0x0000 }, /* R4374 - Write Sequencer 278 */ - [4375] = { 0x010F, 0x010F, 0x0000 }, /* R4375 - Write Sequencer 279 */ - [4376] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4376 - Write Sequencer 280 */ - [4377] = { 0x00FF, 0x00FF, 0x0000 }, /* R4377 - Write Sequencer 281 */ - [4378] = { 0x070F, 0x070F, 0x0000 }, /* R4378 - Write Sequencer 282 */ - [4379] = { 0x010F, 0x010F, 0x0000 }, /* R4379 - Write Sequencer 283 */ - [4380] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4380 - Write Sequencer 284 */ - [4381] = { 0x00FF, 0x00FF, 0x0000 }, /* R4381 - Write Sequencer 285 */ - [4382] = { 0x070F, 0x070F, 0x0000 }, /* R4382 - Write Sequencer 286 */ - [4383] = { 0x010F, 0x010F, 0x0000 }, /* R4383 - Write Sequencer 287 */ - [4384] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4384 - Write Sequencer 288 */ - [4385] = { 0x00FF, 0x00FF, 0x0000 }, /* R4385 - Write Sequencer 289 */ - [4386] = { 0x070F, 0x070F, 0x0000 }, /* R4386 - Write Sequencer 290 */ - [4387] = { 0x010F, 0x010F, 0x0000 }, /* R4387 - Write Sequencer 291 */ - [4388] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4388 - Write Sequencer 292 */ - [4389] = { 0x00FF, 0x00FF, 0x0000 }, /* R4389 - Write Sequencer 293 */ - [4390] = { 0x070F, 0x070F, 0x0000 }, /* R4390 - Write Sequencer 294 */ - [4391] = { 0x010F, 0x010F, 0x0000 }, /* R4391 - Write Sequencer 295 */ - [4392] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4392 - Write Sequencer 296 */ - [4393] = { 0x00FF, 0x00FF, 0x0000 }, /* R4393 - Write Sequencer 297 */ - [4394] = { 0x070F, 0x070F, 0x0000 }, /* R4394 - Write Sequencer 298 */ - [4395] = { 0x010F, 0x010F, 0x0000 }, /* R4395 - Write Sequencer 299 */ - [4396] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4396 - Write Sequencer 300 */ - [4397] = { 0x00FF, 0x00FF, 0x0000 }, /* R4397 - Write Sequencer 301 */ - [4398] = { 0x070F, 0x070F, 0x0000 }, /* R4398 - Write Sequencer 302 */ - [4399] = { 0x010F, 0x010F, 0x0000 }, /* R4399 - Write Sequencer 303 */ - [4400] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4400 - Write Sequencer 304 */ - [4401] = { 0x00FF, 0x00FF, 0x0000 }, /* R4401 - Write Sequencer 305 */ - [4402] = { 0x070F, 0x070F, 0x0000 }, /* R4402 - Write Sequencer 306 */ - [4403] = { 0x010F, 0x010F, 0x0000 }, /* R4403 - Write Sequencer 307 */ - [4404] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4404 - Write Sequencer 308 */ - [4405] = { 0x00FF, 0x00FF, 0x0000 }, /* R4405 - Write Sequencer 309 */ - [4406] = { 0x070F, 0x070F, 0x0000 }, /* R4406 - Write Sequencer 310 */ - [4407] = { 0x010F, 0x010F, 0x0000 }, /* R4407 - Write Sequencer 311 */ - [4408] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4408 - Write Sequencer 312 */ - [4409] = { 0x00FF, 0x00FF, 0x0000 }, /* R4409 - Write Sequencer 313 */ - [4410] = { 0x070F, 0x070F, 0x0000 }, /* R4410 - Write Sequencer 314 */ - [4411] = { 0x010F, 0x010F, 0x0000 }, /* R4411 - Write Sequencer 315 */ - [4412] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4412 - Write Sequencer 316 */ - [4413] = { 0x00FF, 0x00FF, 0x0000 }, /* R4413 - Write Sequencer 317 */ - [4414] = { 0x070F, 0x070F, 0x0000 }, /* R4414 - Write Sequencer 318 */ - [4415] = { 0x010F, 0x010F, 0x0000 }, /* R4415 - Write Sequencer 319 */ - [4416] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4416 - Write Sequencer 320 */ - [4417] = { 0x00FF, 0x00FF, 0x0000 }, /* R4417 - Write Sequencer 321 */ - [4418] = { 0x070F, 0x070F, 0x0000 }, /* R4418 - Write Sequencer 322 */ - [4419] = { 0x010F, 0x010F, 0x0000 }, /* R4419 - Write Sequencer 323 */ - [4420] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4420 - Write Sequencer 324 */ - [4421] = { 0x00FF, 0x00FF, 0x0000 }, /* R4421 - Write Sequencer 325 */ - [4422] = { 0x070F, 0x070F, 0x0000 }, /* R4422 - Write Sequencer 326 */ - [4423] = { 0x010F, 0x010F, 0x0000 }, /* R4423 - Write Sequencer 327 */ - [4424] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4424 - Write Sequencer 328 */ - [4425] = { 0x00FF, 0x00FF, 0x0000 }, /* R4425 - Write Sequencer 329 */ - [4426] = { 0x070F, 0x070F, 0x0000 }, /* R4426 - Write Sequencer 330 */ - [4427] = { 0x010F, 0x010F, 0x0000 }, /* R4427 - Write Sequencer 331 */ - [4428] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4428 - Write Sequencer 332 */ - [4429] = { 0x00FF, 0x00FF, 0x0000 }, /* R4429 - Write Sequencer 333 */ - [4430] = { 0x070F, 0x070F, 0x0000 }, /* R4430 - Write Sequencer 334 */ - [4431] = { 0x010F, 0x010F, 0x0000 }, /* R4431 - Write Sequencer 335 */ - [4432] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4432 - Write Sequencer 336 */ - [4433] = { 0x00FF, 0x00FF, 0x0000 }, /* R4433 - Write Sequencer 337 */ - [4434] = { 0x070F, 0x070F, 0x0000 }, /* R4434 - Write Sequencer 338 */ - [4435] = { 0x010F, 0x010F, 0x0000 }, /* R4435 - Write Sequencer 339 */ - [4436] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4436 - Write Sequencer 340 */ - [4437] = { 0x00FF, 0x00FF, 0x0000 }, /* R4437 - Write Sequencer 341 */ - [4438] = { 0x070F, 0x070F, 0x0000 }, /* R4438 - Write Sequencer 342 */ - [4439] = { 0x010F, 0x010F, 0x0000 }, /* R4439 - Write Sequencer 343 */ - [4440] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4440 - Write Sequencer 344 */ - [4441] = { 0x00FF, 0x00FF, 0x0000 }, /* R4441 - Write Sequencer 345 */ - [4442] = { 0x070F, 0x070F, 0x0000 }, /* R4442 - Write Sequencer 346 */ - [4443] = { 0x010F, 0x010F, 0x0000 }, /* R4443 - Write Sequencer 347 */ - [4444] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4444 - Write Sequencer 348 */ - [4445] = { 0x00FF, 0x00FF, 0x0000 }, /* R4445 - Write Sequencer 349 */ - [4446] = { 0x070F, 0x070F, 0x0000 }, /* R4446 - Write Sequencer 350 */ - [4447] = { 0x010F, 0x010F, 0x0000 }, /* R4447 - Write Sequencer 351 */ - [4448] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4448 - Write Sequencer 352 */ - [4449] = { 0x00FF, 0x00FF, 0x0000 }, /* R4449 - Write Sequencer 353 */ - [4450] = { 0x070F, 0x070F, 0x0000 }, /* R4450 - Write Sequencer 354 */ - [4451] = { 0x010F, 0x010F, 0x0000 }, /* R4451 - Write Sequencer 355 */ - [4452] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4452 - Write Sequencer 356 */ - [4453] = { 0x00FF, 0x00FF, 0x0000 }, /* R4453 - Write Sequencer 357 */ - [4454] = { 0x070F, 0x070F, 0x0000 }, /* R4454 - Write Sequencer 358 */ - [4455] = { 0x010F, 0x010F, 0x0000 }, /* R4455 - Write Sequencer 359 */ - [4456] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4456 - Write Sequencer 360 */ - [4457] = { 0x00FF, 0x00FF, 0x0000 }, /* R4457 - Write Sequencer 361 */ - [4458] = { 0x070F, 0x070F, 0x0000 }, /* R4458 - Write Sequencer 362 */ - [4459] = { 0x010F, 0x010F, 0x0000 }, /* R4459 - Write Sequencer 363 */ - [4460] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4460 - Write Sequencer 364 */ - [4461] = { 0x00FF, 0x00FF, 0x0000 }, /* R4461 - Write Sequencer 365 */ - [4462] = { 0x070F, 0x070F, 0x0000 }, /* R4462 - Write Sequencer 366 */ - [4463] = { 0x010F, 0x010F, 0x0000 }, /* R4463 - Write Sequencer 367 */ - [4464] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4464 - Write Sequencer 368 */ - [4465] = { 0x00FF, 0x00FF, 0x0000 }, /* R4465 - Write Sequencer 369 */ - [4466] = { 0x070F, 0x070F, 0x0000 }, /* R4466 - Write Sequencer 370 */ - [4467] = { 0x010F, 0x010F, 0x0000 }, /* R4467 - Write Sequencer 371 */ - [4468] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4468 - Write Sequencer 372 */ - [4469] = { 0x00FF, 0x00FF, 0x0000 }, /* R4469 - Write Sequencer 373 */ - [4470] = { 0x070F, 0x070F, 0x0000 }, /* R4470 - Write Sequencer 374 */ - [4471] = { 0x010F, 0x010F, 0x0000 }, /* R4471 - Write Sequencer 375 */ - [4472] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4472 - Write Sequencer 376 */ - [4473] = { 0x00FF, 0x00FF, 0x0000 }, /* R4473 - Write Sequencer 377 */ - [4474] = { 0x070F, 0x070F, 0x0000 }, /* R4474 - Write Sequencer 378 */ - [4475] = { 0x010F, 0x010F, 0x0000 }, /* R4475 - Write Sequencer 379 */ - [4476] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4476 - Write Sequencer 380 */ - [4477] = { 0x00FF, 0x00FF, 0x0000 }, /* R4477 - Write Sequencer 381 */ - [4478] = { 0x070F, 0x070F, 0x0000 }, /* R4478 - Write Sequencer 382 */ - [4479] = { 0x010F, 0x010F, 0x0000 }, /* R4479 - Write Sequencer 383 */ - [4480] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4480 - Write Sequencer 384 */ - [4481] = { 0x00FF, 0x00FF, 0x0000 }, /* R4481 - Write Sequencer 385 */ - [4482] = { 0x070F, 0x070F, 0x0000 }, /* R4482 - Write Sequencer 386 */ - [4483] = { 0x010F, 0x010F, 0x0000 }, /* R4483 - Write Sequencer 387 */ - [4484] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4484 - Write Sequencer 388 */ - [4485] = { 0x00FF, 0x00FF, 0x0000 }, /* R4485 - Write Sequencer 389 */ - [4486] = { 0x070F, 0x070F, 0x0000 }, /* R4486 - Write Sequencer 390 */ - [4487] = { 0x010F, 0x010F, 0x0000 }, /* R4487 - Write Sequencer 391 */ - [4488] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4488 - Write Sequencer 392 */ - [4489] = { 0x00FF, 0x00FF, 0x0000 }, /* R4489 - Write Sequencer 393 */ - [4490] = { 0x070F, 0x070F, 0x0000 }, /* R4490 - Write Sequencer 394 */ - [4491] = { 0x010F, 0x010F, 0x0000 }, /* R4491 - Write Sequencer 395 */ - [4492] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4492 - Write Sequencer 396 */ - [4493] = { 0x00FF, 0x00FF, 0x0000 }, /* R4493 - Write Sequencer 397 */ - [4494] = { 0x070F, 0x070F, 0x0000 }, /* R4494 - Write Sequencer 398 */ - [4495] = { 0x010F, 0x010F, 0x0000 }, /* R4495 - Write Sequencer 399 */ - [4496] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4496 - Write Sequencer 400 */ - [4497] = { 0x00FF, 0x00FF, 0x0000 }, /* R4497 - Write Sequencer 401 */ - [4498] = { 0x070F, 0x070F, 0x0000 }, /* R4498 - Write Sequencer 402 */ - [4499] = { 0x010F, 0x010F, 0x0000 }, /* R4499 - Write Sequencer 403 */ - [4500] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4500 - Write Sequencer 404 */ - [4501] = { 0x00FF, 0x00FF, 0x0000 }, /* R4501 - Write Sequencer 405 */ - [4502] = { 0x070F, 0x070F, 0x0000 }, /* R4502 - Write Sequencer 406 */ - [4503] = { 0x010F, 0x010F, 0x0000 }, /* R4503 - Write Sequencer 407 */ - [4504] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4504 - Write Sequencer 408 */ - [4505] = { 0x00FF, 0x00FF, 0x0000 }, /* R4505 - Write Sequencer 409 */ - [4506] = { 0x070F, 0x070F, 0x0000 }, /* R4506 - Write Sequencer 410 */ - [4507] = { 0x010F, 0x010F, 0x0000 }, /* R4507 - Write Sequencer 411 */ - [4508] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4508 - Write Sequencer 412 */ - [4509] = { 0x00FF, 0x00FF, 0x0000 }, /* R4509 - Write Sequencer 413 */ - [4510] = { 0x070F, 0x070F, 0x0000 }, /* R4510 - Write Sequencer 414 */ - [4511] = { 0x010F, 0x010F, 0x0000 }, /* R4511 - Write Sequencer 415 */ - [4512] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4512 - Write Sequencer 416 */ - [4513] = { 0x00FF, 0x00FF, 0x0000 }, /* R4513 - Write Sequencer 417 */ - [4514] = { 0x070F, 0x070F, 0x0000 }, /* R4514 - Write Sequencer 418 */ - [4515] = { 0x010F, 0x010F, 0x0000 }, /* R4515 - Write Sequencer 419 */ - [4516] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4516 - Write Sequencer 420 */ - [4517] = { 0x00FF, 0x00FF, 0x0000 }, /* R4517 - Write Sequencer 421 */ - [4518] = { 0x070F, 0x070F, 0x0000 }, /* R4518 - Write Sequencer 422 */ - [4519] = { 0x010F, 0x010F, 0x0000 }, /* R4519 - Write Sequencer 423 */ - [4520] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4520 - Write Sequencer 424 */ - [4521] = { 0x00FF, 0x00FF, 0x0000 }, /* R4521 - Write Sequencer 425 */ - [4522] = { 0x070F, 0x070F, 0x0000 }, /* R4522 - Write Sequencer 426 */ - [4523] = { 0x010F, 0x010F, 0x0000 }, /* R4523 - Write Sequencer 427 */ - [4524] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4524 - Write Sequencer 428 */ - [4525] = { 0x00FF, 0x00FF, 0x0000 }, /* R4525 - Write Sequencer 429 */ - [4526] = { 0x070F, 0x070F, 0x0000 }, /* R4526 - Write Sequencer 430 */ - [4527] = { 0x010F, 0x010F, 0x0000 }, /* R4527 - Write Sequencer 431 */ - [4528] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4528 - Write Sequencer 432 */ - [4529] = { 0x00FF, 0x00FF, 0x0000 }, /* R4529 - Write Sequencer 433 */ - [4530] = { 0x070F, 0x070F, 0x0000 }, /* R4530 - Write Sequencer 434 */ - [4531] = { 0x010F, 0x010F, 0x0000 }, /* R4531 - Write Sequencer 435 */ - [4532] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4532 - Write Sequencer 436 */ - [4533] = { 0x00FF, 0x00FF, 0x0000 }, /* R4533 - Write Sequencer 437 */ - [4534] = { 0x070F, 0x070F, 0x0000 }, /* R4534 - Write Sequencer 438 */ - [4535] = { 0x010F, 0x010F, 0x0000 }, /* R4535 - Write Sequencer 439 */ - [4536] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4536 - Write Sequencer 440 */ - [4537] = { 0x00FF, 0x00FF, 0x0000 }, /* R4537 - Write Sequencer 441 */ - [4538] = { 0x070F, 0x070F, 0x0000 }, /* R4538 - Write Sequencer 442 */ - [4539] = { 0x010F, 0x010F, 0x0000 }, /* R4539 - Write Sequencer 443 */ - [4540] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4540 - Write Sequencer 444 */ - [4541] = { 0x00FF, 0x00FF, 0x0000 }, /* R4541 - Write Sequencer 445 */ - [4542] = { 0x070F, 0x070F, 0x0000 }, /* R4542 - Write Sequencer 446 */ - [4543] = { 0x010F, 0x010F, 0x0000 }, /* R4543 - Write Sequencer 447 */ - [4544] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4544 - Write Sequencer 448 */ - [4545] = { 0x00FF, 0x00FF, 0x0000 }, /* R4545 - Write Sequencer 449 */ - [4546] = { 0x070F, 0x070F, 0x0000 }, /* R4546 - Write Sequencer 450 */ - [4547] = { 0x010F, 0x010F, 0x0000 }, /* R4547 - Write Sequencer 451 */ - [4548] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4548 - Write Sequencer 452 */ - [4549] = { 0x00FF, 0x00FF, 0x0000 }, /* R4549 - Write Sequencer 453 */ - [4550] = { 0x070F, 0x070F, 0x0000 }, /* R4550 - Write Sequencer 454 */ - [4551] = { 0x010F, 0x010F, 0x0000 }, /* R4551 - Write Sequencer 455 */ - [4552] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4552 - Write Sequencer 456 */ - [4553] = { 0x00FF, 0x00FF, 0x0000 }, /* R4553 - Write Sequencer 457 */ - [4554] = { 0x070F, 0x070F, 0x0000 }, /* R4554 - Write Sequencer 458 */ - [4555] = { 0x010F, 0x010F, 0x0000 }, /* R4555 - Write Sequencer 459 */ - [4556] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4556 - Write Sequencer 460 */ - [4557] = { 0x00FF, 0x00FF, 0x0000 }, /* R4557 - Write Sequencer 461 */ - [4558] = { 0x070F, 0x070F, 0x0000 }, /* R4558 - Write Sequencer 462 */ - [4559] = { 0x010F, 0x010F, 0x0000 }, /* R4559 - Write Sequencer 463 */ - [4560] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4560 - Write Sequencer 464 */ - [4561] = { 0x00FF, 0x00FF, 0x0000 }, /* R4561 - Write Sequencer 465 */ - [4562] = { 0x070F, 0x070F, 0x0000 }, /* R4562 - Write Sequencer 466 */ - [4563] = { 0x010F, 0x010F, 0x0000 }, /* R4563 - Write Sequencer 467 */ - [4564] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4564 - Write Sequencer 468 */ - [4565] = { 0x00FF, 0x00FF, 0x0000 }, /* R4565 - Write Sequencer 469 */ - [4566] = { 0x070F, 0x070F, 0x0000 }, /* R4566 - Write Sequencer 470 */ - [4567] = { 0x010F, 0x010F, 0x0000 }, /* R4567 - Write Sequencer 471 */ - [4568] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4568 - Write Sequencer 472 */ - [4569] = { 0x00FF, 0x00FF, 0x0000 }, /* R4569 - Write Sequencer 473 */ - [4570] = { 0x070F, 0x070F, 0x0000 }, /* R4570 - Write Sequencer 474 */ - [4571] = { 0x010F, 0x010F, 0x0000 }, /* R4571 - Write Sequencer 475 */ - [4572] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4572 - Write Sequencer 476 */ - [4573] = { 0x00FF, 0x00FF, 0x0000 }, /* R4573 - Write Sequencer 477 */ - [4574] = { 0x070F, 0x070F, 0x0000 }, /* R4574 - Write Sequencer 478 */ - [4575] = { 0x010F, 0x010F, 0x0000 }, /* R4575 - Write Sequencer 479 */ - [4576] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4576 - Write Sequencer 480 */ - [4577] = { 0x00FF, 0x00FF, 0x0000 }, /* R4577 - Write Sequencer 481 */ - [4578] = { 0x070F, 0x070F, 0x0000 }, /* R4578 - Write Sequencer 482 */ - [4579] = { 0x010F, 0x010F, 0x0000 }, /* R4579 - Write Sequencer 483 */ - [4580] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4580 - Write Sequencer 484 */ - [4581] = { 0x00FF, 0x00FF, 0x0000 }, /* R4581 - Write Sequencer 485 */ - [4582] = { 0x070F, 0x070F, 0x0000 }, /* R4582 - Write Sequencer 486 */ - [4583] = { 0x010F, 0x010F, 0x0000 }, /* R4583 - Write Sequencer 487 */ - [4584] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4584 - Write Sequencer 488 */ - [4585] = { 0x00FF, 0x00FF, 0x0000 }, /* R4585 - Write Sequencer 489 */ - [4586] = { 0x070F, 0x070F, 0x0000 }, /* R4586 - Write Sequencer 490 */ - [4587] = { 0x010F, 0x010F, 0x0000 }, /* R4587 - Write Sequencer 491 */ - [4588] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4588 - Write Sequencer 492 */ - [4589] = { 0x00FF, 0x00FF, 0x0000 }, /* R4589 - Write Sequencer 493 */ - [4590] = { 0x070F, 0x070F, 0x0000 }, /* R4590 - Write Sequencer 494 */ - [4591] = { 0x010F, 0x010F, 0x0000 }, /* R4591 - Write Sequencer 495 */ - [4592] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4592 - Write Sequencer 496 */ - [4593] = { 0x00FF, 0x00FF, 0x0000 }, /* R4593 - Write Sequencer 497 */ - [4594] = { 0x070F, 0x070F, 0x0000 }, /* R4594 - Write Sequencer 498 */ - [4595] = { 0x010F, 0x010F, 0x0000 }, /* R4595 - Write Sequencer 499 */ - [4596] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4596 - Write Sequencer 500 */ - [4597] = { 0x00FF, 0x00FF, 0x0000 }, /* R4597 - Write Sequencer 501 */ - [4598] = { 0x070F, 0x070F, 0x0000 }, /* R4598 - Write Sequencer 502 */ - [4599] = { 0x010F, 0x010F, 0x0000 }, /* R4599 - Write Sequencer 503 */ - [4600] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4600 - Write Sequencer 504 */ - [4601] = { 0x00FF, 0x00FF, 0x0000 }, /* R4601 - Write Sequencer 505 */ - [4602] = { 0x070F, 0x070F, 0x0000 }, /* R4602 - Write Sequencer 506 */ - [4603] = { 0x010F, 0x010F, 0x0000 }, /* R4603 - Write Sequencer 507 */ - [4604] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4604 - Write Sequencer 508 */ - [4605] = { 0x00FF, 0x00FF, 0x0000 }, /* R4605 - Write Sequencer 509 */ - [4606] = { 0x070F, 0x070F, 0x0000 }, /* R4606 - Write Sequencer 510 */ - [4607] = { 0x010F, 0x010F, 0x0000 }, /* R4607 - Write Sequencer 511 */ - [8192] = { 0x03FF, 0x03FF, 0x0000 }, /* R8192 - DSP2 Instruction RAM 0 */ - [9216] = { 0x003F, 0x003F, 0x0000 }, /* R9216 - DSP2 Address RAM 2 */ - [9217] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R9217 - DSP2 Address RAM 1 */ - [9218] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R9218 - DSP2 Address RAM 0 */ - [12288] = { 0x00FF, 0x00FF, 0x0000 }, /* R12288 - DSP2 Data1 RAM 1 */ - [12289] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R12289 - DSP2 Data1 RAM 0 */ - [13312] = { 0x00FF, 0x00FF, 0x0000 }, /* R13312 - DSP2 Data2 RAM 1 */ - [13313] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R13313 - DSP2 Data2 RAM 0 */ - [14336] = { 0x00FF, 0x00FF, 0x0000 }, /* R14336 - DSP2 Data3 RAM 1 */ - [14337] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R14337 - DSP2 Data3 RAM 0 */ - [15360] = { 0x07FF, 0x07FF, 0x0000 }, /* R15360 - DSP2 Coeff RAM 0 */ - [16384] = { 0x00FF, 0x00FF, 0x0000 }, /* R16384 - RETUNEADC_SHARED_COEFF_1 */ - [16385] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16385 - RETUNEADC_SHARED_COEFF_0 */ - [16386] = { 0x00FF, 0x00FF, 0x0000 }, /* R16386 - RETUNEDAC_SHARED_COEFF_1 */ - [16387] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16387 - RETUNEDAC_SHARED_COEFF_0 */ - [16388] = { 0x00FF, 0x00FF, 0x0000 }, /* R16388 - SOUNDSTAGE_ENABLES_1 */ - [16389] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16389 - SOUNDSTAGE_ENABLES_0 */ - [16896] = { 0x00FF, 0x00FF, 0x0000 }, /* R16896 - HDBASS_AI_1 */ - [16897] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16897 - HDBASS_AI_0 */ - [16898] = { 0x00FF, 0x00FF, 0x0000 }, /* R16898 - HDBASS_AR_1 */ - [16899] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16899 - HDBASS_AR_0 */ - [16900] = { 0x00FF, 0x00FF, 0x0000 }, /* R16900 - HDBASS_B_1 */ - [16901] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16901 - HDBASS_B_0 */ - [16902] = { 0x00FF, 0x00FF, 0x0000 }, /* R16902 - HDBASS_K_1 */ - [16903] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16903 - HDBASS_K_0 */ - [16904] = { 0x00FF, 0x00FF, 0x0000 }, /* R16904 - HDBASS_N1_1 */ - [16905] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16905 - HDBASS_N1_0 */ - [16906] = { 0x00FF, 0x00FF, 0x0000 }, /* R16906 - HDBASS_N2_1 */ - [16907] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16907 - HDBASS_N2_0 */ - [16908] = { 0x00FF, 0x00FF, 0x0000 }, /* R16908 - HDBASS_N3_1 */ - [16909] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16909 - HDBASS_N3_0 */ - [16910] = { 0x00FF, 0x00FF, 0x0000 }, /* R16910 - HDBASS_N4_1 */ - [16911] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16911 - HDBASS_N4_0 */ - [16912] = { 0x00FF, 0x00FF, 0x0000 }, /* R16912 - HDBASS_N5_1 */ - [16913] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16913 - HDBASS_N5_0 */ - [16914] = { 0x00FF, 0x00FF, 0x0000 }, /* R16914 - HDBASS_X1_1 */ - [16915] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16915 - HDBASS_X1_0 */ - [16916] = { 0x00FF, 0x00FF, 0x0000 }, /* R16916 - HDBASS_X2_1 */ - [16917] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16917 - HDBASS_X2_0 */ - [16918] = { 0x00FF, 0x00FF, 0x0000 }, /* R16918 - HDBASS_X3_1 */ - [16919] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16919 - HDBASS_X3_0 */ - [16920] = { 0x00FF, 0x00FF, 0x0000 }, /* R16920 - HDBASS_ATK_1 */ - [16921] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16921 - HDBASS_ATK_0 */ - [16922] = { 0x00FF, 0x00FF, 0x0000 }, /* R16922 - HDBASS_DCY_1 */ - [16923] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16923 - HDBASS_DCY_0 */ - [16924] = { 0x00FF, 0x00FF, 0x0000 }, /* R16924 - HDBASS_PG_1 */ - [16925] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16925 - HDBASS_PG_0 */ - [17408] = { 0x00FF, 0x00FF, 0x0000 }, /* R17408 - HPF_C_1 */ - [17409] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17409 - HPF_C_0 */ - [17920] = { 0x00FF, 0x00FF, 0x0000 }, /* R17920 - ADCL_RETUNE_C1_1 */ - [17921] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17921 - ADCL_RETUNE_C1_0 */ - [17922] = { 0x00FF, 0x00FF, 0x0000 }, /* R17922 - ADCL_RETUNE_C2_1 */ - [17923] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17923 - ADCL_RETUNE_C2_0 */ - [17924] = { 0x00FF, 0x00FF, 0x0000 }, /* R17924 - ADCL_RETUNE_C3_1 */ - [17925] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17925 - ADCL_RETUNE_C3_0 */ - [17926] = { 0x00FF, 0x00FF, 0x0000 }, /* R17926 - ADCL_RETUNE_C4_1 */ - [17927] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17927 - ADCL_RETUNE_C4_0 */ - [17928] = { 0x00FF, 0x00FF, 0x0000 }, /* R17928 - ADCL_RETUNE_C5_1 */ - [17929] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17929 - ADCL_RETUNE_C5_0 */ - [17930] = { 0x00FF, 0x00FF, 0x0000 }, /* R17930 - ADCL_RETUNE_C6_1 */ - [17931] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17931 - ADCL_RETUNE_C6_0 */ - [17932] = { 0x00FF, 0x00FF, 0x0000 }, /* R17932 - ADCL_RETUNE_C7_1 */ - [17933] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17933 - ADCL_RETUNE_C7_0 */ - [17934] = { 0x00FF, 0x00FF, 0x0000 }, /* R17934 - ADCL_RETUNE_C8_1 */ - [17935] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17935 - ADCL_RETUNE_C8_0 */ - [17936] = { 0x00FF, 0x00FF, 0x0000 }, /* R17936 - ADCL_RETUNE_C9_1 */ - [17937] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17937 - ADCL_RETUNE_C9_0 */ - [17938] = { 0x00FF, 0x00FF, 0x0000 }, /* R17938 - ADCL_RETUNE_C10_1 */ - [17939] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17939 - ADCL_RETUNE_C10_0 */ - [17940] = { 0x00FF, 0x00FF, 0x0000 }, /* R17940 - ADCL_RETUNE_C11_1 */ - [17941] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17941 - ADCL_RETUNE_C11_0 */ - [17942] = { 0x00FF, 0x00FF, 0x0000 }, /* R17942 - ADCL_RETUNE_C12_1 */ - [17943] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17943 - ADCL_RETUNE_C12_0 */ - [17944] = { 0x00FF, 0x00FF, 0x0000 }, /* R17944 - ADCL_RETUNE_C13_1 */ - [17945] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17945 - ADCL_RETUNE_C13_0 */ - [17946] = { 0x00FF, 0x00FF, 0x0000 }, /* R17946 - ADCL_RETUNE_C14_1 */ - [17947] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17947 - ADCL_RETUNE_C14_0 */ - [17948] = { 0x00FF, 0x00FF, 0x0000 }, /* R17948 - ADCL_RETUNE_C15_1 */ - [17949] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17949 - ADCL_RETUNE_C15_0 */ - [17950] = { 0x00FF, 0x00FF, 0x0000 }, /* R17950 - ADCL_RETUNE_C16_1 */ - [17951] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17951 - ADCL_RETUNE_C16_0 */ - [17952] = { 0x00FF, 0x00FF, 0x0000 }, /* R17952 - ADCL_RETUNE_C17_1 */ - [17953] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17953 - ADCL_RETUNE_C17_0 */ - [17954] = { 0x00FF, 0x00FF, 0x0000 }, /* R17954 - ADCL_RETUNE_C18_1 */ - [17955] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17955 - ADCL_RETUNE_C18_0 */ - [17956] = { 0x00FF, 0x00FF, 0x0000 }, /* R17956 - ADCL_RETUNE_C19_1 */ - [17957] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17957 - ADCL_RETUNE_C19_0 */ - [17958] = { 0x00FF, 0x00FF, 0x0000 }, /* R17958 - ADCL_RETUNE_C20_1 */ - [17959] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17959 - ADCL_RETUNE_C20_0 */ - [17960] = { 0x00FF, 0x00FF, 0x0000 }, /* R17960 - ADCL_RETUNE_C21_1 */ - [17961] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17961 - ADCL_RETUNE_C21_0 */ - [17962] = { 0x00FF, 0x00FF, 0x0000 }, /* R17962 - ADCL_RETUNE_C22_1 */ - [17963] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17963 - ADCL_RETUNE_C22_0 */ - [17964] = { 0x00FF, 0x00FF, 0x0000 }, /* R17964 - ADCL_RETUNE_C23_1 */ - [17965] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17965 - ADCL_RETUNE_C23_0 */ - [17966] = { 0x00FF, 0x00FF, 0x0000 }, /* R17966 - ADCL_RETUNE_C24_1 */ - [17967] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17967 - ADCL_RETUNE_C24_0 */ - [17968] = { 0x00FF, 0x00FF, 0x0000 }, /* R17968 - ADCL_RETUNE_C25_1 */ - [17969] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17969 - ADCL_RETUNE_C25_0 */ - [17970] = { 0x00FF, 0x00FF, 0x0000 }, /* R17970 - ADCL_RETUNE_C26_1 */ - [17971] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17971 - ADCL_RETUNE_C26_0 */ - [17972] = { 0x00FF, 0x00FF, 0x0000 }, /* R17972 - ADCL_RETUNE_C27_1 */ - [17973] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17973 - ADCL_RETUNE_C27_0 */ - [17974] = { 0x00FF, 0x00FF, 0x0000 }, /* R17974 - ADCL_RETUNE_C28_1 */ - [17975] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17975 - ADCL_RETUNE_C28_0 */ - [17976] = { 0x00FF, 0x00FF, 0x0000 }, /* R17976 - ADCL_RETUNE_C29_1 */ - [17977] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17977 - ADCL_RETUNE_C29_0 */ - [17978] = { 0x00FF, 0x00FF, 0x0000 }, /* R17978 - ADCL_RETUNE_C30_1 */ - [17979] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17979 - ADCL_RETUNE_C30_0 */ - [17980] = { 0x00FF, 0x00FF, 0x0000 }, /* R17980 - ADCL_RETUNE_C31_1 */ - [17981] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17981 - ADCL_RETUNE_C31_0 */ - [17982] = { 0x00FF, 0x00FF, 0x0000 }, /* R17982 - ADCL_RETUNE_C32_1 */ - [17983] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17983 - ADCL_RETUNE_C32_0 */ - [18432] = { 0x00FF, 0x00FF, 0x0000 }, /* R18432 - RETUNEADC_PG2_1 */ - [18433] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18433 - RETUNEADC_PG2_0 */ - [18434] = { 0x00FF, 0x00FF, 0x0000 }, /* R18434 - RETUNEADC_PG_1 */ - [18435] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18435 - RETUNEADC_PG_0 */ - [18944] = { 0x00FF, 0x00FF, 0x0000 }, /* R18944 - ADCR_RETUNE_C1_1 */ - [18945] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18945 - ADCR_RETUNE_C1_0 */ - [18946] = { 0x00FF, 0x00FF, 0x0000 }, /* R18946 - ADCR_RETUNE_C2_1 */ - [18947] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18947 - ADCR_RETUNE_C2_0 */ - [18948] = { 0x00FF, 0x00FF, 0x0000 }, /* R18948 - ADCR_RETUNE_C3_1 */ - [18949] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18949 - ADCR_RETUNE_C3_0 */ - [18950] = { 0x00FF, 0x00FF, 0x0000 }, /* R18950 - ADCR_RETUNE_C4_1 */ - [18951] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18951 - ADCR_RETUNE_C4_0 */ - [18952] = { 0x00FF, 0x00FF, 0x0000 }, /* R18952 - ADCR_RETUNE_C5_1 */ - [18953] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18953 - ADCR_RETUNE_C5_0 */ - [18954] = { 0x00FF, 0x00FF, 0x0000 }, /* R18954 - ADCR_RETUNE_C6_1 */ - [18955] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18955 - ADCR_RETUNE_C6_0 */ - [18956] = { 0x00FF, 0x00FF, 0x0000 }, /* R18956 - ADCR_RETUNE_C7_1 */ - [18957] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18957 - ADCR_RETUNE_C7_0 */ - [18958] = { 0x00FF, 0x00FF, 0x0000 }, /* R18958 - ADCR_RETUNE_C8_1 */ - [18959] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18959 - ADCR_RETUNE_C8_0 */ - [18960] = { 0x00FF, 0x00FF, 0x0000 }, /* R18960 - ADCR_RETUNE_C9_1 */ - [18961] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18961 - ADCR_RETUNE_C9_0 */ - [18962] = { 0x00FF, 0x00FF, 0x0000 }, /* R18962 - ADCR_RETUNE_C10_1 */ - [18963] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18963 - ADCR_RETUNE_C10_0 */ - [18964] = { 0x00FF, 0x00FF, 0x0000 }, /* R18964 - ADCR_RETUNE_C11_1 */ - [18965] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18965 - ADCR_RETUNE_C11_0 */ - [18966] = { 0x00FF, 0x00FF, 0x0000 }, /* R18966 - ADCR_RETUNE_C12_1 */ - [18967] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18967 - ADCR_RETUNE_C12_0 */ - [18968] = { 0x00FF, 0x00FF, 0x0000 }, /* R18968 - ADCR_RETUNE_C13_1 */ - [18969] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18969 - ADCR_RETUNE_C13_0 */ - [18970] = { 0x00FF, 0x00FF, 0x0000 }, /* R18970 - ADCR_RETUNE_C14_1 */ - [18971] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18971 - ADCR_RETUNE_C14_0 */ - [18972] = { 0x00FF, 0x00FF, 0x0000 }, /* R18972 - ADCR_RETUNE_C15_1 */ - [18973] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18973 - ADCR_RETUNE_C15_0 */ - [18974] = { 0x00FF, 0x00FF, 0x0000 }, /* R18974 - ADCR_RETUNE_C16_1 */ - [18975] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18975 - ADCR_RETUNE_C16_0 */ - [18976] = { 0x00FF, 0x00FF, 0x0000 }, /* R18976 - ADCR_RETUNE_C17_1 */ - [18977] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18977 - ADCR_RETUNE_C17_0 */ - [18978] = { 0x00FF, 0x00FF, 0x0000 }, /* R18978 - ADCR_RETUNE_C18_1 */ - [18979] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18979 - ADCR_RETUNE_C18_0 */ - [18980] = { 0x00FF, 0x00FF, 0x0000 }, /* R18980 - ADCR_RETUNE_C19_1 */ - [18981] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18981 - ADCR_RETUNE_C19_0 */ - [18982] = { 0x00FF, 0x00FF, 0x0000 }, /* R18982 - ADCR_RETUNE_C20_1 */ - [18983] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18983 - ADCR_RETUNE_C20_0 */ - [18984] = { 0x00FF, 0x00FF, 0x0000 }, /* R18984 - ADCR_RETUNE_C21_1 */ - [18985] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18985 - ADCR_RETUNE_C21_0 */ - [18986] = { 0x00FF, 0x00FF, 0x0000 }, /* R18986 - ADCR_RETUNE_C22_1 */ - [18987] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18987 - ADCR_RETUNE_C22_0 */ - [18988] = { 0x00FF, 0x00FF, 0x0000 }, /* R18988 - ADCR_RETUNE_C23_1 */ - [18989] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18989 - ADCR_RETUNE_C23_0 */ - [18990] = { 0x00FF, 0x00FF, 0x0000 }, /* R18990 - ADCR_RETUNE_C24_1 */ - [18991] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18991 - ADCR_RETUNE_C24_0 */ - [18992] = { 0x00FF, 0x00FF, 0x0000 }, /* R18992 - ADCR_RETUNE_C25_1 */ - [18993] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18993 - ADCR_RETUNE_C25_0 */ - [18994] = { 0x00FF, 0x00FF, 0x0000 }, /* R18994 - ADCR_RETUNE_C26_1 */ - [18995] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18995 - ADCR_RETUNE_C26_0 */ - [18996] = { 0x00FF, 0x00FF, 0x0000 }, /* R18996 - ADCR_RETUNE_C27_1 */ - [18997] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18997 - ADCR_RETUNE_C27_0 */ - [18998] = { 0x00FF, 0x00FF, 0x0000 }, /* R18998 - ADCR_RETUNE_C28_1 */ - [18999] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18999 - ADCR_RETUNE_C28_0 */ - [19000] = { 0x00FF, 0x00FF, 0x0000 }, /* R19000 - ADCR_RETUNE_C29_1 */ - [19001] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19001 - ADCR_RETUNE_C29_0 */ - [19002] = { 0x00FF, 0x00FF, 0x0000 }, /* R19002 - ADCR_RETUNE_C30_1 */ - [19003] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19003 - ADCR_RETUNE_C30_0 */ - [19004] = { 0x00FF, 0x00FF, 0x0000 }, /* R19004 - ADCR_RETUNE_C31_1 */ - [19005] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19005 - ADCR_RETUNE_C31_0 */ - [19006] = { 0x00FF, 0x00FF, 0x0000 }, /* R19006 - ADCR_RETUNE_C32_1 */ - [19007] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19007 - ADCR_RETUNE_C32_0 */ - [19456] = { 0x00FF, 0x00FF, 0x0000 }, /* R19456 - DACL_RETUNE_C1_1 */ - [19457] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19457 - DACL_RETUNE_C1_0 */ - [19458] = { 0x00FF, 0x00FF, 0x0000 }, /* R19458 - DACL_RETUNE_C2_1 */ - [19459] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19459 - DACL_RETUNE_C2_0 */ - [19460] = { 0x00FF, 0x00FF, 0x0000 }, /* R19460 - DACL_RETUNE_C3_1 */ - [19461] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19461 - DACL_RETUNE_C3_0 */ - [19462] = { 0x00FF, 0x00FF, 0x0000 }, /* R19462 - DACL_RETUNE_C4_1 */ - [19463] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19463 - DACL_RETUNE_C4_0 */ - [19464] = { 0x00FF, 0x00FF, 0x0000 }, /* R19464 - DACL_RETUNE_C5_1 */ - [19465] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19465 - DACL_RETUNE_C5_0 */ - [19466] = { 0x00FF, 0x00FF, 0x0000 }, /* R19466 - DACL_RETUNE_C6_1 */ - [19467] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19467 - DACL_RETUNE_C6_0 */ - [19468] = { 0x00FF, 0x00FF, 0x0000 }, /* R19468 - DACL_RETUNE_C7_1 */ - [19469] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19469 - DACL_RETUNE_C7_0 */ - [19470] = { 0x00FF, 0x00FF, 0x0000 }, /* R19470 - DACL_RETUNE_C8_1 */ - [19471] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19471 - DACL_RETUNE_C8_0 */ - [19472] = { 0x00FF, 0x00FF, 0x0000 }, /* R19472 - DACL_RETUNE_C9_1 */ - [19473] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19473 - DACL_RETUNE_C9_0 */ - [19474] = { 0x00FF, 0x00FF, 0x0000 }, /* R19474 - DACL_RETUNE_C10_1 */ - [19475] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19475 - DACL_RETUNE_C10_0 */ - [19476] = { 0x00FF, 0x00FF, 0x0000 }, /* R19476 - DACL_RETUNE_C11_1 */ - [19477] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19477 - DACL_RETUNE_C11_0 */ - [19478] = { 0x00FF, 0x00FF, 0x0000 }, /* R19478 - DACL_RETUNE_C12_1 */ - [19479] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19479 - DACL_RETUNE_C12_0 */ - [19480] = { 0x00FF, 0x00FF, 0x0000 }, /* R19480 - DACL_RETUNE_C13_1 */ - [19481] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19481 - DACL_RETUNE_C13_0 */ - [19482] = { 0x00FF, 0x00FF, 0x0000 }, /* R19482 - DACL_RETUNE_C14_1 */ - [19483] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19483 - DACL_RETUNE_C14_0 */ - [19484] = { 0x00FF, 0x00FF, 0x0000 }, /* R19484 - DACL_RETUNE_C15_1 */ - [19485] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19485 - DACL_RETUNE_C15_0 */ - [19486] = { 0x00FF, 0x00FF, 0x0000 }, /* R19486 - DACL_RETUNE_C16_1 */ - [19487] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19487 - DACL_RETUNE_C16_0 */ - [19488] = { 0x00FF, 0x00FF, 0x0000 }, /* R19488 - DACL_RETUNE_C17_1 */ - [19489] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19489 - DACL_RETUNE_C17_0 */ - [19490] = { 0x00FF, 0x00FF, 0x0000 }, /* R19490 - DACL_RETUNE_C18_1 */ - [19491] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19491 - DACL_RETUNE_C18_0 */ - [19492] = { 0x00FF, 0x00FF, 0x0000 }, /* R19492 - DACL_RETUNE_C19_1 */ - [19493] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19493 - DACL_RETUNE_C19_0 */ - [19494] = { 0x00FF, 0x00FF, 0x0000 }, /* R19494 - DACL_RETUNE_C20_1 */ - [19495] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19495 - DACL_RETUNE_C20_0 */ - [19496] = { 0x00FF, 0x00FF, 0x0000 }, /* R19496 - DACL_RETUNE_C21_1 */ - [19497] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19497 - DACL_RETUNE_C21_0 */ - [19498] = { 0x00FF, 0x00FF, 0x0000 }, /* R19498 - DACL_RETUNE_C22_1 */ - [19499] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19499 - DACL_RETUNE_C22_0 */ - [19500] = { 0x00FF, 0x00FF, 0x0000 }, /* R19500 - DACL_RETUNE_C23_1 */ - [19501] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19501 - DACL_RETUNE_C23_0 */ - [19502] = { 0x00FF, 0x00FF, 0x0000 }, /* R19502 - DACL_RETUNE_C24_1 */ - [19503] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19503 - DACL_RETUNE_C24_0 */ - [19504] = { 0x00FF, 0x00FF, 0x0000 }, /* R19504 - DACL_RETUNE_C25_1 */ - [19505] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19505 - DACL_RETUNE_C25_0 */ - [19506] = { 0x00FF, 0x00FF, 0x0000 }, /* R19506 - DACL_RETUNE_C26_1 */ - [19507] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19507 - DACL_RETUNE_C26_0 */ - [19508] = { 0x00FF, 0x00FF, 0x0000 }, /* R19508 - DACL_RETUNE_C27_1 */ - [19509] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19509 - DACL_RETUNE_C27_0 */ - [19510] = { 0x00FF, 0x00FF, 0x0000 }, /* R19510 - DACL_RETUNE_C28_1 */ - [19511] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19511 - DACL_RETUNE_C28_0 */ - [19512] = { 0x00FF, 0x00FF, 0x0000 }, /* R19512 - DACL_RETUNE_C29_1 */ - [19513] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19513 - DACL_RETUNE_C29_0 */ - [19514] = { 0x00FF, 0x00FF, 0x0000 }, /* R19514 - DACL_RETUNE_C30_1 */ - [19515] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19515 - DACL_RETUNE_C30_0 */ - [19516] = { 0x00FF, 0x00FF, 0x0000 }, /* R19516 - DACL_RETUNE_C31_1 */ - [19517] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19517 - DACL_RETUNE_C31_0 */ - [19518] = { 0x00FF, 0x00FF, 0x0000 }, /* R19518 - DACL_RETUNE_C32_1 */ - [19519] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19519 - DACL_RETUNE_C32_0 */ - [19968] = { 0x00FF, 0x00FF, 0x0000 }, /* R19968 - RETUNEDAC_PG2_1 */ - [19969] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19969 - RETUNEDAC_PG2_0 */ - [19970] = { 0x00FF, 0x00FF, 0x0000 }, /* R19970 - RETUNEDAC_PG_1 */ - [19971] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19971 - RETUNEDAC_PG_0 */ - [20480] = { 0x00FF, 0x00FF, 0x0000 }, /* R20480 - DACR_RETUNE_C1_1 */ - [20481] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20481 - DACR_RETUNE_C1_0 */ - [20482] = { 0x00FF, 0x00FF, 0x0000 }, /* R20482 - DACR_RETUNE_C2_1 */ - [20483] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20483 - DACR_RETUNE_C2_0 */ - [20484] = { 0x00FF, 0x00FF, 0x0000 }, /* R20484 - DACR_RETUNE_C3_1 */ - [20485] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20485 - DACR_RETUNE_C3_0 */ - [20486] = { 0x00FF, 0x00FF, 0x0000 }, /* R20486 - DACR_RETUNE_C4_1 */ - [20487] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20487 - DACR_RETUNE_C4_0 */ - [20488] = { 0x00FF, 0x00FF, 0x0000 }, /* R20488 - DACR_RETUNE_C5_1 */ - [20489] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20489 - DACR_RETUNE_C5_0 */ - [20490] = { 0x00FF, 0x00FF, 0x0000 }, /* R20490 - DACR_RETUNE_C6_1 */ - [20491] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20491 - DACR_RETUNE_C6_0 */ - [20492] = { 0x00FF, 0x00FF, 0x0000 }, /* R20492 - DACR_RETUNE_C7_1 */ - [20493] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20493 - DACR_RETUNE_C7_0 */ - [20494] = { 0x00FF, 0x00FF, 0x0000 }, /* R20494 - DACR_RETUNE_C8_1 */ - [20495] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20495 - DACR_RETUNE_C8_0 */ - [20496] = { 0x00FF, 0x00FF, 0x0000 }, /* R20496 - DACR_RETUNE_C9_1 */ - [20497] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20497 - DACR_RETUNE_C9_0 */ - [20498] = { 0x00FF, 0x00FF, 0x0000 }, /* R20498 - DACR_RETUNE_C10_1 */ - [20499] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20499 - DACR_RETUNE_C10_0 */ - [20500] = { 0x00FF, 0x00FF, 0x0000 }, /* R20500 - DACR_RETUNE_C11_1 */ - [20501] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20501 - DACR_RETUNE_C11_0 */ - [20502] = { 0x00FF, 0x00FF, 0x0000 }, /* R20502 - DACR_RETUNE_C12_1 */ - [20503] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20503 - DACR_RETUNE_C12_0 */ - [20504] = { 0x00FF, 0x00FF, 0x0000 }, /* R20504 - DACR_RETUNE_C13_1 */ - [20505] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20505 - DACR_RETUNE_C13_0 */ - [20506] = { 0x00FF, 0x00FF, 0x0000 }, /* R20506 - DACR_RETUNE_C14_1 */ - [20507] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20507 - DACR_RETUNE_C14_0 */ - [20508] = { 0x00FF, 0x00FF, 0x0000 }, /* R20508 - DACR_RETUNE_C15_1 */ - [20509] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20509 - DACR_RETUNE_C15_0 */ - [20510] = { 0x00FF, 0x00FF, 0x0000 }, /* R20510 - DACR_RETUNE_C16_1 */ - [20511] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20511 - DACR_RETUNE_C16_0 */ - [20512] = { 0x00FF, 0x00FF, 0x0000 }, /* R20512 - DACR_RETUNE_C17_1 */ - [20513] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20513 - DACR_RETUNE_C17_0 */ - [20514] = { 0x00FF, 0x00FF, 0x0000 }, /* R20514 - DACR_RETUNE_C18_1 */ - [20515] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20515 - DACR_RETUNE_C18_0 */ - [20516] = { 0x00FF, 0x00FF, 0x0000 }, /* R20516 - DACR_RETUNE_C19_1 */ - [20517] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20517 - DACR_RETUNE_C19_0 */ - [20518] = { 0x00FF, 0x00FF, 0x0000 }, /* R20518 - DACR_RETUNE_C20_1 */ - [20519] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20519 - DACR_RETUNE_C20_0 */ - [20520] = { 0x00FF, 0x00FF, 0x0000 }, /* R20520 - DACR_RETUNE_C21_1 */ - [20521] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20521 - DACR_RETUNE_C21_0 */ - [20522] = { 0x00FF, 0x00FF, 0x0000 }, /* R20522 - DACR_RETUNE_C22_1 */ - [20523] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20523 - DACR_RETUNE_C22_0 */ - [20524] = { 0x00FF, 0x00FF, 0x0000 }, /* R20524 - DACR_RETUNE_C23_1 */ - [20525] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20525 - DACR_RETUNE_C23_0 */ - [20526] = { 0x00FF, 0x00FF, 0x0000 }, /* R20526 - DACR_RETUNE_C24_1 */ - [20527] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20527 - DACR_RETUNE_C24_0 */ - [20528] = { 0x00FF, 0x00FF, 0x0000 }, /* R20528 - DACR_RETUNE_C25_1 */ - [20529] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20529 - DACR_RETUNE_C25_0 */ - [20530] = { 0x00FF, 0x00FF, 0x0000 }, /* R20530 - DACR_RETUNE_C26_1 */ - [20531] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20531 - DACR_RETUNE_C26_0 */ - [20532] = { 0x00FF, 0x00FF, 0x0000 }, /* R20532 - DACR_RETUNE_C27_1 */ - [20533] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20533 - DACR_RETUNE_C27_0 */ - [20534] = { 0x00FF, 0x00FF, 0x0000 }, /* R20534 - DACR_RETUNE_C28_1 */ - [20535] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20535 - DACR_RETUNE_C28_0 */ - [20536] = { 0x00FF, 0x00FF, 0x0000 }, /* R20536 - DACR_RETUNE_C29_1 */ - [20537] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20537 - DACR_RETUNE_C29_0 */ - [20538] = { 0x00FF, 0x00FF, 0x0000 }, /* R20538 - DACR_RETUNE_C30_1 */ - [20539] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20539 - DACR_RETUNE_C30_0 */ - [20540] = { 0x00FF, 0x00FF, 0x0000 }, /* R20540 - DACR_RETUNE_C31_1 */ - [20541] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20541 - DACR_RETUNE_C31_0 */ - [20542] = { 0x00FF, 0x00FF, 0x0000 }, /* R20542 - DACR_RETUNE_C32_1 */ - [20543] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20543 - DACR_RETUNE_C32_0 */ - [20992] = { 0x00FF, 0x00FF, 0x0000 }, /* R20992 - VSS_XHD2_1 */ - [20993] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20993 - VSS_XHD2_0 */ - [20994] = { 0x00FF, 0x00FF, 0x0000 }, /* R20994 - VSS_XHD3_1 */ - [20995] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20995 - VSS_XHD3_0 */ - [20996] = { 0x00FF, 0x00FF, 0x0000 }, /* R20996 - VSS_XHN1_1 */ - [20997] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20997 - VSS_XHN1_0 */ - [20998] = { 0x00FF, 0x00FF, 0x0000 }, /* R20998 - VSS_XHN2_1 */ - [20999] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20999 - VSS_XHN2_0 */ - [21000] = { 0x00FF, 0x00FF, 0x0000 }, /* R21000 - VSS_XHN3_1 */ - [21001] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21001 - VSS_XHN3_0 */ - [21002] = { 0x00FF, 0x00FF, 0x0000 }, /* R21002 - VSS_XLA_1 */ - [21003] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21003 - VSS_XLA_0 */ - [21004] = { 0x00FF, 0x00FF, 0x0000 }, /* R21004 - VSS_XLB_1 */ - [21005] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21005 - VSS_XLB_0 */ - [21006] = { 0x00FF, 0x00FF, 0x0000 }, /* R21006 - VSS_XLG_1 */ - [21007] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21007 - VSS_XLG_0 */ - [21008] = { 0x00FF, 0x00FF, 0x0000 }, /* R21008 - VSS_PG2_1 */ - [21009] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21009 - VSS_PG2_0 */ - [21010] = { 0x00FF, 0x00FF, 0x0000 }, /* R21010 - VSS_PG_1 */ - [21011] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21011 - VSS_PG_0 */ - [21012] = { 0x00FF, 0x00FF, 0x0000 }, /* R21012 - VSS_XTD1_1 */ - [21013] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21013 - VSS_XTD1_0 */ - [21014] = { 0x00FF, 0x00FF, 0x0000 }, /* R21014 - VSS_XTD2_1 */ - [21015] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21015 - VSS_XTD2_0 */ - [21016] = { 0x00FF, 0x00FF, 0x0000 }, /* R21016 - VSS_XTD3_1 */ - [21017] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21017 - VSS_XTD3_0 */ - [21018] = { 0x00FF, 0x00FF, 0x0000 }, /* R21018 - VSS_XTD4_1 */ - [21019] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21019 - VSS_XTD4_0 */ - [21020] = { 0x00FF, 0x00FF, 0x0000 }, /* R21020 - VSS_XTD5_1 */ - [21021] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21021 - VSS_XTD5_0 */ - [21022] = { 0x00FF, 0x00FF, 0x0000 }, /* R21022 - VSS_XTD6_1 */ - [21023] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21023 - VSS_XTD6_0 */ - [21024] = { 0x00FF, 0x00FF, 0x0000 }, /* R21024 - VSS_XTD7_1 */ - [21025] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21025 - VSS_XTD7_0 */ - [21026] = { 0x00FF, 0x00FF, 0x0000 }, /* R21026 - VSS_XTD8_1 */ - [21027] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21027 - VSS_XTD8_0 */ - [21028] = { 0x00FF, 0x00FF, 0x0000 }, /* R21028 - VSS_XTD9_1 */ - [21029] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21029 - VSS_XTD9_0 */ - [21030] = { 0x00FF, 0x00FF, 0x0000 }, /* R21030 - VSS_XTD10_1 */ - [21031] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21031 - VSS_XTD10_0 */ - [21032] = { 0x00FF, 0x00FF, 0x0000 }, /* R21032 - VSS_XTD11_1 */ - [21033] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21033 - VSS_XTD11_0 */ - [21034] = { 0x00FF, 0x00FF, 0x0000 }, /* R21034 - VSS_XTD12_1 */ - [21035] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21035 - VSS_XTD12_0 */ - [21036] = { 0x00FF, 0x00FF, 0x0000 }, /* R21036 - VSS_XTD13_1 */ - [21037] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21037 - VSS_XTD13_0 */ - [21038] = { 0x00FF, 0x00FF, 0x0000 }, /* R21038 - VSS_XTD14_1 */ - [21039] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21039 - VSS_XTD14_0 */ - [21040] = { 0x00FF, 0x00FF, 0x0000 }, /* R21040 - VSS_XTD15_1 */ - [21041] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21041 - VSS_XTD15_0 */ - [21042] = { 0x00FF, 0x00FF, 0x0000 }, /* R21042 - VSS_XTD16_1 */ - [21043] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21043 - VSS_XTD16_0 */ - [21044] = { 0x00FF, 0x00FF, 0x0000 }, /* R21044 - VSS_XTD17_1 */ - [21045] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21045 - VSS_XTD17_0 */ - [21046] = { 0x00FF, 0x00FF, 0x0000 }, /* R21046 - VSS_XTD18_1 */ - [21047] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21047 - VSS_XTD18_0 */ - [21048] = { 0x00FF, 0x00FF, 0x0000 }, /* R21048 - VSS_XTD19_1 */ - [21049] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21049 - VSS_XTD19_0 */ - [21050] = { 0x00FF, 0x00FF, 0x0000 }, /* R21050 - VSS_XTD20_1 */ - [21051] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21051 - VSS_XTD20_0 */ - [21052] = { 0x00FF, 0x00FF, 0x0000 }, /* R21052 - VSS_XTD21_1 */ - [21053] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21053 - VSS_XTD21_0 */ - [21054] = { 0x00FF, 0x00FF, 0x0000 }, /* R21054 - VSS_XTD22_1 */ - [21055] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21055 - VSS_XTD22_0 */ - [21056] = { 0x00FF, 0x00FF, 0x0000 }, /* R21056 - VSS_XTD23_1 */ - [21057] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21057 - VSS_XTD23_0 */ - [21058] = { 0x00FF, 0x00FF, 0x0000 }, /* R21058 - VSS_XTD24_1 */ - [21059] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21059 - VSS_XTD24_0 */ - [21060] = { 0x00FF, 0x00FF, 0x0000 }, /* R21060 - VSS_XTD25_1 */ - [21061] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21061 - VSS_XTD25_0 */ - [21062] = { 0x00FF, 0x00FF, 0x0000 }, /* R21062 - VSS_XTD26_1 */ - [21063] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21063 - VSS_XTD26_0 */ - [21064] = { 0x00FF, 0x00FF, 0x0000 }, /* R21064 - VSS_XTD27_1 */ - [21065] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21065 - VSS_XTD27_0 */ - [21066] = { 0x00FF, 0x00FF, 0x0000 }, /* R21066 - VSS_XTD28_1 */ - [21067] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21067 - VSS_XTD28_0 */ - [21068] = { 0x00FF, 0x00FF, 0x0000 }, /* R21068 - VSS_XTD29_1 */ - [21069] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21069 - VSS_XTD29_0 */ - [21070] = { 0x00FF, 0x00FF, 0x0000 }, /* R21070 - VSS_XTD30_1 */ - [21071] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21071 - VSS_XTD30_0 */ - [21072] = { 0x00FF, 0x00FF, 0x0000 }, /* R21072 - VSS_XTD31_1 */ - [21073] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21073 - VSS_XTD31_0 */ - [21074] = { 0x00FF, 0x00FF, 0x0000 }, /* R21074 - VSS_XTD32_1 */ - [21075] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21075 - VSS_XTD32_0 */ - [21076] = { 0x00FF, 0x00FF, 0x0000 }, /* R21076 - VSS_XTS1_1 */ - [21077] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21077 - VSS_XTS1_0 */ - [21078] = { 0x00FF, 0x00FF, 0x0000 }, /* R21078 - VSS_XTS2_1 */ - [21079] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21079 - VSS_XTS2_0 */ - [21080] = { 0x00FF, 0x00FF, 0x0000 }, /* R21080 - VSS_XTS3_1 */ - [21081] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21081 - VSS_XTS3_0 */ - [21082] = { 0x00FF, 0x00FF, 0x0000 }, /* R21082 - VSS_XTS4_1 */ - [21083] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21083 - VSS_XTS4_0 */ - [21084] = { 0x00FF, 0x00FF, 0x0000 }, /* R21084 - VSS_XTS5_1 */ - [21085] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21085 - VSS_XTS5_0 */ - [21086] = { 0x00FF, 0x00FF, 0x0000 }, /* R21086 - VSS_XTS6_1 */ - [21087] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21087 - VSS_XTS6_0 */ - [21088] = { 0x00FF, 0x00FF, 0x0000 }, /* R21088 - VSS_XTS7_1 */ - [21089] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21089 - VSS_XTS7_0 */ - [21090] = { 0x00FF, 0x00FF, 0x0000 }, /* R21090 - VSS_XTS8_1 */ - [21091] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21091 - VSS_XTS8_0 */ - [21092] = { 0x00FF, 0x00FF, 0x0000 }, /* R21092 - VSS_XTS9_1 */ - [21093] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21093 - VSS_XTS9_0 */ - [21094] = { 0x00FF, 0x00FF, 0x0000 }, /* R21094 - VSS_XTS10_1 */ - [21095] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21095 - VSS_XTS10_0 */ - [21096] = { 0x00FF, 0x00FF, 0x0000 }, /* R21096 - VSS_XTS11_1 */ - [21097] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21097 - VSS_XTS11_0 */ - [21098] = { 0x00FF, 0x00FF, 0x0000 }, /* R21098 - VSS_XTS12_1 */ - [21099] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21099 - VSS_XTS12_0 */ - [21100] = { 0x00FF, 0x00FF, 0x0000 }, /* R21100 - VSS_XTS13_1 */ - [21101] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21101 - VSS_XTS13_0 */ - [21102] = { 0x00FF, 0x00FF, 0x0000 }, /* R21102 - VSS_XTS14_1 */ - [21103] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21103 - VSS_XTS14_0 */ - [21104] = { 0x00FF, 0x00FF, 0x0000 }, /* R21104 - VSS_XTS15_1 */ - [21105] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21105 - VSS_XTS15_0 */ - [21106] = { 0x00FF, 0x00FF, 0x0000 }, /* R21106 - VSS_XTS16_1 */ - [21107] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21107 - VSS_XTS16_0 */ - [21108] = { 0x00FF, 0x00FF, 0x0000 }, /* R21108 - VSS_XTS17_1 */ - [21109] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21109 - VSS_XTS17_0 */ - [21110] = { 0x00FF, 0x00FF, 0x0000 }, /* R21110 - VSS_XTS18_1 */ - [21111] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21111 - VSS_XTS18_0 */ - [21112] = { 0x00FF, 0x00FF, 0x0000 }, /* R21112 - VSS_XTS19_1 */ - [21113] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21113 - VSS_XTS19_0 */ - [21114] = { 0x00FF, 0x00FF, 0x0000 }, /* R21114 - VSS_XTS20_1 */ - [21115] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21115 - VSS_XTS20_0 */ - [21116] = { 0x00FF, 0x00FF, 0x0000 }, /* R21116 - VSS_XTS21_1 */ - [21117] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21117 - VSS_XTS21_0 */ - [21118] = { 0x00FF, 0x00FF, 0x0000 }, /* R21118 - VSS_XTS22_1 */ - [21119] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21119 - VSS_XTS22_0 */ - [21120] = { 0x00FF, 0x00FF, 0x0000 }, /* R21120 - VSS_XTS23_1 */ - [21121] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21121 - VSS_XTS23_0 */ - [21122] = { 0x00FF, 0x00FF, 0x0000 }, /* R21122 - VSS_XTS24_1 */ - [21123] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21123 - VSS_XTS24_0 */ - [21124] = { 0x00FF, 0x00FF, 0x0000 }, /* R21124 - VSS_XTS25_1 */ - [21125] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21125 - VSS_XTS25_0 */ - [21126] = { 0x00FF, 0x00FF, 0x0000 }, /* R21126 - VSS_XTS26_1 */ - [21127] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21127 - VSS_XTS26_0 */ - [21128] = { 0x00FF, 0x00FF, 0x0000 }, /* R21128 - VSS_XTS27_1 */ - [21129] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21129 - VSS_XTS27_0 */ - [21130] = { 0x00FF, 0x00FF, 0x0000 }, /* R21130 - VSS_XTS28_1 */ - [21131] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21131 - VSS_XTS28_0 */ - [21132] = { 0x00FF, 0x00FF, 0x0000 }, /* R21132 - VSS_XTS29_1 */ - [21133] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21133 - VSS_XTS29_0 */ - [21134] = { 0x00FF, 0x00FF, 0x0000 }, /* R21134 - VSS_XTS30_1 */ - [21135] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21135 - VSS_XTS30_0 */ - [21136] = { 0x00FF, 0x00FF, 0x0000 }, /* R21136 - VSS_XTS31_1 */ - [21137] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21137 - VSS_XTS31_0 */ - [21138] = { 0x00FF, 0x00FF, 0x0000 }, /* R21138 - VSS_XTS32_1 */ - [21139] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21139 - VSS_XTS32_0 */ -}; - static bool wm8962_volatile_register(struct device *dev, unsigned int reg) { - if (wm8962_reg_access[reg].vol) - return 1; - else - return 0; + switch (reg) { + case WM8962_CLOCKING1: + case WM8962_CLOCKING2: + case WM8962_SOFTWARE_RESET: + case WM8962_ALC2: + case WM8962_THERMAL_SHUTDOWN_STATUS: + case WM8962_ADDITIONAL_CONTROL_4: + case WM8962_CLASS_D_CONTROL_1: + case WM8962_DC_SERVO_6: + case WM8962_INTERRUPT_STATUS_1: + case WM8962_INTERRUPT_STATUS_2: + case WM8962_DSP2_EXECCONTROL: + return true; + default: + return false; + } } static bool wm8962_readable_register(struct device *dev, unsigned int reg) { - if (wm8962_reg_access[reg].read) - return 1; - else - return 0; + switch (reg) { + case WM8962_LEFT_INPUT_VOLUME: + case WM8962_RIGHT_INPUT_VOLUME: + case WM8962_HPOUTL_VOLUME: + case WM8962_HPOUTR_VOLUME: + case WM8962_CLOCKING1: + case WM8962_ADC_DAC_CONTROL_1: + case WM8962_ADC_DAC_CONTROL_2: + case WM8962_AUDIO_INTERFACE_0: + case WM8962_CLOCKING2: + case WM8962_AUDIO_INTERFACE_1: + case WM8962_LEFT_DAC_VOLUME: + case WM8962_RIGHT_DAC_VOLUME: + case WM8962_AUDIO_INTERFACE_2: + case WM8962_SOFTWARE_RESET: + case WM8962_ALC1: + case WM8962_ALC2: + case WM8962_ALC3: + case WM8962_NOISE_GATE: + case WM8962_LEFT_ADC_VOLUME: + case WM8962_RIGHT_ADC_VOLUME: + case WM8962_ADDITIONAL_CONTROL_1: + case WM8962_ADDITIONAL_CONTROL_2: + case WM8962_PWR_MGMT_1: + case WM8962_PWR_MGMT_2: + case WM8962_ADDITIONAL_CONTROL_3: + case WM8962_ANTI_POP: + case WM8962_CLOCKING_3: + case WM8962_INPUT_MIXER_CONTROL_1: + case WM8962_LEFT_INPUT_MIXER_VOLUME: + case WM8962_RIGHT_INPUT_MIXER_VOLUME: + case WM8962_INPUT_MIXER_CONTROL_2: + case WM8962_INPUT_BIAS_CONTROL: + case WM8962_LEFT_INPUT_PGA_CONTROL: + case WM8962_RIGHT_INPUT_PGA_CONTROL: + case WM8962_SPKOUTL_VOLUME: + case WM8962_SPKOUTR_VOLUME: + case WM8962_THERMAL_SHUTDOWN_STATUS: + case WM8962_ADDITIONAL_CONTROL_4: + case WM8962_CLASS_D_CONTROL_1: + case WM8962_CLASS_D_CONTROL_2: + case WM8962_CLOCKING_4: + case WM8962_DAC_DSP_MIXING_1: + case WM8962_DAC_DSP_MIXING_2: + case WM8962_DC_SERVO_0: + case WM8962_DC_SERVO_1: + case WM8962_DC_SERVO_4: + case WM8962_DC_SERVO_6: + case WM8962_ANALOGUE_PGA_BIAS: + case WM8962_ANALOGUE_HP_0: + case WM8962_ANALOGUE_HP_2: + case WM8962_CHARGE_PUMP_1: + case WM8962_CHARGE_PUMP_B: + case WM8962_WRITE_SEQUENCER_CONTROL_1: + case WM8962_WRITE_SEQUENCER_CONTROL_2: + case WM8962_WRITE_SEQUENCER_CONTROL_3: + case WM8962_CONTROL_INTERFACE: + case WM8962_MIXER_ENABLES: + case WM8962_HEADPHONE_MIXER_1: + case WM8962_HEADPHONE_MIXER_2: + case WM8962_HEADPHONE_MIXER_3: + case WM8962_HEADPHONE_MIXER_4: + case WM8962_SPEAKER_MIXER_1: + case WM8962_SPEAKER_MIXER_2: + case WM8962_SPEAKER_MIXER_3: + case WM8962_SPEAKER_MIXER_4: + case WM8962_SPEAKER_MIXER_5: + case WM8962_BEEP_GENERATOR_1: + case WM8962_OSCILLATOR_TRIM_3: + case WM8962_OSCILLATOR_TRIM_4: + case WM8962_OSCILLATOR_TRIM_7: + case WM8962_ANALOGUE_CLOCKING1: + case WM8962_ANALOGUE_CLOCKING2: + case WM8962_ANALOGUE_CLOCKING3: + case WM8962_PLL_SOFTWARE_RESET: + case WM8962_PLL2: + case WM8962_PLL_4: + case WM8962_PLL_9: + case WM8962_PLL_10: + case WM8962_PLL_11: + case WM8962_PLL_12: + case WM8962_PLL_13: + case WM8962_PLL_14: + case WM8962_PLL_15: + case WM8962_PLL_16: + case WM8962_FLL_CONTROL_1: + case WM8962_FLL_CONTROL_2: + case WM8962_FLL_CONTROL_3: + case WM8962_FLL_CONTROL_5: + case WM8962_FLL_CONTROL_6: + case WM8962_FLL_CONTROL_7: + case WM8962_FLL_CONTROL_8: + case WM8962_GENERAL_TEST_1: + case WM8962_DF1: + case WM8962_DF2: + case WM8962_DF3: + case WM8962_DF4: + case WM8962_DF5: + case WM8962_DF6: + case WM8962_DF7: + case WM8962_LHPF1: + case WM8962_LHPF2: + case WM8962_THREED1: + case WM8962_THREED2: + case WM8962_THREED3: + case WM8962_THREED4: + case WM8962_DRC_1: + case WM8962_DRC_2: + case WM8962_DRC_3: + case WM8962_DRC_4: + case WM8962_DRC_5: + case WM8962_TLOOPBACK: + case WM8962_EQ1: + case WM8962_EQ2: + case WM8962_EQ3: + case WM8962_EQ4: + case WM8962_EQ5: + case WM8962_EQ6: + case WM8962_EQ7: + case WM8962_EQ8: + case WM8962_EQ9: + case WM8962_EQ10: + case WM8962_EQ11: + case WM8962_EQ12: + case WM8962_EQ13: + case WM8962_EQ14: + case WM8962_EQ15: + case WM8962_EQ16: + case WM8962_EQ17: + case WM8962_EQ18: + case WM8962_EQ19: + case WM8962_EQ20: + case WM8962_EQ21: + case WM8962_EQ22: + case WM8962_EQ23: + case WM8962_EQ24: + case WM8962_EQ25: + case WM8962_EQ26: + case WM8962_EQ27: + case WM8962_EQ28: + case WM8962_EQ29: + case WM8962_EQ30: + case WM8962_EQ31: + case WM8962_EQ32: + case WM8962_EQ33: + case WM8962_EQ34: + case WM8962_EQ35: + case WM8962_EQ36: + case WM8962_EQ37: + case WM8962_EQ38: + case WM8962_EQ39: + case WM8962_EQ40: + case WM8962_EQ41: + case WM8962_GPIO_BASE: + case WM8962_GPIO_2: + case WM8962_GPIO_3: + case WM8962_GPIO_5: + case WM8962_GPIO_6: + case WM8962_INTERRUPT_STATUS_1: + case WM8962_INTERRUPT_STATUS_2: + case WM8962_INTERRUPT_STATUS_1_MASK: + case WM8962_INTERRUPT_STATUS_2_MASK: + case WM8962_INTERRUPT_CONTROL: + case WM8962_IRQ_DEBOUNCE: + case WM8962_MICINT_SOURCE_POL: + case WM8962_DSP2_POWER_MANAGEMENT: + case WM8962_DSP2_EXECCONTROL: + case WM8962_DSP2_INSTRUCTION_RAM_0: + case WM8962_DSP2_ADDRESS_RAM_2: + case WM8962_DSP2_ADDRESS_RAM_1: + case WM8962_DSP2_ADDRESS_RAM_0: + case WM8962_DSP2_DATA1_RAM_1: + case WM8962_DSP2_DATA1_RAM_0: + case WM8962_DSP2_DATA2_RAM_1: + case WM8962_DSP2_DATA2_RAM_0: + case WM8962_DSP2_DATA3_RAM_1: + case WM8962_DSP2_DATA3_RAM_0: + case WM8962_DSP2_COEFF_RAM_0: + case WM8962_RETUNEADC_SHARED_COEFF_1: + case WM8962_RETUNEADC_SHARED_COEFF_0: + case WM8962_RETUNEDAC_SHARED_COEFF_1: + case WM8962_RETUNEDAC_SHARED_COEFF_0: + case WM8962_SOUNDSTAGE_ENABLES_1: + case WM8962_SOUNDSTAGE_ENABLES_0: + case WM8962_HDBASS_AI_1: + case WM8962_HDBASS_AI_0: + case WM8962_HDBASS_AR_1: + case WM8962_HDBASS_AR_0: + case WM8962_HDBASS_B_1: + case WM8962_HDBASS_B_0: + case WM8962_HDBASS_K_1: + case WM8962_HDBASS_K_0: + case WM8962_HDBASS_N1_1: + case WM8962_HDBASS_N1_0: + case WM8962_HDBASS_N2_1: + case WM8962_HDBASS_N2_0: + case WM8962_HDBASS_N3_1: + case WM8962_HDBASS_N3_0: + case WM8962_HDBASS_N4_1: + case WM8962_HDBASS_N4_0: + case WM8962_HDBASS_N5_1: + case WM8962_HDBASS_N5_0: + case WM8962_HDBASS_X1_1: + case WM8962_HDBASS_X1_0: + case WM8962_HDBASS_X2_1: + case WM8962_HDBASS_X2_0: + case WM8962_HDBASS_X3_1: + case WM8962_HDBASS_X3_0: + case WM8962_HDBASS_ATK_1: + case WM8962_HDBASS_ATK_0: + case WM8962_HDBASS_DCY_1: + case WM8962_HDBASS_DCY_0: + case WM8962_HDBASS_PG_1: + case WM8962_HDBASS_PG_0: + case WM8962_HPF_C_1: + case WM8962_HPF_C_0: + case WM8962_ADCL_RETUNE_C1_1: + case WM8962_ADCL_RETUNE_C1_0: + case WM8962_ADCL_RETUNE_C2_1: + case WM8962_ADCL_RETUNE_C2_0: + case WM8962_ADCL_RETUNE_C3_1: + case WM8962_ADCL_RETUNE_C3_0: + case WM8962_ADCL_RETUNE_C4_1: + case WM8962_ADCL_RETUNE_C4_0: + case WM8962_ADCL_RETUNE_C5_1: + case WM8962_ADCL_RETUNE_C5_0: + case WM8962_ADCL_RETUNE_C6_1: + case WM8962_ADCL_RETUNE_C6_0: + case WM8962_ADCL_RETUNE_C7_1: + case WM8962_ADCL_RETUNE_C7_0: + case WM8962_ADCL_RETUNE_C8_1: + case WM8962_ADCL_RETUNE_C8_0: + case WM8962_ADCL_RETUNE_C9_1: + case WM8962_ADCL_RETUNE_C9_0: + case WM8962_ADCL_RETUNE_C10_1: + case WM8962_ADCL_RETUNE_C10_0: + case WM8962_ADCL_RETUNE_C11_1: + case WM8962_ADCL_RETUNE_C11_0: + case WM8962_ADCL_RETUNE_C12_1: + case WM8962_ADCL_RETUNE_C12_0: + case WM8962_ADCL_RETUNE_C13_1: + case WM8962_ADCL_RETUNE_C13_0: + case WM8962_ADCL_RETUNE_C14_1: + case WM8962_ADCL_RETUNE_C14_0: + case WM8962_ADCL_RETUNE_C15_1: + case WM8962_ADCL_RETUNE_C15_0: + case WM8962_ADCL_RETUNE_C16_1: + case WM8962_ADCL_RETUNE_C16_0: + case WM8962_ADCL_RETUNE_C17_1: + case WM8962_ADCL_RETUNE_C17_0: + case WM8962_ADCL_RETUNE_C18_1: + case WM8962_ADCL_RETUNE_C18_0: + case WM8962_ADCL_RETUNE_C19_1: + case WM8962_ADCL_RETUNE_C19_0: + case WM8962_ADCL_RETUNE_C20_1: + case WM8962_ADCL_RETUNE_C20_0: + case WM8962_ADCL_RETUNE_C21_1: + case WM8962_ADCL_RETUNE_C21_0: + case WM8962_ADCL_RETUNE_C22_1: + case WM8962_ADCL_RETUNE_C22_0: + case WM8962_ADCL_RETUNE_C23_1: + case WM8962_ADCL_RETUNE_C23_0: + case WM8962_ADCL_RETUNE_C24_1: + case WM8962_ADCL_RETUNE_C24_0: + case WM8962_ADCL_RETUNE_C25_1: + case WM8962_ADCL_RETUNE_C25_0: + case WM8962_ADCL_RETUNE_C26_1: + case WM8962_ADCL_RETUNE_C26_0: + case WM8962_ADCL_RETUNE_C27_1: + case WM8962_ADCL_RETUNE_C27_0: + case WM8962_ADCL_RETUNE_C28_1: + case WM8962_ADCL_RETUNE_C28_0: + case WM8962_ADCL_RETUNE_C29_1: + case WM8962_ADCL_RETUNE_C29_0: + case WM8962_ADCL_RETUNE_C30_1: + case WM8962_ADCL_RETUNE_C30_0: + case WM8962_ADCL_RETUNE_C31_1: + case WM8962_ADCL_RETUNE_C31_0: + case WM8962_ADCL_RETUNE_C32_1: + case WM8962_ADCL_RETUNE_C32_0: + case WM8962_RETUNEADC_PG2_1: + case WM8962_RETUNEADC_PG2_0: + case WM8962_RETUNEADC_PG_1: + case WM8962_RETUNEADC_PG_0: + case WM8962_ADCR_RETUNE_C1_1: + case WM8962_ADCR_RETUNE_C1_0: + case WM8962_ADCR_RETUNE_C2_1: + case WM8962_ADCR_RETUNE_C2_0: + case WM8962_ADCR_RETUNE_C3_1: + case WM8962_ADCR_RETUNE_C3_0: + case WM8962_ADCR_RETUNE_C4_1: + case WM8962_ADCR_RETUNE_C4_0: + case WM8962_ADCR_RETUNE_C5_1: + case WM8962_ADCR_RETUNE_C5_0: + case WM8962_ADCR_RETUNE_C6_1: + case WM8962_ADCR_RETUNE_C6_0: + case WM8962_ADCR_RETUNE_C7_1: + case WM8962_ADCR_RETUNE_C7_0: + case WM8962_ADCR_RETUNE_C8_1: + case WM8962_ADCR_RETUNE_C8_0: + case WM8962_ADCR_RETUNE_C9_1: + case WM8962_ADCR_RETUNE_C9_0: + case WM8962_ADCR_RETUNE_C10_1: + case WM8962_ADCR_RETUNE_C10_0: + case WM8962_ADCR_RETUNE_C11_1: + case WM8962_ADCR_RETUNE_C11_0: + case WM8962_ADCR_RETUNE_C12_1: + case WM8962_ADCR_RETUNE_C12_0: + case WM8962_ADCR_RETUNE_C13_1: + case WM8962_ADCR_RETUNE_C13_0: + case WM8962_ADCR_RETUNE_C14_1: + case WM8962_ADCR_RETUNE_C14_0: + case WM8962_ADCR_RETUNE_C15_1: + case WM8962_ADCR_RETUNE_C15_0: + case WM8962_ADCR_RETUNE_C16_1: + case WM8962_ADCR_RETUNE_C16_0: + case WM8962_ADCR_RETUNE_C17_1: + case WM8962_ADCR_RETUNE_C17_0: + case WM8962_ADCR_RETUNE_C18_1: + case WM8962_ADCR_RETUNE_C18_0: + case WM8962_ADCR_RETUNE_C19_1: + case WM8962_ADCR_RETUNE_C19_0: + case WM8962_ADCR_RETUNE_C20_1: + case WM8962_ADCR_RETUNE_C20_0: + case WM8962_ADCR_RETUNE_C21_1: + case WM8962_ADCR_RETUNE_C21_0: + case WM8962_ADCR_RETUNE_C22_1: + case WM8962_ADCR_RETUNE_C22_0: + case WM8962_ADCR_RETUNE_C23_1: + case WM8962_ADCR_RETUNE_C23_0: + case WM8962_ADCR_RETUNE_C24_1: + case WM8962_ADCR_RETUNE_C24_0: + case WM8962_ADCR_RETUNE_C25_1: + case WM8962_ADCR_RETUNE_C25_0: + case WM8962_ADCR_RETUNE_C26_1: + case WM8962_ADCR_RETUNE_C26_0: + case WM8962_ADCR_RETUNE_C27_1: + case WM8962_ADCR_RETUNE_C27_0: + case WM8962_ADCR_RETUNE_C28_1: + case WM8962_ADCR_RETUNE_C28_0: + case WM8962_ADCR_RETUNE_C29_1: + case WM8962_ADCR_RETUNE_C29_0: + case WM8962_ADCR_RETUNE_C30_1: + case WM8962_ADCR_RETUNE_C30_0: + case WM8962_ADCR_RETUNE_C31_1: + case WM8962_ADCR_RETUNE_C31_0: + case WM8962_ADCR_RETUNE_C32_1: + case WM8962_ADCR_RETUNE_C32_0: + case WM8962_DACL_RETUNE_C1_1: + case WM8962_DACL_RETUNE_C1_0: + case WM8962_DACL_RETUNE_C2_1: + case WM8962_DACL_RETUNE_C2_0: + case WM8962_DACL_RETUNE_C3_1: + case WM8962_DACL_RETUNE_C3_0: + case WM8962_DACL_RETUNE_C4_1: + case WM8962_DACL_RETUNE_C4_0: + case WM8962_DACL_RETUNE_C5_1: + case WM8962_DACL_RETUNE_C5_0: + case WM8962_DACL_RETUNE_C6_1: + case WM8962_DACL_RETUNE_C6_0: + case WM8962_DACL_RETUNE_C7_1: + case WM8962_DACL_RETUNE_C7_0: + case WM8962_DACL_RETUNE_C8_1: + case WM8962_DACL_RETUNE_C8_0: + case WM8962_DACL_RETUNE_C9_1: + case WM8962_DACL_RETUNE_C9_0: + case WM8962_DACL_RETUNE_C10_1: + case WM8962_DACL_RETUNE_C10_0: + case WM8962_DACL_RETUNE_C11_1: + case WM8962_DACL_RETUNE_C11_0: + case WM8962_DACL_RETUNE_C12_1: + case WM8962_DACL_RETUNE_C12_0: + case WM8962_DACL_RETUNE_C13_1: + case WM8962_DACL_RETUNE_C13_0: + case WM8962_DACL_RETUNE_C14_1: + case WM8962_DACL_RETUNE_C14_0: + case WM8962_DACL_RETUNE_C15_1: + case WM8962_DACL_RETUNE_C15_0: + case WM8962_DACL_RETUNE_C16_1: + case WM8962_DACL_RETUNE_C16_0: + case WM8962_DACL_RETUNE_C17_1: + case WM8962_DACL_RETUNE_C17_0: + case WM8962_DACL_RETUNE_C18_1: + case WM8962_DACL_RETUNE_C18_0: + case WM8962_DACL_RETUNE_C19_1: + case WM8962_DACL_RETUNE_C19_0: + case WM8962_DACL_RETUNE_C20_1: + case WM8962_DACL_RETUNE_C20_0: + case WM8962_DACL_RETUNE_C21_1: + case WM8962_DACL_RETUNE_C21_0: + case WM8962_DACL_RETUNE_C22_1: + case WM8962_DACL_RETUNE_C22_0: + case WM8962_DACL_RETUNE_C23_1: + case WM8962_DACL_RETUNE_C23_0: + case WM8962_DACL_RETUNE_C24_1: + case WM8962_DACL_RETUNE_C24_0: + case WM8962_DACL_RETUNE_C25_1: + case WM8962_DACL_RETUNE_C25_0: + case WM8962_DACL_RETUNE_C26_1: + case WM8962_DACL_RETUNE_C26_0: + case WM8962_DACL_RETUNE_C27_1: + case WM8962_DACL_RETUNE_C27_0: + case WM8962_DACL_RETUNE_C28_1: + case WM8962_DACL_RETUNE_C28_0: + case WM8962_DACL_RETUNE_C29_1: + case WM8962_DACL_RETUNE_C29_0: + case WM8962_DACL_RETUNE_C30_1: + case WM8962_DACL_RETUNE_C30_0: + case WM8962_DACL_RETUNE_C31_1: + case WM8962_DACL_RETUNE_C31_0: + case WM8962_DACL_RETUNE_C32_1: + case WM8962_DACL_RETUNE_C32_0: + case WM8962_RETUNEDAC_PG2_1: + case WM8962_RETUNEDAC_PG2_0: + case WM8962_RETUNEDAC_PG_1: + case WM8962_RETUNEDAC_PG_0: + case WM8962_DACR_RETUNE_C1_1: + case WM8962_DACR_RETUNE_C1_0: + case WM8962_DACR_RETUNE_C2_1: + case WM8962_DACR_RETUNE_C2_0: + case WM8962_DACR_RETUNE_C3_1: + case WM8962_DACR_RETUNE_C3_0: + case WM8962_DACR_RETUNE_C4_1: + case WM8962_DACR_RETUNE_C4_0: + case WM8962_DACR_RETUNE_C5_1: + case WM8962_DACR_RETUNE_C5_0: + case WM8962_DACR_RETUNE_C6_1: + case WM8962_DACR_RETUNE_C6_0: + case WM8962_DACR_RETUNE_C7_1: + case WM8962_DACR_RETUNE_C7_0: + case WM8962_DACR_RETUNE_C8_1: + case WM8962_DACR_RETUNE_C8_0: + case WM8962_DACR_RETUNE_C9_1: + case WM8962_DACR_RETUNE_C9_0: + case WM8962_DACR_RETUNE_C10_1: + case WM8962_DACR_RETUNE_C10_0: + case WM8962_DACR_RETUNE_C11_1: + case WM8962_DACR_RETUNE_C11_0: + case WM8962_DACR_RETUNE_C12_1: + case WM8962_DACR_RETUNE_C12_0: + case WM8962_DACR_RETUNE_C13_1: + case WM8962_DACR_RETUNE_C13_0: + case WM8962_DACR_RETUNE_C14_1: + case WM8962_DACR_RETUNE_C14_0: + case WM8962_DACR_RETUNE_C15_1: + case WM8962_DACR_RETUNE_C15_0: + case WM8962_DACR_RETUNE_C16_1: + case WM8962_DACR_RETUNE_C16_0: + case WM8962_DACR_RETUNE_C17_1: + case WM8962_DACR_RETUNE_C17_0: + case WM8962_DACR_RETUNE_C18_1: + case WM8962_DACR_RETUNE_C18_0: + case WM8962_DACR_RETUNE_C19_1: + case WM8962_DACR_RETUNE_C19_0: + case WM8962_DACR_RETUNE_C20_1: + case WM8962_DACR_RETUNE_C20_0: + case WM8962_DACR_RETUNE_C21_1: + case WM8962_DACR_RETUNE_C21_0: + case WM8962_DACR_RETUNE_C22_1: + case WM8962_DACR_RETUNE_C22_0: + case WM8962_DACR_RETUNE_C23_1: + case WM8962_DACR_RETUNE_C23_0: + case WM8962_DACR_RETUNE_C24_1: + case WM8962_DACR_RETUNE_C24_0: + case WM8962_DACR_RETUNE_C25_1: + case WM8962_DACR_RETUNE_C25_0: + case WM8962_DACR_RETUNE_C26_1: + case WM8962_DACR_RETUNE_C26_0: + case WM8962_DACR_RETUNE_C27_1: + case WM8962_DACR_RETUNE_C27_0: + case WM8962_DACR_RETUNE_C28_1: + case WM8962_DACR_RETUNE_C28_0: + case WM8962_DACR_RETUNE_C29_1: + case WM8962_DACR_RETUNE_C29_0: + case WM8962_DACR_RETUNE_C30_1: + case WM8962_DACR_RETUNE_C30_0: + case WM8962_DACR_RETUNE_C31_1: + case WM8962_DACR_RETUNE_C31_0: + case WM8962_DACR_RETUNE_C32_1: + case WM8962_DACR_RETUNE_C32_0: + case WM8962_VSS_XHD2_1: + case WM8962_VSS_XHD2_0: + case WM8962_VSS_XHD3_1: + case WM8962_VSS_XHD3_0: + case WM8962_VSS_XHN1_1: + case WM8962_VSS_XHN1_0: + case WM8962_VSS_XHN2_1: + case WM8962_VSS_XHN2_0: + case WM8962_VSS_XHN3_1: + case WM8962_VSS_XHN3_0: + case WM8962_VSS_XLA_1: + case WM8962_VSS_XLA_0: + case WM8962_VSS_XLB_1: + case WM8962_VSS_XLB_0: + case WM8962_VSS_XLG_1: + case WM8962_VSS_XLG_0: + case WM8962_VSS_PG2_1: + case WM8962_VSS_PG2_0: + case WM8962_VSS_PG_1: + case WM8962_VSS_PG_0: + case WM8962_VSS_XTD1_1: + case WM8962_VSS_XTD1_0: + case WM8962_VSS_XTD2_1: + case WM8962_VSS_XTD2_0: + case WM8962_VSS_XTD3_1: + case WM8962_VSS_XTD3_0: + case WM8962_VSS_XTD4_1: + case WM8962_VSS_XTD4_0: + case WM8962_VSS_XTD5_1: + case WM8962_VSS_XTD5_0: + case WM8962_VSS_XTD6_1: + case WM8962_VSS_XTD6_0: + case WM8962_VSS_XTD7_1: + case WM8962_VSS_XTD7_0: + case WM8962_VSS_XTD8_1: + case WM8962_VSS_XTD8_0: + case WM8962_VSS_XTD9_1: + case WM8962_VSS_XTD9_0: + case WM8962_VSS_XTD10_1: + case WM8962_VSS_XTD10_0: + case WM8962_VSS_XTD11_1: + case WM8962_VSS_XTD11_0: + case WM8962_VSS_XTD12_1: + case WM8962_VSS_XTD12_0: + case WM8962_VSS_XTD13_1: + case WM8962_VSS_XTD13_0: + case WM8962_VSS_XTD14_1: + case WM8962_VSS_XTD14_0: + case WM8962_VSS_XTD15_1: + case WM8962_VSS_XTD15_0: + case WM8962_VSS_XTD16_1: + case WM8962_VSS_XTD16_0: + case WM8962_VSS_XTD17_1: + case WM8962_VSS_XTD17_0: + case WM8962_VSS_XTD18_1: + case WM8962_VSS_XTD18_0: + case WM8962_VSS_XTD19_1: + case WM8962_VSS_XTD19_0: + case WM8962_VSS_XTD20_1: + case WM8962_VSS_XTD20_0: + case WM8962_VSS_XTD21_1: + case WM8962_VSS_XTD21_0: + case WM8962_VSS_XTD22_1: + case WM8962_VSS_XTD22_0: + case WM8962_VSS_XTD23_1: + case WM8962_VSS_XTD23_0: + case WM8962_VSS_XTD24_1: + case WM8962_VSS_XTD24_0: + case WM8962_VSS_XTD25_1: + case WM8962_VSS_XTD25_0: + case WM8962_VSS_XTD26_1: + case WM8962_VSS_XTD26_0: + case WM8962_VSS_XTD27_1: + case WM8962_VSS_XTD27_0: + case WM8962_VSS_XTD28_1: + case WM8962_VSS_XTD28_0: + case WM8962_VSS_XTD29_1: + case WM8962_VSS_XTD29_0: + case WM8962_VSS_XTD30_1: + case WM8962_VSS_XTD30_0: + case WM8962_VSS_XTD31_1: + case WM8962_VSS_XTD31_0: + case WM8962_VSS_XTD32_1: + case WM8962_VSS_XTD32_0: + case WM8962_VSS_XTS1_1: + case WM8962_VSS_XTS1_0: + case WM8962_VSS_XTS2_1: + case WM8962_VSS_XTS2_0: + case WM8962_VSS_XTS3_1: + case WM8962_VSS_XTS3_0: + case WM8962_VSS_XTS4_1: + case WM8962_VSS_XTS4_0: + case WM8962_VSS_XTS5_1: + case WM8962_VSS_XTS5_0: + case WM8962_VSS_XTS6_1: + case WM8962_VSS_XTS6_0: + case WM8962_VSS_XTS7_1: + case WM8962_VSS_XTS7_0: + case WM8962_VSS_XTS8_1: + case WM8962_VSS_XTS8_0: + case WM8962_VSS_XTS9_1: + case WM8962_VSS_XTS9_0: + case WM8962_VSS_XTS10_1: + case WM8962_VSS_XTS10_0: + case WM8962_VSS_XTS11_1: + case WM8962_VSS_XTS11_0: + case WM8962_VSS_XTS12_1: + case WM8962_VSS_XTS12_0: + case WM8962_VSS_XTS13_1: + case WM8962_VSS_XTS13_0: + case WM8962_VSS_XTS14_1: + case WM8962_VSS_XTS14_0: + case WM8962_VSS_XTS15_1: + case WM8962_VSS_XTS15_0: + case WM8962_VSS_XTS16_1: + case WM8962_VSS_XTS16_0: + case WM8962_VSS_XTS17_1: + case WM8962_VSS_XTS17_0: + case WM8962_VSS_XTS18_1: + case WM8962_VSS_XTS18_0: + case WM8962_VSS_XTS19_1: + case WM8962_VSS_XTS19_0: + case WM8962_VSS_XTS20_1: + case WM8962_VSS_XTS20_0: + case WM8962_VSS_XTS21_1: + case WM8962_VSS_XTS21_0: + case WM8962_VSS_XTS22_1: + case WM8962_VSS_XTS22_0: + case WM8962_VSS_XTS23_1: + case WM8962_VSS_XTS23_0: + case WM8962_VSS_XTS24_1: + case WM8962_VSS_XTS24_0: + case WM8962_VSS_XTS25_1: + case WM8962_VSS_XTS25_0: + case WM8962_VSS_XTS26_1: + case WM8962_VSS_XTS26_0: + case WM8962_VSS_XTS27_1: + case WM8962_VSS_XTS27_0: + case WM8962_VSS_XTS28_1: + case WM8962_VSS_XTS28_0: + case WM8962_VSS_XTS29_1: + case WM8962_VSS_XTS29_0: + case WM8962_VSS_XTS30_1: + case WM8962_VSS_XTS30_0: + case WM8962_VSS_XTS31_1: + case WM8962_VSS_XTS31_0: + case WM8962_VSS_XTS32_1: + case WM8962_VSS_XTS32_0: + return true; + default: + return false; + } } static int wm8962_reset(struct wm8962_priv *wm8962) -- cgit v0.10.2 From b33005f3ef6a85be3202ee1b8a2513ed1ef4019d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 6 Jan 2012 11:30:10 +0800 Subject: ASoC: jz4740: Convert qi_lb60 to use snd_soc_register_card() Use snd_soc_register_card() instead of creating a "soc-audio" platform device. Signed-off-by: Axel Lin Acked-by: Lars-Peter Clausen Signed-off-by: Mark Brown diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index 639e3ce..9a91fe9 100644 --- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c @@ -418,6 +418,11 @@ static struct platform_device qi_lb60_charger_device = { }, }; +/* audio */ +static struct platform_device qi_lb60_audio_device = { + .name = "qi-lb60-audio", + .id = -1, +}; static struct platform_device *jz_platform_devices[] __initdata = { &jz4740_udc_device, @@ -434,6 +439,7 @@ static struct platform_device *jz_platform_devices[] __initdata = { &qi_lb60_gpio_keys, &qi_lb60_pwm_beeper, &qi_lb60_charger_device, + &qi_lb60_audio_device, }; static void __init board_gpio_setup(void) diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c index 0097c3b..e8aaff1 100644 --- a/sound/soc/jz4740/qi_lb60.c +++ b/sound/soc/jz4740/qi_lb60.c @@ -91,56 +91,52 @@ static struct snd_soc_card qi_lb60 = { .num_dapm_routes = ARRAY_SIZE(qi_lb60_routes), }; -static struct platform_device *qi_lb60_snd_device; - static const struct gpio qi_lb60_gpios[] = { { QI_LB60_SND_GPIO, GPIOF_OUT_INIT_LOW, "SND" }, { QI_LB60_AMP_GPIO, GPIOF_OUT_INIT_LOW, "AMP" }, }; -static int __init qi_lb60_init(void) +static int __devinit qi_lb60_probe(struct platform_device *pdev) { + struct snd_soc_card *card = &qi_lb60; int ret; - qi_lb60_snd_device = platform_device_alloc("soc-audio", -1); - - if (!qi_lb60_snd_device) - return -ENOMEM; - ret = gpio_request_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios)); - if (ret) { - pr_err("qi_lb60 snd: Failed to request gpios: %d\n", ret); - goto err_device_put; - } + if (ret) + return ret; - platform_set_drvdata(qi_lb60_snd_device, &qi_lb60); + card->dev = &pdev->dev; - ret = platform_device_add(qi_lb60_snd_device); + ret = snd_soc_register_card(card); if (ret) { - pr_err("qi_lb60 snd: Failed to add snd soc device: %d\n", ret); - goto err_unset_pdata; + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", + ret); + gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios)); } - - return 0; - -err_unset_pdata: - platform_set_drvdata(qi_lb60_snd_device, NULL); -/*err_gpio_free_array:*/ - gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios)); -err_device_put: - platform_device_put(qi_lb60_snd_device); - return ret; } -module_init(qi_lb60_init); -static void __exit qi_lb60_exit(void) +static int __devexit qi_lb60_remove(struct platform_device *pdev) { - platform_device_unregister(qi_lb60_snd_device); + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios)); + return 0; } -module_exit(qi_lb60_exit); + +static struct platform_driver qi_lb60_driver = { + .driver = { + .name = "qi-lb60-audio", + .owner = THIS_MODULE, + }, + .probe = qi_lb60_probe, + .remove = __devexit_p(qi_lb60_remove), +}; + +module_platform_driver(qi_lb60_driver); MODULE_AUTHOR("Lars-Peter Clausen "); MODULE_DESCRIPTION("ALSA SoC QI LB60 Audio support"); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:qi-lb60-audio"); -- cgit v0.10.2 From d19fd5db3e6b72e84c2012a28f6d7cf6f737193a Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Mon, 16 Jan 2012 10:44:13 +0000 Subject: ASoC: wm8983: Remove useless snd_kcontrol This must be a leftover from a previous driver. Signed-off-by: Dimitris Papastamos Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index cebde56..367388f 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c @@ -249,9 +249,6 @@ static const char *eq5_cutoff_text[] = { static const SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8983_EQ5_HIGH_SHELF, 5, eq5_cutoff_text); -static const char *speaker_mode_text[] = { "Class A/B", "Class D" }; -static const SOC_ENUM_SINGLE_DECL(speaker_mode, 0x17, 8, speaker_mode_text); - static const char *depth_3d_text[] = { "Off", "6.67%", @@ -369,8 +366,6 @@ static const struct snd_kcontrol_new wm8983_snd_controls[] = { SOC_SINGLE_TLV("EQ5 Volume", WM8983_EQ5_HIGH_SHELF, 0, 24, 1, eq_tlv), SOC_ENUM("3D Depth", depth_3d), - - SOC_ENUM("Speaker Mode", speaker_mode) }; static const struct snd_kcontrol_new left_out_mixer[] = { -- cgit v0.10.2 From 5f52ee48751e63ed555b56a82db446745f60bc82 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 11 Jan 2012 16:31:00 -0800 Subject: ASoC: Add WM8962 DAC and ADC L/R swap support Simple switches since there's no per-channel control. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index a20e2b7..cc4049e 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -1714,6 +1714,8 @@ SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1, SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8962_LEFT_DAC_VOLUME, WM8962_RIGHT_DAC_VOLUME, 1, 127, 0, digital_tlv), SOC_SINGLE("DAC High Performance Switch", WM8962_ADC_DAC_CONTROL_2, 0, 1, 0), +SOC_SINGLE("DAC L/R Swap Switch", WM8962_AUDIO_INTERFACE_0, 5, 1, 0), +SOC_SINGLE("ADC L/R Swap Switch", WM8962_AUDIO_INTERFACE_0, 8, 1, 0), SOC_SINGLE("ADC High Performance Switch", WM8962_ADDITIONAL_CONTROL_1, 5, 1, 0), -- cgit v0.10.2 From 58ba9b25454fe9b6ded804f69cb7ed4500b685fc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 16 Jan 2012 18:38:51 +0000 Subject: ASoC: Allow drivers to specify how many bits are significant on a DAI Most devices accept data in formats that don't correspond directly to their internal format. ALSA allows us to set a msbits constraint which tells userspace about this in case it finds it useful (for example, in order to avoid wasting effort dithering bits that will be ignored when raising the sample size of data) so provide a mechanism for drivers to specify the number of bits that are actually significant on a DAI and add the appropriate constraints along with all the others. This is done slightly awkwardly as the constraint is specified per sample size - we loop over every possible sample size, including ones that the device doesn't support and including ones that have fewer bits than are actually used, but this is harmless as the upper layers do the right thing in these cases. Signed-off-by: Mark Brown Acked-by: Liam Girdwood diff --git a/include/sound/soc.h b/include/sound/soc.h index 0992dff..55381fc 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -505,6 +505,7 @@ struct snd_soc_pcm_stream { unsigned int rate_max; /* max rate */ unsigned int channels_min; /* min channels */ unsigned int channels_max; /* max channels */ + unsigned int sig_bits; /* number of bits of content */ }; /* SoC audio ops */ diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index cdc860a..8bb1793 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -63,6 +63,39 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, } /* + * List of sample sizes that might go over the bus for parameter + * application. There ought to be a wildcard sample size for things + * like the DAC/ADC resolution to use but there isn't right now. + */ +static int sample_sizes[] = { + 8, 16, 24, 32, +}; + +static void soc_pcm_apply_msb(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + int ret, i, bits; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + bits = dai->driver->playback.sig_bits; + else + bits = dai->driver->capture.sig_bits; + + if (!bits) + return; + + for (i = 0; i < ARRAY_SIZE(sample_sizes); i++) { + ret = snd_pcm_hw_constraint_msbits(substream->runtime, + 0, sample_sizes[i], + bits); + if (ret != 0) + dev_warn(dai->dev, + "Failed to set MSB %d/%d: %d\n", + bits, sample_sizes[i], ret); + } +} + +/* * Called by ALSA when a PCM substream is opened, the runtime->hw record is * then initialized and any private data can be allocated. This also calls * startup for the cpu DAI, platform, machine and codec DAI. @@ -187,6 +220,9 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) goto config_err; } + soc_pcm_apply_msb(substream, codec_dai); + soc_pcm_apply_msb(substream, cpu_dai); + /* Symmetry only applies if we've already got an active stream. */ if (cpu_dai->active) { ret = soc_pcm_apply_symmetry(substream, cpu_dai); -- cgit v0.10.2 From a4b5233792443a2caed0db91003e5a75c50bc6c9 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 16 Jan 2012 18:39:21 +0000 Subject: ASoC: 24 bits are significant on the WM8996 audio interfaces Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 86f5b6b..8e8f8d1 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -3086,6 +3086,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = { .channels_max = 6, .rates = WM8996_RATES, .formats = WM8996_FORMATS, + .sig_bits = 24, }, .capture = { .stream_name = "AIF1 Capture", @@ -3093,6 +3094,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = { .channels_max = 6, .rates = WM8996_RATES, .formats = WM8996_FORMATS, + .sig_bits = 24, }, .ops = &wm8996_dai_ops, }, @@ -3104,6 +3106,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = { .channels_max = 2, .rates = WM8996_RATES, .formats = WM8996_FORMATS, + .sig_bits = 24, }, .capture = { .stream_name = "AIF2 Capture", @@ -3111,6 +3114,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = { .channels_max = 2, .rates = WM8996_RATES, .formats = WM8996_FORMATS, + .sig_bits = 24, }, .ops = &wm8996_dai_ops, }, -- cgit v0.10.2 From 164548d3b3733b10990274e1e92848656e9d6d1e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 17 Jan 2012 16:42:05 +0000 Subject: ASoC: Implement basic WM8993 interrupt support If an interrupt is supplied then use it for thermal warning and FLL lock notifications. When using the interrupt raise the timeout for the FLL lock substantially to reduce the chances of spurious warnings. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index e7ae9fd..eca9352 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -204,9 +204,11 @@ static struct { struct wm8993_priv { struct wm_hubs_data hubs_data; + struct device *dev; struct regmap *regmap; struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES]; struct wm8993_platform_data pdata; + struct completion fll_lock; int master; int sysclk_source; int tdm_slots; @@ -225,6 +227,7 @@ static bool wm8993_volatile(struct device *dev, unsigned int reg) { switch (reg) { case WM8993_SOFTWARE_RESET: + case WM8993_GPIO_CTRL_1: case WM8993_DC_SERVO_0: case WM8993_DC_SERVO_READBACK_0: case WM8993_DC_SERVO_READBACK_1: @@ -467,8 +470,10 @@ static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source, unsigned int Fref, unsigned int Fout) { struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); + struct i2c_client *i2c = to_i2c_client(codec->dev); u16 reg1, reg4, reg5; struct _fll_div fll_div; + unsigned int timeout; int ret; /* Any change? */ @@ -539,14 +544,22 @@ static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source, reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT; snd_soc_write(codec, WM8993_FLL_CONTROL_5, reg5); + /* If we've got an interrupt wired up make sure we get it */ + if (i2c->irq) + timeout = msecs_to_jiffies(20); + else if (Fref < 1000000) + timeout = msecs_to_jiffies(3); + else + timeout = msecs_to_jiffies(1); + + try_wait_for_completion(&wm8993->fll_lock); + /* Enable the FLL */ snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA); - /* Both overestimates */ - if (Fref < 1000000) - msleep(3); - else - msleep(1); + timeout = wait_for_completion_timeout(&wm8993->fll_lock, timeout); + if (i2c->irq && !timeout) + dev_warn(codec->dev, "Timed out waiting for FLL\n"); dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout); @@ -1471,6 +1484,45 @@ out: return 0; } +static irqreturn_t wm8993_irq(int irq, void *data) +{ + struct wm8993_priv *wm8993 = data; + int mask, val, ret; + + ret = regmap_read(wm8993->regmap, WM8993_GPIO_CTRL_1, &val); + if (ret != 0) { + dev_err(wm8993->dev, "Failed to read interrupt status: %d\n", + ret); + return IRQ_NONE; + } + + ret = regmap_read(wm8993->regmap, WM8993_GPIOCTRL_2, &mask); + if (ret != 0) { + dev_err(wm8993->dev, "Failed to read interrupt mask: %d\n", + ret); + return IRQ_NONE; + } + + /* The IRQ pin status is visible in the register too */ + val &= ~(mask | WM8993_IRQ); + if (!val) + return IRQ_NONE; + + if (val & WM8993_TEMPOK_EINT) + dev_crit(wm8993->dev, "Thermal warning\n"); + + if (val & WM8993_FLL_LOCK_EINT) { + dev_dbg(wm8993->dev, "FLL locked\n"); + complete(&wm8993->fll_lock); + } + + ret = regmap_write(wm8993->regmap, WM8993_GPIO_CTRL_1, val); + if (ret != 0) + dev_err(wm8993->dev, "Failed to ack interrupt: %d\n", ret); + + return IRQ_HANDLED; +} + static const struct snd_soc_dai_ops wm8993_ops = { .set_sysclk = wm8993_set_sysclk, .set_fmt = wm8993_set_dai_fmt, @@ -1671,6 +1723,9 @@ static __devinit int wm8993_i2c_probe(struct i2c_client *i2c, if (wm8993 == NULL) return -ENOMEM; + wm8993->dev = &i2c->dev; + init_completion(&wm8993->fll_lock); + wm8993->regmap = regmap_init_i2c(i2c, &wm8993_regmap); if (IS_ERR(wm8993->regmap)) { ret = PTR_ERR(wm8993->regmap); @@ -1713,6 +1768,22 @@ static __devinit int wm8993_i2c_probe(struct i2c_client *i2c, if (ret != 0) goto err_enable; + if (i2c->irq) { + /* Put GPIO1 into interrupt mode (only GPIO1 can output IRQ) */ + ret = regmap_update_bits(wm8993->regmap, WM8993_GPIO1, + WM8993_GPIO1_PD | + WM8993_GPIO1_SEL_MASK, 7); + if (ret != 0) + goto err_enable; + + ret = request_threaded_irq(i2c->irq, NULL, wm8993_irq, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "wm8993", wm8993); + if (ret != 0) + goto err_enable; + + } + regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); regcache_cache_only(wm8993->regmap, true); @@ -1721,11 +1792,14 @@ static __devinit int wm8993_i2c_probe(struct i2c_client *i2c, &soc_codec_dev_wm8993, &wm8993_dai, 1); if (ret != 0) { dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); - goto err_enable; + goto err_irq; } return 0; +err_irq: + if (i2c->irq) + free_irq(i2c->irq, wm8993); err_enable: regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); err_get: @@ -1735,11 +1809,13 @@ err: return ret; } -static __devexit int wm8993_i2c_remove(struct i2c_client *client) +static __devexit int wm8993_i2c_remove(struct i2c_client *i2c) { - struct wm8993_priv *wm8993 = i2c_get_clientdata(client); + struct wm8993_priv *wm8993 = i2c_get_clientdata(i2c); - snd_soc_unregister_codec(&client->dev); + snd_soc_unregister_codec(&i2c->dev); + if (i2c->irq) + free_irq(i2c->irq, wm8993); regmap_exit(wm8993->regmap); regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); -- cgit v0.10.2 From 85f883933cd7353ab2227d5d2041312dce323e6b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 17 Jan 2012 15:08:35 +0000 Subject: ASoC: Make WM8993 I2C usage unconditional The WM8993 only supports I2C so don't ifdef the I2C support in the driver. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index eca9352..5502543 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -1710,7 +1710,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8993 = { .set_bias_level = wm8993_set_bias_level, }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static __devinit int wm8993_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -1838,27 +1837,22 @@ static struct i2c_driver wm8993_i2c_driver = { .remove = __devexit_p(wm8993_i2c_remove), .id_table = wm8993_i2c_id, }; -#endif static int __init wm8993_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&wm8993_i2c_driver); if (ret != 0) { pr_err("WM8993: Unable to register I2C driver: %d\n", ret); } -#endif return ret; } module_init(wm8993_modinit); static void __exit wm8993_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) i2c_del_driver(&wm8993_i2c_driver); -#endif } module_exit(wm8993_exit); -- cgit v0.10.2 From 99b0292d94975429eacc0c1ce4c985f7207394ba Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 17 Jan 2012 11:50:26 +0000 Subject: ASoC: 24 bits are significant on wm_hubs DAIs Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 5502543..dd687c3 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -1547,6 +1547,7 @@ static struct snd_soc_dai_driver wm8993_dai = { .channels_max = 2, .rates = WM8993_RATES, .formats = WM8993_FORMATS, + .sig_bits = 24, }, .capture = { .stream_name = "Capture", @@ -1554,6 +1555,7 @@ static struct snd_soc_dai_driver wm8993_dai = { .channels_max = 2, .rates = WM8993_RATES, .formats = WM8993_FORMATS, + .sig_bits = 24, }, .ops = &wm8993_ops, .symmetric_rates = 1, diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 93d27b6..b047bfa 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -2645,6 +2645,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = { .channels_max = 2, .rates = WM8994_RATES, .formats = WM8994_FORMATS, + .sig_bits = 24, }, .capture = { .stream_name = "AIF1 Capture", @@ -2652,6 +2653,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = { .channels_max = 2, .rates = WM8994_RATES, .formats = WM8994_FORMATS, + .sig_bits = 24, }, .ops = &wm8994_aif1_dai_ops, }, @@ -2664,6 +2666,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = { .channels_max = 2, .rates = WM8994_RATES, .formats = WM8994_FORMATS, + .sig_bits = 24, }, .capture = { .stream_name = "AIF2 Capture", @@ -2671,6 +2674,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = { .channels_max = 2, .rates = WM8994_RATES, .formats = WM8994_FORMATS, + .sig_bits = 24, }, .probe = wm8994_aif2_probe, .ops = &wm8994_aif2_dai_ops, @@ -2684,6 +2688,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = { .channels_max = 2, .rates = WM8994_RATES, .formats = WM8994_FORMATS, + .sig_bits = 24, }, .capture = { .stream_name = "AIF3 Capture", @@ -2691,7 +2696,8 @@ static struct snd_soc_dai_driver wm8994_dai[] = { .channels_max = 2, .rates = WM8994_RATES, .formats = WM8994_FORMATS, - }, + .sig_bits = 24, + }, .ops = &wm8994_aif3_dai_ops, } }; -- cgit v0.10.2 From 2688738ebac66b4e276321248eb3e12d59cbcd7f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 17 Jan 2012 19:18:27 +0000 Subject: ASoC: When releasing WM5100 put /RESET into reset Reset is active low, make sure we leave it asserted when release the device. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 66f0611..c112f5e 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -2764,7 +2764,7 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, err_reset: wm5100_free_gpio(i2c); if (wm5100->pdata.reset) { - gpio_set_value_cansleep(wm5100->pdata.reset, 1); + gpio_set_value_cansleep(wm5100->pdata.reset, 0); gpio_free(wm5100->pdata.reset); } err_ldo: @@ -2797,7 +2797,7 @@ static __devexit int wm5100_i2c_remove(struct i2c_client *client) snd_soc_unregister_codec(&client->dev); wm5100_free_gpio(client); if (wm5100->pdata.reset) { - gpio_set_value_cansleep(wm5100->pdata.reset, 1); + gpio_set_value_cansleep(wm5100->pdata.reset, 0); gpio_free(wm5100->pdata.reset); } if (wm5100->pdata.ldo_ena) { -- cgit v0.10.2 From 0132615da5bd97c74e4a015721039ef17a4841de Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 17 Jan 2012 19:27:04 +0000 Subject: ASoC: Say we can't read WM5100 ID register Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index c112f5e..de86042 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -2702,7 +2702,7 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, ret = regmap_read(wm5100->regmap, WM5100_SOFTWARE_RESET, ®); if (ret < 0) { - dev_err(&i2c->dev, "Failed to read ID register\n"); + dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret); goto err_reset; } switch (reg) { -- cgit v0.10.2 From f2c6e757f60d3d3e90dc5d1f1ff1a241dc0ea916 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 16 Jan 2012 17:32:21 -0200 Subject: ASoC: sgtl5000: Print revision number in hex Throughout the sgtl5000 driver source code and also in the sgtl5000 datasheet the revision code is shown in hexadecimal. Print it hex format, for consistency. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 7f4ba81..04ea485 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -1248,7 +1248,7 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec) } rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT; - dev_info(codec->dev, "sgtl5000 revision %d\n", rev); + dev_info(codec->dev, "sgtl5000 revision 0x%x\n", rev); /* * workaround for revision 0x11 and later, -- cgit v0.10.2 From 8d725b2bcb82ff46236bf745c9ab7cc4dde74699 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 18 Jan 2012 12:18:25 +0100 Subject: ASoC: tlv320dac33: Use core to set the msbits constraint Core can set the msbits constraint in behalf of the dai. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index f0aad26..21ccf0a 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -806,8 +806,6 @@ static int dac33_startup(struct snd_pcm_substream *substream, /* Stream started, save the substream pointer */ dac33->substream = substream; - snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24); - return 0; } @@ -1516,6 +1514,7 @@ static struct snd_soc_dai_driver dac33_dai = { .channels_max = 2, .rates = DAC33_RATES, .formats = DAC33_FORMATS,}, + .sig_bits = 24, .ops = &dac33_dai_ops, }; -- cgit v0.10.2 From 8819f65ceca118561c9d59a04cfd91625c74a262 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 18 Jan 2012 12:18:26 +0100 Subject: ASoC: twl4030: Use core to set the msbits constraint Core can set the msbits constraint in behalf of the dai. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 18e7101..a193f5f 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -1689,7 +1689,6 @@ static int twl4030_startup(struct snd_pcm_substream *substream, struct snd_soc_codec *codec = rtd->codec; struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); - snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24); if (twl4030->master_substream) { twl4030->slave_substream = substream; /* The DAI has one configuration for playback and capture, so @@ -2175,13 +2174,15 @@ static struct snd_soc_dai_driver twl4030_dai[] = { .channels_min = 2, .channels_max = 4, .rates = TWL4030_RATES | SNDRV_PCM_RATE_96000, - .formats = TWL4030_FORMATS,}, + .formats = TWL4030_FORMATS, + .sig_bits = 24,}, .capture = { .stream_name = "Capture", .channels_min = 2, .channels_max = 4, .rates = TWL4030_RATES, - .formats = TWL4030_FORMATS,}, + .formats = TWL4030_FORMATS, + .sig_bits = 24,}, .ops = &twl4030_dai_hifi_ops, }, { -- cgit v0.10.2 From 7df6f2551f2255f55adab7338a3a1e6594a12f63 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 18 Jan 2012 12:18:23 +0100 Subject: ASoC: omap-dmic: Use core to set the msbits constraint Core can set the msbits constraint in behalf of the dai. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index 0855c1c..4dcb5a7 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -113,12 +113,10 @@ static int omap_dmic_dai_startup(struct snd_pcm_substream *substream, mutex_lock(&dmic->mutex); - if (!dai->active) { - snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24); + if (!dai->active) dmic->active = 1; - } else { + else ret = -EBUSY; - } mutex_unlock(&dmic->mutex); @@ -445,6 +443,7 @@ static struct snd_soc_dai_driver omap_dmic_dai = { .channels_max = 6, .rates = SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000, .formats = SNDRV_PCM_FMTBIT_S32_LE, + .sig_bits = 24, }, .ops = &omap_dmic_dai_ops, }; -- cgit v0.10.2 From b4badd4960c9937fcbdcab2a57f0dd7e4ad45c8e Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 18 Jan 2012 12:18:24 +0100 Subject: ASoC: omap-mcpdm: Set 24msbits constraint McPDM internal FIFO is 24 bit wide. From the 32 bit sample 8 bit is discarded. Let application know about this via msbits constraint. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 0e25df4..3970556 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -419,12 +419,14 @@ static struct snd_soc_dai_driver omap_mcpdm_dai = { .channels_max = 5, .rates = OMAP_MCPDM_RATES, .formats = OMAP_MCPDM_FORMATS, + .sig_bits = 24, }, .capture = { .channels_min = 1, .channels_max = 3, .rates = OMAP_MCPDM_RATES, .formats = OMAP_MCPDM_FORMATS, + .sig_bits = 24, }, .ops = &omap_mcpdm_dai_ops, }; -- cgit v0.10.2 From 218240e27f89b477564a638ff77d45147e42a8fd Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 18 Jan 2012 13:47:02 +0000 Subject: ASoC: Remove redundant set_bias_level() from WM5100 remove() The framework should bring the device down before it calls the driver. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index de86042..8ea2089 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -2562,7 +2562,6 @@ static int wm5100_remove(struct snd_soc_codec *codec) struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); struct i2c_client *i2c = to_i2c_client(codec->dev); - wm5100_set_bias_level(codec, SND_SOC_BIAS_OFF); if (wm5100->pdata.hp_pol) { gpio_free(wm5100->pdata.hp_pol); } -- cgit v0.10.2 From 46c1a877c6fc29519760a3aaedf807332cd8a781 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 18 Jan 2012 14:53:08 +0000 Subject: ASoC: Make WM5100 interrupt path use regmap directly This will allow us to move the interrupt allocation out of the ASoC part of the driver and simplifies the locking by removing any reliance in the bulk of the interrupt path on the big CODEC lock. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 8ea2089..4b2c724 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -50,6 +50,7 @@ struct wm5100_fll { /* codec private data */ struct wm5100_priv { + struct device *dev; struct regmap *regmap; struct snd_soc_codec *codec; @@ -855,48 +856,48 @@ static int wm5100_dbvdd_ev(struct snd_soc_dapm_widget *w, } } -static void wm5100_log_status3(struct snd_soc_codec *codec, int val) +static void wm5100_log_status3(struct wm5100_priv *wm5100, int val) { if (val & WM5100_SPK_SHUTDOWN_WARN_EINT) - dev_crit(codec->dev, "Speaker shutdown warning\n"); + dev_crit(wm5100->dev, "Speaker shutdown warning\n"); if (val & WM5100_SPK_SHUTDOWN_EINT) - dev_crit(codec->dev, "Speaker shutdown\n"); + dev_crit(wm5100->dev, "Speaker shutdown\n"); if (val & WM5100_CLKGEN_ERR_EINT) - dev_crit(codec->dev, "SYSCLK underclocked\n"); + dev_crit(wm5100->dev, "SYSCLK underclocked\n"); if (val & WM5100_CLKGEN_ERR_ASYNC_EINT) - dev_crit(codec->dev, "ASYNCCLK underclocked\n"); + dev_crit(wm5100->dev, "ASYNCCLK underclocked\n"); } -static void wm5100_log_status4(struct snd_soc_codec *codec, int val) +static void wm5100_log_status4(struct wm5100_priv *wm5100, int val) { if (val & WM5100_AIF3_ERR_EINT) - dev_err(codec->dev, "AIF3 configuration error\n"); + dev_err(wm5100->dev, "AIF3 configuration error\n"); if (val & WM5100_AIF2_ERR_EINT) - dev_err(codec->dev, "AIF2 configuration error\n"); + dev_err(wm5100->dev, "AIF2 configuration error\n"); if (val & WM5100_AIF1_ERR_EINT) - dev_err(codec->dev, "AIF1 configuration error\n"); + dev_err(wm5100->dev, "AIF1 configuration error\n"); if (val & WM5100_CTRLIF_ERR_EINT) - dev_err(codec->dev, "Control interface error\n"); + dev_err(wm5100->dev, "Control interface error\n"); if (val & WM5100_ISRC2_UNDERCLOCKED_EINT) - dev_err(codec->dev, "ISRC2 underclocked\n"); + dev_err(wm5100->dev, "ISRC2 underclocked\n"); if (val & WM5100_ISRC1_UNDERCLOCKED_EINT) - dev_err(codec->dev, "ISRC1 underclocked\n"); + dev_err(wm5100->dev, "ISRC1 underclocked\n"); if (val & WM5100_FX_UNDERCLOCKED_EINT) - dev_err(codec->dev, "FX underclocked\n"); + dev_err(wm5100->dev, "FX underclocked\n"); if (val & WM5100_AIF3_UNDERCLOCKED_EINT) - dev_err(codec->dev, "AIF3 underclocked\n"); + dev_err(wm5100->dev, "AIF3 underclocked\n"); if (val & WM5100_AIF2_UNDERCLOCKED_EINT) - dev_err(codec->dev, "AIF2 underclocked\n"); + dev_err(wm5100->dev, "AIF2 underclocked\n"); if (val & WM5100_AIF1_UNDERCLOCKED_EINT) - dev_err(codec->dev, "AIF1 underclocked\n"); + dev_err(wm5100->dev, "AIF1 underclocked\n"); if (val & WM5100_ASRC_UNDERCLOCKED_EINT) - dev_err(codec->dev, "ASRC underclocked\n"); + dev_err(wm5100->dev, "ASRC underclocked\n"); if (val & WM5100_DAC_UNDERCLOCKED_EINT) - dev_err(codec->dev, "DAC underclocked\n"); + dev_err(wm5100->dev, "DAC underclocked\n"); if (val & WM5100_ADC_UNDERCLOCKED_EINT) - dev_err(codec->dev, "ADC underclocked\n"); + dev_err(wm5100->dev, "ADC underclocked\n"); if (val & WM5100_MIXER_UNDERCLOCKED_EINT) - dev_err(codec->dev, "Mixer underclocked\n"); + dev_err(wm5100->dev, "Mixer underclocked\n"); } static int wm5100_post_ev(struct snd_soc_dapm_widget *w, @@ -904,16 +905,17 @@ static int wm5100_post_ev(struct snd_soc_dapm_widget *w, int event) { struct snd_soc_codec *codec = w->codec; + struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); int ret; ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_3); ret &= WM5100_SPK_SHUTDOWN_WARN_STS | WM5100_SPK_SHUTDOWN_STS | WM5100_CLKGEN_ERR_STS | WM5100_CLKGEN_ERR_ASYNC_STS; - wm5100_log_status3(codec, ret); + wm5100_log_status3(wm5100, ret); ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_4); - wm5100_log_status4(codec, ret); + wm5100_log_status4(wm5100, ret); return 0; } @@ -2123,55 +2125,59 @@ static int wm5100_dig_vu[] = { WM5100_DAC_DIGITAL_VOLUME_6R, }; -static void wm5100_set_detect_mode(struct snd_soc_codec *codec, int the_mode) +static void wm5100_set_detect_mode(struct wm5100_priv *wm5100, int the_mode) { - struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); struct wm5100_jack_mode *mode = &wm5100->pdata.jack_modes[the_mode]; BUG_ON(the_mode >= ARRAY_SIZE(wm5100->pdata.jack_modes)); gpio_set_value_cansleep(wm5100->pdata.hp_pol, mode->hp_pol); - snd_soc_update_bits(codec, WM5100_ACCESSORY_DETECT_MODE_1, - WM5100_ACCDET_BIAS_SRC_MASK | - WM5100_ACCDET_SRC, - (mode->bias << WM5100_ACCDET_BIAS_SRC_SHIFT) | - mode->micd_src << WM5100_ACCDET_SRC_SHIFT); - snd_soc_update_bits(codec, WM5100_MISC_CONTROL, - WM5100_HPCOM_SRC, - mode->micd_src << WM5100_HPCOM_SRC_SHIFT); + regmap_update_bits(wm5100->regmap, WM5100_ACCESSORY_DETECT_MODE_1, + WM5100_ACCDET_BIAS_SRC_MASK | + WM5100_ACCDET_SRC, + (mode->bias << WM5100_ACCDET_BIAS_SRC_SHIFT) | + mode->micd_src << WM5100_ACCDET_SRC_SHIFT); + regmap_update_bits(wm5100->regmap, WM5100_MISC_CONTROL, + WM5100_HPCOM_SRC, + mode->micd_src << WM5100_HPCOM_SRC_SHIFT); wm5100->jack_mode = the_mode; - dev_dbg(codec->dev, "Set microphone polarity to %d\n", + dev_dbg(wm5100->dev, "Set microphone polarity to %d\n", wm5100->jack_mode); } -static void wm5100_micd_irq(struct snd_soc_codec *codec) +static void wm5100_micd_irq(struct wm5100_priv *wm5100) { - struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); - int val; + unsigned int val; + int ret; - val = snd_soc_read(codec, WM5100_MIC_DETECT_3); + ret = regmap_read(wm5100->regmap, WM5100_MIC_DETECT_3, &val); + if (ret != 0) { + dev_err(wm5100->dev, "Failed to read micropone status: %d\n", + ret); + return; + } - dev_dbg(codec->dev, "Microphone event: %x\n", val); + dev_dbg(wm5100->dev, "Microphone event: %x\n", val); if (!(val & WM5100_ACCDET_VALID)) { - dev_warn(codec->dev, "Microphone detection state invalid\n"); + dev_warn(wm5100->dev, "Microphone detection state invalid\n"); return; } /* No accessory, reset everything and report removal */ if (!(val & WM5100_ACCDET_STS)) { - dev_dbg(codec->dev, "Jack removal detected\n"); + dev_dbg(wm5100->dev, "Jack removal detected\n"); wm5100->jack_mic = false; wm5100->jack_detecting = true; snd_soc_jack_report(wm5100->jack, 0, SND_JACK_LINEOUT | SND_JACK_HEADSET | SND_JACK_BTN_0); - snd_soc_update_bits(codec, WM5100_MIC_DETECT_1, - WM5100_ACCDET_RATE_MASK, - WM5100_ACCDET_RATE_MASK); + regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1, + WM5100_ACCDET_RATE_MASK, + WM5100_ACCDET_RATE_MASK); return; } @@ -2181,7 +2187,7 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec) */ if (val & 0x400) { if (wm5100->jack_detecting) { - dev_dbg(codec->dev, "Microphone detected\n"); + dev_dbg(wm5100->dev, "Microphone detected\n"); wm5100->jack_mic = true; snd_soc_jack_report(wm5100->jack, SND_JACK_HEADSET, @@ -2189,11 +2195,11 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec) /* Increase poll rate to give better responsiveness * for buttons */ - snd_soc_update_bits(codec, WM5100_MIC_DETECT_1, - WM5100_ACCDET_RATE_MASK, - 5 << WM5100_ACCDET_RATE_SHIFT); + regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1, + WM5100_ACCDET_RATE_MASK, + 5 << WM5100_ACCDET_RATE_SHIFT); } else { - dev_dbg(codec->dev, "Mic button up\n"); + dev_dbg(wm5100->dev, "Mic button up\n"); snd_soc_jack_report(wm5100->jack, 0, SND_JACK_BTN_0); } @@ -2206,7 +2212,7 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec) * plain headphones. */ if (wm5100->jack_detecting && (val & 0x3f8)) { - wm5100_set_detect_mode(codec, !wm5100->jack_mode); + wm5100_set_detect_mode(wm5100, !wm5100->jack_mode); return; } @@ -2216,20 +2222,20 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec) */ if (val & 0x3fc) { if (wm5100->jack_mic) { - dev_dbg(codec->dev, "Mic button detected\n"); + dev_dbg(wm5100->dev, "Mic button detected\n"); snd_soc_jack_report(wm5100->jack, SND_JACK_BTN_0, SND_JACK_BTN_0); } else if (wm5100->jack_detecting) { - dev_dbg(codec->dev, "Headphone detected\n"); + dev_dbg(wm5100->dev, "Headphone detected\n"); snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE, SND_JACK_HEADPHONE); /* Increase the detection rate a bit for * responsiveness. */ - snd_soc_update_bits(codec, WM5100_MIC_DETECT_1, - WM5100_ACCDET_RATE_MASK, - 7 << WM5100_ACCDET_RATE_SHIFT); + regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1, + WM5100_ACCDET_RATE_MASK, + 7 << WM5100_ACCDET_RATE_SHIFT); } } } @@ -2242,7 +2248,7 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) wm5100->jack = jack; wm5100->jack_detecting = true; - wm5100_set_detect_mode(codec, 0); + wm5100_set_detect_mode(wm5100, 0); /* Slowest detection rate, gives debounce for initial * detection */ @@ -2281,52 +2287,70 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) static irqreturn_t wm5100_irq(int irq, void *data) { - struct snd_soc_codec *codec = data; - struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); + struct wm5100_priv *wm5100 = data; irqreturn_t status = IRQ_NONE; - int irq_val; + unsigned int irq_val, mask_val; + int ret; - irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3); - if (irq_val < 0) { - dev_err(codec->dev, "Failed to read IRQ status 3: %d\n", - irq_val); + ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_3, &irq_val); + if (ret < 0) { + dev_err(wm5100->dev, "Failed to read IRQ status 3: %d\n", + ret); irq_val = 0; } - irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3_MASK); - snd_soc_write(codec, WM5100_INTERRUPT_STATUS_3, irq_val); + ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_3_MASK, + &mask_val); + if (ret < 0) { + dev_err(wm5100->dev, "Failed to read IRQ mask 3: %d\n", + ret); + mask_val = 0xffff; + } + + irq_val &= ~mask_val; + + regmap_write(wm5100->regmap, WM5100_INTERRUPT_STATUS_3, irq_val); if (irq_val) status = IRQ_HANDLED; - wm5100_log_status3(codec, irq_val); + wm5100_log_status3(wm5100, irq_val); if (irq_val & WM5100_FLL1_LOCK_EINT) { - dev_dbg(codec->dev, "FLL1 locked\n"); + dev_dbg(wm5100->dev, "FLL1 locked\n"); complete(&wm5100->fll[0].lock); } if (irq_val & WM5100_FLL2_LOCK_EINT) { - dev_dbg(codec->dev, "FLL2 locked\n"); + dev_dbg(wm5100->dev, "FLL2 locked\n"); complete(&wm5100->fll[1].lock); } if (irq_val & WM5100_ACCDET_EINT) - wm5100_micd_irq(codec); + wm5100_micd_irq(wm5100); - irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4); - if (irq_val < 0) { - dev_err(codec->dev, "Failed to read IRQ status 4: %d\n", - irq_val); + ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_4, &irq_val); + if (ret < 0) { + dev_err(wm5100->dev, "Failed to read IRQ status 4: %d\n", + ret); irq_val = 0; } - irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4_MASK); + + ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_4_MASK, + &mask_val); + if (ret < 0) { + dev_err(wm5100->dev, "Failed to read IRQ mask 4: %d\n", + ret); + mask_val = 0xffff; + } + + irq_val &= ~mask_val; if (irq_val) status = IRQ_HANDLED; - snd_soc_write(codec, WM5100_INTERRUPT_STATUS_4, irq_val); + regmap_write(wm5100->regmap, WM5100_INTERRUPT_STATUS_4, irq_val); - wm5100_log_status4(codec, irq_val); + wm5100_log_status4(wm5100, irq_val); return status; } @@ -2485,11 +2509,12 @@ static int wm5100_probe(struct snd_soc_codec *codec) if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) ret = request_threaded_irq(i2c->irq, NULL, - wm5100_edge_irq, - irq_flags, "wm5100", codec); + wm5100_edge_irq, irq_flags, + "wm5100", wm5100); else ret = request_threaded_irq(i2c->irq, NULL, wm5100_irq, - irq_flags, "wm5100", codec); + irq_flags, "wm5100", + wm5100); if (ret != 0) { dev_err(codec->dev, "Failed to request IRQ %d: %d\n", @@ -2552,7 +2577,7 @@ static int wm5100_probe(struct snd_soc_codec *codec) err_gpio: if (i2c->irq) - free_irq(i2c->irq, codec); + free_irq(i2c->irq, wm5100); return ret; } @@ -2566,7 +2591,8 @@ static int wm5100_remove(struct snd_soc_codec *codec) gpio_free(wm5100->pdata.hp_pol); } if (i2c->irq) - free_irq(i2c->irq, codec); + free_irq(i2c->irq, wm5100); + return 0; } @@ -2622,6 +2648,8 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, if (wm5100 == NULL) return -ENOMEM; + wm5100->dev = &i2c->dev; + wm5100->regmap = regmap_init_i2c(i2c, &wm5100_regmap); if (IS_ERR(wm5100->regmap)) { ret = PTR_ERR(wm5100->regmap); -- cgit v0.10.2 From 09452f23eb01241fa19c2e99585af5e340a0961b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 18 Jan 2012 15:05:46 +0000 Subject: ASoC: Push WM5100 interrupt request into I2C probe This is more what the device model wants us to do and will allow use by non-audio functions before the audio part of the device has come up. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 4b2c724..c291f8e 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -2475,7 +2475,7 @@ static int wm5100_probe(struct snd_soc_codec *codec) { struct i2c_client *i2c = to_i2c_client(codec->dev); struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); - int ret, i, irq_flags; + int ret, i; wm5100->codec = codec; codec->control_data = wm5100->regmap; @@ -2499,61 +2499,10 @@ static int wm5100_probe(struct snd_soc_codec *codec) /* TODO: check if we're symmetric */ - if (i2c->irq) { - if (wm5100->pdata.irq_flags) - irq_flags = wm5100->pdata.irq_flags; - else - irq_flags = IRQF_TRIGGER_LOW; - - irq_flags |= IRQF_ONESHOT; - - if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) - ret = request_threaded_irq(i2c->irq, NULL, - wm5100_edge_irq, irq_flags, - "wm5100", wm5100); - else - ret = request_threaded_irq(i2c->irq, NULL, wm5100_irq, - irq_flags, "wm5100", - wm5100); - - if (ret != 0) { - dev_err(codec->dev, "Failed to request IRQ %d: %d\n", - i2c->irq, ret); - } else { - /* Enable default interrupts */ - snd_soc_update_bits(codec, - WM5100_INTERRUPT_STATUS_3_MASK, - WM5100_IM_SPK_SHUTDOWN_WARN_EINT | - WM5100_IM_SPK_SHUTDOWN_EINT | - WM5100_IM_ASRC2_LOCK_EINT | - WM5100_IM_ASRC1_LOCK_EINT | - WM5100_IM_FLL2_LOCK_EINT | - WM5100_IM_FLL1_LOCK_EINT | - WM5100_CLKGEN_ERR_EINT | - WM5100_CLKGEN_ERR_ASYNC_EINT, 0); - - snd_soc_update_bits(codec, - WM5100_INTERRUPT_STATUS_4_MASK, - WM5100_AIF3_ERR_EINT | - WM5100_AIF2_ERR_EINT | - WM5100_AIF1_ERR_EINT | - WM5100_CTRLIF_ERR_EINT | - WM5100_ISRC2_UNDERCLOCKED_EINT | - WM5100_ISRC1_UNDERCLOCKED_EINT | - WM5100_FX_UNDERCLOCKED_EINT | - WM5100_AIF3_UNDERCLOCKED_EINT | - WM5100_AIF2_UNDERCLOCKED_EINT | - WM5100_AIF1_UNDERCLOCKED_EINT | - WM5100_ASRC_UNDERCLOCKED_EINT | - WM5100_DAC_UNDERCLOCKED_EINT | - WM5100_ADC_UNDERCLOCKED_EINT | - WM5100_MIXER_UNDERCLOCKED_EINT, 0); - } - } else { + if (i2c->irq) snd_soc_dapm_new_controls(&codec->dapm, wm5100_dapm_widgets_noirq, ARRAY_SIZE(wm5100_dapm_widgets_noirq)); - } if (wm5100->pdata.hp_pol) { ret = gpio_request_one(wm5100->pdata.hp_pol, @@ -2641,7 +2590,7 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev); struct wm5100_priv *wm5100; unsigned int reg; - int ret, i; + int ret, i, irq_flags; wm5100 = devm_kzalloc(&i2c->dev, sizeof(struct wm5100_priv), GFP_KERNEL); @@ -2778,6 +2727,58 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, WM5100_IN1_DMIC_SUP_SHIFT)); } + if (i2c->irq) { + if (wm5100->pdata.irq_flags) + irq_flags = wm5100->pdata.irq_flags; + else + irq_flags = IRQF_TRIGGER_LOW; + + irq_flags |= IRQF_ONESHOT; + + if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) + ret = request_threaded_irq(i2c->irq, NULL, + wm5100_edge_irq, irq_flags, + "wm5100", wm5100); + else + ret = request_threaded_irq(i2c->irq, NULL, wm5100_irq, + irq_flags, "wm5100", + wm5100); + + if (ret != 0) { + dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n", + i2c->irq, ret); + } else { + /* Enable default interrupts */ + regmap_update_bits(wm5100->regmap, + WM5100_INTERRUPT_STATUS_3_MASK, + WM5100_IM_SPK_SHUTDOWN_WARN_EINT | + WM5100_IM_SPK_SHUTDOWN_EINT | + WM5100_IM_ASRC2_LOCK_EINT | + WM5100_IM_ASRC1_LOCK_EINT | + WM5100_IM_FLL2_LOCK_EINT | + WM5100_IM_FLL1_LOCK_EINT | + WM5100_CLKGEN_ERR_EINT | + WM5100_CLKGEN_ERR_ASYNC_EINT, 0); + + regmap_update_bits(wm5100->regmap, + WM5100_INTERRUPT_STATUS_4_MASK, + WM5100_AIF3_ERR_EINT | + WM5100_AIF2_ERR_EINT | + WM5100_AIF1_ERR_EINT | + WM5100_CTRLIF_ERR_EINT | + WM5100_ISRC2_UNDERCLOCKED_EINT | + WM5100_ISRC1_UNDERCLOCKED_EINT | + WM5100_FX_UNDERCLOCKED_EINT | + WM5100_AIF3_UNDERCLOCKED_EINT | + WM5100_AIF2_UNDERCLOCKED_EINT | + WM5100_AIF1_UNDERCLOCKED_EINT | + WM5100_ASRC_UNDERCLOCKED_EINT | + WM5100_DAC_UNDERCLOCKED_EINT | + WM5100_ADC_UNDERCLOCKED_EINT | + WM5100_MIXER_UNDERCLOCKED_EINT, 0); + } + } + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm5100, wm5100_dai, ARRAY_SIZE(wm5100_dai)); @@ -2789,6 +2790,8 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, return ret; err_reset: + if (i2c->irq) + free_irq(i2c->irq, wm5100); wm5100_free_gpio(i2c); if (wm5100->pdata.reset) { gpio_set_value_cansleep(wm5100->pdata.reset, 0); @@ -2817,12 +2820,14 @@ err: return ret; } -static __devexit int wm5100_i2c_remove(struct i2c_client *client) +static __devexit int wm5100_i2c_remove(struct i2c_client *i2c) { - struct wm5100_priv *wm5100 = i2c_get_clientdata(client); + struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c); - snd_soc_unregister_codec(&client->dev); - wm5100_free_gpio(client); + snd_soc_unregister_codec(&i2c->dev); + if (i2c->irq) + free_irq(i2c->irq, wm5100); + wm5100_free_gpio(i2c); if (wm5100->pdata.reset) { gpio_set_value_cansleep(wm5100->pdata.reset, 0); gpio_free(wm5100->pdata.reset); -- cgit v0.10.2 From 278047fd654dde7ed95c8604fcefeeacc5c0bb2b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 19 Jan 2012 18:04:18 +0000 Subject: ASoC: Don't tell applications about msbits unless we're ignoring input On the off chance that an application both pays attention and gets confused. Signed-off-by: Mark Brown diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 8bb1793..3268901 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -85,9 +85,11 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream, return; for (i = 0; i < ARRAY_SIZE(sample_sizes); i++) { - ret = snd_pcm_hw_constraint_msbits(substream->runtime, - 0, sample_sizes[i], - bits); + if (bits >= sample_sizes[i]) + continue; + + ret = snd_pcm_hw_constraint_msbits(substream->runtime, 0, + sample_sizes[i], bits); if (ret != 0) dev_warn(dai->dev, "Failed to set MSB %d/%d: %d\n", -- cgit v0.10.2 From 8a713da8d1ce9ceaf738b32e2b24f22d4432f886 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 3 Dec 2011 12:33:55 +0000 Subject: ASoC: Use regmap update bits operation for drivers using regmap If a driver is using regmap directly ensure that we're coherent with non-ASoC register updates by using the regmap API directly to do our read/modify/write cycles. This will bypass the ASoC cache but drivers using regmap directly should not be using the ASoC cache. Signed-off-by: Mark Brown diff --git a/include/sound/soc.h b/include/sound/soc.h index 55381fc..2f687ed 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -560,6 +560,7 @@ struct snd_soc_codec { unsigned int ac97_created:1; /* Codec has been created by SoC */ unsigned int sysfs_registered:1; /* codec has been sysfs registered */ unsigned int cache_init:1; /* codec cache has been initialized */ + unsigned int using_regmap:1; /* using regmap access */ u32 cache_only; /* Suppress writes to hardware */ u32 cache_sync; /* Cache needs to be synced to hardware */ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 41c8e45..35a1e63 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1869,23 +1869,28 @@ EXPORT_SYMBOL_GPL(snd_soc_bulk_write_raw); int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, unsigned int mask, unsigned int value) { - int change; + bool change; unsigned int old, new; int ret; - ret = snd_soc_read(codec, reg); - if (ret < 0) - return ret; - - old = ret; - new = (old & ~mask) | (value & mask); - change = old != new; - if (change) { - ret = snd_soc_write(codec, reg, new); + if (codec->using_regmap) { + ret = regmap_update_bits_check(codec->control_data, reg, + mask, value, &change); + } else { + ret = snd_soc_read(codec, reg); if (ret < 0) return ret; + + old = ret; + new = (old & ~mask) | (value & mask); + change = old != new; + if (change) + ret = snd_soc_write(codec, reg, new); } + if (ret < 0) + return ret; + return change; } EXPORT_SYMBOL_GPL(snd_soc_update_bits); diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 1f55ded..31a06b2 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -197,21 +197,28 @@ static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, int val) static int soc_widget_update_bits(struct snd_soc_dapm_widget *w, unsigned short reg, unsigned int mask, unsigned int value) { - int change; + bool change; unsigned int old, new; int ret; - ret = soc_widget_read(w, reg); - if (ret < 0) - return ret; - - old = ret; - new = (old & ~mask) | (value & mask); - change = old != new; - if (change) { - ret = soc_widget_write(w, reg, new); + if (w->codec && w->codec->using_regmap) { + ret = regmap_update_bits_check(w->codec->control_data, + reg, mask, value, &change); + if (ret != 0) + return ret; + } else { + ret = soc_widget_read(w, reg); if (ret < 0) return ret; + + old = ret; + new = (old & ~mask) | (value & mask); + change = old != new; + if (change) { + ret = soc_widget_write(w, reg, new); + if (ret < 0) + return ret; + } } return change; diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c index c8610cb..39ba507 100644 --- a/sound/soc/soc-io.c +++ b/sound/soc/soc-io.c @@ -140,6 +140,7 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, case SND_SOC_REGMAP: /* Device has made its own regmap arrangements */ + codec->using_regmap = true; break; default: -- cgit v0.10.2 From 3a4cbf88963963aacbeef63a1a795f8ea05d1d30 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 20 Jan 2012 17:52:39 +0000 Subject: ASoC: Fix build of tlv320dac33 The problem was introduced due to the obscure formatting some of the older drivers use. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 21ccf0a..c06c3e4 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -1513,8 +1513,9 @@ static struct snd_soc_dai_driver dac33_dai = { .channels_min = 2, .channels_max = 2, .rates = DAC33_RATES, - .formats = DAC33_FORMATS,}, + .formats = DAC33_FORMATS, .sig_bits = 24, + }, .ops = &dac33_dai_ops, }; -- cgit v0.10.2 From 78adaeb2ae7d5e9e1a6e93e06db26d07fdd829fb Mon Sep 17 00:00:00 2001 From: Javier Martin Date: Fri, 20 Jan 2012 10:16:57 +0100 Subject: ASoC: Add external amplifier controls for Visstrim_M10. Visstrim_M10 has an external class D amplifier. This patch provides support for controlling the 4 possible gain levels and per channel muting. Signed-off-by: Javier Martin Signed-off-by: Mark Brown diff --git a/sound/soc/imx/mx27vis-aic32x4.c b/sound/soc/imx/mx27vis-aic32x4.c index d37e23c..155899c 100644 --- a/sound/soc/imx/mx27vis-aic32x4.c +++ b/sound/soc/imx/mx27vis-aic32x4.c @@ -25,16 +25,37 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include "../codecs/tlv320aic32x4.h" #include "imx-ssi.h" +#define MX27VIS_AMP_GAIN 0 +#define MX27VIS_AMP_MUTE 1 + +#define MX27VIS_PIN_G0 (GPIO_PORTF + 9) +#define MX27VIS_PIN_G1 (GPIO_PORTF + 8) +#define MX27VIS_PIN_SDL (GPIO_PORTE + 5) +#define MX27VIS_PIN_SDR (GPIO_PORTF + 7) + +static int mx27vis_amp_gain; +static int mx27vis_amp_mute; + +static const int mx27vis_amp_pins[] = { + MX27VIS_PIN_G0 | GPIO_GPIO | GPIO_OUT, + MX27VIS_PIN_G1 | GPIO_GPIO | GPIO_OUT, + MX27VIS_PIN_SDL | GPIO_GPIO | GPIO_OUT, + MX27VIS_PIN_SDR | GPIO_GPIO | GPIO_OUT, +}; + static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -74,8 +95,60 @@ static struct snd_soc_ops mx27vis_aic32x4_snd_ops = { .hw_params = mx27vis_aic32x4_hw_params, }; +static int mx27vis_amp_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + int value = ucontrol->value.integer.value[0]; + unsigned int reg = mc->reg; + int max = mc->max; + + if (value > max) + return -EINVAL; + + switch (reg) { + case MX27VIS_AMP_GAIN: + gpio_set_value(MX27VIS_PIN_G0, value & 1); + gpio_set_value(MX27VIS_PIN_G1, value >> 1); + mx27vis_amp_gain = value; + break; + case MX27VIS_AMP_MUTE: + gpio_set_value(MX27VIS_PIN_SDL, value & 1); + gpio_set_value(MX27VIS_PIN_SDR, value >> 1); + mx27vis_amp_mute = value; + break; + } + return 0; +} + +static int mx27vis_amp_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + unsigned int reg = mc->reg; + + switch (reg) { + case MX27VIS_AMP_GAIN: + ucontrol->value.integer.value[0] = mx27vis_amp_gain; + break; + case MX27VIS_AMP_MUTE: + ucontrol->value.integer.value[0] = mx27vis_amp_mute; + break; + } + return 0; +} + +/* From 6dB to 24dB in steps of 6dB */ +static const DECLARE_TLV_DB_SCALE(mx27vis_amp_tlv, 600, 600, 0); + static const struct snd_kcontrol_new mx27vis_aic32x4_controls[] = { SOC_DAPM_PIN_SWITCH("External Mic"), + SOC_SINGLE_EXT_TLV("LO Ext Boost", MX27VIS_AMP_GAIN, 0, 3, 0, + mx27vis_amp_get, mx27vis_amp_set, mx27vis_amp_tlv), + SOC_DOUBLE_EXT("LO Ext Mute Switch", MX27VIS_AMP_MUTE, 0, 1, 1, 0, + mx27vis_amp_get, mx27vis_amp_set), }; static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = { @@ -146,6 +219,13 @@ static int __init mx27vis_aic32x4_init(void) MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0) ); + ret = mxc_gpio_setup_multiple_pins(mx27vis_amp_pins, + ARRAY_SIZE(mx27vis_amp_pins), "MX27VIS_AMP"); + if (ret) { + printk(KERN_ERR "ASoC: unable to setup gpios\n"); + platform_device_put(mx27vis_aic32x4_snd_device); + } + return ret; } -- cgit v0.10.2 From a1fea9404f6b400dcbda952599649e6d37aad1c0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 21 Jan 2012 15:23:26 +0000 Subject: ASoC: wm8985: Convert to devm_kzalloc() Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index c0c86b3..e62a4c5 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -1079,7 +1079,7 @@ static int __devinit wm8985_spi_probe(struct spi_device *spi) struct wm8985_priv *wm8985; int ret; - wm8985 = kzalloc(sizeof *wm8985, GFP_KERNEL); + wm8985 = devm_kzalloc(&spi->dev, sizeof *wm8985, GFP_KERNEL); if (!wm8985) return -ENOMEM; @@ -1088,15 +1088,12 @@ static int __devinit wm8985_spi_probe(struct spi_device *spi) ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8985, &wm8985_dai, 1); - if (ret < 0) - kfree(wm8985); return ret; } static int __devexit wm8985_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); - kfree(spi_get_drvdata(spi)); return 0; } @@ -1117,7 +1114,7 @@ static __devinit int wm8985_i2c_probe(struct i2c_client *i2c, struct wm8985_priv *wm8985; int ret; - wm8985 = kzalloc(sizeof *wm8985, GFP_KERNEL); + wm8985 = devm_kzalloc(&i2c->dev, sizeof *wm8985, GFP_KERNEL); if (!wm8985) return -ENOMEM; @@ -1126,15 +1123,12 @@ static __devinit int wm8985_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8985, &wm8985_dai, 1); - if (ret < 0) - kfree(wm8985); return ret; } static __devexit int wm8985_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } -- cgit v0.10.2 From eb8f7693df0426b3c7aa6e6e401486962a033d5e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 21 Jan 2012 15:36:08 +0000 Subject: ASoC: wm8985: Convert to table based DAPM and control init Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index e62a4c5..ee3aba3 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -428,7 +428,7 @@ static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("SPKR") }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route wm8985_dapm_routes[] = { { "Right Output Mixer", "PCM Switch", "Right DAC" }, { "Right Output Mixer", "Aux Switch", "AUXR" }, { "Right Output Mixer", "Line Switch", "Right Boost Mixer" }, @@ -531,17 +531,6 @@ static int eqmode_put(struct snd_kcontrol *kcontrol, return 0; } -static int wm8985_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, wm8985_dapm_widgets, - ARRAY_SIZE(wm8985_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, audio_map, - ARRAY_SIZE(audio_map)); - return 0; -} - static int wm8985_reset(struct snd_soc_codec *codec) { return snd_soc_write(codec, WM8985_SOFTWARE_RESET, 0x0); @@ -1017,10 +1006,6 @@ static int wm8985_probe(struct snd_soc_codec *codec) cache[WM8985_BIAS_CTRL] |= WM8985_BIASCUT; codec->cache_sync = 1; - snd_soc_add_controls(codec, wm8985_snd_controls, - ARRAY_SIZE(wm8985_snd_controls)); - wm8985_add_widgets(codec); - wm8985_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; @@ -1068,9 +1053,16 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8985 = { .suspend = wm8985_suspend, .resume = wm8985_resume, .set_bias_level = wm8985_set_bias_level, + + .controls = wm8985_snd_controls, + .num_controls = ARRAY_SIZE(wm8985_snd_controls), + .dapm_widgets = wm8985_dapm_widgets, .reg_cache_size = ARRAY_SIZE(wm8985_reg_defs), .reg_word_size = sizeof(u16), .reg_cache_default = wm8985_reg_defs + .num_dapm_widgets = ARRAY_SIZE(wm8985_dapm_widgets), + .dapm_routes = wm8985_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8985_dapm_routes), }; #if defined(CONFIG_SPI_MASTER) -- cgit v0.10.2 From 8b71d441f75d180d3174b2e1b649db385552c266 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 21 Jan 2012 15:36:30 +0000 Subject: ASoC: wm8985: Use standard cache sync implementation Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index ee3aba3..297119f 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -834,25 +834,6 @@ static int wm8985_set_sysclk(struct snd_soc_dai *dai, return 0; } -static void wm8985_sync_cache(struct snd_soc_codec *codec) -{ - short i; - u16 *cache; - - if (!codec->cache_sync) - return; - codec->cache_only = 0; - /* restore cache */ - cache = codec->reg_cache; - for (i = 0; i < codec->driver->reg_cache_size; i++) { - if (i == WM8985_SOFTWARE_RESET - || cache[i] == wm8985_reg_defs[i]) - continue; - snd_soc_write(codec, i, cache[i]); - } - codec->cache_sync = 0; -} - static int wm8985_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { @@ -879,7 +860,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec, return ret; } - wm8985_sync_cache(codec); + snd_soc_cache_sync(codec); /* enable anti-pop features */ snd_soc_update_bits(codec, WM8985_OUT4_TO_ADC, -- cgit v0.10.2 From 9f8cbae4163ab132cd7a56385341efdd41fcd429 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 21 Jan 2012 15:39:34 +0000 Subject: ASoC: wm8985 Don't directly reference the cache data structure In preparation for conversion to regmap. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index 297119f..bbe19b2 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -946,7 +946,6 @@ static int wm8985_probe(struct snd_soc_codec *codec) size_t i; struct wm8985_priv *wm8985; int ret; - u16 *cache; wm8985 = snd_soc_codec_get_drvdata(codec); @@ -979,13 +978,13 @@ static int wm8985_probe(struct snd_soc_codec *codec) goto err_reg_enable; } - cache = codec->reg_cache; /* latch volume update bits */ for (i = 0; i < ARRAY_SIZE(volume_update_regs); ++i) - cache[volume_update_regs[i]] |= 0x100; + snd_soc_update_bits(codec, volume_update_regs[i], + 0x100, 0x100); /* enable BIASCUT */ - cache[WM8985_BIAS_CTRL] |= WM8985_BIASCUT; - codec->cache_sync = 1; + snd_soc_update_bits(codec, WM8985_BIAS_CTRL, WM8985_BIASCUT, + WM8985_BIASCUT); wm8985_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; -- cgit v0.10.2 From 411a3450c9539043c794a5f4a6bdb03bb040670a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 21 Jan 2012 15:41:48 +0000 Subject: ASoC: wm8985: Convert to direct regmap API usage Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index bbe19b2..14f6663 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -39,73 +40,127 @@ static const char *wm8985_supply_names[WM8985_NUM_SUPPLIES] = { "AVDD2" }; -static const u16 wm8985_reg_defs[] = { - 0x0000, /* R0 - Software Reset */ - 0x0000, /* R1 - Power management 1 */ - 0x0000, /* R2 - Power management 2 */ - 0x0000, /* R3 - Power management 3 */ - 0x0050, /* R4 - Audio Interface */ - 0x0000, /* R5 - Companding control */ - 0x0140, /* R6 - Clock Gen control */ - 0x0000, /* R7 - Additional control */ - 0x0000, /* R8 - GPIO Control */ - 0x0000, /* R9 - Jack Detect Control 1 */ - 0x0000, /* R10 - DAC Control */ - 0x00FF, /* R11 - Left DAC digital Vol */ - 0x00FF, /* R12 - Right DAC digital vol */ - 0x0000, /* R13 - Jack Detect Control 2 */ - 0x0100, /* R14 - ADC Control */ - 0x00FF, /* R15 - Left ADC Digital Vol */ - 0x00FF, /* R16 - Right ADC Digital Vol */ - 0x0000, /* R17 */ - 0x012C, /* R18 - EQ1 - low shelf */ - 0x002C, /* R19 - EQ2 - peak 1 */ - 0x002C, /* R20 - EQ3 - peak 2 */ - 0x002C, /* R21 - EQ4 - peak 3 */ - 0x002C, /* R22 - EQ5 - high shelf */ - 0x0000, /* R23 */ - 0x0032, /* R24 - DAC Limiter 1 */ - 0x0000, /* R25 - DAC Limiter 2 */ - 0x0000, /* R26 */ - 0x0000, /* R27 - Notch Filter 1 */ - 0x0000, /* R28 - Notch Filter 2 */ - 0x0000, /* R29 - Notch Filter 3 */ - 0x0000, /* R30 - Notch Filter 4 */ - 0x0000, /* R31 */ - 0x0038, /* R32 - ALC control 1 */ - 0x000B, /* R33 - ALC control 2 */ - 0x0032, /* R34 - ALC control 3 */ - 0x0000, /* R35 - Noise Gate */ - 0x0008, /* R36 - PLL N */ - 0x000C, /* R37 - PLL K 1 */ - 0x0093, /* R38 - PLL K 2 */ - 0x00E9, /* R39 - PLL K 3 */ - 0x0000, /* R40 */ - 0x0000, /* R41 - 3D control */ - 0x0000, /* R42 - OUT4 to ADC */ - 0x0000, /* R43 - Beep control */ - 0x0033, /* R44 - Input ctrl */ - 0x0010, /* R45 - Left INP PGA gain ctrl */ - 0x0010, /* R46 - Right INP PGA gain ctrl */ - 0x0100, /* R47 - Left ADC BOOST ctrl */ - 0x0100, /* R48 - Right ADC BOOST ctrl */ - 0x0002, /* R49 - Output ctrl */ - 0x0001, /* R50 - Left mixer ctrl */ - 0x0001, /* R51 - Right mixer ctrl */ - 0x0039, /* R52 - LOUT1 (HP) volume ctrl */ - 0x0039, /* R53 - ROUT1 (HP) volume ctrl */ - 0x0039, /* R54 - LOUT2 (SPK) volume ctrl */ - 0x0039, /* R55 - ROUT2 (SPK) volume ctrl */ - 0x0001, /* R56 - OUT3 mixer ctrl */ - 0x0001, /* R57 - OUT4 (MONO) mix ctrl */ - 0x0001, /* R58 */ - 0x0000, /* R59 */ - 0x0004, /* R60 - OUTPUT ctrl */ - 0x0000, /* R61 - BIAS CTRL */ - 0x0180, /* R62 */ - 0x0000 /* R63 */ +static const struct reg_default wm8985_reg_defaults[] = { + { 1, 0x0000 }, /* R1 - Power management 1 */ + { 2, 0x0000 }, /* R2 - Power management 2 */ + { 3, 0x0000 }, /* R3 - Power management 3 */ + { 4, 0x0050 }, /* R4 - Audio Interface */ + { 5, 0x0000 }, /* R5 - Companding control */ + { 6, 0x0140 }, /* R6 - Clock Gen control */ + { 7, 0x0000 }, /* R7 - Additional control */ + { 8, 0x0000 }, /* R8 - GPIO Control */ + { 9, 0x0000 }, /* R9 - Jack Detect Control 1 */ + { 10, 0x0000 }, /* R10 - DAC Control */ + { 11, 0x00FF }, /* R11 - Left DAC digital Vol */ + { 12, 0x00FF }, /* R12 - Right DAC digital vol */ + { 13, 0x0000 }, /* R13 - Jack Detect Control 2 */ + { 14, 0x0100 }, /* R14 - ADC Control */ + { 15, 0x00FF }, /* R15 - Left ADC Digital Vol */ + { 16, 0x00FF }, /* R16 - Right ADC Digital Vol */ + { 18, 0x012C }, /* R18 - EQ1 - low shelf */ + { 19, 0x002C }, /* R19 - EQ2 - peak 1 */ + { 20, 0x002C }, /* R20 - EQ3 - peak 2 */ + { 21, 0x002C }, /* R21 - EQ4 - peak 3 */ + { 22, 0x002C }, /* R22 - EQ5 - high shelf */ + { 24, 0x0032 }, /* R24 - DAC Limiter 1 */ + { 25, 0x0000 }, /* R25 - DAC Limiter 2 */ + { 27, 0x0000 }, /* R27 - Notch Filter 1 */ + { 28, 0x0000 }, /* R28 - Notch Filter 2 */ + { 29, 0x0000 }, /* R29 - Notch Filter 3 */ + { 30, 0x0000 }, /* R30 - Notch Filter 4 */ + { 32, 0x0038 }, /* R32 - ALC control 1 */ + { 33, 0x000B }, /* R33 - ALC control 2 */ + { 34, 0x0032 }, /* R34 - ALC control 3 */ + { 35, 0x0000 }, /* R35 - Noise Gate */ + { 36, 0x0008 }, /* R36 - PLL N */ + { 37, 0x000C }, /* R37 - PLL K 1 */ + { 38, 0x0093 }, /* R38 - PLL K 2 */ + { 39, 0x00E9 }, /* R39 - PLL K 3 */ + { 41, 0x0000 }, /* R41 - 3D control */ + { 42, 0x0000 }, /* R42 - OUT4 to ADC */ + { 43, 0x0000 }, /* R43 - Beep control */ + { 44, 0x0033 }, /* R44 - Input ctrl */ + { 45, 0x0010 }, /* R45 - Left INP PGA gain ctrl */ + { 46, 0x0010 }, /* R46 - Right INP PGA gain ctrl */ + { 47, 0x0100 }, /* R47 - Left ADC BOOST ctrl */ + { 48, 0x0100 }, /* R48 - Right ADC BOOST ctrl */ + { 49, 0x0002 }, /* R49 - Output ctrl */ + { 50, 0x0001 }, /* R50 - Left mixer ctrl */ + { 51, 0x0001 }, /* R51 - Right mixer ctrl */ + { 52, 0x0039 }, /* R52 - LOUT1 (HP) volume ctrl */ + { 53, 0x0039 }, /* R53 - ROUT1 (HP) volume ctrl */ + { 54, 0x0039 }, /* R54 - LOUT2 (SPK) volume ctrl */ + { 55, 0x0039 }, /* R55 - ROUT2 (SPK) volume ctrl */ + { 56, 0x0001 }, /* R56 - OUT3 mixer ctrl */ + { 57, 0x0001 }, /* R57 - OUT4 (MONO) mix ctrl */ + { 60, 0x0004 }, /* R60 - OUTPUT ctrl */ + { 61, 0x0000 }, /* R61 - BIAS CTRL */ }; +static bool wm8985_writeable(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WM8985_SOFTWARE_RESET: + case WM8985_POWER_MANAGEMENT_1: + case WM8985_POWER_MANAGEMENT_2: + case WM8985_POWER_MANAGEMENT_3: + case WM8985_AUDIO_INTERFACE: + case WM8985_COMPANDING_CONTROL: + case WM8985_CLOCK_GEN_CONTROL: + case WM8985_ADDITIONAL_CONTROL: + case WM8985_GPIO_CONTROL: + case WM8985_JACK_DETECT_CONTROL_1: + case WM8985_DAC_CONTROL: + case WM8985_LEFT_DAC_DIGITAL_VOL: + case WM8985_RIGHT_DAC_DIGITAL_VOL: + case WM8985_JACK_DETECT_CONTROL_2: + case WM8985_ADC_CONTROL: + case WM8985_LEFT_ADC_DIGITAL_VOL: + case WM8985_RIGHT_ADC_DIGITAL_VOL: + case WM8985_EQ1_LOW_SHELF: + case WM8985_EQ2_PEAK_1: + case WM8985_EQ3_PEAK_2: + case WM8985_EQ4_PEAK_3: + case WM8985_EQ5_HIGH_SHELF: + case WM8985_DAC_LIMITER_1: + case WM8985_DAC_LIMITER_2: + case WM8985_NOTCH_FILTER_1: + case WM8985_NOTCH_FILTER_2: + case WM8985_NOTCH_FILTER_3: + case WM8985_NOTCH_FILTER_4: + case WM8985_ALC_CONTROL_1: + case WM8985_ALC_CONTROL_2: + case WM8985_ALC_CONTROL_3: + case WM8985_NOISE_GATE: + case WM8985_PLL_N: + case WM8985_PLL_K_1: + case WM8985_PLL_K_2: + case WM8985_PLL_K_3: + case WM8985_3D_CONTROL: + case WM8985_OUT4_TO_ADC: + case WM8985_BEEP_CONTROL: + case WM8985_INPUT_CTRL: + case WM8985_LEFT_INP_PGA_GAIN_CTRL: + case WM8985_RIGHT_INP_PGA_GAIN_CTRL: + case WM8985_LEFT_ADC_BOOST_CTRL: + case WM8985_RIGHT_ADC_BOOST_CTRL: + case WM8985_OUTPUT_CTRL0: + case WM8985_LEFT_MIXER_CTRL: + case WM8985_RIGHT_MIXER_CTRL: + case WM8985_LOUT1_HP_VOLUME_CTRL: + case WM8985_ROUT1_HP_VOLUME_CTRL: + case WM8985_LOUT2_SPK_VOLUME_CTRL: + case WM8985_ROUT2_SPK_VOLUME_CTRL: + case WM8985_OUT3_MIXER_CTRL: + case WM8985_OUT4_MONO_MIX_CTRL: + case WM8985_OUTPUT_CTRL1: + case WM8985_BIAS_CTRL: + return true; + default: + return false; + } +} + /* * latch bit 8 of these registers to ensure instant * volume updates @@ -124,7 +179,7 @@ static const int volume_update_regs[] = { }; struct wm8985_priv { - enum snd_soc_control_type control_type; + struct regmap *regmap; struct regulator_bulk_data supplies[WM8985_NUM_SUPPLIES]; unsigned int sysclk; unsigned int bclk; @@ -860,7 +915,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec, return ret; } - snd_soc_cache_sync(codec); + regcache_sync(wm8985->regmap); /* enable anti-pop features */ snd_soc_update_bits(codec, WM8985_OUT4_TO_ADC, @@ -903,7 +958,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, WM8985_POWER_MANAGEMENT_2, 0); snd_soc_write(codec, WM8985_POWER_MANAGEMENT_3, 0); - codec->cache_sync = 1; + regcache_mark_dirty(wm8985->regmap); regulator_bulk_disable(ARRAY_SIZE(wm8985->supplies), wm8985->supplies); @@ -948,8 +1003,9 @@ static int wm8985_probe(struct snd_soc_codec *codec) int ret; wm8985 = snd_soc_codec_get_drvdata(codec); + codec->control_data = wm8985->regmap; - ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8985->control_type); + ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); if (ret < 0) { dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); return ret; @@ -1037,14 +1093,23 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8985 = { .controls = wm8985_snd_controls, .num_controls = ARRAY_SIZE(wm8985_snd_controls), .dapm_widgets = wm8985_dapm_widgets, - .reg_cache_size = ARRAY_SIZE(wm8985_reg_defs), - .reg_word_size = sizeof(u16), - .reg_cache_default = wm8985_reg_defs .num_dapm_widgets = ARRAY_SIZE(wm8985_dapm_widgets), .dapm_routes = wm8985_dapm_routes, .num_dapm_routes = ARRAY_SIZE(wm8985_dapm_routes), }; +static const struct regmap_config wm8985_regmap = { + .reg_bits = 7, + .val_bits = 9, + + .max_register = WM8985_MAX_REGISTER, + .writeable_reg = wm8985_writeable, + + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wm8985_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8985_reg_defaults), +}; + #if defined(CONFIG_SPI_MASTER) static int __devinit wm8985_spi_probe(struct spi_device *spi) { @@ -1055,17 +1120,35 @@ static int __devinit wm8985_spi_probe(struct spi_device *spi) if (!wm8985) return -ENOMEM; - wm8985->control_type = SND_SOC_SPI; spi_set_drvdata(spi, wm8985); + wm8985->regmap = regmap_init_spi(spi, &wm8985_regmap); + if (IS_ERR(wm8985->regmap)) { + ret = PTR_ERR(wm8985->regmap); + dev_err(&spi->dev, "Failed to allocate register map: %d\n", + ret); + goto err; + } + ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8985, &wm8985_dai, 1); + if (ret != 0) + goto err; + + return 0; + +err: + regmap_exit(wm8985->regmap); return ret; } static int __devexit wm8985_spi_remove(struct spi_device *spi) { + struct wm8985_priv *wm8985 = spi_get_drvdata(spi); + snd_soc_unregister_codec(&spi->dev); + regmap_exit(wm8985->regmap); + return 0; } @@ -1090,17 +1173,35 @@ static __devinit int wm8985_i2c_probe(struct i2c_client *i2c, if (!wm8985) return -ENOMEM; - wm8985->control_type = SND_SOC_I2C; i2c_set_clientdata(i2c, wm8985); + wm8985->regmap = regmap_init_i2c(i2c, &wm8985_regmap); + if (IS_ERR(wm8985->regmap)) { + ret = PTR_ERR(wm8985->regmap); + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + ret); + goto err; + } + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8985, &wm8985_dai, 1); + if (ret != 0) + goto err; + + return 0; + +err: + regmap_exit(wm8985->regmap); return ret; } -static __devexit int wm8985_i2c_remove(struct i2c_client *client) +static __devexit int wm8985_i2c_remove(struct i2c_client *i2c) { - snd_soc_unregister_codec(&client->dev); + struct wm8985_priv *wm8985 = i2c_get_clientdata(i2c); + + snd_soc_unregister_codec(&i2c->dev); + regmap_exit(wm8985->regmap); + return 0; } -- cgit v0.10.2 From dd21353f35082fa77d1c8672fffebf324954eb09 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 21 Jan 2012 23:24:25 +0000 Subject: ASoC: wm8988: Convert to table based DAPM and control init Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index ab52963..40aebaf 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -317,7 +317,7 @@ static const struct snd_soc_dapm_widget wm8988_dapm_widgets[] = { SND_SOC_DAPM_INPUT("RINPUT2"), }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route wm8988_dapm_routes[] = { { "Left Line Mux", "Line 1", "LINPUT1" }, { "Left Line Mux", "Line 2", "LINPUT2" }, @@ -743,7 +743,6 @@ static int wm8988_resume(struct snd_soc_codec *codec) static int wm8988_probe(struct snd_soc_codec *codec) { struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); - struct snd_soc_dapm_context *dapm = &codec->dapm; int ret = 0; ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8988->control_type); @@ -767,12 +766,6 @@ static int wm8988_probe(struct snd_soc_codec *codec) wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_controls(codec, wm8988_snd_controls, - ARRAY_SIZE(wm8988_snd_controls)); - snd_soc_dapm_new_controls(dapm, wm8988_dapm_widgets, - ARRAY_SIZE(wm8988_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - return 0; } @@ -791,6 +784,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8988 = { .reg_cache_size = ARRAY_SIZE(wm8988_reg), .reg_word_size = sizeof(u16), .reg_cache_default = wm8988_reg, + + .controls = wm8988_snd_controls, + .num_controls = ARRAY_SIZE(wm8988_snd_controls), + .dapm_widgets = wm8988_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8988_dapm_widgets), + .dapm_routes = wm8988_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes), }; #if defined(CONFIG_SPI_MASTER) -- cgit v0.10.2 From 82fa3670575143031517531936b1cc308d4981fa Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 21 Jan 2012 23:25:16 +0000 Subject: ASoC: wm8988: Convert to devm_kzalloc() Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 40aebaf..4ef9d4c 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -799,7 +799,8 @@ static int __devinit wm8988_spi_probe(struct spi_device *spi) struct wm8988_priv *wm8988; int ret; - wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL); + wm8988 = devm_kzalloc(&spi->dev, sizeof(struct wm8988_priv), + GFP_KERNEL); if (wm8988 == NULL) return -ENOMEM; @@ -808,15 +809,13 @@ static int __devinit wm8988_spi_probe(struct spi_device *spi) ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8988, &wm8988_dai, 1); - if (ret < 0) - kfree(wm8988); + return ret; } static int __devexit wm8988_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); - kfree(spi_get_drvdata(spi)); return 0; } @@ -837,7 +836,8 @@ static __devinit int wm8988_i2c_probe(struct i2c_client *i2c, struct wm8988_priv *wm8988; int ret; - wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL); + wm8988 = devm_kzalloc(&i2c->dev, sizeof(struct wm8988_priv), + GFP_KERNEL); if (wm8988 == NULL) return -ENOMEM; @@ -846,15 +846,12 @@ static __devinit int wm8988_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8988, &wm8988_dai, 1); - if (ret < 0) - kfree(wm8988); return ret; } static __devexit int wm8988_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } -- cgit v0.10.2 From d5ad34f7cb8b23ab165cabef69577a2a20d53195 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 20 Jan 2012 20:09:18 +0000 Subject: regulator: Implement devm_regulator_free() Allow consumers to free regulators allocated using devm_regulator_get() if they need to. This will not normally be required. Signed-off-by: Mark Brown diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 214640d..88bcb11 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1421,6 +1421,34 @@ void regulator_put(struct regulator *regulator) } EXPORT_SYMBOL_GPL(regulator_put); +static int devm_regulator_match(struct device *dev, void *res, void *data) +{ + struct regulator **r = res; + if (!r || !*r) { + WARN_ON(!r || !*r); + return 0; + } + return *r == data; +} + +/** + * devm_regulator_put - Resource managed regulator_put() + * @regulator: regulator to free + * + * Deallocate a regulator allocated with devm_regulator_get(). Normally + * this function will not need to be called and the resource management + * code will ensure that the resource is freed. + */ +void devm_regulator_put(struct regulator *regulator) +{ + int rc; + + rc = devres_destroy(regulator->dev, devm_regulator_release, + devm_regulator_match, regulator); + WARN_ON(rc); +} +EXPORT_SYMBOL_GPL(devm_regulator_put); + static int _regulator_can_change_status(struct regulator_dev *rdev) { if (!rdev->constraints) diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index bcfe106..60c2f99 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -137,6 +137,7 @@ struct regulator *__must_check devm_regulator_get(struct device *dev, struct regulator *__must_check regulator_get_exclusive(struct device *dev, const char *id); void regulator_put(struct regulator *regulator); +void devm_regulator_free(struct regulator *regulator); /* regulator output control and status */ int regulator_enable(struct regulator *regulator); -- cgit v0.10.2 From e6e740304aa2a49ef09497e6c0bb906ed7987f6b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 20 Jan 2012 20:10:08 +0000 Subject: regulator: Provide devm_regulator_bulk_get() Allow drivers to benefit from both the bulk APIs and managed resources simultaneously. Signed-off-by: Mark Brown diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 88bcb11..1432c22 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2463,6 +2463,52 @@ err: } EXPORT_SYMBOL_GPL(regulator_bulk_get); +/** + * devm_regulator_bulk_get - managed get multiple regulator consumers + * + * @dev: Device to supply + * @num_consumers: Number of consumers to register + * @consumers: Configuration of consumers; clients are stored here. + * + * @return 0 on success, an errno on failure. + * + * This helper function allows drivers to get several regulator + * consumers in one operation with management, the regulators will + * automatically be freed when the device is unbound. If any of the + * regulators cannot be acquired then any regulators that were + * allocated will be freed before returning to the caller. + */ +int devm_regulator_bulk_get(struct device *dev, int num_consumers, + struct regulator_bulk_data *consumers) +{ + int i; + int ret; + + for (i = 0; i < num_consumers; i++) + consumers[i].consumer = NULL; + + for (i = 0; i < num_consumers; i++) { + consumers[i].consumer = devm_regulator_get(dev, + consumers[i].supply); + if (IS_ERR(consumers[i].consumer)) { + ret = PTR_ERR(consumers[i].consumer); + dev_err(dev, "Failed to get supply '%s': %d\n", + consumers[i].supply, ret); + consumers[i].consumer = NULL; + goto err; + } + } + + return 0; + +err: + for (i = 0; i < num_consumers && consumers[i].consumer; i++) + devm_regulator_put(consumers[i].consumer); + + return ret; +} +EXPORT_SYMBOL_GPL(devm_regulator_bulk_get); + static void regulator_bulk_enable_async(void *data, async_cookie_t cookie) { struct regulator_bulk_data *bulk = data; diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 60c2f99..35c4283 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -148,6 +148,8 @@ int regulator_disable_deferred(struct regulator *regulator, int ms); int regulator_bulk_get(struct device *dev, int num_consumers, struct regulator_bulk_data *consumers); +int devm_regulator_bulk_get(struct device *dev, int num_consumers, + struct regulator_bulk_data *consumers); int regulator_bulk_enable(int num_consumers, struct regulator_bulk_data *consumers); int regulator_bulk_disable(int num_consumers, -- cgit v0.10.2 From 899896379670f885072564669e395feb649105a6 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 22 Jan 2012 14:49:42 -0200 Subject: ASoC: sgtl5000: Convert to table based DAPM and control init Convert to table based DAPM and control init. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 04ea485..18e61a0 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -227,7 +227,7 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = { }; /* routes for sgtl5000 */ -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route sgtl5000_dapm_routes[] = { {"Capture Mux", "LINE_IN", "LINE_IN"}, /* line_in --> adc_mux */ {"Capture Mux", "MIC_IN", "MIC_IN"}, /* mic_in --> adc_mux */ @@ -1353,15 +1353,6 @@ static int sgtl5000_probe(struct snd_soc_codec *codec) if (ret) goto err; - snd_soc_add_controls(codec, sgtl5000_snd_controls, - ARRAY_SIZE(sgtl5000_snd_controls)); - - snd_soc_dapm_new_controls(&codec->dapm, sgtl5000_dapm_widgets, - ARRAY_SIZE(sgtl5000_dapm_widgets)); - - snd_soc_dapm_add_routes(&codec->dapm, audio_map, - ARRAY_SIZE(audio_map)); - snd_soc_dapm_new_widgets(&codec->dapm); return 0; @@ -1402,6 +1393,12 @@ static struct snd_soc_codec_driver sgtl5000_driver = { .reg_cache_step = 2, .reg_cache_default = sgtl5000_regs, .volatile_register = sgtl5000_volatile_register, + .controls = sgtl5000_snd_controls, + .num_controls = ARRAY_SIZE(sgtl5000_snd_controls), + .dapm_widgets = sgtl500_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(sgtl500_dapm_widgets), + .dapm_routes = sgtl500_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(sgtl500_dapm_routes), }; static __devinit int sgtl5000_i2c_probe(struct i2c_client *client, -- cgit v0.10.2 From 5e0ac527fd8bd81be1aaaaa484832846193f9a17 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 23 Jan 2012 10:16:31 +0000 Subject: ASoC: sgtl5000: It's sgtl5000 not sgtl500 Reported-by: Stephen Rothwell Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 18e61a0..d192626 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -1395,10 +1395,10 @@ static struct snd_soc_codec_driver sgtl5000_driver = { .volatile_register = sgtl5000_volatile_register, .controls = sgtl5000_snd_controls, .num_controls = ARRAY_SIZE(sgtl5000_snd_controls), - .dapm_widgets = sgtl500_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(sgtl500_dapm_widgets), - .dapm_routes = sgtl500_dapm_routes, - .num_dapm_routes = ARRAY_SIZE(sgtl500_dapm_routes), + .dapm_widgets = sgtl5000_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(sgtl5000_dapm_widgets), + .dapm_routes = sgtl5000_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes), }; static __devinit int sgtl5000_i2c_probe(struct i2c_client *client, -- cgit v0.10.2 From 5091f5b797564930371c218dbc57cc4d99732c1e Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 23 Jan 2012 11:18:17 +0800 Subject: ASoC: Add __devinit/__devexit annotations at necessary places MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix below build warning when CONFIG_HOTPLUG is not set. CC sound/soc/codecs/alc5623.o sound/soc/codecs/alc5623.c:1062: warning: ‘alc5623_i2c_remove’ defined but not used CC sound/soc/codecs/alc5632.o sound/soc/codecs/alc5632.c:1112: warning: ‘alc5632_i2c_remove’ defined but not used Signed-off-by: Axel Lin Acked-by: Leon Romanovsky Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index 3feee56..08f2419 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c @@ -992,7 +992,7 @@ static struct snd_soc_codec_driver soc_codec_device_alc5623 = { * low = 0x1a * high = 0x1b */ -static int alc5623_i2c_probe(struct i2c_client *client, +static __devinit int alc5623_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct alc5623_platform_data *pdata; @@ -1059,7 +1059,7 @@ static int alc5623_i2c_probe(struct i2c_client *client, return ret; } -static int alc5623_i2c_remove(struct i2c_client *client) +static __devexit int alc5623_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); return 0; diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index 390e437..af9c27a 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c @@ -1109,7 +1109,7 @@ static __devinit int alc5632_i2c_probe(struct i2c_client *client, return ret; } -static int alc5632_i2c_remove(struct i2c_client *client) +static __devexit int alc5632_i2c_remove(struct i2c_client *client) { struct alc5632_priv *alc5632 = i2c_get_clientdata(client); snd_soc_unregister_codec(&client->dev); -- cgit v0.10.2 From 22f0d90a34827812413bb3fbeda6a2a79bb58423 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 21 Jan 2012 12:01:14 +0000 Subject: regmap: Support register patch sets Device manufacturers frequently provide register sequences, usually not fully documented, to be run at startup in order to provide better defaults for devices (for example, improving performance in the light of silicon evaluation). Support such updates by allowing drivers to register update sets with the core. These updates will be written to the device immediately and will also be rewritten when the cache is synced. The assumption is that the reason for resyncing the cache will always be that the device has been powered off. If this turns out to not be the case then a separate operation can be provided. Currently the implementation only allows a single set of updates to be specified for a device, this could be extended in future. Signed-off-by: Mark Brown diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 1a02b75..d141b80 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -75,6 +75,9 @@ struct regmap { const void *reg_defaults_raw; void *cache; bool cache_dirty; + + struct reg_default *patch; + int patch_regs; }; struct regcache_ops { diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 1ead661..ce2034c 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -268,6 +268,17 @@ int regcache_sync(struct regmap *map) map->cache_ops->name); name = map->cache_ops->name; trace_regcache_sync(map->dev, name, "start"); + + /* Apply any patch first */ + for (i = 0; i < map->patch_regs; i++) { + ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def); + if (ret != 0) { + dev_err(map->dev, "Failed to write %x = %x: %d\n", + map->patch[i].reg, map->patch[i].def, ret); + goto out; + } + } + if (!map->cache_dirty) goto out; if (map->cache_ops->sync) { diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index be10a4f..28e89fd 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -669,6 +669,64 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg, } EXPORT_SYMBOL_GPL(regmap_update_bits_check); +/** + * regmap_register_patch: Register and apply register updates to be applied + * on device initialistion + * + * @map: Register map to apply updates to. + * @regs: Values to update. + * @num_regs: Number of entries in regs. + * + * Register a set of register updates to be applied to the device + * whenever the device registers are synchronised with the cache and + * apply them immediately. Typically this is used to apply + * corrections to be applied to the device defaults on startup, such + * as the updates some vendors provide to undocumented registers. + */ +int regmap_register_patch(struct regmap *map, const struct reg_default *regs, + int num_regs) +{ + int i, ret; + bool bypass; + + /* If needed the implementation can be extended to support this */ + if (map->patch) + return -EBUSY; + + mutex_lock(&map->lock); + + bypass = map->cache_bypass; + + map->cache_bypass = true; + + /* Write out first; it's useful to apply even if we fail later. */ + for (i = 0; i < num_regs; i++) { + ret = _regmap_write(map, regs[i].reg, regs[i].def); + if (ret != 0) { + dev_err(map->dev, "Failed to write %x = %x: %d\n", + regs[i].reg, regs[i].def, ret); + goto out; + } + } + + map->patch = kcalloc(sizeof(struct reg_default), num_regs, GFP_KERNEL); + if (map->patch != NULL) { + memcpy(map->patch, regs, + num_regs * sizeof(struct reg_default)); + map->patch_regs = num_regs; + } else { + ret = -ENOMEM; + } + +out: + map->cache_bypass = bypass; + + mutex_unlock(&map->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(regmap_register_patch); + static int __init regmap_initcall(void) { regmap_debugfs_initcall(); diff --git a/include/linux/regmap.h b/include/linux/regmap.h index eb93921..860739a 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -149,6 +149,9 @@ void regcache_cache_only(struct regmap *map, bool enable); void regcache_cache_bypass(struct regmap *map, bool enable); void regcache_mark_dirty(struct regmap *map); +int regmap_register_patch(struct regmap *map, const struct reg_default *regs, + int num_regs); + /** * Description of an IRQ for the generic regmap irq_chip. * -- cgit v0.10.2 From 05d448e2c9bc587216549d690332c72a74271abd Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 21 Nov 2011 12:10:03 +0000 Subject: ASoC: Convert WM8731 to direct regmap API usage Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 8821af7..a32caa7 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -41,7 +42,7 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = { /* codec private data */ struct wm8731_priv { - enum snd_soc_control_type control_type; + struct regmap *regmap; struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; unsigned int sysclk; int sysclk_type; @@ -52,16 +53,30 @@ struct wm8731_priv { /* * wm8731 register cache - * We can't read the WM8731 register space when we are - * using 2 wire for device control, so we cache them instead. - * There is no point in caching the reset register */ -static const u16 wm8731_reg[WM8731_CACHEREGNUM] = { - 0x0097, 0x0097, 0x0079, 0x0079, - 0x000a, 0x0008, 0x009f, 0x000a, - 0x0000, 0x0000 +static const struct reg_default wm8731_reg_defaults[] = { + { 0, 0x0097 }, + { 1, 0x0097 }, + { 2, 0x0079 }, + { 3, 0x0079 }, + { 4, 0x000a }, + { 5, 0x0008 }, + { 6, 0x009f }, + { 7, 0x000a }, + { 8, 0x0000 }, + { 9, 0x0000 }, }; +static bool wm8731_volatile(struct device *dev, unsigned int reg) +{ + return reg == WM8731_RESET; +} + +static bool wm8731_writeable(struct device *dev, unsigned int reg) +{ + return reg <= WM8731_RESET; +} + #define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0) static const char *wm8731_input_select[] = {"Line In", "Mic"}; @@ -441,7 +456,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, if (ret != 0) return ret; - snd_soc_cache_sync(codec); + regcache_sync(wm8731->regmap); } /* Clear PWROFF, gate CLKOUT, everything else as-is */ @@ -452,7 +467,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, WM8731_PWR, 0xffff); regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); - codec->cache_sync = 1; + regcache_mark_dirty(wm8731->regmap); break; } codec->dapm.bias_level = level; @@ -513,7 +528,8 @@ static int wm8731_probe(struct snd_soc_codec *codec) struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); int ret = 0, i; - ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8731->control_type); + codec->control_data = wm8731->regmap; + ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); if (ret < 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; @@ -585,9 +601,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8731 = { .suspend = wm8731_suspend, .resume = wm8731_resume, .set_bias_level = wm8731_set_bias_level, - .reg_cache_size = ARRAY_SIZE(wm8731_reg), - .reg_word_size = sizeof(u16), - .reg_cache_default = wm8731_reg, .dapm_widgets = wm8731_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), .dapm_routes = wm8731_intercon, @@ -603,6 +616,19 @@ static const struct of_device_id wm8731_of_match[] = { MODULE_DEVICE_TABLE(of, wm8731_of_match); +static const struct regmap_config wm8731_regmap = { + .reg_bits = 7, + .val_bits = 9, + + .max_register = WM8731_RESET, + .volatile_reg = wm8731_volatile, + .writeable_reg = wm8731_writeable, + + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wm8731_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8731_reg_defaults), +}; + #if defined(CONFIG_SPI_MASTER) static int __devinit wm8731_spi_probe(struct spi_device *spi) { @@ -613,20 +639,39 @@ static int __devinit wm8731_spi_probe(struct spi_device *spi) if (wm8731 == NULL) return -ENOMEM; - wm8731->control_type = SND_SOC_SPI; + wm8731->regmap = regmap_init_spi(spi, &wm8731_regmap); + if (IS_ERR(wm8731->regmap)) { + ret = PTR_ERR(wm8731->regmap); + dev_err(&spi->dev, "Failed to allocate register map: %d\n", + ret); + goto err; + } + spi_set_drvdata(spi, wm8731); ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8731, &wm8731_dai, 1); - if (ret < 0) - kfree(wm8731); + if (ret != 0) { + dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret); + goto err_regmap; + } + + return 0; + +err_regmap: + regmap_exit(wm8731->regmap); +err: + kfree(wm8731); return ret; } static int __devexit wm8731_spi_remove(struct spi_device *spi) { + struct wm8731_priv *wm8731 = spi_get_drvdata(spi); + snd_soc_unregister_codec(&spi->dev); - kfree(spi_get_drvdata(spi)); + regmap_exit(wm8731->regmap); + kfree(wm8731); return 0; } @@ -652,20 +697,38 @@ static __devinit int wm8731_i2c_probe(struct i2c_client *i2c, if (wm8731 == NULL) return -ENOMEM; + wm8731->regmap = regmap_init_i2c(i2c, &wm8731_regmap); + if (IS_ERR(wm8731->regmap)) { + ret = PTR_ERR(wm8731->regmap); + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + ret); + goto err; + } + i2c_set_clientdata(i2c, wm8731); - wm8731->control_type = SND_SOC_I2C; - ret = snd_soc_register_codec(&i2c->dev, + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8731, &wm8731_dai, 1); - if (ret < 0) - kfree(wm8731); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); + goto err_regmap; + } + + return 0; + +err_regmap: + regmap_exit(wm8731->regmap); +err: + kfree(wm8731); return ret; } static __devexit int wm8731_i2c_remove(struct i2c_client *client) { + struct wm8731_priv *wm8731 = i2c_get_clientdata(client); snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); + regmap_exit(wm8731->regmap); + kfree(wm8731); return 0; } -- cgit v0.10.2 From e8770dd878970140b7ef486ec0fe86d43eb50265 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 24 Jan 2012 12:11:20 +0000 Subject: ASoC: wm5100: Fix mismerge of IRQ frees We only want them at the device level, not at the CODEC level. Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index c291f8e..81056d8 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -2525,8 +2525,6 @@ static int wm5100_probe(struct snd_soc_codec *codec) return 0; err_gpio: - if (i2c->irq) - free_irq(i2c->irq, wm5100); return ret; } @@ -2539,8 +2537,6 @@ static int wm5100_remove(struct snd_soc_codec *codec) if (wm5100->pdata.hp_pol) { gpio_free(wm5100->pdata.hp_pol); } - if (i2c->irq) - free_irq(i2c->irq, wm5100); return 0; } -- cgit v0.10.2 From 15b52f10ec6131e1aff49e7823a67732cdc066a0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 21 Jan 2012 12:14:53 +0000 Subject: ASoC: Convert the WM5100 revision A updates to a regmap patch Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 81056d8..e40c81eae 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -1310,10 +1310,7 @@ static const struct snd_soc_dapm_route wm5100_dapm_routes[] = { { "PWM2", NULL, "PWM2 Driver" }, }; -static struct { - int reg; - int val; -} wm5100_reva_patches[] = { +static const __devinitdata struct reg_default wm5100_reva_patches[] = { { WM5100_AUDIO_IF_1_10, 0 }, { WM5100_AUDIO_IF_1_11, 1 }, { WM5100_AUDIO_IF_1_12, 2 }, @@ -1376,31 +1373,6 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec, } regcache_cache_only(wm5100->regmap, false); - - switch (wm5100->rev) { - case 0: - regcache_cache_bypass(wm5100->regmap, true); - snd_soc_write(codec, 0x11, 0x3); - snd_soc_write(codec, 0x203, 0xc); - snd_soc_write(codec, 0x206, 0); - snd_soc_write(codec, 0x207, 0xf0); - snd_soc_write(codec, 0x208, 0x3c); - snd_soc_write(codec, 0x209, 0); - snd_soc_write(codec, 0x211, 0x20d8); - snd_soc_write(codec, 0x11, 0); - - for (i = 0; - i < ARRAY_SIZE(wm5100_reva_patches); - i++) - snd_soc_write(codec, - wm5100_reva_patches[i].reg, - wm5100_reva_patches[i].val); - regcache_cache_bypass(wm5100->regmap, false); - break; - default: - break; - } - regcache_sync(wm5100->regmap); } break; @@ -2703,6 +2675,22 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, goto err_reset; } + switch (wm5100->rev) { + case 0: + ret = regmap_register_patch(wm5100->regmap, + wm5100_reva_patches, + ARRAY_SIZE(wm5100_reva_patches)); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to register patches: %d\n", + ret); + goto err_reset; + } + break; + default: + break; + } + + wm5100_init_gpio(i2c); for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) { -- cgit v0.10.2 From 5509f2f80c711add6bbcec9af7f4bbba2e2cc22b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 24 Jan 2012 19:51:34 +0000 Subject: ASoC: wm5100: Fix warnings from recent patches Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index e40c81eae..714256e 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -1346,7 +1346,7 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); - int ret, i; + int ret; switch (level) { case SND_SOC_BIAS_ON: @@ -2504,7 +2504,6 @@ err_gpio: static int wm5100_remove(struct snd_soc_codec *codec) { struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); - struct i2c_client *i2c = to_i2c_client(codec->dev); if (wm5100->pdata.hp_pol) { gpio_free(wm5100->pdata.hp_pol); -- cgit v0.10.2 From 182c51ce7944a214dd77a0b5c0462241e49dd418 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 24 Jan 2012 21:07:55 +0000 Subject: ASoC: wm8962: Optimise power consumption for IN4 DC measurement usage When the hardware is configured with one or both of the IN4 inputs used for DC measurement (with no DC blocking capacitor connected) then we can improve power consumption slightly in idle modes by applying a register write sequence. Provide platform data to enable this, implemented using a regmap patch. Signed-off-by: Mark Brown diff --git a/include/sound/wm8962.h b/include/sound/wm8962.h index 1750bed..79e6d42 100644 --- a/include/sound/wm8962.h +++ b/include/sound/wm8962.h @@ -49,6 +49,12 @@ struct wm8962_pdata { bool irq_active_low; bool spk_mono; /* Speaker outputs tied together as mono */ + + /** + * This flag should be set if one or both IN4 inputs is wired + * in a DC measurement configuration. + */ + bool in4_dc_measure; }; #endif diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index cc4049e..2a654fd 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -3638,6 +3638,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8962 = { .volatile_register = wm8962_soc_volatile, }; +/* Improve power consumption for IN4 DC measurement mode */ +static const struct reg_default wm8962_dc_measure[] = { + { 0xfd, 0x1 }, + { 0xcc, 0x40 }, + { 0xfd, 0 }, +}; + static const struct regmap_config wm8962_regmap = { .reg_bits = 16, .val_bits = 16, @@ -3653,6 +3660,7 @@ static const struct regmap_config wm8962_regmap = { static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { + struct wm8962_pdata *pdata = dev_get_platdata(&i2c->dev); struct wm8962_priv *wm8962; unsigned int reg; int ret, i; @@ -3731,6 +3739,16 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, goto err_regmap; } + if (pdata && pdata->in4_dc_measure) { + ret = regmap_register_patch(wm8962->regmap, + wm8962_dc_measure, + ARRAY_SIZE(wm8962_dc_measure)); + if (ret != 0) + dev_err(&i2c->dev, + "Failed to configure for DC mesurement: %d\n", + ret); + } + regcache_cache_only(wm8962->regmap, true); ret = snd_soc_register_codec(&i2c->dev, -- cgit v0.10.2 From 88e339541d28153b6d2bfad9b25b3462fcd2bcaa Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 25 Jan 2012 10:09:41 +0200 Subject: ASoC: soc-pcm: msbits constraint: Drop 8 and 16 bit sample sizes As per discussion we can safely ignore the 8 and 16 bit sample sizes when applying the msbits constraint. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 3268901..93be95b 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -68,7 +68,7 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, * like the DAC/ADC resolution to use but there isn't right now. */ static int sample_sizes[] = { - 8, 16, 24, 32, + 24, 32, }; static void soc_pcm_apply_msb(struct snd_pcm_substream *substream, -- cgit v0.10.2 From 8747a6b7d5685ebb64f1ec4d58d9b1969df3e34d Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 7 Dec 2011 15:31:26 +0200 Subject: ASoC: sdp4430: Correct author e-mail address Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c index 175ba9a..ceadb13 100644 --- a/sound/soc/omap/sdp4430.c +++ b/sound/soc/omap/sdp4430.c @@ -1,7 +1,7 @@ /* * sdp4430.c -- SoC audio for TI OMAP4430 SDP * - * Author: Misael Lopez Cruz + * Author: Misael Lopez Cruz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -273,7 +273,7 @@ static void __exit sdp4430_soc_exit(void) } module_exit(sdp4430_soc_exit); -MODULE_AUTHOR("Misael Lopez Cruz "); +MODULE_AUTHOR("Misael Lopez Cruz "); MODULE_DESCRIPTION("ALSA SoC SDP4430"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From e15422edd463fbba7f38ffd8a2e2ca8564da1160 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 7 Dec 2011 15:38:38 +0200 Subject: ASoC: OMAP4: Rename the sdp4430 machine driver The same machine driver will support other boards with similar audio configuration (OMAP4, ABE, twl6040). Rename the driver to have more generic name. Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index fb1bf25..4eae929 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig @@ -97,7 +97,7 @@ config SND_OMAP_SOC_SDP3430 Say Y if you want to add support for SoC audio on Texas Instruments SDP3430. -config SND_OMAP_SOC_SDP4430 +config SND_OMAP_SOC_OMAP_ABE_TWL6040 tristate "SoC Audio support for Texas Instruments SDP4430" depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_4430SDP select SND_OMAP_SOC_DMIC diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile index 1fd723f..123ac18 100644 --- a/sound/soc/omap/Makefile +++ b/sound/soc/omap/Makefile @@ -20,7 +20,7 @@ snd-soc-overo-objs := overo.o snd-soc-omap3evm-objs := omap3evm.o snd-soc-am3517evm-objs := am3517evm.o snd-soc-sdp3430-objs := sdp3430.o -snd-soc-sdp4430-objs := sdp4430.o +snd-soc-omap-abe-twl6040-objs := omap-abe-twl6040.o snd-soc-omap3pandora-objs := omap3pandora.o snd-soc-omap3beagle-objs := omap3beagle.o snd-soc-zoom2-objs := zoom2.o @@ -36,7 +36,7 @@ obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o -obj-$(CONFIG_SND_OMAP_SOC_SDP4430) += snd-soc-sdp4430.o +obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c new file mode 100644 index 0000000..ceadb13 --- /dev/null +++ b/sound/soc/omap/omap-abe-twl6040.c @@ -0,0 +1,279 @@ +/* + * sdp4430.c -- SoC audio for TI OMAP4430 SDP + * + * Author: Misael Lopez Cruz + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "omap-dmic.h" +#include "omap-mcpdm.h" +#include "omap-pcm.h" +#include "../codecs/twl6040.h" + +static int sdp4430_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + int clk_id, freq; + int ret; + + clk_id = twl6040_get_clk_id(rtd->codec); + if (clk_id == TWL6040_SYSCLK_SEL_HPPLL) + freq = 38400000; + else if (clk_id == TWL6040_SYSCLK_SEL_LPPLL) + freq = 32768; + else + return -EINVAL; + + /* set the codec mclk */ + ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, freq, + SND_SOC_CLOCK_IN); + if (ret) { + printk(KERN_ERR "can't set codec system clock\n"); + return ret; + } + return ret; +} + +static struct snd_soc_ops sdp4430_ops = { + .hw_params = sdp4430_hw_params, +}; + +static int sdp4430_dmic_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + + ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_SYSCLK_PAD_CLKS, + 19200000, SND_SOC_CLOCK_IN); + if (ret < 0) { + printk(KERN_ERR "can't set DMIC cpu system clock\n"); + return ret; + } + ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_ABE_DMIC_CLK, 2400000, + SND_SOC_CLOCK_OUT); + if (ret < 0) { + printk(KERN_ERR "can't set DMIC output clock\n"); + return ret; + } + return 0; +} + +static struct snd_soc_ops sdp4430_dmic_ops = { + .hw_params = sdp4430_dmic_hw_params, +}; + +/* Headset jack */ +static struct snd_soc_jack hs_jack; + +/*Headset jack detection DAPM pins */ +static struct snd_soc_jack_pin hs_jack_pins[] = { + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, + { + .pin = "Headset Stereophone", + .mask = SND_JACK_HEADPHONE, + }, +}; + +/* SDP4430 machine DAPM */ +static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = { + SND_SOC_DAPM_MIC("Ext Mic", NULL), + SND_SOC_DAPM_SPK("Ext Spk", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_HP("Headset Stereophone", NULL), + SND_SOC_DAPM_SPK("Earphone Spk", NULL), + SND_SOC_DAPM_INPUT("FM Stereo In"), +}; + +static const struct snd_soc_dapm_route audio_map[] = { + /* External Mics: MAINMIC, SUBMIC with bias*/ + {"MAINMIC", NULL, "Main Mic Bias"}, + {"SUBMIC", NULL, "Main Mic Bias"}, + {"Main Mic Bias", NULL, "Ext Mic"}, + + /* External Speakers: HFL, HFR */ + {"Ext Spk", NULL, "HFL"}, + {"Ext Spk", NULL, "HFR"}, + + /* Headset Mic: HSMIC with bias */ + {"HSMIC", NULL, "Headset Mic Bias"}, + {"Headset Mic Bias", NULL, "Headset Mic"}, + + /* Headset Stereophone (Headphone): HSOL, HSOR */ + {"Headset Stereophone", NULL, "HSOL"}, + {"Headset Stereophone", NULL, "HSOR"}, + + /* Earphone speaker */ + {"Earphone Spk", NULL, "EP"}, + + /* Aux/FM Stereo In: AFML, AFMR */ + {"AFML", NULL, "FM Stereo In"}, + {"AFMR", NULL, "FM Stereo In"}, +}; + +static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + int ret, hs_trim; + + /* + * Configure McPDM offset cancellation based on the HSOTRIM value from + * twl6040. + */ + hs_trim = twl6040_get_trim_value(codec, TWL6040_TRIM_HSOTRIM); + omap_mcpdm_configure_dn_offsets(rtd, TWL6040_HSF_TRIM_LEFT(hs_trim), + TWL6040_HSF_TRIM_RIGHT(hs_trim)); + + /* Headset jack detection */ + ret = snd_soc_jack_new(codec, "Headset Jack", + SND_JACK_HEADSET, &hs_jack); + if (ret) + return ret; + + ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), + hs_jack_pins); + + if (machine_is_omap_4430sdp()) + twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET); + else + snd_soc_jack_report(&hs_jack, SND_JACK_HEADSET, SND_JACK_HEADSET); + + return ret; +} + +static const struct snd_soc_dapm_widget sdp4430_dmic_dapm_widgets[] = { + SND_SOC_DAPM_MIC("Digital Mic", NULL), +}; + +static const struct snd_soc_dapm_route dmic_audio_map[] = { + {"DMic", NULL, "Digital Mic1 Bias"}, + {"Digital Mic1 Bias", NULL, "Digital Mic"}, +}; + +static int sdp4430_dmic_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + int ret; + + ret = snd_soc_dapm_new_controls(dapm, sdp4430_dmic_dapm_widgets, + ARRAY_SIZE(sdp4430_dmic_dapm_widgets)); + if (ret) + return ret; + + return snd_soc_dapm_add_routes(dapm, dmic_audio_map, + ARRAY_SIZE(dmic_audio_map)); +} + +/* Digital audio interface glue - connects codec <--> CPU */ +static struct snd_soc_dai_link sdp4430_dai[] = { + { + .name = "TWL6040", + .stream_name = "TWL6040", + .cpu_dai_name = "omap-mcpdm", + .codec_dai_name = "twl6040-legacy", + .platform_name = "omap-pcm-audio", + .codec_name = "twl6040-codec", + .init = sdp4430_twl6040_init, + .ops = &sdp4430_ops, + }, + { + .name = "DMIC", + .stream_name = "DMIC Capture", + .cpu_dai_name = "omap-dmic", + .codec_dai_name = "dmic-hifi", + .platform_name = "omap-pcm-audio", + .codec_name = "dmic-codec", + .init = sdp4430_dmic_init, + .ops = &sdp4430_dmic_ops, + }, +}; + +/* Audio machine driver */ +static struct snd_soc_card snd_soc_sdp4430 = { + .name = "SDP4430", + .owner = THIS_MODULE, + .dai_link = sdp4430_dai, + .num_links = ARRAY_SIZE(sdp4430_dai), + + .dapm_widgets = sdp4430_twl6040_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(sdp4430_twl6040_dapm_widgets), + .dapm_routes = audio_map, + .num_dapm_routes = ARRAY_SIZE(audio_map), +}; + +static struct platform_device *sdp4430_snd_device; + +static int __init sdp4430_soc_init(void) +{ + int ret; + + if (!machine_is_omap_4430sdp()) + return -ENODEV; + printk(KERN_INFO "SDP4430 SoC init\n"); + + sdp4430_snd_device = platform_device_alloc("soc-audio", -1); + if (!sdp4430_snd_device) { + printk(KERN_ERR "Platform device allocation failed\n"); + return -ENOMEM; + } + + platform_set_drvdata(sdp4430_snd_device, &snd_soc_sdp4430); + + ret = platform_device_add(sdp4430_snd_device); + if (ret) + goto err; + + return 0; + +err: + printk(KERN_ERR "Unable to add platform device\n"); + platform_device_put(sdp4430_snd_device); + return ret; +} +module_init(sdp4430_soc_init); + +static void __exit sdp4430_soc_exit(void) +{ + platform_device_unregister(sdp4430_snd_device); +} +module_exit(sdp4430_soc_exit); + +MODULE_AUTHOR("Misael Lopez Cruz "); +MODULE_DESCRIPTION("ALSA SoC SDP4430"); +MODULE_LICENSE("GPL"); + diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c deleted file mode 100644 index ceadb13..0000000 --- a/sound/soc/omap/sdp4430.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * sdp4430.c -- SoC audio for TI OMAP4430 SDP - * - * Author: Misael Lopez Cruz - * - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "omap-dmic.h" -#include "omap-mcpdm.h" -#include "omap-pcm.h" -#include "../codecs/twl6040.h" - -static int sdp4430_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - int clk_id, freq; - int ret; - - clk_id = twl6040_get_clk_id(rtd->codec); - if (clk_id == TWL6040_SYSCLK_SEL_HPPLL) - freq = 38400000; - else if (clk_id == TWL6040_SYSCLK_SEL_LPPLL) - freq = 32768; - else - return -EINVAL; - - /* set the codec mclk */ - ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, freq, - SND_SOC_CLOCK_IN); - if (ret) { - printk(KERN_ERR "can't set codec system clock\n"); - return ret; - } - return ret; -} - -static struct snd_soc_ops sdp4430_ops = { - .hw_params = sdp4430_hw_params, -}; - -static int sdp4430_dmic_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int ret = 0; - - ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_SYSCLK_PAD_CLKS, - 19200000, SND_SOC_CLOCK_IN); - if (ret < 0) { - printk(KERN_ERR "can't set DMIC cpu system clock\n"); - return ret; - } - ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_ABE_DMIC_CLK, 2400000, - SND_SOC_CLOCK_OUT); - if (ret < 0) { - printk(KERN_ERR "can't set DMIC output clock\n"); - return ret; - } - return 0; -} - -static struct snd_soc_ops sdp4430_dmic_ops = { - .hw_params = sdp4430_dmic_hw_params, -}; - -/* Headset jack */ -static struct snd_soc_jack hs_jack; - -/*Headset jack detection DAPM pins */ -static struct snd_soc_jack_pin hs_jack_pins[] = { - { - .pin = "Headset Mic", - .mask = SND_JACK_MICROPHONE, - }, - { - .pin = "Headset Stereophone", - .mask = SND_JACK_HEADPHONE, - }, -}; - -/* SDP4430 machine DAPM */ -static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = { - SND_SOC_DAPM_MIC("Ext Mic", NULL), - SND_SOC_DAPM_SPK("Ext Spk", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_HP("Headset Stereophone", NULL), - SND_SOC_DAPM_SPK("Earphone Spk", NULL), - SND_SOC_DAPM_INPUT("FM Stereo In"), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - /* External Mics: MAINMIC, SUBMIC with bias*/ - {"MAINMIC", NULL, "Main Mic Bias"}, - {"SUBMIC", NULL, "Main Mic Bias"}, - {"Main Mic Bias", NULL, "Ext Mic"}, - - /* External Speakers: HFL, HFR */ - {"Ext Spk", NULL, "HFL"}, - {"Ext Spk", NULL, "HFR"}, - - /* Headset Mic: HSMIC with bias */ - {"HSMIC", NULL, "Headset Mic Bias"}, - {"Headset Mic Bias", NULL, "Headset Mic"}, - - /* Headset Stereophone (Headphone): HSOL, HSOR */ - {"Headset Stereophone", NULL, "HSOL"}, - {"Headset Stereophone", NULL, "HSOR"}, - - /* Earphone speaker */ - {"Earphone Spk", NULL, "EP"}, - - /* Aux/FM Stereo In: AFML, AFMR */ - {"AFML", NULL, "FM Stereo In"}, - {"AFMR", NULL, "FM Stereo In"}, -}; - -static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - int ret, hs_trim; - - /* - * Configure McPDM offset cancellation based on the HSOTRIM value from - * twl6040. - */ - hs_trim = twl6040_get_trim_value(codec, TWL6040_TRIM_HSOTRIM); - omap_mcpdm_configure_dn_offsets(rtd, TWL6040_HSF_TRIM_LEFT(hs_trim), - TWL6040_HSF_TRIM_RIGHT(hs_trim)); - - /* Headset jack detection */ - ret = snd_soc_jack_new(codec, "Headset Jack", - SND_JACK_HEADSET, &hs_jack); - if (ret) - return ret; - - ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), - hs_jack_pins); - - if (machine_is_omap_4430sdp()) - twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET); - else - snd_soc_jack_report(&hs_jack, SND_JACK_HEADSET, SND_JACK_HEADSET); - - return ret; -} - -static const struct snd_soc_dapm_widget sdp4430_dmic_dapm_widgets[] = { - SND_SOC_DAPM_MIC("Digital Mic", NULL), -}; - -static const struct snd_soc_dapm_route dmic_audio_map[] = { - {"DMic", NULL, "Digital Mic1 Bias"}, - {"Digital Mic1 Bias", NULL, "Digital Mic"}, -}; - -static int sdp4430_dmic_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - int ret; - - ret = snd_soc_dapm_new_controls(dapm, sdp4430_dmic_dapm_widgets, - ARRAY_SIZE(sdp4430_dmic_dapm_widgets)); - if (ret) - return ret; - - return snd_soc_dapm_add_routes(dapm, dmic_audio_map, - ARRAY_SIZE(dmic_audio_map)); -} - -/* Digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link sdp4430_dai[] = { - { - .name = "TWL6040", - .stream_name = "TWL6040", - .cpu_dai_name = "omap-mcpdm", - .codec_dai_name = "twl6040-legacy", - .platform_name = "omap-pcm-audio", - .codec_name = "twl6040-codec", - .init = sdp4430_twl6040_init, - .ops = &sdp4430_ops, - }, - { - .name = "DMIC", - .stream_name = "DMIC Capture", - .cpu_dai_name = "omap-dmic", - .codec_dai_name = "dmic-hifi", - .platform_name = "omap-pcm-audio", - .codec_name = "dmic-codec", - .init = sdp4430_dmic_init, - .ops = &sdp4430_dmic_ops, - }, -}; - -/* Audio machine driver */ -static struct snd_soc_card snd_soc_sdp4430 = { - .name = "SDP4430", - .owner = THIS_MODULE, - .dai_link = sdp4430_dai, - .num_links = ARRAY_SIZE(sdp4430_dai), - - .dapm_widgets = sdp4430_twl6040_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(sdp4430_twl6040_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), -}; - -static struct platform_device *sdp4430_snd_device; - -static int __init sdp4430_soc_init(void) -{ - int ret; - - if (!machine_is_omap_4430sdp()) - return -ENODEV; - printk(KERN_INFO "SDP4430 SoC init\n"); - - sdp4430_snd_device = platform_device_alloc("soc-audio", -1); - if (!sdp4430_snd_device) { - printk(KERN_ERR "Platform device allocation failed\n"); - return -ENOMEM; - } - - platform_set_drvdata(sdp4430_snd_device, &snd_soc_sdp4430); - - ret = platform_device_add(sdp4430_snd_device); - if (ret) - goto err; - - return 0; - -err: - printk(KERN_ERR "Unable to add platform device\n"); - platform_device_put(sdp4430_snd_device); - return ret; -} -module_init(sdp4430_soc_init); - -static void __exit sdp4430_soc_exit(void) -{ - platform_device_unregister(sdp4430_snd_device); -} -module_exit(sdp4430_soc_exit); - -MODULE_AUTHOR("Misael Lopez Cruz "); -MODULE_DESCRIPTION("ALSA SoC SDP4430"); -MODULE_LICENSE("GPL"); - -- cgit v0.10.2 From 13f81d65959eb3512b39e8c338e81e018d1c515b Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 7 Dec 2011 15:54:50 +0200 Subject: ASoC: omap-abe-twl6040: Correct internal prefix, Kconfig entry Change the internal prefixes within the driver from sdp4430. At he same time correct the Kconfig text as well. Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index 4eae929..98410b8 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig @@ -98,15 +98,16 @@ config SND_OMAP_SOC_SDP3430 SDP3430. config SND_OMAP_SOC_OMAP_ABE_TWL6040 - tristate "SoC Audio support for Texas Instruments SDP4430" + tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_4430SDP select SND_OMAP_SOC_DMIC select SND_OMAP_SOC_MCPDM select SND_SOC_TWL6040 select SND_SOC_DMIC help - Say Y if you want to add support for SoC audio on Texas Instruments - SDP4430. + Say Y if you want to add support for SoC audio on OMAP boards using + ABE and twl6040 codec. This driver currently supports: + - SDP4430/Blaze boards config SND_OMAP_SOC_OMAP4_HDMI tristate "SoC Audio support for Texas Instruments OMAP4 HDMI" diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c index ceadb13..376ca35 100644 --- a/sound/soc/omap/omap-abe-twl6040.c +++ b/sound/soc/omap/omap-abe-twl6040.c @@ -1,5 +1,6 @@ /* - * sdp4430.c -- SoC audio for TI OMAP4430 SDP + * omap-abe-twl6040.c -- SoC audio for TI OMAP based boards with ABE and + * twl6040 codec * * Author: Misael Lopez Cruz * @@ -38,7 +39,7 @@ #include "omap-pcm.h" #include "../codecs/twl6040.h" -static int sdp4430_hw_params(struct snd_pcm_substream *substream, +static int omap_abe_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; @@ -64,11 +65,11 @@ static int sdp4430_hw_params(struct snd_pcm_substream *substream, return ret; } -static struct snd_soc_ops sdp4430_ops = { - .hw_params = sdp4430_hw_params, +static struct snd_soc_ops omap_abe_ops = { + .hw_params = omap_abe_hw_params, }; -static int sdp4430_dmic_hw_params(struct snd_pcm_substream *substream, +static int omap_abe_dmic_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; @@ -90,8 +91,8 @@ static int sdp4430_dmic_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_ops sdp4430_dmic_ops = { - .hw_params = sdp4430_dmic_hw_params, +static struct snd_soc_ops omap_abe_dmic_ops = { + .hw_params = omap_abe_dmic_hw_params, }; /* Headset jack */ @@ -110,7 +111,7 @@ static struct snd_soc_jack_pin hs_jack_pins[] = { }; /* SDP4430 machine DAPM */ -static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = { +static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { SND_SOC_DAPM_MIC("Ext Mic", NULL), SND_SOC_DAPM_SPK("Ext Spk", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), @@ -145,7 +146,7 @@ static const struct snd_soc_dapm_route audio_map[] = { {"AFMR", NULL, "FM Stereo In"}, }; -static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) +static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; int ret, hs_trim; @@ -175,7 +176,7 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) return ret; } -static const struct snd_soc_dapm_widget sdp4430_dmic_dapm_widgets[] = { +static const struct snd_soc_dapm_widget dmic_dapm_widgets[] = { SND_SOC_DAPM_MIC("Digital Mic", NULL), }; @@ -184,14 +185,14 @@ static const struct snd_soc_dapm_route dmic_audio_map[] = { {"Digital Mic1 Bias", NULL, "Digital Mic"}, }; -static int sdp4430_dmic_init(struct snd_soc_pcm_runtime *rtd) +static int omap_abe_dmic_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; - ret = snd_soc_dapm_new_controls(dapm, sdp4430_dmic_dapm_widgets, - ARRAY_SIZE(sdp4430_dmic_dapm_widgets)); + ret = snd_soc_dapm_new_controls(dapm, dmic_dapm_widgets, + ARRAY_SIZE(dmic_dapm_widgets)); if (ret) return ret; @@ -208,8 +209,8 @@ static struct snd_soc_dai_link sdp4430_dai[] = { .codec_dai_name = "twl6040-legacy", .platform_name = "omap-pcm-audio", .codec_name = "twl6040-codec", - .init = sdp4430_twl6040_init, - .ops = &sdp4430_ops, + .init = omap_abe_twl6040_init, + .ops = &omap_abe_ops, }, { .name = "DMIC", @@ -218,27 +219,27 @@ static struct snd_soc_dai_link sdp4430_dai[] = { .codec_dai_name = "dmic-hifi", .platform_name = "omap-pcm-audio", .codec_name = "dmic-codec", - .init = sdp4430_dmic_init, - .ops = &sdp4430_dmic_ops, + .init = omap_abe_dmic_init, + .ops = &omap_abe_dmic_ops, }, }; /* Audio machine driver */ -static struct snd_soc_card snd_soc_sdp4430 = { +static struct snd_soc_card omap_abe_card = { .name = "SDP4430", .owner = THIS_MODULE, .dai_link = sdp4430_dai, .num_links = ARRAY_SIZE(sdp4430_dai), - .dapm_widgets = sdp4430_twl6040_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(sdp4430_twl6040_dapm_widgets), + .dapm_widgets = twl6040_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets), .dapm_routes = audio_map, .num_dapm_routes = ARRAY_SIZE(audio_map), }; -static struct platform_device *sdp4430_snd_device; +static struct platform_device *omap_abe_snd_device; -static int __init sdp4430_soc_init(void) +static int __init omap_abe_soc_init(void) { int ret; @@ -246,15 +247,15 @@ static int __init sdp4430_soc_init(void) return -ENODEV; printk(KERN_INFO "SDP4430 SoC init\n"); - sdp4430_snd_device = platform_device_alloc("soc-audio", -1); - if (!sdp4430_snd_device) { + omap_abe_snd_device = platform_device_alloc("soc-audio", -1); + if (!omap_abe_snd_device) { printk(KERN_ERR "Platform device allocation failed\n"); return -ENOMEM; } - platform_set_drvdata(sdp4430_snd_device, &snd_soc_sdp4430); + platform_set_drvdata(omap_abe_snd_device, &omap_abe_card); - ret = platform_device_add(sdp4430_snd_device); + ret = platform_device_add(omap_abe_snd_device); if (ret) goto err; @@ -262,18 +263,18 @@ static int __init sdp4430_soc_init(void) err: printk(KERN_ERR "Unable to add platform device\n"); - platform_device_put(sdp4430_snd_device); + platform_device_put(omap_abe_snd_device); return ret; } -module_init(sdp4430_soc_init); +module_init(omap_abe_soc_init); -static void __exit sdp4430_soc_exit(void) +static void __exit omap_abe_soc_exit(void) { - platform_device_unregister(sdp4430_snd_device); + platform_device_unregister(omap_abe_snd_device); } -module_exit(sdp4430_soc_exit); +module_exit(omap_abe_soc_exit); MODULE_AUTHOR("Misael Lopez Cruz "); -MODULE_DESCRIPTION("ALSA SoC SDP4430"); +MODULE_DESCRIPTION("ALSA SoC for OMAP boards with ABE and twl6040 codec"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From d71e600836aa5597837970cb754057b2b884035c Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 7 Dec 2011 15:57:10 +0200 Subject: include: platform_data: Platform data header for OMAP4 ASoC audio Include file to be used with the upcoming ASoC machine driver for OMAP platform using ABE with twl6040 codec. Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown diff --git a/include/linux/platform_data/omap-abe-twl6040.h b/include/linux/platform_data/omap-abe-twl6040.h new file mode 100644 index 0000000..5d298ac --- /dev/null +++ b/include/linux/platform_data/omap-abe-twl6040.h @@ -0,0 +1,49 @@ +/** + * omap-abe-twl6040.h - ASoC machine driver OMAP4+ devices, header. + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com + * All rights reserved. + * + * Author: Peter Ujfalusi + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef _OMAP_ABE_TWL6040_H_ +#define _OMAP_ABE_TWL6040_H_ + +/* To select if only one channel is connected in a stereo port */ +#define ABE_TWL6040_LEFT (1 << 0) +#define ABE_TWL6040_RIGHT (1 << 1) + +struct omap_abe_twl6040_data { + char *card_name; + /* Feature flags for connected audio pins */ + u8 has_hs; + u8 has_hf; + bool has_ep; + u8 has_aux; + u8 has_vibra; + bool has_dmic; + bool has_hsmic; + bool has_mainmic; + bool has_submic; + u8 has_afm; + /* Other features */ + bool jack_detection; /* board can detect jack events */ + int mclk_freq; /* MCLK frequency speed for twl6040 */ +}; + +#endif /* _OMAP_ABE_TWL6040_H_ */ -- cgit v0.10.2 From a433ffabab2996637ac941b75a7b22ecb41ef1a4 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 7 Dec 2011 15:59:35 +0200 Subject: OMAP4: 4430sdp: Register platform device for OMAP4 audio To avoid breakage in audio support with the coming change in ASoC machine driver (conversion to platfrom device). Signed-off-by: Peter Ujfalusi CC: Santosh Shilimkar Acked-by: Tony Lindgren Acked-by: Santosh Shilimkar diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 39fba9d..7eaeb08 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -41,6 +41,7 @@ #include