Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 32b258e7 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "asoc: codecs: Add support for rouleur codec"

parents e1757aef 91208451
Loading
Loading
Loading
Loading
+65 −0
Original line number Diff line number Diff line
# Android makefile for audio kernel modules

# Assume no targets will be supported

# Check if this driver needs be built for current target
ifeq ($(call is-board-platform,bengal),true)
AUDIO_SELECT  := CONFIG_SND_SOC_BENGAL=m
endif

AUDIO_CHIPSET := audio
# Build/Package only in case of supported target
ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) bengal),true)

LOCAL_PATH := $(call my-dir)

# This makefile is only for DLKM
ifneq ($(findstring vendor,$(LOCAL_PATH)),)

ifneq ($(findstring opensource,$(LOCAL_PATH)),)
	AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel
endif # opensource

DLKM_DIR := $(TOP)/device/qcom/common/dlkm

# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko
###########################################################
# This is set once per LOCAL_PATH, not per (kernel) module
KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR)

# We are actually building audio.ko here, as per the
# requirement we are specifying <chipset>_audio.ko as LOCAL_MODULE.
# This means we need to rename the module to <chipset>_audio.ko
# after audio.ko is built.
KBUILD_OPTIONS += MODNAME=rouleur_dlkm
KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM)
KBUILD_OPTIONS += $(AUDIO_SELECT)

###########################################################
include $(CLEAR_VARS)
LOCAL_MODULE              := $(AUDIO_CHIPSET)_rouleur.ko
LOCAL_MODULE_KBUILD_NAME  := rouleur_dlkm.ko
LOCAL_MODULE_TAGS         := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH         := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
###########################################################
include $(CLEAR_VARS)
LOCAL_MODULE              := $(AUDIO_CHIPSET)_rouleur_slave.ko
LOCAL_MODULE_KBUILD_NAME  := rouleur_slave_dlkm.ko
LOCAL_MODULE_TAGS         := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH         := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
###########################################################
include $(CLEAR_VARS)
LOCAL_MODULE              := $(AUDIO_CHIPSET)_pm2250_spmi.ko
LOCAL_MODULE_KBUILD_NAME  := pm2250_spmi_dlkm.ko
LOCAL_MODULE_TAGS         := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH         := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
###########################################################

endif # DLKM check
endif # supported target check
+120 −0
Original line number Diff line number Diff line
# We can build either as part of a standalone Kernel build or as
# an external module.  Determine which mechanism is being used
ifeq ($(MODNAME),)
	KERNEL_BUILD := 1
else
	KERNEL_BUILD := 0
endif



ifeq ($(KERNEL_BUILD), 1)
	# These are configurable via Kconfig for kernel-based builds
	# Need to explicitly configure for Android-based builds
	AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.19
	AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio
endif

ifeq ($(KERNEL_BUILD), 0)
	ifeq ($(CONFIG_ARCH_BENGAL), y)
		include $(AUDIO_ROOT)/config/bengalauto.conf
		export
		INCS    +=  -include $(AUDIO_ROOT)/config/bengalautoconf.h
	endif
endif

# As per target team, build is done as follows:
# Defconfig : build with default flags
# Slub      : defconfig  + CONFIG_SLUB_DEBUG := y +
#	      CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y
# Perf      : Using appropriate msmXXXX-perf_defconfig
#
# Shipment builds (user variants) should not have any debug feature
# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds
# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since
# there is no other way to identify defconfig builds, QTI internal
# representation of perf builds (identified using the string 'perf'),
# is used to identify if the build is a slub or defconfig one. This
# way no critical debug feature will be enabled for perf and shipment
# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT
# config.

############ UAPI ############
UAPI_DIR :=	uapi
UAPI_INC :=	-I$(AUDIO_ROOT)/include/$(UAPI_DIR)

############ COMMON ############
COMMON_DIR :=	include
COMMON_INC :=	-I$(AUDIO_ROOT)/$(COMMON_DIR)

