Loading sound/soc/codecs/wcd9306.c +57 −25 Original line number Diff line number Diff line Loading @@ -153,6 +153,13 @@ static struct afe_param_id_cdc_aanc_version tapan_cdc_aanc_version = { .aanc_hw_version = AANC_HW_BLOCK_VERSION_2, }; enum tapan_codec_type { WCD9306, WCD9302, }; static enum tapan_codec_type codec_ver; enum { AIF1_PB = 0, AIF1_CAP, Loading Loading @@ -5455,7 +5462,25 @@ static void tapan_enable_config_rco(struct wcd9xxx *core, bool enable) struct wcd9xxx_core_resource *core_res = &core->core_res; if (enable) { /* Enable RC Oscillator */ /* * Enable Bandgap * sleep required by codec hardware to enable bandgap */ wcd9xxx_reg_update(core, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x80, 0x80); wcd9xxx_reg_update(core, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x04, 0x04); wcd9xxx_reg_update(core, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x01, 0x01); usleep_range(1000, 1100); wcd9xxx_reg_update(core, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x80, 0x00); /* * Enable RC Oscillator * Add sleep required by codec hardware after each register * write to enable RC oscillator */ wcd9xxx_reg_update(core, WCD9XXX_A_RC_OSC_FREQ, 0x10, 0x00); wcd9xxx_reg_write(core_res, WCD9XXX_A_BIAS_OSC_BG_CTL, 0x17); usleep_range(5, 5); Loading @@ -5481,29 +5506,39 @@ static void tapan_enable_config_rco(struct wcd9xxx *core, bool enable) /* * Disable RC oscillator, reset the registers to their * default values * Add sleep required by codec hardware after each register * write to disable RC oscillator */ wcd9xxx_reg_write(core_res, WCD9XXX_A_CDC_CLK_MCLK_CTL, 0x00); wcd9xxx_reg_write(core_res, WCD9XXX_A_CLK_BUFF_EN2, 0x02); wcd9xxx_reg_write(core_res, WCD9XXX_A_CLK_BUFF_EN1, 0x04); wcd9xxx_reg_write(core_res, WCD9XXX_A_RC_OSC_TEST, 0x0A); wcd9xxx_reg_write(core_res, WCD9XXX_A_RC_OSC_FREQ, 0x46); wcd9xxx_reg_update(core, WCD9XXX_A_CLK_BUFF_EN2, 0x04, 0x00); usleep_range(50, 100); wcd9xxx_reg_update(core, WCD9XXX_A_CLK_BUFF_EN2, 0x02, 0x02); wcd9xxx_reg_update(core, WCD9XXX_A_CLK_BUFF_EN1, 0x05, 0x00); usleep_range(50, 100); wcd9xxx_reg_update(core, WCD9XXX_A_RC_OSC_FREQ, 0x80, 0x00); usleep_range(10, 50); wcd9xxx_reg_write(core_res, WCD9XXX_A_BIAS_OSC_BG_CTL, 0x16); /* Disable Bandgap and wait 100us till it gets disabled */ wcd9xxx_reg_update(core, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x03, 0x00); usleep_range(100, 150); } } static bool tapan_check_wcd9306(struct device *cdc_dev, bool sensed) static enum tapan_codec_type tapan_get_codec_ver(struct device *cdc_dev, bool sensed) { struct wcd9xxx *core = dev_get_drvdata(cdc_dev->parent); u8 reg_val; bool ret = true; enum tapan_codec_type cdc_type = WCD9306; unsigned long timeout; bool timedout; struct wcd9xxx_core_resource *core_res = &core->core_res; if (!core) { dev_err(cdc_dev, "%s: core not initialized\n", __func__); return -EINVAL; return cdc_type; } tapan_enable_config_rco(core, 1); Loading @@ -5523,12 +5558,13 @@ static bool tapan_check_wcd9306(struct device *cdc_dev, bool sensed) if (wcd9xxx_reg_read(core_res, TAPAN_A_QFUSE_DATA_OUT1) || wcd9xxx_reg_read(core_res, TAPAN_A_QFUSE_DATA_OUT2)) { dev_info(cdc_dev, "%s: wcd9302 detected\n", __func__); ret = false; cdc_type = WCD9302; } else dev_info(cdc_dev, "%s: wcd9306 detected\n", __func__); tapan_enable_config_rco(core, 0); return ret; return cdc_type; }; static int tapan_codec_probe(struct snd_soc_codec *codec) Loading Loading @@ -5653,7 +5689,7 @@ static int tapan_codec_probe(struct snd_soc_codec *codec) tapan_init_slim_slave_cfg(codec); } if (tapan_check_wcd9306(codec->dev, false) == true) { if (codec_ver == WCD9306) { snd_soc_add_codec_controls(codec, tapan_9306_snd_controls, ARRAY_SIZE(tapan_9306_snd_controls)); snd_soc_dapm_new_controls(dapm, tapan_9306_dapm_widgets, Loading @@ -5678,11 +5714,13 @@ static int tapan_codec_probe(struct snd_soc_codec *codec) atomic_set(&kp_tapan_priv, (unsigned long)tapan); mutex_lock(&dapm->codec->mutex); if (codec_ver == WCD9306) { snd_soc_dapm_disable_pin(dapm, "ANC HPHL"); snd_soc_dapm_disable_pin(dapm, "ANC HPHR"); snd_soc_dapm_disable_pin(dapm, "ANC HEADPHONE"); snd_soc_dapm_disable_pin(dapm, "ANC EAR PA"); snd_soc_dapm_disable_pin(dapm, "ANC EAR"); } snd_soc_dapm_sync(dapm); mutex_unlock(&dapm->codec->mutex); Loading Loading @@ -5775,16 +5813,10 @@ static const struct dev_pm_ops tapan_pm_ops = { static int tapan_probe(struct platform_device *pdev) { int ret = 0; bool is_wcd9306; is_wcd9306 = tapan_check_wcd9306(&pdev->dev, false); if (is_wcd9306 < 0) { dev_info(&pdev->dev, "%s: cannot find codec type, default to 9306\n", __func__); is_wcd9306 = true; } codec_ver = tapan_get_codec_ver(&pdev->dev, false); if (!is_wcd9306) { if (codec_ver == WCD9302) { if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS) ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tapan, Loading Loading
sound/soc/codecs/wcd9306.c +57 −25 Original line number Diff line number Diff line Loading @@ -153,6 +153,13 @@ static struct afe_param_id_cdc_aanc_version tapan_cdc_aanc_version = { .aanc_hw_version = AANC_HW_BLOCK_VERSION_2, }; enum tapan_codec_type { WCD9306, WCD9302, }; static enum tapan_codec_type codec_ver; enum { AIF1_PB = 0, AIF1_CAP, Loading Loading @@ -5455,7 +5462,25 @@ static void tapan_enable_config_rco(struct wcd9xxx *core, bool enable) struct wcd9xxx_core_resource *core_res = &core->core_res; if (enable) { /* Enable RC Oscillator */ /* * Enable Bandgap * sleep required by codec hardware to enable bandgap */ wcd9xxx_reg_update(core, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x80, 0x80); wcd9xxx_reg_update(core, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x04, 0x04); wcd9xxx_reg_update(core, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x01, 0x01); usleep_range(1000, 1100); wcd9xxx_reg_update(core, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x80, 0x00); /* * Enable RC Oscillator * Add sleep required by codec hardware after each register * write to enable RC oscillator */ wcd9xxx_reg_update(core, WCD9XXX_A_RC_OSC_FREQ, 0x10, 0x00); wcd9xxx_reg_write(core_res, WCD9XXX_A_BIAS_OSC_BG_CTL, 0x17); usleep_range(5, 5); Loading @@ -5481,29 +5506,39 @@ static void tapan_enable_config_rco(struct wcd9xxx *core, bool enable) /* * Disable RC oscillator, reset the registers to their * default values * Add sleep required by codec hardware after each register * write to disable RC oscillator */ wcd9xxx_reg_write(core_res, WCD9XXX_A_CDC_CLK_MCLK_CTL, 0x00); wcd9xxx_reg_write(core_res, WCD9XXX_A_CLK_BUFF_EN2, 0x02); wcd9xxx_reg_write(core_res, WCD9XXX_A_CLK_BUFF_EN1, 0x04); wcd9xxx_reg_write(core_res, WCD9XXX_A_RC_OSC_TEST, 0x0A); wcd9xxx_reg_write(core_res, WCD9XXX_A_RC_OSC_FREQ, 0x46); wcd9xxx_reg_update(core, WCD9XXX_A_CLK_BUFF_EN2, 0x04, 0x00); usleep_range(50, 100); wcd9xxx_reg_update(core, WCD9XXX_A_CLK_BUFF_EN2, 0x02, 0x02); wcd9xxx_reg_update(core, WCD9XXX_A_CLK_BUFF_EN1, 0x05, 0x00); usleep_range(50, 100); wcd9xxx_reg_update(core, WCD9XXX_A_RC_OSC_FREQ, 0x80, 0x00); usleep_range(10, 50); wcd9xxx_reg_write(core_res, WCD9XXX_A_BIAS_OSC_BG_CTL, 0x16); /* Disable Bandgap and wait 100us till it gets disabled */ wcd9xxx_reg_update(core, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x03, 0x00); usleep_range(100, 150); } } static bool tapan_check_wcd9306(struct device *cdc_dev, bool sensed) static enum tapan_codec_type tapan_get_codec_ver(struct device *cdc_dev, bool sensed) { struct wcd9xxx *core = dev_get_drvdata(cdc_dev->parent); u8 reg_val; bool ret = true; enum tapan_codec_type cdc_type = WCD9306; unsigned long timeout; bool timedout; struct wcd9xxx_core_resource *core_res = &core->core_res; if (!core) { dev_err(cdc_dev, "%s: core not initialized\n", __func__); return -EINVAL; return cdc_type; } tapan_enable_config_rco(core, 1); Loading @@ -5523,12 +5558,13 @@ static bool tapan_check_wcd9306(struct device *cdc_dev, bool sensed) if (wcd9xxx_reg_read(core_res, TAPAN_A_QFUSE_DATA_OUT1) || wcd9xxx_reg_read(core_res, TAPAN_A_QFUSE_DATA_OUT2)) { dev_info(cdc_dev, "%s: wcd9302 detected\n", __func__); ret = false; cdc_type = WCD9302; } else dev_info(cdc_dev, "%s: wcd9306 detected\n", __func__); tapan_enable_config_rco(core, 0); return ret; return cdc_type; }; static int tapan_codec_probe(struct snd_soc_codec *codec) Loading Loading @@ -5653,7 +5689,7 @@ static int tapan_codec_probe(struct snd_soc_codec *codec) tapan_init_slim_slave_cfg(codec); } if (tapan_check_wcd9306(codec->dev, false) == true) { if (codec_ver == WCD9306) { snd_soc_add_codec_controls(codec, tapan_9306_snd_controls, ARRAY_SIZE(tapan_9306_snd_controls)); snd_soc_dapm_new_controls(dapm, tapan_9306_dapm_widgets, Loading @@ -5678,11 +5714,13 @@ static int tapan_codec_probe(struct snd_soc_codec *codec) atomic_set(&kp_tapan_priv, (unsigned long)tapan); mutex_lock(&dapm->codec->mutex); if (codec_ver == WCD9306) { snd_soc_dapm_disable_pin(dapm, "ANC HPHL"); snd_soc_dapm_disable_pin(dapm, "ANC HPHR"); snd_soc_dapm_disable_pin(dapm, "ANC HEADPHONE"); snd_soc_dapm_disable_pin(dapm, "ANC EAR PA"); snd_soc_dapm_disable_pin(dapm, "ANC EAR"); } snd_soc_dapm_sync(dapm); mutex_unlock(&dapm->codec->mutex); Loading Loading @@ -5775,16 +5813,10 @@ static const struct dev_pm_ops tapan_pm_ops = { static int tapan_probe(struct platform_device *pdev) { int ret = 0; bool is_wcd9306; is_wcd9306 = tapan_check_wcd9306(&pdev->dev, false); if (is_wcd9306 < 0) { dev_info(&pdev->dev, "%s: cannot find codec type, default to 9306\n", __func__); is_wcd9306 = true; } codec_ver = tapan_get_codec_ver(&pdev->dev, false); if (!is_wcd9306) { if (codec_ver == WCD9302) { if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS) ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tapan, Loading