Loading asoc/codecs/wsa881x-temp-sensor.c +46 −1 Original line number Diff line number Diff line /* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. /* Copyright (c) 2015, 2017-2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -12,6 +12,7 @@ #include <linux/bitops.h> #include <linux/kernel.h> #include <linux/suspend.h> #include <linux/errno.h> #include <linux/delay.h> #include <linux/thermal.h> Loading Loading @@ -61,6 +62,20 @@ int wsa881x_get_temp(struct thermal_zone_device *thermal, pr_err("%s: pdata is NULL\n", __func__); return -EINVAL; } if (atomic_cmpxchg(&pdata->is_suspend_spk, 1, 0)) { /* * get_temp query happens as part of POST_PM_SUSPEND * from thermal core. To avoid calls to slimbus * as part of this thermal query, return default temp * and reset the suspend flag. */ if (!pdata->t0_init) { if (temp) *temp = pdata->curr_temp; return 0; } } temp_retry: if (pdata->wsa_temp_reg_read) { ret = pdata->wsa_temp_reg_read(codec, ®); Loading Loading @@ -108,6 +123,8 @@ int wsa881x_get_temp(struct thermal_zone_device *thermal, goto temp_retry; } } pdata->curr_temp = temp_val; if (temp) *temp = temp_val; pr_debug("%s: t0 measured: %d dmeas = %d, d1 = %d, d2 = %d\n", Loading @@ -120,6 +137,23 @@ static struct thermal_zone_device_ops wsa881x_thermal_ops = { .get_temp = wsa881x_get_temp, }; static int wsa881x_pm_notify(struct notifier_block *nb, unsigned long mode, void *_unused) { struct wsa881x_tz_priv *pdata = container_of(nb, struct wsa881x_tz_priv, pm_nb); switch (mode) { case PM_SUSPEND_PREPARE: atomic_set(&pdata->is_suspend_spk, 1); break; default: break; } return 0; } int wsa881x_init_thermal(struct wsa881x_tz_priv *tz_pdata) { struct thermal_zone_device *tz_dev; Loading @@ -137,12 +171,23 @@ int wsa881x_init_thermal(struct wsa881x_tz_priv *tz_pdata) return -EINVAL; } tz_pdata->tz_dev = tz_dev; tz_pdata->pm_nb.notifier_call = wsa881x_pm_notify; register_pm_notifier(&tz_pdata->pm_nb); atomic_set(&tz_pdata->is_suspend_spk, 0); return 0; } EXPORT_SYMBOL(wsa881x_init_thermal); void wsa881x_deinit_thermal(struct thermal_zone_device *tz_dev) { struct wsa881x_tz_priv *pdata; if (tz_dev && tz_dev->devdata) { pdata = tz_dev->devdata; if (pdata) unregister_pm_notifier(&pdata->pm_nb); } if (tz_dev) thermal_zone_device_unregister(tz_dev); } Loading asoc/codecs/wsa881x-temp-sensor.h +5 −1 Original line number Diff line number Diff line /* Copyright (c) 2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -31,6 +31,10 @@ struct wsa881x_tz_priv { struct wsa_temp_register *wsa_temp_reg; char name[80]; wsa_temp_register_read wsa_temp_reg_read; struct notifier_block pm_nb; atomic_t is_suspend_spk; int t0_init; int curr_temp; }; int wsa881x_get_temp(struct thermal_zone_device *tz_dev, int *temp); Loading asoc/codecs/wsa881x.c +28 −0 Original line number Diff line number Diff line Loading @@ -200,12 +200,40 @@ static int wsa881x_set_mute(struct snd_kcontrol *kcontrol, return 0; } static int wsa881x_get_t0_init(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); struct wsa881x_tz_priv *pdata = &wsa881x->tz_pdata; ucontrol->value.integer.value[0] = pdata->t0_init; dev_dbg(codec->dev, "%s: t0 init %d\n", __func__, pdata->t0_init); return 0; } static int wsa881x_set_t0_init(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); struct wsa881x_tz_priv *pdata = &wsa881x->tz_pdata; pdata->t0_init = ucontrol->value.integer.value[0]; dev_dbg(codec->dev, "%s: t0 init %d\n", __func__, pdata->t0_init); return 0; } static const struct snd_kcontrol_new wsa_snd_controls[] = { SOC_ENUM_EXT("WSA PA Gain", wsa_pa_gain_enum, wsa_pa_gain_get, wsa_pa_gain_put), SOC_SINGLE_EXT("WSA PA Mute", SND_SOC_NOPM, 0, 1, 0, wsa881x_get_mute, wsa881x_set_mute), SOC_SINGLE_EXT("WSA T0 Init", SND_SOC_NOPM, 0, 1, 0, wsa881x_get_t0_init, wsa881x_set_t0_init), }; static int codec_debug_open(struct inode *inode, struct file *file) Loading Loading
asoc/codecs/wsa881x-temp-sensor.c +46 −1 Original line number Diff line number Diff line /* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. /* Copyright (c) 2015, 2017-2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -12,6 +12,7 @@ #include <linux/bitops.h> #include <linux/kernel.h> #include <linux/suspend.h> #include <linux/errno.h> #include <linux/delay.h> #include <linux/thermal.h> Loading Loading @@ -61,6 +62,20 @@ int wsa881x_get_temp(struct thermal_zone_device *thermal, pr_err("%s: pdata is NULL\n", __func__); return -EINVAL; } if (atomic_cmpxchg(&pdata->is_suspend_spk, 1, 0)) { /* * get_temp query happens as part of POST_PM_SUSPEND * from thermal core. To avoid calls to slimbus * as part of this thermal query, return default temp * and reset the suspend flag. */ if (!pdata->t0_init) { if (temp) *temp = pdata->curr_temp; return 0; } } temp_retry: if (pdata->wsa_temp_reg_read) { ret = pdata->wsa_temp_reg_read(codec, ®); Loading Loading @@ -108,6 +123,8 @@ int wsa881x_get_temp(struct thermal_zone_device *thermal, goto temp_retry; } } pdata->curr_temp = temp_val; if (temp) *temp = temp_val; pr_debug("%s: t0 measured: %d dmeas = %d, d1 = %d, d2 = %d\n", Loading @@ -120,6 +137,23 @@ static struct thermal_zone_device_ops wsa881x_thermal_ops = { .get_temp = wsa881x_get_temp, }; static int wsa881x_pm_notify(struct notifier_block *nb, unsigned long mode, void *_unused) { struct wsa881x_tz_priv *pdata = container_of(nb, struct wsa881x_tz_priv, pm_nb); switch (mode) { case PM_SUSPEND_PREPARE: atomic_set(&pdata->is_suspend_spk, 1); break; default: break; } return 0; } int wsa881x_init_thermal(struct wsa881x_tz_priv *tz_pdata) { struct thermal_zone_device *tz_dev; Loading @@ -137,12 +171,23 @@ int wsa881x_init_thermal(struct wsa881x_tz_priv *tz_pdata) return -EINVAL; } tz_pdata->tz_dev = tz_dev; tz_pdata->pm_nb.notifier_call = wsa881x_pm_notify; register_pm_notifier(&tz_pdata->pm_nb); atomic_set(&tz_pdata->is_suspend_spk, 0); return 0; } EXPORT_SYMBOL(wsa881x_init_thermal); void wsa881x_deinit_thermal(struct thermal_zone_device *tz_dev) { struct wsa881x_tz_priv *pdata; if (tz_dev && tz_dev->devdata) { pdata = tz_dev->devdata; if (pdata) unregister_pm_notifier(&pdata->pm_nb); } if (tz_dev) thermal_zone_device_unregister(tz_dev); } Loading
asoc/codecs/wsa881x-temp-sensor.h +5 −1 Original line number Diff line number Diff line /* Copyright (c) 2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -31,6 +31,10 @@ struct wsa881x_tz_priv { struct wsa_temp_register *wsa_temp_reg; char name[80]; wsa_temp_register_read wsa_temp_reg_read; struct notifier_block pm_nb; atomic_t is_suspend_spk; int t0_init; int curr_temp; }; int wsa881x_get_temp(struct thermal_zone_device *tz_dev, int *temp); Loading
asoc/codecs/wsa881x.c +28 −0 Original line number Diff line number Diff line Loading @@ -200,12 +200,40 @@ static int wsa881x_set_mute(struct snd_kcontrol *kcontrol, return 0; } static int wsa881x_get_t0_init(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); struct wsa881x_tz_priv *pdata = &wsa881x->tz_pdata; ucontrol->value.integer.value[0] = pdata->t0_init; dev_dbg(codec->dev, "%s: t0 init %d\n", __func__, pdata->t0_init); return 0; } static int wsa881x_set_t0_init(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); struct wsa881x_tz_priv *pdata = &wsa881x->tz_pdata; pdata->t0_init = ucontrol->value.integer.value[0]; dev_dbg(codec->dev, "%s: t0 init %d\n", __func__, pdata->t0_init); return 0; } static const struct snd_kcontrol_new wsa_snd_controls[] = { SOC_ENUM_EXT("WSA PA Gain", wsa_pa_gain_enum, wsa_pa_gain_get, wsa_pa_gain_put), SOC_SINGLE_EXT("WSA PA Mute", SND_SOC_NOPM, 0, 1, 0, wsa881x_get_mute, wsa881x_set_mute), SOC_SINGLE_EXT("WSA T0 Init", SND_SOC_NOPM, 0, 1, 0, wsa881x_get_t0_init, wsa881x_set_t0_init), }; static int codec_debug_open(struct inode *inode, struct file *file) Loading