############ ROULEUR ############

# for ROULEUR Codec
ifdef CONFIG_SND_SOC_ROULEUR
	ROULEUR_OBJS += rouleur.o
	ROULEUR_OBJS += rouleur-regmap.o
	ROULEUR_OBJS += rouleur-tables.o
	ROULEUR_OBJS += rouleur-mbhc.o
endif

ifdef CONFIG_PM2250_SPMI
	PM2250_SPMI_OBJS += pm2250_spmi.o
endif

ifdef CONFIG_SND_SOC_ROULEUR_SLAVE
	ROULEUR_SLAVE_OBJS += rouleur_slave.o
endif

LINUX_INC +=	-Iinclude/linux

INCS +=		$(COMMON_INC) \
		$(UAPI_INC)

EXTRA_CFLAGS += $(INCS)


CDEFINES +=	-DANI_LITTLE_BYTE_ENDIAN \
		-DANI_LITTLE_BIT_ENDIAN \
		-DDOT11F_LITTLE_ENDIAN_HOST \
		-DANI_COMPILER_TYPE_GCC \
		-DANI_OS_TYPE_ANDROID=6 \
		-DPTT_SOCK_SVC_ENABLE \
		-Wall\
		-Werror\
		-D__linux__

KBUILD_CPPFLAGS += $(CDEFINES)

# Currently, for versions of gcc which support it, the kernel Makefile
# is disabling the maybe-uninitialized warning.  Re-enable it for the
# AUDIO driver.  Note that we must use EXTRA_CFLAGS here so that it
# will override the kernel settings.
ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y)
EXTRA_CFLAGS += -Wmaybe-uninitialized
endif
#EXTRA_CFLAGS += -Wmissing-prototypes

ifeq ($(call cc-option-yn, -Wheader-guard),y)
EXTRA_CFLAGS += -Wheader-guard
endif

ifeq ($(KERNEL_BUILD), 0)
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers
endif

# Module information used by KBuild framework
obj-$(CONFIG_SND_SOC_ROULEUR) += rouleur_dlkm.o
rouleur_dlkm-y := $(ROULEUR_OBJS)

obj-$(CONFIG_SND_SOC_ROULEUR_SLAVE) += rouleur_slave_dlkm.o
rouleur_slave_dlkm-y := $(ROULEUR_SLAVE_OBJS)

obj-$(CONFIG_PM2250_SPMI) += pm2250_spmi_dlkm.o
pm2250_spmi_dlkm-y := $(PM2250_SPMI_OBJS)

# inject some build related information
DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\"
+172 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2020, The Linux Foundation. All rights reserved.
 */

#ifndef _ROULEUR_INTERNAL_H
#define _ROULEUR_INTERNAL_H

#include <asoc/wcd-clsh.h>
#include <asoc/wcd-mbhc-v2.h>
#include <asoc/wcd-irq.h>
#include "rouleur-mbhc.h"

#define ROULEUR_MAX_MICBIAS 3

/* Convert from vout ctl to micbias voltage in mV */
#define  WCD_VOUT_CTL_TO_MICB(v)  (1600 + v * 50)
#define MAX_PORT 8
#define MAX_CH_PER_PORT 8

extern struct regmap_config rouleur_regmap_config;

struct codec_port_info {
	u32 slave_port_type;
	u32 master_port_type;
	u32 ch_mask;
	u32 num_ch;
	u32 ch_rate;
};

struct rouleur_priv {
	struct device *dev;

	int variant;
	struct snd_soc_component *component;
	struct device_node *spmi_np;
	struct regmap *regmap;

	struct swr_device *rx_swr_dev;
	struct swr_device *tx_swr_dev;

	s32 micb_ref[ROULEUR_MAX_MICBIAS];
	s32 pullup_ref[ROULEUR_MAX_MICBIAS];

	struct fw_info *fw_data;

