Merge branches 'audio' and 'mic' into combined
This commit is contained in:
commit
2aef34e14a
6 changed files with 243 additions and 2 deletions
|
|
@ -216,7 +216,6 @@
|
|||
pinctrl-names = "default",
|
||||
"sleep";
|
||||
|
||||
/*
|
||||
i2s-dai-link {
|
||||
link-name = "Senary MI2S Playback";
|
||||
|
||||
|
|
@ -232,7 +231,6 @@
|
|||
sound-dai = <&q6apm>;
|
||||
};
|
||||
};
|
||||
*/
|
||||
};
|
||||
|
||||
thermal-zones {
|
||||
|
|
@ -1105,6 +1103,26 @@
|
|||
};
|
||||
};
|
||||
|
||||
&swr1 {
|
||||
status = "okay";
|
||||
|
||||
/* WCD9378 RX */
|
||||
wcd9378_rx: codec@0,4 {
|
||||
compatible = "sdw20217011000";
|
||||
reg = <0 4>;
|
||||
};
|
||||
};
|
||||
|
||||
&swr2 {
|
||||
status = "okay";
|
||||
|
||||
/* WCD9378 TX */
|
||||
wcd9378_tx: codec@0,3 {
|
||||
compatible = "sdw20217011000";
|
||||
reg = <0 3>;
|
||||
};
|
||||
};
|
||||
|
||||
&tlmm {
|
||||
gpio-reserved-ranges = <8 4>, /* Fingerprint SPI */
|
||||
<13 1>, /* NC */
|
||||
|
|
|
|||
|
|
@ -976,6 +976,20 @@ static enum sdw_command_response qcom_swrm_xfer_msg(struct sdw_bus *bus,
|
|||
struct qcom_swrm_ctrl *ctrl = to_qcom_sdw(bus);
|
||||
int ret, i, len;
|
||||
|
||||
if (msg->page) {
|
||||
ret = qcom_swrm_cmd_fifo_wr_cmd(ctrl, msg->addr_page1,
|
||||
msg->dev_num,
|
||||
SDW_SCP_ADDRPAGE1);
|
||||
if (ret)
|
||||
return SDW_CMD_IGNORED;
|
||||
|
||||
ret = qcom_swrm_cmd_fifo_wr_cmd(ctrl, msg->addr_page2,
|
||||
msg->dev_num,
|
||||
SDW_SCP_ADDRPAGE2);
|
||||
if (ret)
|
||||
return SDW_CMD_IGNORED;
|
||||
}
|
||||
|
||||
if (msg->flags == SDW_MSG_FLAG_READ) {
|
||||
for (i = 0; i < msg->len;) {
|
||||
len = min(msg->len - i, QCOM_SWRM_MAX_RD_LEN);
|
||||
|
|
|
|||
|
|
@ -2431,6 +2431,15 @@ config SND_SOC_WCD937X_SDW
|
|||
via soundwire.
|
||||
To compile this codec driver say Y or m.
|
||||
|
||||
config SND_SOC_WCD9378_SDW
|
||||
tristate "WCD9378 Codec - SDW (bring-up skeleton)"
|
||||
depends on SOUNDWIRE
|
||||
select REGMAP_SOUNDWIRE
|
||||
help
|
||||
Bring-up skeleton driver for the Qualcomm WCD9378 audio codec
|
||||
connected via SoundWire, as found on SM7635 phones.
|
||||
To compile this codec driver say Y or m.
|
||||
|
||||
config SND_SOC_WCD938X
|
||||
depends on SND_SOC_WCD938X_SDW
|
||||
tristate
|
||||
|
|
|
|||
|
|
@ -356,6 +356,7 @@ snd-soc-wcd9335-y := wcd9335.o
|
|||
snd-soc-wcd934x-y := wcd934x.o
|
||||
snd-soc-wcd937x-y := wcd937x.o
|
||||
snd-soc-wcd937x-sdw-y := wcd937x-sdw.o
|
||||
snd-soc-wcd9378-sdw-y := wcd9378-sdw.o
|
||||
snd-soc-wcd938x-y := wcd938x.o
|
||||
snd-soc-wcd938x-sdw-y := wcd938x-sdw.o
|
||||
snd-soc-wcd939x-y := wcd939x.o
|
||||
|
|
@ -796,6 +797,7 @@ ifdef CONFIG_SND_SOC_WCD937X_SDW
|
|||
# avoid link failure by forcing sdw code built-in when needed
|
||||
obj-$(CONFIG_SND_SOC_WCD937X) += snd-soc-wcd937x-sdw.o
|
||||
endif
|
||||
obj-$(CONFIG_SND_SOC_WCD9378_SDW) += snd-soc-wcd9378-sdw.o
|
||||
obj-$(CONFIG_SND_SOC_WCD938X) += snd-soc-wcd938x.o
|
||||
ifdef CONFIG_SND_SOC_WCD938X_SDW
|
||||
# avoid link failure by forcing sdw code built-in when needed
|
||||
|
|
|
|||
135
sound/soc/codecs/wcd9378-sdw.c
Normal file
135
sound/soc/codecs/wcd9378-sdw.c
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2026, Jorijn van der Graaf
|
||||
*
|
||||
* SoundWire slave driver for the Qualcomm WCD9378 audio codec.
|
||||
*
|
||||
* Bring-up skeleton: binds to the two WCD9378 SoundWire devices (TX and
|
||||
* RX), maps the SDCA control space through regmap and verifies the device
|
||||
* identity registers. No audio paths yet.
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/soundwire/sdw.h>
|
||||
#include <linux/soundwire/sdw_registers.h>
|
||||
#include <linux/soundwire/sdw_type.h>
|
||||
|
||||
#include "wcd9378.h"
|
||||
|
||||
struct wcd9378_sdw_priv {
|
||||
struct sdw_slave *sdev;
|
||||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
static const struct regmap_config wcd9378_sdw_regmap_config = {
|
||||
.name = "wcd9378_sdw",
|
||||
.reg_bits = 32,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_NONE,
|
||||
.max_register = WCD9378_MAX_REGISTER,
|
||||
};
|
||||
|
||||
static void wcd9378_sdw_read_id(struct wcd9378_sdw_priv *wcd)
|
||||
{
|
||||
struct device *dev = &wcd->sdev->dev;
|
||||
static const struct {
|
||||
const char *name;
|
||||
unsigned int reg;
|
||||
} id_regs[] = {
|
||||
{ "DEV_MANU_ID_0", WCD9378_DEV_MANU_ID_0 },
|
||||
{ "DEV_MANU_ID_1", WCD9378_DEV_MANU_ID_1 },
|
||||
{ "DEV_PART_ID_0", WCD9378_DEV_PART_ID_0 },
|
||||
{ "DEV_PART_ID_1", WCD9378_DEV_PART_ID_1 },
|
||||
{ "DEV_VER", WCD9378_DEV_VER },
|
||||
{ "FUNC_EXT_ID_0", WCD9378_FUNC_EXT_ID_0 },
|
||||
{ "FUNC_EXT_ID_1", WCD9378_FUNC_EXT_ID_1 },
|
||||
{ "ANA_BIAS", WCD9378_ANA_BIAS },
|
||||
{ "ANA_TX_CH1", WCD9378_ANA_TX_CH1 },
|
||||
{ "ANA_MICB1", WCD9378_ANA_MICB1 },
|
||||
{ "SYS_USAGE_CTRL", WCD9378_SYS_USAGE_CTRL },
|
||||
};
|
||||
unsigned int val, packed, pval;
|
||||
int i, ret, pret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(id_regs); i++) {
|
||||
/* downstream WCD9378_REG() wire packing */
|
||||
packed = ((id_regs[i].reg & 0x0ff00000) >> 8) |
|
||||
(id_regs[i].reg & 0xfff);
|
||||
|
||||
ret = regmap_read(wcd->regmap, id_regs[i].reg, &val);
|
||||
pret = regmap_read(wcd->regmap, packed, &pval);
|
||||
dev_info(dev, "%s: virt %#010x = %#04x (ret %d), packed %#07x = %#04x (ret %d)\n",
|
||||
id_regs[i].name,
|
||||
id_regs[i].reg, ret ? 0xdead : val, ret,
|
||||
packed, pret ? 0xdead : pval, pret);
|
||||
}
|
||||
}
|
||||
|
||||
static int wcd9378_sdw_update_status(struct sdw_slave *slave,
|
||||
enum sdw_slave_status status)
|
||||
{
|
||||
struct wcd9378_sdw_priv *wcd = dev_get_drvdata(&slave->dev);
|
||||
|
||||
dev_info(&slave->dev, "status %d (dev_num %d)\n", status,
|
||||
slave->dev_num);
|
||||
|
||||
if (status == SDW_SLAVE_ATTACHED)
|
||||
wcd9378_sdw_read_id(wcd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct sdw_slave_ops wcd9378_sdw_ops = {
|
||||
.update_status = wcd9378_sdw_update_status,
|
||||
};
|
||||
|
||||
static int wcd9378_sdw_probe(struct sdw_slave *pdev,
|
||||
const struct sdw_device_id *id)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct wcd9378_sdw_priv *wcd;
|
||||
|
||||
wcd = devm_kzalloc(dev, sizeof(*wcd), GFP_KERNEL);
|
||||
if (!wcd)
|
||||
return -ENOMEM;
|
||||
|
||||
wcd->sdev = pdev;
|
||||
dev_set_drvdata(dev, wcd);
|
||||
|
||||
pdev->prop.scp_int1_mask = SDW_SCP_INT1_IMPL_DEF |
|
||||
SDW_SCP_INT1_BUS_CLASH |
|
||||
SDW_SCP_INT1_PARITY;
|
||||
pdev->prop.simple_clk_stop_capable = true;
|
||||
/* The SDCA control space sits above the 16-bit address range */
|
||||
pdev->prop.paging_support = true;
|
||||
|
||||
wcd->regmap = devm_regmap_init_sdw(pdev, &wcd9378_sdw_regmap_config);
|
||||
if (IS_ERR(wcd->regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(wcd->regmap),
|
||||
"regmap init failed\n");
|
||||
|
||||
dev_info(dev, "wcd9378 sdw slave probed\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct sdw_device_id wcd9378_sdw_id[] = {
|
||||
SDW_SLAVE_ENTRY(0x0217, 0x0110, 0),
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(sdw, wcd9378_sdw_id);
|
||||
|
||||
static struct sdw_driver wcd9378_sdw_driver = {
|
||||
.probe = wcd9378_sdw_probe,
|
||||
.ops = &wcd9378_sdw_ops,
|
||||
.id_table = wcd9378_sdw_id,
|
||||
.driver = {
|
||||
.name = "wcd9378-sdw",
|
||||
},
|
||||
};
|
||||
module_sdw_driver(wcd9378_sdw_driver);
|
||||
|
||||
MODULE_DESCRIPTION("WCD9378 SoundWire slave driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
63
sound/soc/codecs/wcd9378.h
Normal file
63
sound/soc/codecs/wcd9378.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2026, Jorijn van der Graaf
|
||||
*
|
||||
* Register map for the Qualcomm WCD9378 audio codec.
|
||||
*
|
||||
* The codec exposes its control registers in the SoundWire SDCA control
|
||||
* address space (bit 30 set, SDCA function number in bits 25:22), accessed
|
||||
* through the TX SoundWire slave. The analog core registers (function 0,
|
||||
* implementation-defined region at +0x180000) are layout-compatible with
|
||||
* the WCD937x family.
|
||||
*/
|
||||
|
||||
#ifndef __WCD9378_H__
|
||||
#define __WCD9378_H__
|
||||
|
||||
#include <linux/regmap.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
/* SDCA function 0 (extension unit): device identity */
|
||||
#define WCD9378_FUNC_EXT_ID_0 0x40000048
|
||||
#define WCD9378_FUNC_EXT_ID_1 0x40000049
|
||||
#define WCD9378_FUNC_EXT_VER 0x40000050
|
||||
#define WCD9378_FUNC_STAT 0x40080000
|
||||
#define WCD9378_DEV_MANU_ID_0 0x40100060
|
||||
#define WCD9378_DEV_MANU_ID_1 0x40100061
|
||||
#define WCD9378_DEV_PART_ID_0 0x40100068
|
||||
#define WCD9378_DEV_PART_ID_1 0x40100069
|
||||
#define WCD9378_DEV_VER 0x40100070
|
||||
|
||||
/* Analog core (WCD937x-compatible layout), function 0 + 0x180000 */
|
||||
#define WCD9378_ANA_PAGE 0x40180000
|
||||
#define WCD9378_ANA_BIAS 0x40180001
|
||||
#define WCD9378_ANA_RX_SUPPLIES 0x40180008
|
||||
#define WCD9378_ANA_TX_CH1 0x4018000e
|
||||
#define WCD9378_ANA_TX_CH2 0x4018000f
|
||||
#define WCD9378_ANA_TX_CH3 0x40180010
|
||||
#define WCD9378_ANA_MICB1 0x40180022
|
||||
#define WCD9378_ANA_MICB2 0x40180023
|
||||
#define WCD9378_ANA_MICB2_RAMP 0x40180024
|
||||
#define WCD9378_ANA_MICB3 0x40180025
|
||||
|
||||
/* Sequencer block (SEQR) */
|
||||
#define WCD9378_SYS_USAGE_CTRL 0x40180501
|
||||
#define WCD9378_SM0_MB_SEL 0x401805b0
|
||||
#define WCD9378_SM1_MB_SEL 0x401805b1
|
||||
#define WCD9378_SM2_MB_SEL 0x401805b2
|
||||
|
||||
/* SDCA function activation (one per function) */
|
||||
#define WCD9378_SMP_AMP_FUNC_STAT 0x40880000
|
||||
#define WCD9378_SMP_AMP_FUNC_ACT 0x40880008
|
||||
#define WCD9378_SMP_JACK_FUNC_STAT 0x40c80000
|
||||
#define WCD9378_SMP_JACK_FUNC_ACT 0x40c80008
|
||||
#define WCD9378_SMP_MIC_CTRL0_FUNC_STAT 0x41080000
|
||||
#define WCD9378_SMP_MIC_CTRL0_FUNC_ACT 0x41080008
|
||||
#define WCD9378_SMP_MIC_CTRL1_FUNC_STAT 0x41480000
|
||||
#define WCD9378_SMP_MIC_CTRL1_FUNC_ACT 0x41480008
|
||||
#define WCD9378_SMP_MIC_CTRL2_FUNC_STAT 0x41880000
|
||||
#define WCD9378_SMP_MIC_CTRL2_FUNC_ACT 0x41880008
|
||||
|
||||
#define WCD9378_MAX_REGISTER 0x41900070
|
||||
|
||||
#endif /* __WCD9378_H__ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue