This commit is contained in:
AngeloGioacchino Del Regno 2021-08-10 13:07:36 +02:00 committed by Jami Kettunen
parent 64ec6966f9
commit d95b982acc
7 changed files with 558 additions and 23 deletions

View file

@ -25,6 +25,11 @@
qcom,soft-start-us = <800>;
};
&wcd9335 {
pinctrl-0 = <&cdc_reset_n &wcd_int_n>;
pinctrl-names = "default";
};
&vreg_l22a_2p85 {
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;

View file

@ -76,12 +76,12 @@
&pm8005_gpio {
ear_en_default: ear-en-active {
pins = "gpio1";
function = PMIC_GPIO_FUNC_NORMAL;
output-low;
drive-push-pull;
function = "normal";
bias-disable;
qcom,drive-strength = <PMIC_GPIO_STRENGTH_HIGH>;
power-source = <1>;
drive-push-pull;
output-low;
power-source = <1>; /* 1.8V */
qcom,drive-strength = <1>;
};
};
@ -111,3 +111,7 @@
qcom,enabled-strings = <0 1 2 3>;
};
&wcd9335 {
pinctrl-0 = <&cdc_reset_n &wcd_int_n &ear_en_default>;
pinctrl-names = "default";
};

View file

@ -25,16 +25,9 @@
qcom,soft-start-us = <800>;
};
&pm8005_gpio {
ear_en_default: ear-en-active {
pins = "gpio1";
function = PMIC_GPIO_FUNC_NORMAL;
output-low;
drive-push-pull;
bias-disable;
qcom,drive-strength = <PMIC_GPIO_STRENGTH_HIGH>;
power-source = <1>;
};
&wcd9335 {
pinctrl-0 = <&cdc_reset_n &wcd_int_n>;
pinctrl-names = "default";
};
&vreg_l18a_2p85 {

View file

@ -502,6 +502,27 @@
qcom,enabled-strings = <0 1>;
};
&q6asmdai {
dai@0 {
reg = <0>;
};
dai@1 {
reg = <1>;
};
dai@2 {
reg = <2>;
};
/*
dai@3 {
reg = <3>;
direction = <2>;
is-compress-dai;
};
*/
};
&qusb2phy {
status = "okay";
@ -511,6 +532,7 @@
&remoteproc_adsp {
firmware-name = "adsp.mdt";
status = "okay";
};
&remoteproc_mss {
@ -709,6 +731,181 @@
pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
};
/* Downstream example
&snd_9335 {
qcom,msm-mbhc-hphl-swh = <1>;
/delete-property/ qcom,hph-en1-gpio;
/delete-property/ qcom,hph-en0-gpio;
/delete-property/ qcom,us-euro-gpios;
qcom,ear-en-gpios = <&pm8005_gpios 1 0>;
qcom,audio-routing =
"AIF4 VI", "MCLK",
"RX_BIAS", "MCLK",
"MADINPUT", "MCLK",
"AMIC2", "MIC BIAS2",
"MIC BIAS2", "Headset Mic",
"MIC BIAS2", "ANCRight Headset Mic",
"AMIC3", "MIC BIAS3",
"MIC BIAS3", "ANCLeft Headset Mic",
"DMIC0", "MIC BIAS1",
"MIC BIAS1", "Digital Mic0",
"DMIC3", "MIC BIAS4",
"MIC BIAS4", "Digital Mic3",
"SpkrLeft IN", "SPK1 OUT",
"SpkrRight IN", "SPK2 OUT";
};
*/
&slimbam {
status = "okay";
};
&slim {
status = "okay";
};
&slim_ngd {
tasha_ifd: tas-ifd {
compatible = "slim217,1a0";
reg = <0 0>;
};
wcd9335: codec@1{
compatible = "slim217,1a0";
reg = <1 0>;
clock-names = "mclk", "slimbus";
clocks = <&div1_mclk>,
<&rpmcc RPM_SMD_LN_BB_CLK1>;
#clock-cells = <0>;
vdd-buck-supply = <&vreg_s4a_1p8>;
vdd-buck-sido-supply = <&vreg_s4a_1p8>;
vdd-tx-supply = <&vreg_s4a_1p8>;
vdd-rx-supply = <&vreg_s4a_1p8>;
vdd-io-supply = <&vreg_s4a_1p8>;
interrupt-parent = <&tlmm>;
interrupts = <54 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "intr1";
interrupt-controller;
#interrupt-cells = <1>;
reset-gpios = <&tlmm 64 0>;
slim-ifc-dev = <&tasha_ifd>;
#address-cells = <1>;
#size-cells = <1>;
#sound-dai-cells = <1>;
swm: swm@c85 {
compatible = "qcom,soundwire-v1.3.0";
reg = <0xc85 0x40>;
interrupts-extended = <&wcd9335 13>;
qcom,dout-ports = <6>;
qcom,din-ports = <2>;
qcom,ports-sinterval-low =/bits/ 8 <0x07 0x1F 0x3F 0x7 0x1F 0x3F 0x0F 0x0F>;
qcom,ports-offset1 = /bits/ 8 <0x01 0x02 0x0C 0x6 0x12 0x0D 0x07 0x0A >;
qcom,ports-offset2 = /bits/ 8 <0x00 0x00 0x1F 0x00 0x00 0x1F 0x00 0x00>;
/*downstream is <0xFF 0x00 0x1F 0xFF 0x00 0x1F 0x00 0x00>;*/
qcom,ports-block-pack-mode = /bits/ 8 <0xFF 0xFF 0x01 0xFF 0xFF 0x01 0xFF 0xFF>;
clocks = <&xo>;
clock-names = "iface";
#address-cells = <2>;
#size-cells = <0>;
#sound-dai-cells = <1>;
left_spkr: wsa8810-left {
compatible = "sdw10217201000";
reg = <0 1>;
powerdown-gpios = <&tlmm 65 GPIO_ACTIVE_HIGH>;
pinctrl-0 = <&wsa_leftspk_pwr_n>;
pinctrl-names = "default";
#thermal-sensor-cells = <0>;
sound-name-prefix = "SpkrRight";
#sound-dai-cells = <0>;
};
right_spkr: wsa8810-right {
compatible = "sdw10217201000";
powerdown-gpios = <&tlmm 66 GPIO_ACTIVE_HIGH>;
reg = <0 2>;
pinctrl-0 = <&wsa_rightspk_pwr_n>;
pinctrl-names = "default";
#thermal-sensor-cells = <0>;
sound-name-prefix = "SpkrLeft";
#sound-dai-cells = <0>;
};
};
};
};
&sound {
compatible = "qcom,msm8998-sndcard";
model = "Sony-Xperia-Yoshino";
audio-routing = "RX_BIAS", "MCLK",
"AMIC2", "MIC BIAS2",
"AMIC3", "MIC BIAS3",
"DMIC0", "MIC BIAS1",
"DMIC4", "MIC BIAS4",
"SpkrLeft IN", "SPK1 OUT",
"SpkrRight IN", "SPK2 OUT",
"MM_DL1", "MultiMedia1 Playback";
mm1-dai-link {
link-name = "MultiMedia1";
cpu {
sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>;
};
};
mm2-dai-link {
link-name = "MultiMedia2";
cpu {
sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA2>;
};
};
mm3-dai-link {
link-name = "MultiMedia3";
cpu {
sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA3>;
};
};
slim-dai-link {
link-name = "SLIM Playback";
cpu {
sound-dai = <&q6afedai SLIMBUS_0_RX>;
};
platform {
sound-dai = <&q6routing>;
};
codec {
sound-dai = <&left_spkr>, <&right_spkr>, <&swm 0>, <&wcd9335 0>;
};
};
slimcap-dai-link {
link-name = "SLIM Capture";
cpu {
sound-dai = <&q6afedai SLIMBUS_0_TX>;
};
platform {
sound-dai = <&q6routing>;
};
codec {
sound-dai = <&wcd9335 1>;
};
};
};
&tlmm {
gpio-reserved-ranges = <0 4>, <81 4>;
@ -799,6 +996,38 @@
drive-strength = <2>;
};
wcd_int_n: wcd-int-n {
pins = "gpio54";
function = "gpio";
bias-pull-down;
drive-strength = <2>;
input-enable;
};
cdc_reset_n: cdc-reset-n {
pins = "gpio64";
function = "gpio";
bias-pull-down;
drive-strength = <16>;
output-high;
};
wsa_leftspk_pwr_n: wsa-leftspk-pwr-n {
pins = "gpio65";
function = "gpio";
bias-disable;
drive-strength = <2>;
output-low;
};
wsa_rightspk_pwr_n: wsa-rightspk-pwr-n {
pins = "gpio66";
function = "gpio";
bias-disable;
drive-strength = <2>;
output-low;
};
ts_reset_n: ts-reset-n {
pins = "gpio89";
function = "gpio";

View file

@ -928,6 +928,9 @@
};
};
sound: sound {
};
thermal-zones {
cpu0-thermal {
polling-delay-passive = <250>;
@ -3512,6 +3515,7 @@
#dma-cells = <1>;
qcom,ee = <1>;
qcom,num-ees = <2>;
status = "disabled";
};
slim: slim@171c0000 {
@ -3521,22 +3525,22 @@
qcom,apps-ch-pipes = <0x1f80>;
qcom,ea-pc = <0x210>;
status = "okay";
dmas = <&slimbam 3>, <&slimbam 4>,
<&slimbam 5>, <&slimbam 6>;
dma-names = "rx", "tx", "tx2", "rx2";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
ngd@1 {
slim_ngd: ngd@1 {
reg = <1>;
#address-cells = <2>;
#size-cells = <0>;
#address-cells = <1>;
#size-cells = <1>;
};
};
remoteproc_adsp: remoteproc@17300000 {
compatible = "qcom,msm8998-adsp-pas";
reg = <0x17300000 0x4040>;
@ -3631,7 +3635,7 @@
cb@2 {
compatible = "qcom,fastrpc-compute-cb";
dma-ranges = <0 0x60000000 0 0x18000000>;
//dma-ranges = <0 0x60000000 0 0x18000000>;
reg = <2>;
iommus = <&lpass_q6_smmu 2>;
};

300
drivers/mfd/wcd9335.c Normal file
View file

@ -0,0 +1,300 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2019, Linaro Limited
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mfd/core.h>
#include <linux/mfd/wcd9335/registers.h>
#include <linux/mfd/wcd9335/wcd9335.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slimbus.h>
#define WCD9335_REGMAP_IRQ_REG(_irq, _off, _mask) \
[_irq] = { \
.reg_offset = (_off), \
.mask = (_mask), \
.type = { \
.type_reg_offset = (_off), \
.types_supported = IRQ_TYPE_EDGE_BOTH, \
.type_reg_mask = (_mask), \
.type_level_low_val = (_mask), \
.type_level_high_val = (_mask), \
.type_falling_val = 0, \
.type_rising_val = 0, \
}, \
}
static const struct mfd_cell wcd9335_devices[] = {
{
.name = "wcd9335-codec",
}, {
.name = "wcd9335-gpio",
.of_compatible = "qcom,wcd9340-gpio",
}, {
.name = "wcd9335-soundwire",
.of_compatible = "qcom,soundwire-v1.3.0",
},
};
static const struct regmap_irq wcd9335_irqs[] = {
WCD9335_REGMAP_IRQ_REG(WCD9335_IRQ_SLIMBUS, 0, BIT(0)),
WCD9335_REGMAP_IRQ_REG(WCD9335_IRQ_HPH_PA_OCPL_FAULT, 0, BIT(2)),
WCD9335_REGMAP_IRQ_REG(WCD9335_IRQ_HPH_PA_OCPR_FAULT, 0, BIT(3)),
WCD9335_REGMAP_IRQ_REG(WCD9335_IRQ_MBHC_SW_DET, 1, BIT(0)),
WCD9335_REGMAP_IRQ_REG(WCD9335_IRQ_MBHC_ELECT_INS_REM_DET, 1, BIT(1)),
WCD9335_REGMAP_IRQ_REG(WCD9335_IRQ_MBHC_BUTTON_PRESS_DET, 1, BIT(2)),
WCD9335_REGMAP_IRQ_REG(WCD9335_IRQ_MBHC_BUTTON_RELEASE_DET, 1, BIT(3)),
WCD9335_REGMAP_IRQ_REG(WCD9335_IRQ_MBHC_ELECT_INS_REM_LEG_DET, 1, BIT(4)),
WCD9335_REGMAP_IRQ_REG(WCD9335_IRQ_SOUNDWIRE, 2, BIT(4)),
};
static const struct regmap_irq_chip wcd9335_regmap_irq_chip = {
.name = "wcd9335_irq",
.status_base = WCD9335_INTR_PIN1_STATUS0,
.mask_base = WCD9335_INTR_PIN1_MASK0,
.ack_base = WCD9335_INTR_PIN1_CLEAR0,
.type_base = WCD9335_INTR_LEVEL0,
.num_type_reg = 4,
.type_in_mask = false,
.num_regs = 4,
.irqs = wcd9335_irqs,
.num_irqs = ARRAY_SIZE(wcd9335_irqs),
};
static bool wcd9335_is_volatile_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case WCD9335_INTR_PIN1_STATUS0...WCD9335_INTR_PIN2_CLEAR3:
case WCD9335_SWR_AHB_BRIDGE_RD_DATA_0:
case WCD9335_SWR_AHB_BRIDGE_RD_DATA_1:
case WCD9335_SWR_AHB_BRIDGE_RD_DATA_2:
case WCD9335_SWR_AHB_BRIDGE_RD_DATA_3:
case WCD9335_SWR_AHB_BRIDGE_ACCESS_STATUS:
case WCD9335_ANA_MBHC_RESULT_3:
case WCD9335_ANA_MBHC_RESULT_2:
case WCD9335_ANA_MBHC_RESULT_1:
case WCD9335_ANA_MBHC_MECH:
case WCD9335_ANA_MBHC_ELECT:
case WCD9335_ANA_MBHC_ZDET:
case WCD9335_ANA_MICB2:
case WCD9335_ANA_RCO:
case WCD9335_ANA_BIAS:
return true;
default:
return false;
}
};
static const struct regmap_range_cfg wcd9335_ranges[] = {
{ .name = "WCD9335",
.range_min = 0x0,
.range_max = WCD9335_MAX_REGISTER,
.selector_reg = WCD9335_SEL_REGISTER,
.selector_mask = WCD9335_SEL_MASK,
.selector_shift = WCD9335_SEL_SHIFT,
.window_start = WCD9335_WINDOW_START,
.window_len = WCD9335_WINDOW_LENGTH,
},
};
static struct regmap_config wcd9335_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.max_register = 0xffff,
.can_multi_write = true,
.ranges = wcd9335_ranges,
.num_ranges = ARRAY_SIZE(wcd9335_ranges),
.volatile_reg = wcd9335_is_volatile_register,
};
static int wcd9335_bring_up(struct wcd9335_ddata *ddata)
{
struct regmap *regmap = ddata->regmap;
u16 id_minor, id_major;
int ret;
ret = regmap_bulk_read(regmap, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0,
(u8 *)&id_minor, sizeof(u16));
if (ret)
return ret;
ret = regmap_bulk_read(regmap, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE2,
(u8 *)&id_major, sizeof(u16));
if (ret)
return ret;
dev_info(ddata->dev, "WCD934x chip id major 0x%x, minor 0x%x\n",
id_major, id_minor);
regmap_write(regmap, WCD9335_CODEC_RPM_RST_CTL, 0x01);
regmap_write(regmap, WCD9335_SIDO_NEW_VOUT_A_STARTUP, 0x19);
regmap_write(regmap, WCD9335_SIDO_NEW_VOUT_D_STARTUP, 0x15);
/* Add 1msec delay for VOUT to settle */
usleep_range(1000, 1100);
regmap_write(regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5);
regmap_write(regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7);
regmap_write(regmap, WCD9335_CODEC_RPM_RST_CTL, 0x3);
regmap_write(regmap, WCD9335_CODEC_RPM_RST_CTL, 0x7);
regmap_write(regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3);
return 0;
}
static int wcd9335_slim_status_up(struct slim_device *sdev)
{
struct device *dev = &sdev->dev;
struct wcd9335_ddata *ddata;
int ret;
ddata = dev_get_drvdata(dev);
ddata->regmap = regmap_init_slimbus(sdev, &wcd9335_regmap_config);
if (IS_ERR(ddata->regmap)) {
dev_err(dev, "Error allocating slim regmap\n");
return PTR_ERR(ddata->regmap);
}
ret = wcd9335_bring_up(ddata);
if (ret) {
dev_err(dev, "Failed to bring up WCD9335: err = %d\n", ret);
return ret;
}
ret = devm_regmap_add_irq_chip(dev, ddata->regmap, ddata->irq,
IRQF_TRIGGER_HIGH, 0,
&wcd9335_regmap_irq_chip,
&ddata->irq_data);
if (ret) {
dev_err(dev, "Failed to add IRQ chip: err = %d\n", ret);
return ret;
}
ret = mfd_add_devices(dev, PLATFORM_DEVID_AUTO, wcd9335_devices,
ARRAY_SIZE(wcd9335_devices), NULL, 0, NULL);
if (ret) {
dev_err(dev, "Failed to add child devices: err = %d\n",
ret);
return ret;
}
return ret;
}
static int wcd9335_slim_status(struct slim_device *sdev,
enum slim_device_status status)
{
switch (status) {
case SLIM_DEVICE_STATUS_UP:
return wcd9335_slim_status_up(sdev);
case SLIM_DEVICE_STATUS_DOWN:
mfd_remove_devices(&sdev->dev);
break;
default:
return -EINVAL;
}
return 0;
}
static int wcd9335_slim_probe(struct slim_device *sdev)
{
struct device *dev = &sdev->dev;
struct device_node *np = dev->of_node;
struct wcd9335_ddata *ddata;
int reset_gpio, ret;
ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENOMEM;
ddata->irq = of_irq_get(np, 0);
if (ddata->irq < 0)
return dev_err_probe(ddata->dev, ddata->irq,
"Failed to get IRQ\n");
reset_gpio = of_get_named_gpio(np, "reset-gpios", 0);
if (reset_gpio < 0) {
dev_err(dev, "Failed to get reset gpio: err = %d\n",
reset_gpio);
return reset_gpio;
}
ddata->extclk = devm_clk_get(dev, "extclk");
if (IS_ERR(ddata->extclk)) {
dev_err(dev, "Failed to get extclk");
return PTR_ERR(ddata->extclk);
}
ddata->supplies[0].supply = "vdd-buck";
ddata->supplies[1].supply = "vdd-buck-sido";
ddata->supplies[2].supply = "vdd-tx";
ddata->supplies[3].supply = "vdd-rx";
ddata->supplies[4].supply = "vdd-io";
ret = regulator_bulk_get(dev, WCD9335_MAX_SUPPLY, ddata->supplies);
if (ret) {
dev_err(dev, "Failed to get supplies: err = %d\n", ret);
return ret;
}
ret = regulator_bulk_enable(WCD9335_MAX_SUPPLY, ddata->supplies);
if (ret) {
dev_err(dev, "Failed to enable supplies: err = %d\n", ret);
return ret;
}
/*
* For WCD9335, it takes about 600us for the Vout_A and
* Vout_D to be ready after BUCK_SIDO is powered up.
* SYS_RST_N shouldn't be pulled high during this time
*/
usleep_range(600, 650);
gpio_direction_output(reset_gpio, 0);
msleep(20);
gpio_set_value(reset_gpio, 1);
msleep(20);
ddata->dev = dev;
dev_set_drvdata(dev, ddata);
return 0;
}
static void wcd9335_slim_remove(struct slim_device *sdev)
{
struct wcd9335_ddata *ddata = dev_get_drvdata(&sdev->dev);
regulator_bulk_disable(WCD9335_MAX_SUPPLY, ddata->supplies);
mfd_remove_devices(&sdev->dev);
}
static const struct slim_device_id wcd9335_slim_id[] = {
{ SLIM_MANF_ID_QCOM, SLIM_PROD_CODE_WCD9340,
SLIM_DEV_IDX_WCD9340, SLIM_DEV_INSTANCE_ID_WCD9340 },
{}
};
static struct slim_driver wcd9335_slim_driver = {
.driver = {
.name = "wcd9335-slim",
},
.probe = wcd9335_slim_probe,
.remove = wcd9335_slim_remove,
.device_status = wcd9335_slim_status,
.id_table = wcd9335_slim_id,
};
module_slim_driver(wcd9335_slim_driver);
MODULE_DESCRIPTION("WCD9335 slim driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("slim:217:250:*");
MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org>");

View file

@ -423,9 +423,9 @@ static const struct snd_soc_ops msm8998_be_ops = {
static int msm8998_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
struct snd_interet *rate = hw_param_interet(params,
struct snd_interval *rate = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
struct snd_interet *channels = hw_param_interet(params,
struct snd_interval *channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);