	struct mutex micb_lock;
	s32 dmic_0_1_clk_cnt;
	/* mbhc module */
	struct rouleur_mbhc *mbhc;

	bool comp1_enable;
	bool comp2_enable;

	struct irq_domain *virq;
	struct wcd_irq_info irq_info;
	u32 rx_clk_cnt;
	int num_irq_regs;
	/* to track the status */
	unsigned long status_mask;

	u8 num_tx_ports;
	u8 num_rx_ports;
	struct codec_port_info
			tx_port_mapping[MAX_PORT][MAX_CH_PER_PORT];
	struct codec_port_info
			rx_port_mapping[MAX_PORT][MAX_CH_PER_PORT];
	struct regulator_bulk_data *supplies;
	struct notifier_block nblock;
	/* wcd callback to bolero */
	void *handle;
	int (*update_wcd_event)(void *handle, u16 event, u32 data);
	int (*register_notifier)(void *handle,
				struct notifier_block *nblock,
				bool enable);
	int (*wakeup)(void *handle, bool enable);
	u32 version;
	/* Entry for version info */
	struct snd_info_entry *entry;
	struct snd_info_entry *version_entry;
	struct device *spmi_dev;
	int reset_reg;
	int mbias_cnt;
	struct mutex rx_clk_lock;
	struct mutex main_bias_lock;
};

struct rouleur_micbias_setting {
	u32 micb1_mv;
	u32 micb2_mv;
	u32 micb3_mv;
};

struct rouleur_pdata {
	struct device_node *spmi_np;
	struct device_node *rx_slave;
	struct device_node *tx_slave;
	struct rouleur_micbias_setting micbias;

	struct cdc_regulator *regulator;
	int num_supplies;
	int reset_reg;
};

struct wcd_ctrl_platform_data {
	void *handle;
	int (*update_wcd_event)(void *handle, u16 event, u32 data);
	int (*register_notifier)(void *handle,
				 struct notifier_block *nblock,
				 bool enable);
};

enum {
	WCD_RX1,
	WCD_RX2,
	WCD_RX3
};

enum {
	BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1,
	BOLERO_WCD_EVT_PA_OFF_PRE_SSR,
	BOLERO_WCD_EVT_SSR_DOWN,
	BOLERO_WCD_EVT_SSR_UP,
};

enum {
	WCD_BOLERO_EVT_RX_MUTE = 1,	/* for RX mute/unmute */
	WCD_BOLERO_EVT_IMPED_TRUE,	/* for imped true */
	WCD_BOLERO_EVT_IMPED_FALSE,	/* for imped false */
	WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
	WCD_BOLERO_EVT_BCS_CLK_OFF,
};

enum {
	/* INTR_CTRL_INT_MASK_0 */
	ROULEUR_IRQ_MBHC_BUTTON_PRESS_DET = 0,
	ROULEUR_IRQ_MBHC_BUTTON_RELEASE_DET,
	ROULEUR_IRQ_MBHC_ELECT_INS_REM_DET,
	ROULEUR_IRQ_MBHC_ELECT_INS_REM_LEG_DET,
	ROULEUR_IRQ_MBHC_SW_DET,
	ROULEUR_IRQ_HPHR_OCP_INT,
	ROULEUR_IRQ_HPHR_CNP_INT,
	ROULEUR_IRQ_HPHL_OCP_INT,

	/* INTR_CTRL_INT_MASK_1 */
	ROULEUR_IRQ_HPHL_CNP_INT,
	ROULEUR_IRQ_EAR_CNP_INT,
	ROULEUR_IRQ_EAR_OCP_INT,
	ROULEUR_IRQ_LO_CNP_INT,
	ROULEUR_IRQ_LO_OCP_INT,
	ROULEUR_IRQ_HPHL_PDM_WD_INT,
	ROULEUR_IRQ_HPHR_PDM_WD_INT,
	ROULEUR_IRQ_RESERVED_0,

