diff options
| -rw-r--r-- | sound/soc/codecs/wm8962.c | 218 |
1 files changed, 108 insertions, 110 deletions
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 11d80f3b6137..2bf9ee7c5407 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
| @@ -3242,7 +3242,7 @@ static void wm8962_free_beep(struct snd_soc_codec *codec) | |||
| 3242 | } | 3242 | } |
| 3243 | #endif | 3243 | #endif |
| 3244 | 3244 | ||
| 3245 | static void wm8962_set_gpio_mode(struct snd_soc_codec *codec, int gpio) | 3245 | static void wm8962_set_gpio_mode(struct wm8962_priv *wm8962, int gpio) |
| 3246 | { | 3246 | { |
| 3247 | int mask = 0; | 3247 | int mask = 0; |
| 3248 | int val = 0; | 3248 | int val = 0; |
| @@ -3263,8 +3263,8 @@ static void wm8962_set_gpio_mode(struct snd_soc_codec *codec, int gpio) | |||
| 3263 | } | 3263 | } |
| 3264 | 3264 | ||
| 3265 | if (mask) | 3265 | if (mask) |
| 3266 | snd_soc_update_bits(codec, WM8962_ANALOGUE_CLOCKING1, | 3266 | regmap_update_bits(wm8962->regmap, WM8962_ANALOGUE_CLOCKING1, |
| 3267 | mask, val); | 3267 | mask, val); |
| 3268 | } | 3268 | } |
| 3269 | 3269 | ||
| 3270 | #ifdef CONFIG_GPIOLIB | 3270 | #ifdef CONFIG_GPIOLIB |
| @@ -3276,7 +3276,6 @@ static inline struct wm8962_priv *gpio_to_wm8962(struct gpio_chip *chip) | |||
| 3276 | static int wm8962_gpio_request(struct gpio_chip *chip, unsigned offset) | 3276 | static int wm8962_gpio_request(struct gpio_chip *chip, unsigned offset) |
| 3277 | { | 3277 | { |
| 3278 | struct wm8962_priv *wm8962 = gpio_to_wm8962(chip); | 3278 | struct wm8962_priv *wm8962 = gpio_to_wm8962(chip); |
| 3279 | struct snd_soc_codec *codec = wm8962->codec; | ||
| 3280 | 3279 | ||
| 3281 | /* The WM8962 GPIOs aren't linearly numbered. For simplicity | 3280 | /* The WM8962 GPIOs aren't linearly numbered. For simplicity |
| 3282 | * we export linear numbers and error out if the unsupported | 3281 | * we export linear numbers and error out if the unsupported |
| @@ -3292,7 +3291,7 @@ static int wm8962_gpio_request(struct gpio_chip *chip, unsigned offset) | |||
| 3292 | return -EINVAL; | 3291 | return -EINVAL; |
| 3293 | } | 3292 | } |
| 3294 | 3293 | ||
| 3295 | wm8962_set_gpio_mode(codec, offset + 1); | 3294 | wm8962_set_gpio_mode(wm8962, offset + 1); |
| 3296 | 3295 | ||
| 3297 | return 0; | 3296 | return 0; |
| 3298 | } | 3297 | } |
| @@ -3376,8 +3375,7 @@ static int wm8962_probe(struct snd_soc_codec *codec) | |||
| 3376 | { | 3375 | { |
| 3377 | int ret; | 3376 | int ret; |
| 3378 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | 3377 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); |
| 3379 | struct wm8962_pdata *pdata = &wm8962->pdata; | 3378 | int i; |
| 3380 | int i, trigger, irq_pol; | ||
| 3381 | bool dmicclk, dmicdat; | 3379 | bool dmicclk, dmicdat; |
| 3382 | 3380 | ||
| 3383 | wm8962->codec = codec; | 3381 | wm8962->codec = codec; |
| @@ -3409,75 +3407,6 @@ static int wm8962_probe(struct snd_soc_codec *codec) | |||
| 3409 | } | 3407 | } |
| 3410 | } | 3408 | } |
| 3411 | 3409 | ||
| 3412 | /* SYSCLK defaults to on; make sure it is off so we can safely | ||
| 3413 | * write to registers if the device is declocked. | ||
| 3414 | */ | ||
| 3415 | snd_soc_update_bits(codec, WM8962_CLOCKING2, WM8962_SYSCLK_ENA, 0); | ||
| 3416 | |||
| 3417 | /* Ensure we have soft control over all registers */ | ||
| 3418 | snd_soc_update_bits(codec, WM8962_CLOCKING2, | ||
| 3419 | WM8962_CLKREG_OVD, WM8962_CLKREG_OVD); | ||
| 3420 | |||
| 3421 | /* Ensure that the oscillator and PLLs are disabled */ | ||
| 3422 | snd_soc_update_bits(codec, WM8962_PLL2, | ||
| 3423 | WM8962_OSC_ENA | WM8962_PLL2_ENA | WM8962_PLL3_ENA, | ||
| 3424 | 0); | ||
| 3425 | |||
| 3426 | /* Apply static configuration for GPIOs */ | ||
| 3427 | for (i = 0; i < ARRAY_SIZE(pdata->gpio_init); i++) | ||
| 3428 | if (pdata->gpio_init[i]) { | ||
| 3429 | wm8962_set_gpio_mode(codec, i + 1); | ||
| 3430 | snd_soc_write(codec, 0x200 + i, | ||
| 3431 | pdata->gpio_init[i] & 0xffff); | ||
| 3432 | } | ||
| 3433 | |||
| 3434 | |||
| 3435 | /* Put the speakers into mono mode? */ | ||
| 3436 | if (pdata->spk_mono) | ||
| 3437 | snd_soc_update_bits(codec, WM8962_CLASS_D_CONTROL_2, | ||
| 3438 | WM8962_SPK_MONO_MASK, WM8962_SPK_MONO); | ||
| 3439 | |||
| 3440 | /* Micbias setup, detection enable and detection | ||
| 3441 | * threasholds. */ | ||
| 3442 | if (pdata->mic_cfg) | ||
| 3443 | snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_4, | ||
| 3444 | WM8962_MICDET_ENA | | ||
| 3445 | WM8962_MICDET_THR_MASK | | ||
| 3446 | WM8962_MICSHORT_THR_MASK | | ||
| 3447 | WM8962_MICBIAS_LVL, | ||
| 3448 | pdata->mic_cfg); | ||
| 3449 | |||
| 3450 | /* Latch volume update bits */ | ||
| 3451 | snd_soc_update_bits(codec, WM8962_LEFT_INPUT_VOLUME, | ||
| 3452 | WM8962_IN_VU, WM8962_IN_VU); | ||
| 3453 | snd_soc_update_bits(codec, WM8962_RIGHT_INPUT_VOLUME, | ||
| 3454 | WM8962_IN_VU, WM8962_IN_VU); | ||
| 3455 | snd_soc_update_bits(codec, WM8962_LEFT_ADC_VOLUME, | ||
| 3456 | WM8962_ADC_VU, WM8962_ADC_VU); | ||
| 3457 | snd_soc_update_bits(codec, WM8962_RIGHT_ADC_VOLUME, | ||
| 3458 | WM8962_ADC_VU, WM8962_ADC_VU); | ||
| 3459 | snd_soc_update_bits(codec, WM8962_LEFT_DAC_VOLUME, | ||
| 3460 | WM8962_DAC_VU, WM8962_DAC_VU); | ||
| 3461 | snd_soc_update_bits(codec, WM8962_RIGHT_DAC_VOLUME, | ||
| 3462 | WM8962_DAC_VU, WM8962_DAC_VU); | ||
| 3463 | snd_soc_update_bits(codec, WM8962_SPKOUTL_VOLUME, | ||
| 3464 | WM8962_SPKOUT_VU, WM8962_SPKOUT_VU); | ||
| 3465 | snd_soc_update_bits(codec, WM8962_SPKOUTR_VOLUME, | ||
| 3466 | WM8962_SPKOUT_VU, WM8962_SPKOUT_VU); | ||
| 3467 | snd_soc_update_bits(codec, WM8962_HPOUTL_VOLUME, | ||
| 3468 | WM8962_HPOUT_VU, WM8962_HPOUT_VU); | ||
| 3469 | snd_soc_update_bits(codec, WM8962_HPOUTR_VOLUME, | ||
| 3470 | WM8962_HPOUT_VU, WM8962_HPOUT_VU); | ||
| 3471 | |||
| 3472 | /* Stereo control for EQ */ | ||
| 3473 | snd_soc_update_bits(codec, WM8962_EQ1, WM8962_EQ_SHARED_COEFF, 0); | ||
| 3474 | |||
| 3475 | /* Don't debouce interrupts so we don't need SYSCLK */ | ||
| 3476 | snd_soc_update_bits(codec, WM8962_IRQ_DEBOUNCE, | ||
| 3477 | WM8962_FLL_LOCK_DB | WM8962_PLL3_LOCK_DB | | ||
| 3478 | WM8962_PLL2_LOCK_DB | WM8962_TEMP_SHUT_DB, | ||
| 3479 | 0); | ||
| 3480 | |||
| 3481 | wm8962_add_widgets(codec); | 3410 | wm8962_add_widgets(codec); |
| 3482 | 3411 | ||
| 3483 | /* Save boards having to disable DMIC when not in use */ | 3412 | /* Save boards having to disable DMIC when not in use */ |
| @@ -3506,36 +3435,6 @@ static int wm8962_probe(struct snd_soc_codec *codec) | |||
| 3506 | wm8962_init_beep(codec); | 3435 | wm8962_init_beep(codec); |
| 3507 | wm8962_init_gpio(codec); | 3436 | wm8962_init_gpio(codec); |
| 3508 | 3437 | ||
| 3509 | if (wm8962->irq) { | ||
| 3510 | if (pdata->irq_active_low) { | ||
| 3511 | trigger = IRQF_TRIGGER_LOW; | ||
| 3512 | irq_pol = WM8962_IRQ_POL; | ||
| 3513 | } else { | ||
| 3514 | trigger = IRQF_TRIGGER_HIGH; | ||
| 3515 | irq_pol = 0; | ||
| 3516 | } | ||
| 3517 | |||
| 3518 | snd_soc_update_bits(codec, WM8962_INTERRUPT_CONTROL, | ||
| 3519 | WM8962_IRQ_POL, irq_pol); | ||
| 3520 | |||
| 3521 | ret = request_threaded_irq(wm8962->irq, NULL, wm8962_irq, | ||
| 3522 | trigger | IRQF_ONESHOT, | ||
| 3523 | "wm8962", codec->dev); | ||
| 3524 | if (ret != 0) { | ||
| 3525 | dev_err(codec->dev, "Failed to request IRQ %d: %d\n", | ||
| 3526 | wm8962->irq, ret); | ||
| 3527 | wm8962->irq = 0; | ||
| 3528 | /* Non-fatal */ | ||
| 3529 | } else { | ||
| 3530 | /* Enable some IRQs by default */ | ||
| 3531 | snd_soc_update_bits(codec, | ||
| 3532 | WM8962_INTERRUPT_STATUS_2_MASK, | ||
| 3533 | WM8962_FLL_LOCK_EINT | | ||
| 3534 | WM8962_TEMP_SHUT_EINT | | ||
| 3535 | WM8962_FIFOS_ERR_EINT, 0); | ||
| 3536 | } | ||
| 3537 | } | ||
| 3538 | |||
| 3539 | return 0; | 3438 | return 0; |
| 3540 | } | 3439 | } |
| 3541 | 3440 | ||
| @@ -3544,9 +3443,6 @@ static int wm8962_remove(struct snd_soc_codec *codec) | |||
| 3544 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | 3443 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); |
| 3545 | int i; | 3444 | int i; |
| 3546 | 3445 | ||
| 3547 | if (wm8962->irq) | ||
| 3548 | free_irq(wm8962->irq, codec); | ||
| 3549 | |||
| 3550 | cancel_delayed_work_sync(&wm8962->mic_work); | 3446 | cancel_delayed_work_sync(&wm8962->mic_work); |
| 3551 | 3447 | ||
| 3552 | wm8962_free_gpio(codec); | 3448 | wm8962_free_gpio(codec); |
| @@ -3619,7 +3515,7 @@ static int wm8962_i2c_probe(struct i2c_client *i2c, | |||
| 3619 | struct wm8962_pdata *pdata = dev_get_platdata(&i2c->dev); | 3515 | struct wm8962_pdata *pdata = dev_get_platdata(&i2c->dev); |
| 3620 | struct wm8962_priv *wm8962; | 3516 | struct wm8962_priv *wm8962; |
| 3621 | unsigned int reg; | 3517 | unsigned int reg; |
| 3622 | int ret, i; | 3518 | int ret, i, irq_pol, trigger; |
| 3623 | 3519 | ||
| 3624 | wm8962 = devm_kzalloc(&i2c->dev, sizeof(struct wm8962_priv), | 3520 | wm8962 = devm_kzalloc(&i2c->dev, sizeof(struct wm8962_priv), |
| 3625 | GFP_KERNEL); | 3521 | GFP_KERNEL); |
| @@ -3704,6 +3600,77 @@ static int wm8962_i2c_probe(struct i2c_client *i2c, | |||
| 3704 | goto err_enable; | 3600 | goto err_enable; |
| 3705 | } | 3601 | } |
| 3706 | 3602 | ||
| 3603 | /* SYSCLK defaults to on; make sure it is off so we can safely | ||
| 3604 | * write to registers if the device is declocked. | ||
| 3605 | */ | ||
| 3606 | regmap_update_bits(wm8962->regmap, WM8962_CLOCKING2, | ||
| 3607 | WM8962_SYSCLK_ENA, 0); | ||
| 3608 | |||
| 3609 | /* Ensure we have soft control over all registers */ | ||
| 3610 | regmap_update_bits(wm8962->regmap, WM8962_CLOCKING2, | ||
| 3611 | WM8962_CLKREG_OVD, WM8962_CLKREG_OVD); | ||
| 3612 | |||
| 3613 | /* Ensure that the oscillator and PLLs are disabled */ | ||
| 3614 | regmap_update_bits(wm8962->regmap, WM8962_PLL2, | ||
| 3615 | WM8962_OSC_ENA | WM8962_PLL2_ENA | WM8962_PLL3_ENA, | ||
| 3616 | 0); | ||
| 3617 | |||
| 3618 | /* Apply static configuration for GPIOs */ | ||
| 3619 | for (i = 0; i < ARRAY_SIZE(pdata->gpio_init); i++) | ||
| 3620 | if (pdata->gpio_init[i]) { | ||
| 3621 | wm8962_set_gpio_mode(wm8962, i + 1); | ||
| 3622 | regmap_write(wm8962->regmap, 0x200 + i, | ||
| 3623 | pdata->gpio_init[i] & 0xffff); | ||
| 3624 | } | ||
| 3625 | |||
| 3626 | |||
| 3627 | /* Put the speakers into mono mode? */ | ||
| 3628 | if (pdata->spk_mono) | ||
| 3629 | regmap_update_bits(wm8962->regmap, WM8962_CLASS_D_CONTROL_2, | ||
| 3630 | WM8962_SPK_MONO_MASK, WM8962_SPK_MONO); | ||
| 3631 | |||
| 3632 | /* Micbias setup, detection enable and detection | ||
| 3633 | * threasholds. */ | ||
| 3634 | if (pdata->mic_cfg) | ||
| 3635 | regmap_update_bits(wm8962->regmap, WM8962_ADDITIONAL_CONTROL_4, | ||
| 3636 | WM8962_MICDET_ENA | | ||
| 3637 | WM8962_MICDET_THR_MASK | | ||
| 3638 | WM8962_MICSHORT_THR_MASK | | ||
| 3639 | WM8962_MICBIAS_LVL, | ||
| 3640 | pdata->mic_cfg); | ||
| 3641 | |||
| 3642 | /* Latch volume update bits */ | ||
| 3643 | regmap_update_bits(wm8962->regmap, WM8962_LEFT_INPUT_VOLUME, | ||
| 3644 | WM8962_IN_VU, WM8962_IN_VU); | ||
| 3645 | regmap_update_bits(wm8962->regmap, WM8962_RIGHT_INPUT_VOLUME, | ||
| 3646 | WM8962_IN_VU, WM8962_IN_VU); | ||
| 3647 | regmap_update_bits(wm8962->regmap, WM8962_LEFT_ADC_VOLUME, | ||
| 3648 | WM8962_ADC_VU, WM8962_ADC_VU); | ||
| 3649 | regmap_update_bits(wm8962->regmap, WM8962_RIGHT_ADC_VOLUME, | ||
| 3650 | WM8962_ADC_VU, WM8962_ADC_VU); | ||
| 3651 | regmap_update_bits(wm8962->regmap, WM8962_LEFT_DAC_VOLUME, | ||
| 3652 | WM8962_DAC_VU, WM8962_DAC_VU); | ||
| 3653 | regmap_update_bits(wm8962->regmap, WM8962_RIGHT_DAC_VOLUME, | ||
| 3654 | WM8962_DAC_VU, WM8962_DAC_VU); | ||
| 3655 | regmap_update_bits(wm8962->regmap, WM8962_SPKOUTL_VOLUME, | ||
| 3656 | WM8962_SPKOUT_VU, WM8962_SPKOUT_VU); | ||
| 3657 | regmap_update_bits(wm8962->regmap, WM8962_SPKOUTR_VOLUME, | ||
| 3658 | WM8962_SPKOUT_VU, WM8962_SPKOUT_VU); | ||
| 3659 | regmap_update_bits(wm8962->regmap, WM8962_HPOUTL_VOLUME, | ||
| 3660 | WM8962_HPOUT_VU, WM8962_HPOUT_VU); | ||
| 3661 | regmap_update_bits(wm8962->regmap, WM8962_HPOUTR_VOLUME, | ||
| 3662 | WM8962_HPOUT_VU, WM8962_HPOUT_VU); | ||
| 3663 | |||
| 3664 | /* Stereo control for EQ */ | ||
| 3665 | regmap_update_bits(wm8962->regmap, WM8962_EQ1, | ||
| 3666 | WM8962_EQ_SHARED_COEFF, 0); | ||
| 3667 | |||
| 3668 | /* Don't debouce interrupts so we don't need SYSCLK */ | ||
| 3669 | regmap_update_bits(wm8962->regmap, WM8962_IRQ_DEBOUNCE, | ||
| 3670 | WM8962_FLL_LOCK_DB | WM8962_PLL3_LOCK_DB | | ||
| 3671 | WM8962_PLL2_LOCK_DB | WM8962_TEMP_SHUT_DB, | ||
| 3672 | 0); | ||
| 3673 | |||
| 3707 | if (wm8962->pdata.in4_dc_measure) { | 3674 | if (wm8962->pdata.in4_dc_measure) { |
| 3708 | ret = regmap_register_patch(wm8962->regmap, | 3675 | ret = regmap_register_patch(wm8962->regmap, |
| 3709 | wm8962_dc_measure, | 3676 | wm8962_dc_measure, |
| @@ -3714,6 +3681,37 @@ static int wm8962_i2c_probe(struct i2c_client *i2c, | |||
| 3714 | ret); | 3681 | ret); |
| 3715 | } | 3682 | } |
| 3716 | 3683 | ||
| 3684 | if (wm8962->irq) { | ||
| 3685 | if (pdata->irq_active_low) { | ||
| 3686 | trigger = IRQF_TRIGGER_LOW; | ||
| 3687 | irq_pol = WM8962_IRQ_POL; | ||
| 3688 | } else { | ||
| 3689 | trigger = IRQF_TRIGGER_HIGH; | ||
| 3690 | irq_pol = 0; | ||
| 3691 | } | ||
| 3692 | |||
| 3693 | regmap_update_bits(wm8962->regmap, WM8962_INTERRUPT_CONTROL, | ||
| 3694 | WM8962_IRQ_POL, irq_pol); | ||
| 3695 | |||
| 3696 | ret = devm_request_threaded_irq(&i2c->dev, wm8962->irq, NULL, | ||
| 3697 | wm8962_irq, | ||
| 3698 | trigger | IRQF_ONESHOT, | ||
| 3699 | "wm8962", &i2c->dev); | ||
| 3700 | if (ret != 0) { | ||
| 3701 | dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n", | ||
| 3702 | wm8962->irq, ret); | ||
| 3703 | wm8962->irq = 0; | ||
| 3704 | /* Non-fatal */ | ||
| 3705 | } else { | ||
| 3706 | /* Enable some IRQs by default */ | ||
| 3707 | regmap_update_bits(wm8962->regmap, | ||
| 3708 | WM8962_INTERRUPT_STATUS_2_MASK, | ||
| 3709 | WM8962_FLL_LOCK_EINT | | ||
| 3710 | WM8962_TEMP_SHUT_EINT | | ||
| 3711 | WM8962_FIFOS_ERR_EINT, 0); | ||
| 3712 | } | ||
| 3713 | } | ||
| 3714 | |||
| 3717 | pm_runtime_enable(&i2c->dev); | 3715 | pm_runtime_enable(&i2c->dev); |
| 3718 | pm_request_idle(&i2c->dev); | 3716 | pm_request_idle(&i2c->dev); |
| 3719 | 3717 | ||
