diff options
author | Mark Brown <broonie@linaro.org> | 2013-06-17 12:20:32 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-06-17 12:20:32 -0400 |
commit | f57019aa0a796251e671882004dd58d2cc55f8f1 (patch) | |
tree | 02d4b5e40dbcbf0554e9abed508b958c32ecb864 | |
parent | 7daf390b8bff7a96ae40c1f9d7356c7c5c9ac384 (diff) | |
parent | 384b8345589cbbb18a99ce1b112da90c58c802e8 (diff) |
Merge remote-tracking branch 'asoc/topic/wm8962' into asoc-next
-rw-r--r-- | Documentation/devicetree/bindings/sound/wm8962.txt | 23 | ||||
-rw-r--r-- | sound/soc/codecs/wm8962.c | 112 |
2 files changed, 105 insertions, 30 deletions
diff --git a/Documentation/devicetree/bindings/sound/wm8962.txt b/Documentation/devicetree/bindings/sound/wm8962.txt index dceb3b1c2bb7..7f82b59ec8f9 100644 --- a/Documentation/devicetree/bindings/sound/wm8962.txt +++ b/Documentation/devicetree/bindings/sound/wm8962.txt | |||
@@ -8,9 +8,32 @@ Required properties: | |||
8 | 8 | ||
9 | - reg : the I2C address of the device. | 9 | - reg : the I2C address of the device. |
10 | 10 | ||
11 | Optional properties: | ||
12 | - spk-mono: This is a boolean property. If present, the SPK_MONO bit | ||
13 | of R51 (Class D Control 2) gets set, indicating that the speaker is | ||
14 | in mono mode. | ||
15 | |||
16 | - mic-cfg : Default register value for R48 (Additional Control 4). | ||
17 | If absent, the default should be the register default. | ||
18 | |||
19 | - gpio-cfg : A list of GPIO configuration register values. The list must | ||
20 | be 6 entries long. If absent, no configuration of these registers is | ||
21 | performed. And note that only the value within [0x0, 0xffff] is valid. | ||
22 | Any other value is regarded as setting the GPIO register by its reset | ||
23 | value 0x0. | ||
24 | |||
11 | Example: | 25 | Example: |
12 | 26 | ||
13 | codec: wm8962@1a { | 27 | codec: wm8962@1a { |
14 | compatible = "wlf,wm8962"; | 28 | compatible = "wlf,wm8962"; |
15 | reg = <0x1a>; | 29 | reg = <0x1a>; |
30 | |||
31 | gpio-cfg = < | ||
32 | 0x0000 /* 0:Default */ | ||
33 | 0x0000 /* 1:Default */ | ||
34 | 0x0013 /* 2:FN_DMICCLK */ | ||
35 | 0x0000 /* 3:Default */ | ||
36 | 0x8014 /* 4:FN_DMICCDAT */ | ||
37 | 0x0000 /* 5:Default */ | ||
38 | >; | ||
16 | }; | 39 | }; |
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 4b7915bec2f1..b1dc7d426438 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
@@ -51,6 +51,7 @@ static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = { | |||
51 | 51 | ||
52 | /* codec private data */ | 52 | /* codec private data */ |
53 | struct wm8962_priv { | 53 | struct wm8962_priv { |
54 | struct wm8962_pdata pdata; | ||
54 | struct regmap *regmap; | 55 | struct regmap *regmap; |
55 | struct snd_soc_codec *codec; | 56 | struct snd_soc_codec *codec; |
56 | 57 | ||
@@ -2347,12 +2348,13 @@ static const struct snd_soc_dapm_route wm8962_spk_stereo_intercon[] = { | |||
2347 | 2348 | ||
2348 | static int wm8962_add_widgets(struct snd_soc_codec *codec) | 2349 | static int wm8962_add_widgets(struct snd_soc_codec *codec) |
2349 | { | 2350 | { |
2350 | struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); | 2351 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); |
2352 | struct wm8962_pdata *pdata = &wm8962->pdata; | ||
2351 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 2353 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
2352 | 2354 | ||
2353 | snd_soc_add_codec_controls(codec, wm8962_snd_controls, | 2355 | snd_soc_add_codec_controls(codec, wm8962_snd_controls, |
2354 | ARRAY_SIZE(wm8962_snd_controls)); | 2356 | ARRAY_SIZE(wm8962_snd_controls)); |
2355 | if (pdata && pdata->spk_mono) | 2357 | if (pdata->spk_mono) |
2356 | snd_soc_add_codec_controls(codec, wm8962_spk_mono_controls, | 2358 | snd_soc_add_codec_controls(codec, wm8962_spk_mono_controls, |
2357 | ARRAY_SIZE(wm8962_spk_mono_controls)); | 2359 | ARRAY_SIZE(wm8962_spk_mono_controls)); |
2358 | else | 2360 | else |
@@ -2362,7 +2364,7 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec) | |||
2362 | 2364 | ||
2363 | snd_soc_dapm_new_controls(dapm, wm8962_dapm_widgets, | 2365 | snd_soc_dapm_new_controls(dapm, wm8962_dapm_widgets, |
2364 | ARRAY_SIZE(wm8962_dapm_widgets)); | 2366 | ARRAY_SIZE(wm8962_dapm_widgets)); |
2365 | if (pdata && pdata->spk_mono) | 2367 | if (pdata->spk_mono) |
2366 | snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_mono_widgets, | 2368 | snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_mono_widgets, |
2367 | ARRAY_SIZE(wm8962_dapm_spk_mono_widgets)); | 2369 | ARRAY_SIZE(wm8962_dapm_spk_mono_widgets)); |
2368 | else | 2370 | else |
@@ -2371,7 +2373,7 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec) | |||
2371 | 2373 | ||
2372 | snd_soc_dapm_add_routes(dapm, wm8962_intercon, | 2374 | snd_soc_dapm_add_routes(dapm, wm8962_intercon, |
2373 | ARRAY_SIZE(wm8962_intercon)); | 2375 | ARRAY_SIZE(wm8962_intercon)); |
2374 | if (pdata && pdata->spk_mono) | 2376 | if (pdata->spk_mono) |
2375 | snd_soc_dapm_add_routes(dapm, wm8962_spk_mono_intercon, | 2377 | snd_soc_dapm_add_routes(dapm, wm8962_spk_mono_intercon, |
2376 | ARRAY_SIZE(wm8962_spk_mono_intercon)); | 2378 | ARRAY_SIZE(wm8962_spk_mono_intercon)); |
2377 | else | 2379 | else |
@@ -3335,14 +3337,14 @@ static struct gpio_chip wm8962_template_chip = { | |||
3335 | static void wm8962_init_gpio(struct snd_soc_codec *codec) | 3337 | static void wm8962_init_gpio(struct snd_soc_codec *codec) |
3336 | { | 3338 | { |
3337 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | 3339 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); |
3338 | struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); | 3340 | struct wm8962_pdata *pdata = &wm8962->pdata; |
3339 | int ret; | 3341 | int ret; |
3340 | 3342 | ||
3341 | wm8962->gpio_chip = wm8962_template_chip; | 3343 | wm8962->gpio_chip = wm8962_template_chip; |
3342 | wm8962->gpio_chip.ngpio = WM8962_MAX_GPIO; | 3344 | wm8962->gpio_chip.ngpio = WM8962_MAX_GPIO; |
3343 | wm8962->gpio_chip.dev = codec->dev; | 3345 | wm8962->gpio_chip.dev = codec->dev; |
3344 | 3346 | ||
3345 | if (pdata && pdata->gpio_base) | 3347 | if (pdata->gpio_base) |
3346 | wm8962->gpio_chip.base = pdata->gpio_base; | 3348 | wm8962->gpio_chip.base = pdata->gpio_base; |
3347 | else | 3349 | else |
3348 | wm8962->gpio_chip.base = -1; | 3350 | wm8962->gpio_chip.base = -1; |
@@ -3422,31 +3424,29 @@ static int wm8962_probe(struct snd_soc_codec *codec) | |||
3422 | WM8962_OSC_ENA | WM8962_PLL2_ENA | WM8962_PLL3_ENA, | 3424 | WM8962_OSC_ENA | WM8962_PLL2_ENA | WM8962_PLL3_ENA, |
3423 | 0); | 3425 | 0); |
3424 | 3426 | ||
3425 | if (pdata) { | 3427 | /* Apply static configuration for GPIOs */ |
3426 | /* Apply static configuration for GPIOs */ | 3428 | for (i = 0; i < ARRAY_SIZE(pdata->gpio_init); i++) |
3427 | for (i = 0; i < ARRAY_SIZE(pdata->gpio_init); i++) | 3429 | if (pdata->gpio_init[i]) { |
3428 | if (pdata->gpio_init[i]) { | 3430 | wm8962_set_gpio_mode(codec, i + 1); |
3429 | wm8962_set_gpio_mode(codec, i + 1); | 3431 | snd_soc_write(codec, 0x200 + i, |
3430 | snd_soc_write(codec, 0x200 + i, | 3432 | pdata->gpio_init[i] & 0xffff); |
3431 | pdata->gpio_init[i] & 0xffff); | 3433 | } |
3432 | } | ||
3433 | 3434 | ||
3434 | /* Put the speakers into mono mode? */ | 3435 | |
3435 | if (pdata->spk_mono) | 3436 | /* Put the speakers into mono mode? */ |
3436 | snd_soc_update_bits(codec, WM8962_CLASS_D_CONTROL_2, | 3437 | if (pdata->spk_mono) |
3438 | snd_soc_update_bits(codec, WM8962_CLASS_D_CONTROL_2, | ||
3437 | WM8962_SPK_MONO_MASK, WM8962_SPK_MONO); | 3439 | WM8962_SPK_MONO_MASK, WM8962_SPK_MONO); |
3438 | 3440 | ||
3439 | 3441 | /* Micbias setup, detection enable and detection | |
3440 | /* Micbias setup, detection enable and detection | 3442 | * threasholds. */ |
3441 | * threasholds. */ | 3443 | if (pdata->mic_cfg) |
3442 | if (pdata->mic_cfg) | 3444 | snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_4, |
3443 | snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_4, | 3445 | WM8962_MICDET_ENA | |
3444 | WM8962_MICDET_ENA | | 3446 | WM8962_MICDET_THR_MASK | |
3445 | WM8962_MICDET_THR_MASK | | 3447 | WM8962_MICSHORT_THR_MASK | |
3446 | WM8962_MICSHORT_THR_MASK | | 3448 | WM8962_MICBIAS_LVL, |
3447 | WM8962_MICBIAS_LVL, | 3449 | pdata->mic_cfg); |
3448 | pdata->mic_cfg); | ||
3449 | } | ||
3450 | 3450 | ||
3451 | /* Latch volume update bits */ | 3451 | /* Latch volume update bits */ |
3452 | snd_soc_update_bits(codec, WM8962_LEFT_INPUT_VOLUME, | 3452 | snd_soc_update_bits(codec, WM8962_LEFT_INPUT_VOLUME, |
@@ -3508,7 +3508,7 @@ static int wm8962_probe(struct snd_soc_codec *codec) | |||
3508 | wm8962_init_gpio(codec); | 3508 | wm8962_init_gpio(codec); |
3509 | 3509 | ||
3510 | if (wm8962->irq) { | 3510 | if (wm8962->irq) { |
3511 | if (pdata && pdata->irq_active_low) { | 3511 | if (pdata->irq_active_low) { |
3512 | trigger = IRQF_TRIGGER_LOW; | 3512 | trigger = IRQF_TRIGGER_LOW; |
3513 | irq_pol = WM8962_IRQ_POL; | 3513 | irq_pol = WM8962_IRQ_POL; |
3514 | } else { | 3514 | } else { |
@@ -3586,6 +3586,34 @@ static const struct regmap_config wm8962_regmap = { | |||
3586 | .cache_type = REGCACHE_RBTREE, | 3586 | .cache_type = REGCACHE_RBTREE, |
3587 | }; | 3587 | }; |
3588 | 3588 | ||
3589 | static int wm8962_set_pdata_from_of(struct i2c_client *i2c, | ||
3590 | struct wm8962_pdata *pdata) | ||
3591 | { | ||
3592 | const struct device_node *np = i2c->dev.of_node; | ||
3593 | u32 val32; | ||
3594 | int i; | ||
3595 | |||
3596 | if (of_property_read_bool(np, "spk-mono")) | ||
3597 | pdata->spk_mono = true; | ||
3598 | |||
3599 | if (of_property_read_u32(np, "mic-cfg", &val32) >= 0) | ||
3600 | pdata->mic_cfg = val32; | ||
3601 | |||
3602 | if (of_property_read_u32_array(np, "gpio-cfg", pdata->gpio_init, | ||
3603 | ARRAY_SIZE(pdata->gpio_init)) >= 0) | ||
3604 | for (i = 0; i < ARRAY_SIZE(pdata->gpio_init); i++) { | ||
3605 | /* | ||
3606 | * The range of GPIO register value is [0x0, 0xffff] | ||
3607 | * While the default value of each register is 0x0 | ||
3608 | * Any other value will be regarded as default value | ||
3609 | */ | ||
3610 | if (pdata->gpio_init[i] > 0xffff) | ||
3611 | pdata->gpio_init[i] = 0x0; | ||
3612 | } | ||
3613 | |||
3614 | return 0; | ||
3615 | } | ||
3616 | |||
3589 | static int wm8962_i2c_probe(struct i2c_client *i2c, | 3617 | static int wm8962_i2c_probe(struct i2c_client *i2c, |
3590 | const struct i2c_device_id *id) | 3618 | const struct i2c_device_id *id) |
3591 | { | 3619 | { |
@@ -3605,6 +3633,15 @@ static int wm8962_i2c_probe(struct i2c_client *i2c, | |||
3605 | init_completion(&wm8962->fll_lock); | 3633 | init_completion(&wm8962->fll_lock); |
3606 | wm8962->irq = i2c->irq; | 3634 | wm8962->irq = i2c->irq; |
3607 | 3635 | ||
3636 | /* If platform data was supplied, update the default data in priv */ | ||
3637 | if (pdata) { | ||
3638 | memcpy(&wm8962->pdata, pdata, sizeof(struct wm8962_pdata)); | ||
3639 | } else if (i2c->dev.of_node) { | ||
3640 | ret = wm8962_set_pdata_from_of(i2c, &wm8962->pdata); | ||
3641 | if (ret != 0) | ||
3642 | return ret; | ||
3643 | } | ||
3644 | |||
3608 | for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) | 3645 | for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) |
3609 | wm8962->supplies[i].supply = wm8962_supply_names[i]; | 3646 | wm8962->supplies[i].supply = wm8962_supply_names[i]; |
3610 | 3647 | ||
@@ -3668,7 +3705,7 @@ static int wm8962_i2c_probe(struct i2c_client *i2c, | |||
3668 | goto err_enable; | 3705 | goto err_enable; |
3669 | } | 3706 | } |
3670 | 3707 | ||
3671 | if (pdata && pdata->in4_dc_measure) { | 3708 | if (wm8962->pdata.in4_dc_measure) { |
3672 | ret = regmap_register_patch(wm8962->regmap, | 3709 | ret = regmap_register_patch(wm8962->regmap, |
3673 | wm8962_dc_measure, | 3710 | wm8962_dc_measure, |
3674 | ARRAY_SIZE(wm8962_dc_measure)); | 3711 | ARRAY_SIZE(wm8962_dc_measure)); |
@@ -3721,6 +3758,21 @@ static int wm8962_runtime_resume(struct device *dev) | |||
3721 | 3758 | ||
3722 | wm8962_reset(wm8962); | 3759 | wm8962_reset(wm8962); |
3723 | 3760 | ||
3761 | /* SYSCLK defaults to on; make sure it is off so we can safely | ||
3762 | * write to registers if the device is declocked. | ||
3763 | */ | ||
3764 | regmap_update_bits(wm8962->regmap, WM8962_CLOCKING2, | ||
3765 | WM8962_SYSCLK_ENA, 0); | ||
3766 | |||
3767 | /* Ensure we have soft control over all registers */ | ||
3768 | regmap_update_bits(wm8962->regmap, WM8962_CLOCKING2, | ||
3769 | WM8962_CLKREG_OVD, WM8962_CLKREG_OVD); | ||
3770 | |||
3771 | /* Ensure that the oscillator and PLLs are disabled */ | ||
3772 | regmap_update_bits(wm8962->regmap, WM8962_PLL2, | ||
3773 | WM8962_OSC_ENA | WM8962_PLL2_ENA | WM8962_PLL3_ENA, | ||
3774 | 0); | ||
3775 | |||
3724 | regcache_sync(wm8962->regmap); | 3776 | regcache_sync(wm8962->regmap); |
3725 | 3777 | ||
3726 | regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP, | 3778 | regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP, |