Loading asoc/codecs/wsa881x.c +87 −1 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #include <linux/module.h> Loading @@ -16,6 +16,7 @@ #include <linux/kernel.h> #include <linux/gpio.h> #include <linux/of_gpio.h> #include <linux/of_platform.h> #include <linux/regmap.h> #include <linux/debugfs.h> #include <soc/soundwire.h> Loading Loading @@ -101,6 +102,29 @@ struct wsa881x_priv { struct delayed_work ocp_ctl_work; struct device_node *wsa_rst_np; int pa_mute; struct device_node *bolero_np; struct platform_device* bolero_dev; struct notifier_block bolero_nblock; void *handle; int (*register_notifier)(void *handle, struct notifier_block *nblock, bool enable); }; /* from bolero to WSA events */ enum { BOLERO_WSA_EVT_TX_CH_HOLD_CLEAR = 1, BOLERO_WSA_EVT_PA_OFF_PRE_SSR, BOLERO_WSA_EVT_SSR_DOWN, BOLERO_WSA_EVT_SSR_UP, }; struct wsa_ctrl_platform_data { void *handle; int (*update_wsa_event)(void *handle, u16 event, u32 data); int (*register_notifier)(void *handle, struct notifier_block *nblock, bool enable); }; #define SWR_SLV_MAX_REG_ADDR 0x390 Loading Loading @@ -1338,12 +1362,39 @@ static int wsa881x_gpio_init(struct swr_device *pdev) return ret; } static int wsa881x_event_notify(struct notifier_block *nb, unsigned long val, void *ptr) { u16 event = (val & 0xffff); struct wsa881x_priv *wsa881x = container_of(nb, struct wsa881x_priv, bolero_nblock); if (!wsa881x) return -EINVAL; switch (event) { case BOLERO_WSA_EVT_PA_OFF_PRE_SSR: snd_soc_component_update_bits(wsa881x->component, WSA881X_SPKR_DRV_GAIN, 0xF0, 0xC0); snd_soc_component_update_bits(wsa881x->component, WSA881X_SPKR_DRV_EN, 0x80, 0x00); break; default: break; } return 0; } static int wsa881x_swr_probe(struct swr_device *pdev) { int ret = 0; struct wsa881x_priv *wsa881x; u8 devnum = 0; bool pin_state_current = false; struct wsa_ctrl_platform_data *plat_data = NULL; wsa881x = devm_kzalloc(&pdev->dev, sizeof(struct wsa881x_priv), GFP_KERNEL); Loading Loading @@ -1435,6 +1486,37 @@ static int wsa881x_swr_probe(struct swr_device *pdev) __func__); goto dev_err; } wsa881x->bolero_np = of_parse_phandle(pdev->dev.of_node, "qcom,bolero-handle", 0); if (wsa881x->bolero_np) { wsa881x->bolero_dev = of_find_device_by_node(wsa881x->bolero_np); if (wsa881x->bolero_dev) { plat_data = dev_get_platdata(&wsa881x->bolero_dev->dev); if (plat_data) { wsa881x->bolero_nblock.notifier_call = wsa881x_event_notify; if (plat_data->register_notifier) plat_data->register_notifier( plat_data->handle, &wsa881x->bolero_nblock, true); wsa881x->register_notifier = plat_data->register_notifier; wsa881x->handle = plat_data->handle; } else { dev_err(&pdev->dev, "%s: plat data not found\n", __func__); } } else { dev_err(&pdev->dev, "%s: bolero dev not found\n", __func__); } } else { dev_info(&pdev->dev, "%s: bolero node not found\n", __func__); } mutex_init(&wsa881x->res_lock); mutex_init(&wsa881x->temp_lock); Loading @@ -1457,6 +1539,10 @@ static int wsa881x_swr_remove(struct swr_device *pdev) dev_err(&pdev->dev, "%s: wsa881x is NULL\n", __func__); return -EINVAL; } if (wsa881x->register_notifier) wsa881x->register_notifier(wsa881x->handle, &wsa881x->bolero_nblock, false); debugfs_remove_recursive(debugfs_wsa881x_dent); debugfs_wsa881x_dent = NULL; mutex_destroy(&wsa881x->res_lock); Loading Loading
asoc/codecs/wsa881x.c +87 −1 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #include <linux/module.h> Loading @@ -16,6 +16,7 @@ #include <linux/kernel.h> #include <linux/gpio.h> #include <linux/of_gpio.h> #include <linux/of_platform.h> #include <linux/regmap.h> #include <linux/debugfs.h> #include <soc/soundwire.h> Loading Loading @@ -101,6 +102,29 @@ struct wsa881x_priv { struct delayed_work ocp_ctl_work; struct device_node *wsa_rst_np; int pa_mute; struct device_node *bolero_np; struct platform_device* bolero_dev; struct notifier_block bolero_nblock; void *handle; int (*register_notifier)(void *handle, struct notifier_block *nblock, bool enable); }; /* from bolero to WSA events */ enum { BOLERO_WSA_EVT_TX_CH_HOLD_CLEAR = 1, BOLERO_WSA_EVT_PA_OFF_PRE_SSR, BOLERO_WSA_EVT_SSR_DOWN, BOLERO_WSA_EVT_SSR_UP, }; struct wsa_ctrl_platform_data { void *handle; int (*update_wsa_event)(void *handle, u16 event, u32 data); int (*register_notifier)(void *handle, struct notifier_block *nblock, bool enable); }; #define SWR_SLV_MAX_REG_ADDR 0x390 Loading Loading @@ -1338,12 +1362,39 @@ static int wsa881x_gpio_init(struct swr_device *pdev) return ret; } static int wsa881x_event_notify(struct notifier_block *nb, unsigned long val, void *ptr) { u16 event = (val & 0xffff); struct wsa881x_priv *wsa881x = container_of(nb, struct wsa881x_priv, bolero_nblock); if (!wsa881x) return -EINVAL; switch (event) { case BOLERO_WSA_EVT_PA_OFF_PRE_SSR: snd_soc_component_update_bits(wsa881x->component, WSA881X_SPKR_DRV_GAIN, 0xF0, 0xC0); snd_soc_component_update_bits(wsa881x->component, WSA881X_SPKR_DRV_EN, 0x80, 0x00); break; default: break; } return 0; } static int wsa881x_swr_probe(struct swr_device *pdev) { int ret = 0; struct wsa881x_priv *wsa881x; u8 devnum = 0; bool pin_state_current = false; struct wsa_ctrl_platform_data *plat_data = NULL; wsa881x = devm_kzalloc(&pdev->dev, sizeof(struct wsa881x_priv), GFP_KERNEL); Loading Loading @@ -1435,6 +1486,37 @@ static int wsa881x_swr_probe(struct swr_device *pdev) __func__); goto dev_err; } wsa881x->bolero_np = of_parse_phandle(pdev->dev.of_node, "qcom,bolero-handle", 0); if (wsa881x->bolero_np) { wsa881x->bolero_dev = of_find_device_by_node(wsa881x->bolero_np); if (wsa881x->bolero_dev) { plat_data = dev_get_platdata(&wsa881x->bolero_dev->dev); if (plat_data) { wsa881x->bolero_nblock.notifier_call = wsa881x_event_notify; if (plat_data->register_notifier) plat_data->register_notifier( plat_data->handle, &wsa881x->bolero_nblock, true); wsa881x->register_notifier = plat_data->register_notifier; wsa881x->handle = plat_data->handle; } else { dev_err(&pdev->dev, "%s: plat data not found\n", __func__); } } else { dev_err(&pdev->dev, "%s: bolero dev not found\n", __func__); } } else { dev_info(&pdev->dev, "%s: bolero node not found\n", __func__); } mutex_init(&wsa881x->res_lock); mutex_init(&wsa881x->temp_lock); Loading @@ -1457,6 +1539,10 @@ static int wsa881x_swr_remove(struct swr_device *pdev) dev_err(&pdev->dev, "%s: wsa881x is NULL\n", __func__); return -EINVAL; } if (wsa881x->register_notifier) wsa881x->register_notifier(wsa881x->handle, &wsa881x->bolero_nblock, false); debugfs_remove_recursive(debugfs_wsa881x_dent); debugfs_wsa881x_dent = NULL; mutex_destroy(&wsa881x->res_lock); Loading