	/* INTR_CTRL_INT_MASK_2 */
	ROULEUR_IRQ_RESERVED_1,
	ROULEUR_IRQ_RESERVED_2,
	ROULEUR_IRQ_HPHL_SURGE_DET_INT,
	ROULEUR_IRQ_HPHR_SURGE_DET_INT,
	ROULEUR_NUM_IRQS,
};

extern void rouleur_disable_bcs_before_slow_insert(
				struct snd_soc_component *component,
				bool bcs_disable);
extern struct rouleur_mbhc *rouleur_soc_get_mbhc(
				struct snd_soc_component *component);
extern int rouleur_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
					int volt, int micb_num);
extern int rouleur_get_micb_vout_ctl_val(u32 micb_mv);
extern int rouleur_micbias_control(struct snd_soc_component *component,
			int micb_num, int req, bool is_dapm);
#endif
+17 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2020, The Linux Foundation. All rights reserved.
 */

#ifndef _PM2250_SPMI_H
#define _PM2250_SPMI_H

#ifdef CONFIG_PM2250_SPMI
int pm2250_spmi_write(struct device *dev, int reg, int value);
#else
int pm2250_spmi_write(struct device *dev, int reg, int value)
{
	return 0;
}
#endif	/* CONFIG_PM2250_SPMI */

#endif
+94 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
 */

#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/regmap.h>
#include <linux/slab.h>

/**
 * @regmap: regmap used to access PMIC registers
 */
struct pm2250_spmi {
	struct regmap *regmap;
};

static const struct of_device_id pm2250_id_table[] = {
	{ .compatible = "qcom,pm2250-spmi" },
	{ },
};
MODULE_DEVICE_TABLE(of, pm2250_id_table);

int pm2250_spmi_write(struct device *dev, int reg, int value)
{
	int rc;
	struct pm2250_spmi *spmi_dd;

	if (!of_device_is_compatible(dev->of_node, "qcom,pm2250-spmi")) {
		pr_err("%s: Device node is invalid\n", __func__);
		return -EINVAL;
	}

	spmi_dd = dev_get_drvdata(dev);
	if (!spmi_dd)
		return -EINVAL;

	rc = regmap_write(spmi_dd->regmap, reg, value);
	if (rc)
		dev_err(dev, "%s: Write to PMIC register failed\n", __func__);

	return rc;
}
EXPORT_SYMBOL(pm2250_spmi_write);

static int pm2250_spmi_probe(struct platform_device *pdev)
{
	struct pm2250_spmi *spmi_dd;
	const struct of_device_id *match;

	match = of_match_node(pm2250_id_table, pdev->dev.of_node);
	if (!match)
		return -ENXIO;

	spmi_dd = devm_kzalloc(&pdev->dev, sizeof(*spmi_dd), GFP_KERNEL);
	if (spmi_dd == NULL)
		return -ENOMEM;

	spmi_dd->regmap = dev_get_regmap(pdev->dev.parent, NULL);
	if (!spmi_dd->regmap) {
		dev_err(&pdev->dev, "Parent regmap unavailable.\n");
		return -ENXIO;
	}

	platform_set_drvdata(pdev, spmi_dd);

	dev_dbg(&pdev->dev, "Probe success !!\n");

	return 0;
}

static int pm2250_spmi_remove(struct platform_device *pdev)
{
	of_platform_depopulate(&pdev->dev);
	return 0;
}

static struct platform_driver pm2250_spmi_driver = {
	.probe		= pm2250_spmi_probe,
	.remove		= pm2250_spmi_remove,
	.driver	= {
		.name		= "pm2250-spmi",
		.of_match_table	= pm2250_id_table,
	},
};
module_platform_driver(pm2250_spmi_driver);

MODULE_ALIAS("platform:pm2250-spmi");
MODULE_DESCRIPTION("PMIC SPMI driver");
MODULE_LICENSE("GPL v2");
Loading