mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 04:48:04 +09:00
Merge commit '1feee0d9c0b20750eef52b06b9211a4a3a353895'
* commit '1feee0d9c0b20750eef52b06b9211a4a3a353895': ASoC: codecs: add aw882xx amp ASoC: codecs: add support for IT6621 drm/rockchip: drv: Fix ROCKCHIP_BO_CACHABLE flag Invalid Change-Id: I6c69d064fc0b72fff4ddc93b876ab4c23ad47dfe
This commit is contained in:
@@ -546,10 +546,6 @@ static int rockchip_drm_gem_object_mmap(struct drm_gem_object *obj,
|
||||
int ret;
|
||||
struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj);
|
||||
|
||||
/* default is wc. */
|
||||
if (rk_obj->flags & ROCKCHIP_BO_CACHABLE)
|
||||
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
|
||||
|
||||
/*
|
||||
* Set vm_pgoff (used as a fake buffer offset by DRM) to 0 and map the
|
||||
* whole buffer from the start.
|
||||
@@ -562,7 +558,11 @@ static int rockchip_drm_gem_object_mmap(struct drm_gem_object *obj,
|
||||
*/
|
||||
vm_flags_mod(vma, VM_IO | VM_DONTEXPAND | VM_DONTDUMP, VM_PFNMAP);
|
||||
|
||||
vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
|
||||
/* default is wc. */
|
||||
if (rk_obj->flags & ROCKCHIP_BO_CACHABLE)
|
||||
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
|
||||
else
|
||||
vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
|
||||
vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
|
||||
|
||||
if (rk_obj->buf_type == ROCKCHIP_GEM_BUF_TYPE_SECURE) {
|
||||
|
||||
@@ -2272,5 +2272,7 @@ config SND_SOC_LPASS_TX_MACRO
|
||||
tristate "Qualcomm TX Macro in LPASS(Low Power Audio SubSystem)"
|
||||
|
||||
source "sound/soc/codecs/aw87xxx/Kconfig"
|
||||
source "sound/soc/codecs/aw882xx/Kconfig"
|
||||
source "sound/soc/codecs/aw883xx/Kconfig"
|
||||
source "sound/soc/codecs/it6621/Kconfig"
|
||||
endmenu
|
||||
|
||||
@@ -746,7 +746,9 @@ obj-$(CONFIG_SND_SOC_ZL38060) += snd-soc-zl38060.o
|
||||
|
||||
# Amp
|
||||
obj-$(CONFIG_SND_SOC_AW87XXX) += aw87xxx/
|
||||
obj-$(CONFIG_SND_SOC_AW882XX) += aw882xx/
|
||||
obj-$(CONFIG_SND_SOC_AW883XX) += aw883xx/
|
||||
obj-$(CONFIG_SND_SOC_IT6621) += it6621/
|
||||
obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
|
||||
obj-$(CONFIG_SND_SOC_MAX98504) += snd-soc-max98504.o
|
||||
obj-$(CONFIG_SND_SOC_SIMPLE_AMPLIFIER) += snd-soc-simple-amplifier.o
|
||||
|
||||
5
sound/soc/codecs/aw882xx/Kconfig
Normal file
5
sound/soc/codecs/aw882xx/Kconfig
Normal file
@@ -0,0 +1,5 @@
|
||||
config SND_SOC_AW882XX
|
||||
tristate "SoC Audio for awinic AW883XX series Smart PA"
|
||||
depends on I2C
|
||||
help
|
||||
This option enables support for AW883XX series Smart PA.
|
||||
5
sound/soc/codecs/aw882xx/Makefile
Normal file
5
sound/soc/codecs/aw882xx/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
#for AWINIC AW883XX Smart PA
|
||||
snd-soc-aw882xx-objs := aw882xx.o aw882xx_device.o aw882xx_dsp.o aw882xx_monitor.o aw882xx_bin_parse.o aw882xx_init.o aw882xx_calib.o aw882xx_spin.o
|
||||
obj-$(CONFIG_SND_SOC_AW882XX) += snd-soc-aw882xx.o
|
||||
|
||||
|
||||
2755
sound/soc/codecs/aw882xx/aw882xx.c
Normal file
2755
sound/soc/codecs/aw882xx/aw882xx.c
Normal file
File diff suppressed because it is too large
Load Diff
223
sound/soc/codecs/aw882xx/aw882xx.h
Normal file
223
sound/soc/codecs/aw882xx/aw882xx.h
Normal file
@@ -0,0 +1,223 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
* aw882xx.h
|
||||
*
|
||||
* Copyright (c) 2020 AWINIC Technology CO., LTD
|
||||
*
|
||||
* Author: Nick Li <liweilei@awinic.com.cn>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _AW882XX_H_
|
||||
#define _AW882XX_H_
|
||||
#include <linux/version.h>
|
||||
#include <linux/kernel.h>
|
||||
#include "aw882xx_device.h"
|
||||
|
||||
/*
|
||||
* i2c transaction on Linux limited to 64k
|
||||
* (See Linux kernel documentation: Documentation/i2c/writing-clients)
|
||||
*/
|
||||
#define AW882XX_CHIP_ID_REG (0x00)
|
||||
#define MAX_I2C_BUFFER_SIZE 65536
|
||||
#define AW882XX_I2C_READ_MSG_NUM 2
|
||||
#define AW882XX_DC_DELAY_TIME (1000)
|
||||
#define AW882XX_LOAD_FW_DELAY_TIME (0)
|
||||
#define AW_START_RETRIES (5)
|
||||
|
||||
#define AW_PID_2055_VERSION_DIFF_REG (0x23)
|
||||
|
||||
#define AW_I2C_RETRIES 5 /* 5 times */
|
||||
#define AW_I2C_RETRY_DELAY 5 /* 5 ms */
|
||||
|
||||
#define ACF_BIN_NAME "aw882xx_acf.bin"
|
||||
|
||||
#define AW882XX_RATES SNDRV_PCM_RATE_8000_48000
|
||||
#define AW882XX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
|
||||
SNDRV_PCM_FMTBIT_S24_LE | \
|
||||
SNDRV_PCM_FMTBIT_S32_LE)
|
||||
/*#define AW882XX_IRQ_START_FLAG*/
|
||||
enum {
|
||||
AW882XX_STREAM_CLOSE = 0,
|
||||
AW882XX_STREAM_OPEN,
|
||||
};
|
||||
|
||||
enum aw882xx_chipid {
|
||||
PID_1852_ID = 0x1852,
|
||||
PID_2013_ID = 0x2013,
|
||||
PID_2032_ID = 0x2032,
|
||||
PID_2055_ID = 0x2055,
|
||||
PID_2055A_ID = 0x2055A,
|
||||
PID_2071_ID = 0x2071,
|
||||
PID_2113_ID = 0x2113,
|
||||
PID_2308_ID = 0x2308,
|
||||
};
|
||||
|
||||
#define AW882XX_SOFT_RESET_REG (0x00)
|
||||
#define AW882XX_SOFT_RESET_VALUE (0x55aa)
|
||||
|
||||
enum aw882xx_int_type {
|
||||
INT_TYPE_NONE = 0,
|
||||
INT_TYPE_UVLO = 0x1,
|
||||
INT_TYPE_BSTOC = 0x2,
|
||||
INT_TYPE_OCDI = 0x4,
|
||||
INT_TYPE_OTHI = 0x8,
|
||||
};
|
||||
|
||||
#if KERNEL_VERSION(4, 19, 1) <= LINUX_VERSION_CODE
|
||||
#define AW_KERNEL_VER_OVER_4_19_1
|
||||
#endif
|
||||
|
||||
|
||||
#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE
|
||||
#define AW_KERNEL_VER_OVER_5_4_0
|
||||
MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);
|
||||
#endif
|
||||
|
||||
#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE
|
||||
#define AW_KERNEL_VER_OVER_5_10_0
|
||||
#endif
|
||||
#if KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE
|
||||
#define AW_KERNEL_VER_OVER_6_1_0
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef AW_KERNEL_VER_OVER_4_19_1
|
||||
typedef struct snd_soc_component aw_snd_soc_codec_t;
|
||||
typedef const struct snd_soc_component_driver aw_snd_soc_codec_driver_t;
|
||||
#else
|
||||
typedef struct snd_soc_codec aw_snd_soc_codec_t;
|
||||
typedef const struct snd_soc_codec_driver aw_snd_soc_codec_driver_t;
|
||||
#endif
|
||||
|
||||
struct aw_componet_codec_ops {
|
||||
aw_snd_soc_codec_t *(*kcontrol_codec)(struct snd_kcontrol *kcontrol);
|
||||
void *(*codec_get_drvdata)(aw_snd_soc_codec_t *codec);
|
||||
int (*add_codec_controls)(aw_snd_soc_codec_t *codec,
|
||||
const struct snd_kcontrol_new *controls, unsigned int num_controls);
|
||||
void (*unregister_codec)(struct device *dev);
|
||||
int (*register_codec)(struct device *dev,
|
||||
const aw_snd_soc_codec_driver_t *codec_drv,
|
||||
struct snd_soc_dai_driver *dai_drv,
|
||||
int num_dai);
|
||||
};
|
||||
|
||||
enum {
|
||||
AWRW_I2C_ST_NONE = 0,
|
||||
AWRW_I2C_ST_READ,
|
||||
AWRW_I2C_ST_WRITE,
|
||||
};
|
||||
|
||||
#define AWRW_ADDR_BYTES (1)
|
||||
#define AWRW_DATA_BYTES (2)
|
||||
#define AWRW_HDR_LEN (24)
|
||||
|
||||
|
||||
enum {
|
||||
KCTL_TYPE_PROFILE = 0,
|
||||
KCTL_TYPE_SWITCH,
|
||||
KCTL_TYPE_MONITOR,
|
||||
KCTL_TYPE_VOLUME,
|
||||
KCTL_TYPE_MON_HAL,
|
||||
AW_KCTL_NUM,
|
||||
|
||||
};
|
||||
|
||||
enum {
|
||||
AWRW_FLAG_WRITE = 0,
|
||||
AWRW_FLAG_READ,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_BSTCFG_DISABLE = 0,
|
||||
AW_BSTCFG_ENABLE,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_FRCSET_DISABLE = 0,
|
||||
AW_FRCSET_ENABLE,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_BOP_DISABLE = 0,
|
||||
AW_BOP_ENABLE,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_RENAME_DISABLE = 0,
|
||||
AW_RENAME_ENABLE,
|
||||
};
|
||||
|
||||
enum {
|
||||
AWRW_HDR_WR_FLAG = 0,
|
||||
AWRW_HDR_ADDR_BYTES,
|
||||
AWRW_HDR_DATA_BYTES,
|
||||
AWRW_HDR_REG_NUM,
|
||||
AWRW_HDR_REG_ADDR,
|
||||
AWRW_HDR_MAX,
|
||||
};
|
||||
|
||||
struct aw882xx_i2c_packet {
|
||||
char status;
|
||||
unsigned int reg_num;
|
||||
unsigned int reg_addr;
|
||||
char *reg_data;
|
||||
};
|
||||
|
||||
/********************************************
|
||||
* struct aw882xx
|
||||
*******************************************/
|
||||
struct aw882xx {
|
||||
int sysclk;
|
||||
int rate;
|
||||
int pstream;
|
||||
int cstream;
|
||||
|
||||
unsigned char phase_sync; /* phase sync */
|
||||
unsigned char dc_flag;
|
||||
unsigned char dbg_en_prof; /* debug enable/disable profile function */
|
||||
unsigned char allow_pw; /* allow power */
|
||||
uint32_t rename_flag;
|
||||
unsigned char sync_load; /* sync load fw */
|
||||
|
||||
int reset_gpio;
|
||||
int irq_gpio;
|
||||
unsigned char fw_status;
|
||||
unsigned char fw_retry_cnt;
|
||||
unsigned char rw_reg_addr; /* rw attr node store read addr */
|
||||
|
||||
aw_snd_soc_codec_t *codec;
|
||||
struct aw_componet_codec_ops *codec_ops;
|
||||
|
||||
struct i2c_client *i2c;
|
||||
struct device *dev;
|
||||
struct aw882xx_i2c_packet i2c_packet;
|
||||
struct aw_device *aw_pa;
|
||||
|
||||
struct workqueue_struct *work_queue;
|
||||
struct delayed_work start_work;
|
||||
struct delayed_work interrupt_work;
|
||||
struct delayed_work dc_work;
|
||||
struct delayed_work fw_work;
|
||||
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
void aw882xx_kcontorl_set(struct aw882xx *aw882xx);
|
||||
int aw882xx_get_version(char *buf, int size);
|
||||
int aw882xx_get_dev_num(void);
|
||||
int aw882xx_i2c_write(struct aw882xx *aw882xx,
|
||||
unsigned char reg_addr, unsigned int reg_data);
|
||||
int aw882xx_i2c_read(struct aw882xx *aw882xx,
|
||||
unsigned char reg_addr, unsigned int *reg_data);
|
||||
int aw882xx_i2c_write_bits(struct aw882xx *aw882xx,
|
||||
unsigned char reg_addr, unsigned int mask, unsigned int reg_data);
|
||||
int aw882xx_init(struct aw882xx *aw882xx);
|
||||
int aw882xx_hw_reset(struct aw882xx *aw882xx);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
1421
sound/soc/codecs/aw882xx/aw882xx_bin_parse.c
Normal file
1421
sound/soc/codecs/aw882xx/aw882xx_bin_parse.c
Normal file
File diff suppressed because it is too large
Load Diff
102
sound/soc/codecs/aw882xx/aw882xx_bin_parse.h
Normal file
102
sound/soc/codecs/aw882xx/aw882xx_bin_parse.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
* aw882xx_bin_parse.h
|
||||
*
|
||||
* Copyright (c) 2020 AWINIC Technology CO., LTD
|
||||
*
|
||||
* Author: Nick Li <liweilei@awinic.com.cn>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef __AW882XX_BIN_PARSE_H__
|
||||
#define __AW882XX_BIN_PARSE_H__
|
||||
|
||||
#include "aw882xx_device.h"
|
||||
|
||||
#define NULL ((void *)0)
|
||||
#define GET_32_DATA(w, x, y, z) ((unsigned int)((((uint32_t)w) << 24) | (((uint32_t)x) << 16) | (((uint32_t)y) << 8) | ((uint32_t)z)))
|
||||
#define BIN_NUM_MAX 100
|
||||
#define HEADER_LEN 60
|
||||
/*********************************************************
|
||||
*
|
||||
* header information
|
||||
*
|
||||
********************************************************/
|
||||
enum bin_header_version_enum {
|
||||
HEADER_VERSION_1_0_0 = 0x01000000,
|
||||
};
|
||||
|
||||
enum data_type_enum {
|
||||
DATA_TYPE_REGISTER = 0x00000000,
|
||||
DATA_TYPE_DSP_REG = 0x00000010,
|
||||
DATA_TYPE_DSP_CFG = 0x00000011,
|
||||
DATA_TYPE_SOC_REG = 0x00000020,
|
||||
DATA_TYPE_SOC_APP = 0x00000021,
|
||||
DATA_TYPE_MULTI_BINS = 0x00002000,
|
||||
};
|
||||
|
||||
enum data_version_enum {
|
||||
DATA_VERSION_V1 = 0X00000001, /*default little edian */
|
||||
DATA_VERSION_MAX,
|
||||
};
|
||||
|
||||
struct bin_header_info {
|
||||
unsigned int header_len; /* Frame header length */
|
||||
unsigned int check_sum; /* Frame header information-Checksum */
|
||||
unsigned int header_ver; /* Frame header information-Frame header version */
|
||||
unsigned int bin_data_type; /* Frame header information-Data type */
|
||||
unsigned int bin_data_ver; /* Frame header information-Data version */
|
||||
unsigned int bin_data_len; /* Frame header information-Data length */
|
||||
unsigned int ui_ver; /* Frame header information-ui version */
|
||||
unsigned char chip_type[8]; /* Frame header information-chip type */
|
||||
unsigned int reg_byte_len; /* Frame header information-reg byte len */
|
||||
unsigned int data_byte_len; /* Frame header information-data byte len */
|
||||
unsigned int device_addr; /* Frame header information-device addr */
|
||||
unsigned int valid_data_len; /* Length of valid data obtained after parsing */
|
||||
unsigned int valid_data_addr; /* The offset address of the valid data obtained after parsing relative to info */
|
||||
|
||||
unsigned int reg_num; /* The number of registers obtained after parsing */
|
||||
unsigned int reg_data_byte_len; /* The byte length of the register obtained after parsing */
|
||||
unsigned int download_addr; /* The starting address or download address obtained after parsing */
|
||||
unsigned int app_version; /* The software version number obtained after parsing */
|
||||
};
|
||||
|
||||
/************************************************************
|
||||
*
|
||||
* function define
|
||||
*
|
||||
************************************************************/
|
||||
struct bin_container {
|
||||
unsigned int len; /* The size of the bin file obtained from the firmware */
|
||||
unsigned char data[]; /* Store the bin file obtained from the firmware */
|
||||
};
|
||||
|
||||
struct aw_bin {
|
||||
unsigned char *p_addr; /* Offset pointer (backward offset pointer to obtain frame header information and important information) */
|
||||
unsigned int all_bin_parse_num; /* The number of all bin files */
|
||||
unsigned int multi_bin_parse_num; /* The number of single bin files */
|
||||
unsigned int single_bin_parse_num; /* The number of multiple bin files */
|
||||
struct bin_header_info header_info[BIN_NUM_MAX]; /* Frame header information and other important data obtained after parsing */
|
||||
struct bin_container info; /* Obtained bin file data that needs to be parsed */
|
||||
};
|
||||
|
||||
|
||||
/*******************awinic audio parse acf***********************/
|
||||
|
||||
int aw882xx_dev_parse_check_acf(struct aw_container *aw_cfg);
|
||||
int aw882xx_dev_parse_acf(struct aw_device *aw_dev, struct aw_container *aw_cfg);
|
||||
|
||||
|
||||
int aw882xx_dev_get_profile_count(struct aw_device *aw_dev);
|
||||
int aw88xx_dev_get_profile_name(struct aw_device *aw_dev, char *name, int index);
|
||||
int aw882xx_dev_check_profile_index(struct aw_device *aw_dev, int index);
|
||||
int aw882xx_dev_get_profile_index(struct aw_device *aw_dev);
|
||||
int aw882xx_dev_set_profile_index(struct aw_device *aw_dev, int index);
|
||||
char *aw882xx_dev_get_prof_name(struct aw_device *aw_dev, int index);
|
||||
struct aw_sec_data_desc *aw882xx_dev_get_prof_data(struct aw_device *aw_dev, int index, int data_type);
|
||||
|
||||
|
||||
#endif
|
||||
2453
sound/soc/codecs/aw882xx/aw882xx_calib.c
Normal file
2453
sound/soc/codecs/aw882xx/aw882xx_calib.c
Normal file
File diff suppressed because it is too large
Load Diff
193
sound/soc/codecs/aw882xx/aw882xx_calib.h
Normal file
193
sound/soc/codecs/aw882xx/aw882xx_calib.h
Normal file
@@ -0,0 +1,193 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
* aw882xx_calib.h
|
||||
*
|
||||
* Copyright (c) 2020 AWINIC Technology CO., LTD
|
||||
*
|
||||
* Author: Nick Li <liweilei@awinic.com.cn>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef __AW882XX_CALIBRATION_H__
|
||||
#define __AW882XX_CALIBRATION_H__
|
||||
|
||||
#define AW_CALI_READ_RE_TIMES (8)
|
||||
#define AW_CALI_READ_F0_Q_TIMES (5)
|
||||
#define AW_ERRO_CALI_VALUE (0)
|
||||
#define AW_CALI_RE_DEFAULT_TIMER (3000)
|
||||
|
||||
#define AW_CALI_RE_MAX (15000)
|
||||
#define AW_CALI_RE_MIN (4000)
|
||||
|
||||
#define AW_CALI_CFG_NUM (3)
|
||||
#define AW_CALI_DATA_NUM (6)
|
||||
#define AW_PARAMS_NUM (600)
|
||||
#define AW_KILO_PARAMS_NUM (1000)
|
||||
|
||||
#define AW_CALI_RE_DEFAULT_MAX (50000)
|
||||
#define AW_CALI_RE_DEFAULT_MIN (1000)
|
||||
|
||||
#define AW_DEV_RE_RANGE (RE_RANGE_NUM * AW_DEV_CH_MAX)
|
||||
|
||||
struct aw_device;
|
||||
|
||||
enum afe_module_type {
|
||||
AW_RX_MODULE = 0,
|
||||
AW_TX_MODULE = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
MSG_CALI_DISABLE_DATA = 0,
|
||||
MSG_CALI_RE_ENABLE_DATA,
|
||||
MSG_CALI_F0_ENABLE_DATA,
|
||||
};
|
||||
|
||||
struct cali_cfg {
|
||||
int32_t data[AW_CALI_CFG_NUM];
|
||||
};
|
||||
|
||||
struct cali_data {
|
||||
int32_t data[AW_CALI_DATA_NUM];
|
||||
};
|
||||
|
||||
struct params_data {
|
||||
int32_t data[AW_PARAMS_NUM];
|
||||
};
|
||||
|
||||
struct ptr_params_data {
|
||||
int len;
|
||||
int32_t *data;
|
||||
};
|
||||
|
||||
struct f0_q_data {
|
||||
int32_t data[4];
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_IOCTL_MSG_IOCTL = 0,
|
||||
AW_IOCTL_MSG_RD_DSP,
|
||||
AW_IOCTL_MSG_WR_DSP
|
||||
};
|
||||
|
||||
enum {
|
||||
CALI_CHECK_DISABLE = 0,
|
||||
CALI_CHECK_ENABLE = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
CALI_RESULT_NONE = 0,
|
||||
CALI_RESULT_NORMAL = 1,
|
||||
CALI_RESULT_ERROR = -1,
|
||||
};
|
||||
|
||||
enum {
|
||||
RE_MIN_FLAG = 0,
|
||||
RE_MAX_FLAG = 1,
|
||||
RE_RANGE_NUM = 2,
|
||||
};
|
||||
|
||||
enum {
|
||||
CALI_DATA_RE = 0,
|
||||
CALI_DATA_F0,
|
||||
CALI_DATA_F0_Q,
|
||||
};
|
||||
|
||||
struct re_data {
|
||||
uint32_t re_range[2];
|
||||
};
|
||||
|
||||
#define AW_IOCTL_MSG_VERSION (0)
|
||||
typedef struct {
|
||||
int32_t type;
|
||||
int32_t opcode_id;
|
||||
int32_t version;
|
||||
int32_t data_len;
|
||||
char *data_buf;
|
||||
int32_t reseriver[2];
|
||||
} aw_ioctl_msg_t;
|
||||
|
||||
#define AW_IOCTL_MAGIC 'a'
|
||||
#define AW_IOCTL_SET_CALI_CFG _IOWR(AW_IOCTL_MAGIC, 1, struct cali_cfg)
|
||||
#define AW_IOCTL_GET_CALI_CFG _IOWR(AW_IOCTL_MAGIC, 2, struct cali_cfg)
|
||||
#define AW_IOCTL_GET_CALI_DATA _IOWR(AW_IOCTL_MAGIC, 3, struct cali_data)
|
||||
#define AW_IOCTL_SET_NOISE _IOWR(AW_IOCTL_MAGIC, 4, int32_t)
|
||||
#define AW_IOCTL_GET_F0 _IOWR(AW_IOCTL_MAGIC, 5, int32_t)
|
||||
#define AW_IOCTL_SET_CALI_RE _IOWR(AW_IOCTL_MAGIC, 6, int32_t)
|
||||
#define AW_IOCTL_GET_CALI_RE _IOWR(AW_IOCTL_MAGIC, 7, int32_t)
|
||||
#define AW_IOCTL_SET_VMAX _IOWR(AW_IOCTL_MAGIC, 8, int32_t)
|
||||
#define AW_IOCTL_GET_VMAX _IOWR(AW_IOCTL_MAGIC, 9, int32_t)
|
||||
#define AW_IOCTL_SET_PARAM _IOWR(AW_IOCTL_MAGIC, 10, struct params_data)
|
||||
#define AW_IOCTL_ENABLE_CALI _IOWR(AW_IOCTL_MAGIC, 11, int8_t)
|
||||
#define AW_IOCTL_SET_PTR_PARAM_NUM _IOWR(AW_IOCTL_MAGIC, 12, struct ptr_params_data)
|
||||
#define AW_IOCTL_GET_F0_Q _IOWR(AW_IOCTL_MAGIC, 13, struct f0_q_data)
|
||||
#define AW_IOCTL_SET_DSP_HMUTE _IOWR(AW_IOCTL_MAGIC, 14, int32_t)
|
||||
#define AW_IOCTL_SET_CALI_CFG_FLAG _IOWR(AW_IOCTL_MAGIC, 15, int32_t)
|
||||
#define AW_IOCTL_MSG _IOWR(AW_IOCTL_MAGIC, 16, aw_ioctl_msg_t)
|
||||
#define AW_IOCTL_GET_RE_RANGE _IOWR(AW_IOCTL_MAGIC, 17, struct re_data)
|
||||
|
||||
enum{
|
||||
AW_CALI_MODE_NONE = 0,
|
||||
AW_CALI_MODE_ALL,
|
||||
AW_CALI_MODE_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_CALI_CMD_RE = 0,
|
||||
AW_CALI_CMD_F0,
|
||||
AW_CALI_CMD_RE_F0,
|
||||
AW_CALI_CMD_F0_Q,
|
||||
AW_CALI_CMD_RE_F0_Q,
|
||||
};
|
||||
|
||||
enum {
|
||||
CALI_OPS_HMUTE = 0X0001,
|
||||
CALI_OPS_NOISE = 0X0002,
|
||||
};
|
||||
|
||||
enum {
|
||||
CALI_TYPE_RE = 0,
|
||||
CALI_TYPE_F0,
|
||||
};
|
||||
|
||||
enum {
|
||||
CALI_STR_NONE = 0,
|
||||
CALI_STR_CALI_RE_F0,
|
||||
CALI_STR_CALI_RE,
|
||||
CALI_STR_CALI_F0,
|
||||
CALI_STR_SET_RE,
|
||||
CALI_STR_SHOW_RE, /*show cali_re*/
|
||||
CALI_STR_SHOW_R0, /*show real r0*/
|
||||
CALI_STR_SHOW_CALI_F0, /*GET DEV CALI_F0*/
|
||||
CALI_STR_SHOW_F0, /*SHOW REAL F0*/
|
||||
CALI_STR_SHOW_TE,
|
||||
CALI_STR_SHOW_ST,
|
||||
CALI_STR_DEV_SEL, /*switch device*/
|
||||
CALI_STR_VER,
|
||||
CALI_STR_DEV_NUM,
|
||||
CALI_STR_CALI_F0_Q,
|
||||
CALI_STR_SHOW_F0_Q,
|
||||
CALI_STR_SHOW_RE_RANGE,
|
||||
CALI_STR_MAX,
|
||||
};
|
||||
|
||||
struct aw_cali_desc {
|
||||
unsigned char status;
|
||||
unsigned char mode; /*0:NONE 1:ATTR 2:CLASS 3:MISC */
|
||||
int32_t cali_re; /*set cali_re*/
|
||||
int32_t cali_f0; /*store cali_f0*/
|
||||
int32_t cali_q; /*store cali q*/
|
||||
int8_t cali_result;
|
||||
uint8_t cali_check_st;
|
||||
};
|
||||
|
||||
int aw882xx_cali_init(struct aw_cali_desc *cali_desc);
|
||||
void aw882xx_cali_deinit(struct aw_cali_desc *cali_desc);
|
||||
int aw882xx_cali_svc_get_cali_status(void);
|
||||
int aw882xx_cali_read_re_from_nvram(int32_t *cali_re, int32_t ch_index);
|
||||
bool aw882xx_cali_check_result(struct aw_cali_desc *cali_desc);
|
||||
|
||||
|
||||
#endif
|
||||
165
sound/soc/codecs/aw882xx/aw882xx_data_type.h
Normal file
165
sound/soc/codecs/aw882xx/aw882xx_data_type.h
Normal file
@@ -0,0 +1,165 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
* aw882xx_data_type.h
|
||||
*
|
||||
* Copyright (c) 2020 AWINIC Technology CO., LTD
|
||||
*
|
||||
* Author: Nick Li <liweilei@awinic.com.cn>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef __AW882XX_DATA_TYPE_H__
|
||||
#define __AW882XX_DATA_TYPE_H__
|
||||
|
||||
#define AW_NAME_BUF_MAX (50)
|
||||
|
||||
struct aw_msg_hdr {
|
||||
int32_t type;
|
||||
int32_t opcode_id;
|
||||
int32_t version;
|
||||
int32_t reseriver[3];
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* aw profile
|
||||
*******************************************************************/
|
||||
#define PROJECT_NAME_MAX (24)
|
||||
#define CUSTOMER_NAME_MAX (16)
|
||||
#define CFG_VERSION_MAX (4)
|
||||
#define DEV_NAME_MAX (16)
|
||||
#define PROFILE_STR_MAX (32)
|
||||
#define AW_INIT_PROFILE (0)
|
||||
|
||||
#define ACF_FILE_ID (0xa15f908)
|
||||
|
||||
|
||||
enum aw_cfg_hdr_version {
|
||||
AW_CFG_HDR_VER_0_0_0_1 = 0x00000001,
|
||||
AW_CFG_HDR_VER_1_0_0_0 = 0x01000000,
|
||||
};
|
||||
|
||||
enum aw_cfg_dde_type {
|
||||
AW_DEV_TYPE_ID = 0x00000000,
|
||||
AW_SKT_TYPE_ID = 0x00000001,
|
||||
AW_DEV_DEFAULT_TYPE_ID = 0x00000002,
|
||||
};
|
||||
|
||||
enum aw_sec_type {
|
||||
ACF_SEC_TYPE_REG = 0,
|
||||
ACF_SEC_TYPE_DSP,
|
||||
ACF_SEC_TYPE_DSP_CFG,
|
||||
ACF_SEC_TYPE_DSP_FW,
|
||||
ACF_SEC_TYPE_HDR_REG,
|
||||
ACF_SEC_TYPE_HDR_DSP_CFG,
|
||||
ACF_SEC_TYPE_HDR_DSP_FW,
|
||||
ACF_SEC_TYPE_MUTLBIN,
|
||||
ACF_SEC_TYPE_SKT_PROJECT,
|
||||
ACF_SEC_TYPE_DSP_PROJECT,
|
||||
ACF_SEC_TYPE_MONITOR,
|
||||
ACF_SEC_TYPE_MAX,
|
||||
};
|
||||
|
||||
enum profile_data_type {
|
||||
AW_PROFILE_DATA_TYPE_REG = 0,
|
||||
AW_PROFILE_DATA_TYPE_DSP,
|
||||
AW_PROFILE_DATA_TYPE_MAX,
|
||||
};
|
||||
|
||||
enum aw_prof_type {
|
||||
AW_PROFILE_MUSIC = 0,
|
||||
AW_PROFILE_VOICE,
|
||||
AW_PROFILE_VOIP,
|
||||
AW_PROFILE_RINGTONE,
|
||||
AW_PROFILE_RINGTONE_HS,
|
||||
AW_PROFILE_LOWPOWER,
|
||||
AW_PROFILE_BYPASS,
|
||||
AW_PROFILE_MMI,
|
||||
AW_PROFILE_FM,
|
||||
AW_PROFILE_NOTIFICATION,
|
||||
AW_PROFILE_RECEIVER,
|
||||
AW_PROFILE_MAX,
|
||||
};
|
||||
|
||||
enum aw_profile_status {
|
||||
AW_PROFILE_WAIT = 0,
|
||||
AW_PROFILE_OK,
|
||||
};
|
||||
|
||||
struct aw_cfg_hdr {
|
||||
uint32_t a_id; /*acf file ID 0xa15f908*/
|
||||
char a_project[PROJECT_NAME_MAX]; /*project name*/
|
||||
char a_custom[CUSTOMER_NAME_MAX]; /*custom name :huawei xiaomi vivo oppo*/
|
||||
char a_version[CFG_VERSION_MAX]; /*author update version*/
|
||||
uint32_t a_author_id; /*author id*/
|
||||
uint32_t a_ddt_size; /*sub section table entry size*/
|
||||
uint32_t a_ddt_num; /*sub section table entry num*/
|
||||
uint32_t a_hdr_offset; /*sub section table offset in file*/
|
||||
uint32_t a_hdr_version; /*sub section table version*/
|
||||
uint32_t reserve[3];
|
||||
};
|
||||
|
||||
struct aw_cfg_dde {
|
||||
uint32_t type; /*DDE type id*/
|
||||
char dev_name[DEV_NAME_MAX];
|
||||
uint16_t dev_index; /*dev id*/
|
||||
uint16_t dev_bus; /*dev bus id*/
|
||||
uint16_t dev_addr; /*dev addr id*/
|
||||
uint16_t dev_profile; /*dev profile id*/
|
||||
uint32_t data_type; /*data type id*/
|
||||
uint32_t data_size;
|
||||
uint32_t data_offset;
|
||||
uint32_t data_crc;
|
||||
uint32_t reserve[5];
|
||||
};
|
||||
|
||||
struct aw_cfg_dde_v_1_0_0_0 {
|
||||
uint32_t type; /*DDE type id*/
|
||||
char dev_name[DEV_NAME_MAX];
|
||||
uint16_t dev_index; /*dev id*/
|
||||
uint16_t dev_bus; /*dev bus id*/
|
||||
uint16_t dev_addr; /*dev addr id*/
|
||||
uint16_t dev_profile; /*dev profile id*/
|
||||
uint32_t data_type; /*data type id*/
|
||||
uint32_t data_size;
|
||||
uint32_t data_offset;
|
||||
uint32_t data_crc;
|
||||
char dev_profile_str[PROFILE_STR_MAX];
|
||||
uint32_t chip_id;
|
||||
uint32_t reserve[4];
|
||||
};
|
||||
|
||||
|
||||
struct aw_container {
|
||||
unsigned int len;
|
||||
unsigned char data[];
|
||||
};
|
||||
|
||||
struct aw_sec_data_desc {
|
||||
uint32_t len;
|
||||
char *data;
|
||||
};
|
||||
|
||||
struct aw_prof_desc {
|
||||
uint32_t prof_st; /*Only used in V0.0.0.1 header*/
|
||||
uint32_t id;
|
||||
char *prf_str;
|
||||
struct aw_sec_data_desc sec_desc[AW_PROFILE_DATA_TYPE_MAX];
|
||||
};
|
||||
|
||||
struct aw_all_prof_info {
|
||||
struct aw_prof_desc prof_desc[AW_PROFILE_MAX];
|
||||
};
|
||||
|
||||
struct aw_prof_info {
|
||||
uint32_t count;
|
||||
char **prof_name_list;
|
||||
struct aw_prof_desc *prof_desc;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
1593
sound/soc/codecs/aw882xx/aw882xx_device.c
Normal file
1593
sound/soc/codecs/aw882xx/aw882xx_device.c
Normal file
File diff suppressed because it is too large
Load Diff
463
sound/soc/codecs/aw882xx/aw882xx_device.h
Normal file
463
sound/soc/codecs/aw882xx/aw882xx_device.h
Normal file
@@ -0,0 +1,463 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
* aw882xx_device.h
|
||||
*
|
||||
* Copyright (c) 2020 AWINIC Technology CO., LTD
|
||||
*
|
||||
* Author: Nick Li <liweilei@awinic.com.cn>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef __AW882XX_DEVICE_FILE_H__
|
||||
#define __AW882XX_DEVICE_FILE_H__
|
||||
#include "aw882xx_data_type.h"
|
||||
#include "aw882xx_calib.h"
|
||||
#include "aw882xx_monitor.h"
|
||||
#include "aw882xx_dsp.h"
|
||||
|
||||
#define AW_VOLUME_STEP_DB (6 * 2)
|
||||
#define AW_REG_NONE (0xFF)
|
||||
#define AW_NAME_MAX (50)
|
||||
#define ALGO_VERSION_MAX (80)
|
||||
|
||||
#define AW_GET_MIN_VALUE(value1, value2) \
|
||||
((value1) > (value2) ? (value2) : (value1))
|
||||
|
||||
#define AW_GET_MAX_VALUE(value1, value2) \
|
||||
((value1) > (value2) ? (value1) : (value2))
|
||||
|
||||
extern int g_algo_auth_st;
|
||||
|
||||
enum {
|
||||
AW_1000_US = 1000,
|
||||
AW_2000_US = 2000,
|
||||
AW_3000_US = 3000,
|
||||
AW_4000_US = 4000,
|
||||
AW_5000_US = 5000,
|
||||
AW_10000_US = 10000,
|
||||
AW_32000_US = 32000,
|
||||
AW_70000_US = 70000,
|
||||
AW_100000_US = 100000,
|
||||
};
|
||||
|
||||
struct aw_device;
|
||||
|
||||
enum {
|
||||
AW_DEV_TYPE_NONE = 0,
|
||||
AW_DEV_TYPE_OK,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_EF_AND_CHECK = 0,
|
||||
AW_EF_OR_CHECK,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_DEV_CH_PRI_L = 0,
|
||||
AW_DEV_CH_PRI_R = 1,
|
||||
AW_DEV_CH_SEC_L = 2,
|
||||
AW_DEV_CH_SEC_R = 3,
|
||||
AW_DEV_CH_TERT_L = 4,
|
||||
AW_DEV_CH_TERT_R = 5,
|
||||
AW_DEV_CH_QUAT_L = 6,
|
||||
AW_DEV_CH_QUAT_R = 7,
|
||||
AW_DEV_CH_MAX,
|
||||
};
|
||||
|
||||
enum AW_DEV_INIT {
|
||||
AW_DEV_INIT_ST = 0,
|
||||
AW_DEV_INIT_OK = 1,
|
||||
AW_DEV_INIT_NG = 2,
|
||||
};
|
||||
|
||||
enum AW_DEV_STATUS {
|
||||
AW_DEV_PW_OFF = 0,
|
||||
AW_DEV_PW_ON,
|
||||
};
|
||||
|
||||
enum AW_DEV_FW_STATUS {
|
||||
AW_DEV_FW_FAILED = 0,
|
||||
AW_DEV_FW_OK,
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
AW_EXT_DSP_WRITE_NONE = 0,
|
||||
AW_EXT_DSP_WRITE,
|
||||
};
|
||||
|
||||
enum AW_SPIN_KCONTROL_STATUS {
|
||||
AW_SPIN_KCONTROL_DISABLE = 0,
|
||||
AW_SPIN_KCONTROL_ENABLE,
|
||||
};
|
||||
|
||||
enum AW_ALGO_AUTH_MODE {
|
||||
AW_ALGO_AUTH_DISABLE = 0,
|
||||
AW_ALGO_AUTH_MODE_MAGIC_ID,
|
||||
AW_ALGO_AUTH_MODE_REG_CRC,
|
||||
};
|
||||
|
||||
enum AW_ALGO_AUTH_ID {
|
||||
AW_ALGO_AUTH_MAGIC_ID = 0x4157,
|
||||
};
|
||||
|
||||
enum AW_ALGO_AUTH_STATUS {
|
||||
AW_ALGO_AUTH_WAIT = 0,
|
||||
AW_ALGO_AUTH_OK = 1,
|
||||
};
|
||||
|
||||
struct aw_device_ops {
|
||||
int (*aw_i2c_write)(struct aw_device *aw_dev, unsigned char reg_addr, unsigned int reg_data);
|
||||
int (*aw_i2c_read)(struct aw_device *aw_dev, unsigned char reg_addr, unsigned int *reg_data);
|
||||
int (*aw_i2c_write_bits)(struct aw_device *aw_dev, unsigned char reg_addr, unsigned int mask, unsigned int reg_data);
|
||||
int (*aw_set_hw_volume)(struct aw_device *aw_dev, unsigned int value);
|
||||
int (*aw_get_hw_volume)(struct aw_device *aw_dev, unsigned int *value);
|
||||
unsigned int (*aw_reg_val_to_db)(unsigned int value);
|
||||
bool (*aw_check_wr_access)(int reg);
|
||||
bool (*aw_check_rd_access)(int reg);
|
||||
int (*aw_get_reg_num)(void);
|
||||
int (*aw_get_version)(char *buf, int size);
|
||||
int (*aw_get_dev_num)(void);
|
||||
void (*aw_set_algo)(struct aw_device *aw_dev);
|
||||
unsigned int (*aw_get_irq_type)(struct aw_device *aw_dev, unsigned int value);
|
||||
void (*aw_reg_force_set)(struct aw_device *aw_dev);
|
||||
int (*aw_frcset_check)(struct aw_device *aw_dev);
|
||||
};
|
||||
|
||||
struct aw_int_desc {
|
||||
unsigned int mask_reg; /*interrupt mask reg*/
|
||||
unsigned int st_reg; /*interrupt status reg*/
|
||||
unsigned int mask_default; /*default mask close all*/
|
||||
unsigned int int_mask; /*set mask*/
|
||||
};
|
||||
|
||||
struct aw_work_mode {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int spk_val;
|
||||
unsigned int rcv_val;
|
||||
};
|
||||
|
||||
struct aw_soft_rst {
|
||||
int reg;
|
||||
int reg_value;
|
||||
};
|
||||
|
||||
struct aw_pwd_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int enable;
|
||||
unsigned int disable;
|
||||
};
|
||||
|
||||
struct aw_amppd_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int enable;
|
||||
unsigned int disable;
|
||||
};
|
||||
|
||||
struct aw_bop_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int enable;
|
||||
unsigned int disbale;
|
||||
};
|
||||
|
||||
struct aw_vcalb_desc {
|
||||
unsigned int icalk_reg;
|
||||
unsigned int icalk_reg_mask;
|
||||
unsigned int icalk_shift;
|
||||
unsigned int icalkl_reg;
|
||||
unsigned int icalkl_reg_mask;
|
||||
unsigned int icalkl_shift;
|
||||
unsigned int icalk_sign_mask;
|
||||
unsigned int icalk_neg_mask;
|
||||
int icalk_value_factor;
|
||||
|
||||
unsigned int vcalk_reg;
|
||||
unsigned int vcalk_reg_mask;
|
||||
unsigned int vcalk_shift;
|
||||
unsigned int vcalkl_reg;
|
||||
unsigned int vcalkl_reg_mask;
|
||||
unsigned int vcalkl_shift;
|
||||
unsigned int vcalk_sign_mask;
|
||||
unsigned int vcalk_neg_mask;
|
||||
int vcalk_value_factor;
|
||||
|
||||
unsigned int vcalb_reg;
|
||||
int cabl_base_value;
|
||||
int vcal_factor;
|
||||
};
|
||||
|
||||
struct aw_mute_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int enable;
|
||||
unsigned int disable;
|
||||
};
|
||||
|
||||
struct aw_uls_hmute_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int enable;
|
||||
unsigned int disable;
|
||||
};
|
||||
|
||||
struct aw_txen_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int enable;
|
||||
unsigned int disable;
|
||||
unsigned int reserve_val;
|
||||
};
|
||||
|
||||
struct aw_sysst_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int st_check;
|
||||
unsigned int st_sws_check;
|
||||
unsigned int pll_check;
|
||||
};
|
||||
|
||||
struct aw_profctrl_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int spk_mode;
|
||||
unsigned int cfg_prof_mode;
|
||||
};
|
||||
|
||||
struct aw_bstctrl_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int frc_bst;
|
||||
unsigned int tsp_type;
|
||||
unsigned int cfg_bst_type;
|
||||
};
|
||||
|
||||
struct aw_cco_mux_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int divided_val;
|
||||
unsigned int bypass_val;
|
||||
};
|
||||
|
||||
struct aw_volume_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int shift;
|
||||
int init_volume;
|
||||
int mute_volume;
|
||||
int ctl_volume;
|
||||
int monitor_volume;
|
||||
};
|
||||
|
||||
struct aw_voltage_desc {
|
||||
unsigned int reg;
|
||||
unsigned int vbat_range;
|
||||
unsigned int int_bit;
|
||||
};
|
||||
|
||||
struct aw_temperature_desc {
|
||||
unsigned int reg;
|
||||
unsigned int sign_mask;
|
||||
unsigned int neg_mask;
|
||||
};
|
||||
|
||||
struct aw_ipeak_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
};
|
||||
|
||||
struct aw_spin_ch {
|
||||
uint16_t rx_val;
|
||||
};
|
||||
|
||||
struct aw_reg_ch {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int left_val;
|
||||
unsigned int right_val;
|
||||
};
|
||||
|
||||
struct aw_spin_desc {
|
||||
int aw_spin_kcontrol_st;
|
||||
struct aw_spin_ch spin_table[AW_SPIN_MAX];
|
||||
struct aw_reg_ch rx_desc;
|
||||
};
|
||||
|
||||
struct aw_efcheck_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int and_val;
|
||||
unsigned int or_val;
|
||||
};
|
||||
|
||||
struct aw_dither_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int enable;
|
||||
unsigned int disable;
|
||||
};
|
||||
|
||||
struct aw_noise_gate_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
};
|
||||
|
||||
struct aw_psm_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int enable;
|
||||
unsigned int disable;
|
||||
};
|
||||
|
||||
struct aw_mpd_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int enable;
|
||||
unsigned int disable;
|
||||
};
|
||||
|
||||
struct aw_dsmzth_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int enable;
|
||||
unsigned int disable;
|
||||
};
|
||||
|
||||
struct aw_auth_desc {
|
||||
uint8_t reg_in;
|
||||
uint8_t reg_out;
|
||||
int32_t auth_mode;
|
||||
int32_t reg_crc;
|
||||
int32_t random;
|
||||
int32_t chip_id;
|
||||
int32_t check_result;
|
||||
};
|
||||
|
||||
struct algo_auth_data {
|
||||
int32_t auth_mode; /* 0: disable 1 : chip ID 2 : reg crc */
|
||||
int32_t reg_crc;
|
||||
int32_t random;
|
||||
int32_t chip_id;
|
||||
int32_t check_result;
|
||||
};
|
||||
|
||||
#define AW_IOCTL_MAGIC_S 'w'
|
||||
#define AW_IOCTL_GET_ALGO_AUTH _IOWR(AW_IOCTL_MAGIC_S, 1, struct algo_auth_data)
|
||||
#define AW_IOCTL_SET_ALGO_AUTH _IOWR(AW_IOCTL_MAGIC_S, 2, struct algo_auth_data)
|
||||
|
||||
|
||||
struct aw_device {
|
||||
int status;
|
||||
unsigned int chip_id;
|
||||
unsigned int monitor_start;
|
||||
int bstcfg_enable;
|
||||
int frcset_en;
|
||||
int bop_en;
|
||||
int efuse_check;
|
||||
int fade_en;
|
||||
unsigned int mute_st;
|
||||
unsigned int amppd_st;
|
||||
unsigned int dither_st;
|
||||
unsigned int txen_st;
|
||||
|
||||
unsigned char cur_prof; /*current profile index*/
|
||||
unsigned char set_prof; /*set profile index*/
|
||||
unsigned int channel; /*pa channel select*/
|
||||
unsigned int vol_step;
|
||||
unsigned int re_max;
|
||||
unsigned int re_min;
|
||||
|
||||
struct device *dev;
|
||||
struct i2c_client *i2c;
|
||||
char monitor_name[AW_NAME_MAX];
|
||||
void *private_data;
|
||||
|
||||
struct aw_int_desc int_desc;
|
||||
struct aw_work_mode work_mode;
|
||||
struct aw_pwd_desc pwd_desc;
|
||||
struct aw_amppd_desc amppd_desc;
|
||||
struct aw_mute_desc mute_desc;
|
||||
struct aw_uls_hmute_desc uls_hmute_desc;
|
||||
struct aw_txen_desc txen_desc;
|
||||
struct aw_vcalb_desc vcalb_desc;
|
||||
struct aw_sysst_desc sysst_desc;
|
||||
struct aw_profctrl_desc profctrl_desc;
|
||||
struct aw_bstctrl_desc bstctrl_desc;
|
||||
struct aw_cco_mux_desc cco_mux_desc;
|
||||
struct aw_voltage_desc voltage_desc;
|
||||
struct aw_temperature_desc temp_desc;
|
||||
struct aw_ipeak_desc ipeak_desc;
|
||||
struct aw_volume_desc volume_desc;
|
||||
struct aw_prof_info prof_info;
|
||||
struct aw_cali_desc cali_desc;
|
||||
struct aw_monitor_desc monitor_desc;
|
||||
struct aw_soft_rst soft_rst;
|
||||
struct aw_spin_desc spin_desc;
|
||||
struct aw_bop_desc bop_desc;
|
||||
struct aw_efcheck_desc efcheck_desc;
|
||||
struct aw_dither_desc dither_desc;
|
||||
struct aw_noise_gate_desc noise_gate_desc;
|
||||
struct aw_psm_desc psm_desc;
|
||||
struct aw_mpd_desc mpd_desc;
|
||||
struct aw_dsmzth_desc dsmzth_desc;
|
||||
struct aw_auth_desc auth_desc;
|
||||
struct aw_device_ops ops;
|
||||
struct list_head list_node;
|
||||
};
|
||||
|
||||
|
||||
void aw882xx_dev_deinit(struct aw_device *aw_dev);
|
||||
int aw882xx_device_init(struct aw_device *aw_dev, struct aw_container *aw_cfg);
|
||||
int aw882xx_device_start(struct aw_device *aw_dev);
|
||||
int aw882xx_device_stop(struct aw_device *aw_dev);
|
||||
int aw882xx_dev_reg_update(struct aw_device *aw_dev, bool force);
|
||||
int aw882xx_device_irq_reinit(struct aw_device *aw_dev);
|
||||
|
||||
struct mutex *aw882xx_dev_get_ext_dsp_prof_wr_lock(void);
|
||||
char *aw882xx_dev_get_ext_dsp_prof_write(void);
|
||||
|
||||
/*re*/
|
||||
int aw882xx_dev_get_cali_re(struct aw_device *aw_dev, int32_t *cali_re);
|
||||
int aw882xx_dev_init_cali_re(struct aw_device *aw_dev);
|
||||
int aw882xx_dev_dc_status(struct aw_device *aw_dev);
|
||||
|
||||
/*interrupt*/
|
||||
int aw882xx_dev_status(struct aw_device *aw_dev);
|
||||
int aw882xx_dev_get_int_status(struct aw_device *aw_dev, uint16_t *int_status);
|
||||
void aw882xx_dev_clear_int_status(struct aw_device *aw_dev);
|
||||
int aw882xx_dev_set_intmask(struct aw_device *aw_dev, bool flag);
|
||||
|
||||
/*fade int / out*/
|
||||
void aw882xx_dev_set_fade_vol_step(struct aw_device *aw_dev, unsigned int step);
|
||||
int aw882xx_dev_get_fade_vol_step(struct aw_device *aw_dev);
|
||||
void aw882xx_dev_get_fade_time(unsigned int *time, bool fade_in);
|
||||
void aw882xx_dev_set_fade_time(unsigned int time, bool fade_in);
|
||||
|
||||
/*dsp kcontrol*/
|
||||
int aw882xx_dev_set_afe_module_en(int type, int enable);
|
||||
int aw882xx_dev_get_afe_module_en(int type, int *status);
|
||||
int aw882xx_dev_set_copp_module_en(bool enable);
|
||||
|
||||
int aw882xx_device_probe(struct aw_device *aw_dev);
|
||||
int aw882xx_device_remove(struct aw_device *aw_dev);
|
||||
int aw882xx_dev_get_list_head(struct list_head **head);
|
||||
|
||||
int aw882xx_dev_set_volume(struct aw_device *aw_dev, unsigned int set_vol);
|
||||
int aw882xx_dev_get_volume(struct aw_device *aw_dev, unsigned int *get_vol);
|
||||
void aw882xx_dev_mute(struct aw_device *aw_dev, bool mute);
|
||||
|
||||
|
||||
void aw882xx_dev_monitor_hal_get_time(struct aw_device *aw_dev, uint32_t *time);
|
||||
void aw882xx_dev_monitor_hal_work(struct aw_device *aw_dev, uint32_t *vmax);
|
||||
|
||||
int aw882xx_dev_algo_auth_mode(struct aw_device *aw_dev, struct algo_auth_data *algo_data);
|
||||
void aw882xx_dev_iv_forbidden_output(struct aw_device *aw_dev, bool power_waste);
|
||||
|
||||
#endif
|
||||
|
||||
1309
sound/soc/codecs/aw882xx/aw882xx_dsp.c
Normal file
1309
sound/soc/codecs/aw882xx/aw882xx_dsp.c
Normal file
File diff suppressed because it is too large
Load Diff
109
sound/soc/codecs/aw882xx/aw882xx_dsp.h
Normal file
109
sound/soc/codecs/aw882xx/aw882xx_dsp.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
* aw882xx_dsp.h
|
||||
*
|
||||
* Copyright (c) 2020 AWINIC Technology CO., LTD
|
||||
*
|
||||
* Author: Nick Li <liweilei@awinic.com.cn>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef __AW882XX_DSP_H__
|
||||
#define __AW882XX_DSP_H__
|
||||
|
||||
//#define AW_MTK_PLATFORM_WITH_DSP
|
||||
|
||||
//#define AW_QCOM_ADM_MSG
|
||||
/*#define AW_ALGO_AUTH_DSP*/
|
||||
/*factor form 12bit(4096) to 1000*/
|
||||
#define AW_DSP_RE_TO_SHOW_RE(re) (((re) * (1000)) >> (12))
|
||||
#define AW_SHOW_RE_TO_DSP_RE(re) (((re) << 12) / (1000))
|
||||
|
||||
#define AW_DSP_SLEEP_TIME (10)
|
||||
|
||||
#define AW_TX_DEFAULT_TOPO_ID (0x1000FF00)
|
||||
#define AW_RX_DEFAULT_TOPO_ID (0x1000FF01)
|
||||
#define AW_TX_DEFAULT_PORT_ID (0x1007)
|
||||
#define AW_RX_DEFAULT_PORT_ID (0x1006)
|
||||
|
||||
#define AW_DSP_MSG_VER (0x10000000)
|
||||
#define AW_DSP_CHANNEL_DEFAULT_NUM (1)
|
||||
|
||||
enum aw_dsp_msg_type {
|
||||
AW_DSP_MSG_TYPE_DATA = 0,
|
||||
AW_DSP_MSG_TYPE_CMD = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_SPIN_0 = 0,
|
||||
AW_SPIN_90,
|
||||
AW_SPIN_180,
|
||||
AW_SPIN_270,
|
||||
AW_SPIN_MAX,
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
AW_AUDIO_MIX_DSIABLE = 0,
|
||||
AW_AUDIO_MIX_ENABLE,
|
||||
};
|
||||
|
||||
#define AW_DSP_MSG_HDR_VER (1)
|
||||
typedef struct aw_msg_hdr aw_dsp_msg_t;
|
||||
|
||||
enum {
|
||||
DSP_MSG_TYPE_WRITE_CMD = 0,
|
||||
DSP_MSG_TYPE_WRITE_DATA,
|
||||
DSP_MSG_TYPE_READ_DATA,
|
||||
};
|
||||
|
||||
typedef struct aw_msg_hdr_v_1_0_0_0 {
|
||||
int32_t checksum;
|
||||
int32_t version;
|
||||
int32_t type;
|
||||
int32_t params_id;
|
||||
int32_t channel;
|
||||
int32_t num;
|
||||
int32_t data_size;
|
||||
int32_t reseriver[3];
|
||||
} aw_msg_hdr_t;
|
||||
|
||||
int aw882xx_dsp_read_dsp_msg(struct aw_device *aw_dev, uint32_t msg_id, char *data_ptr, unsigned int size);
|
||||
int aw882xx_dsp_write_dsp_msg(struct aw_device *aw_dev, uint32_t msg_id, char *data_ptr, unsigned int size);
|
||||
int aw882xx_dsp_write_cali_cfg(struct aw_device *aw_dev, char *data, unsigned int data_len);
|
||||
int aw882xx_dsp_read_cali_cfg(struct aw_device *aw_dev, char *data, unsigned int data_len);
|
||||
int aw882xx_dsp_noise_en(struct aw_device *aw_dev, bool is_noise);
|
||||
int aw882xx_dsp_write_vmax(struct aw_device *aw_dev, char *data, unsigned int data_len);
|
||||
int aw882xx_dsp_read_vmax(struct aw_device *aw_dev, char *data, unsigned int data_len);
|
||||
int aw882xx_dsp_write_params(struct aw_device *aw_dev, char *data, unsigned int data_len);
|
||||
int aw882xx_dsp_write_cali_re(struct aw_device *aw_dev, int32_t cali_re);
|
||||
int aw882xx_dsp_read_cali_re(struct aw_device *aw_dev, int32_t *cali_re);
|
||||
int aw882xx_dsp_read_r0(struct aw_device *aw_dev, int32_t *r0);
|
||||
int aw882xx_dsp_read_st(struct aw_device *aw_dev, int32_t *r0, int32_t *te);
|
||||
int aw882xx_dsp_read_te(struct aw_device *aw_dev, int32_t *te);
|
||||
int aw882xx_dsp_get_dc_status(struct aw_device *aw_dev);
|
||||
int aw882xx_dsp_hmute_en(struct aw_device *aw_dev, bool is_hmute);
|
||||
int aw882xx_dsp_cali_en(struct aw_device *aw_dev, int32_t cali_msg_data);
|
||||
int aw882xx_dsp_read_f0(struct aw_device *aw_dev, int32_t *f0);
|
||||
int aw882xx_dsp_read_f0_q(struct aw_device *aw_dev, int32_t *f0, int32_t *q);
|
||||
int aw882xx_dsp_read_cali_data(struct aw_device *aw_dev, char *data, unsigned int data_len);
|
||||
int aw882xx_dsp_set_afe_module_en(int type, int enable);
|
||||
int aw882xx_dsp_get_afe_module_en(int type, int *status);
|
||||
int aw882xx_dsp_set_copp_module_en(bool enable);
|
||||
int aw882xx_dsp_write_spin(int spin_mode);
|
||||
int aw882xx_dsp_read_spin(int *spin_mode);
|
||||
int aw882xx_get_algo_version(struct aw_device *aw_dev, char *algo_ver_buf);
|
||||
void aw882xx_device_parse_topo_id_dt(struct aw_device *aw_dev);
|
||||
void aw882xx_device_parse_port_id_dt(struct aw_device *aw_dev);
|
||||
int aw882xx_dsp_set_mixer_en(struct aw_device *aw_dev, uint32_t mixer_en);
|
||||
#ifdef AW_ALGO_AUTH_DSP
|
||||
int aw882xx_dsp_read_algo_auth_data(struct aw_device *aw_dev,
|
||||
char *data, unsigned int data_len);
|
||||
int aw882xx_dsp_write_algo_auth_data(struct aw_device *aw_dev,
|
||||
char *data, unsigned int data_len);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
2277
sound/soc/codecs/aw882xx/aw882xx_init.c
Normal file
2277
sound/soc/codecs/aw882xx/aw882xx_init.c
Normal file
File diff suppressed because it is too large
Load Diff
35
sound/soc/codecs/aw882xx/aw882xx_log.h
Normal file
35
sound/soc/codecs/aw882xx/aw882xx_log.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
* aw882xx_log.h
|
||||
*
|
||||
* Copyright (c) 2020 AWINIC Technology CO., LTD
|
||||
*
|
||||
* Author: Nick Li <liweilei@awinic.com.cn>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef __AW882XX_LOG_H__
|
||||
#define __AW882XX_LOG_H__
|
||||
|
||||
/********************************************
|
||||
* print information control
|
||||
*******************************************/
|
||||
#define aw_dev_err(dev, format, ...) \
|
||||
pr_err("[Awinic][%s]%s: " format "\n", dev_name(dev), __func__, ##__VA_ARGS__)
|
||||
#define aw_dev_info(dev, format, ...) \
|
||||
pr_info("[Awinic][%s]%s: " format "\n", dev_name(dev), __func__, ##__VA_ARGS__)
|
||||
#define aw_dev_dbg(dev, format, ...) \
|
||||
pr_debug("[Awinic][%s]%s: " format "\n", dev_name(dev), __func__, ##__VA_ARGS__)
|
||||
|
||||
#define aw_pr_err(format, ...) \
|
||||
pr_err("[Awinic]%s: " format "\n", __func__, ##__VA_ARGS__)
|
||||
#define aw_pr_info(format, ...) \
|
||||
pr_info("[Awinic]%s: " format "\n", __func__, ##__VA_ARGS__)
|
||||
#define aw_pr_dbg(format, ...) \
|
||||
pr_debug("[Awinic]%s: " format "\n", __func__, ##__VA_ARGS__)
|
||||
|
||||
#endif
|
||||
|
||||
1431
sound/soc/codecs/aw882xx/aw882xx_monitor.c
Normal file
1431
sound/soc/codecs/aw882xx/aw882xx_monitor.c
Normal file
File diff suppressed because it is too large
Load Diff
234
sound/soc/codecs/aw882xx/aw882xx_monitor.h
Normal file
234
sound/soc/codecs/aw882xx/aw882xx_monitor.h
Normal file
@@ -0,0 +1,234 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
* aw882xx_monitor.h
|
||||
*
|
||||
* Copyright (c) 2020 AWINIC Technology CO., LTD
|
||||
*
|
||||
* Author: Nick Li <liweilei@awinic.com.cn>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef __AW882XX_MONITOR_H__
|
||||
#define __AW882XX_MONITOR_H__
|
||||
|
||||
/*#define AW_DEBUG*/
|
||||
|
||||
struct aw_table;
|
||||
|
||||
#define AW_TABLE_SIZE sizeof(struct aw_table)
|
||||
#define AW_MONITOR_DEFAULT_FLAG (0)
|
||||
|
||||
#define IPEAK_NONE (0xFF)
|
||||
#define GAIN_NONE (0xFF)
|
||||
#define VMAX_NONE (0xFFFFFFFF)
|
||||
|
||||
|
||||
#define AW_GET_32_DATA(w, x, y, z) \
|
||||
((uint32_t)((((uint8_t)w) << 24) | (((uint8_t)x) << 16) | (((uint8_t)y) << 8) | ((uint8_t)z)))
|
||||
#define AW_GET_16_DATA(x, y) \
|
||||
((uint16_t)((((uint8_t)x) << 8) | (uint8_t)y))
|
||||
|
||||
enum {
|
||||
AW_MON_LOGIC_OR = 0,
|
||||
AW_MON_LOGIC_AND = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_FIRST_ENTRY = 0,
|
||||
AW_NOT_FIRST_ENTRY = 1,
|
||||
};
|
||||
|
||||
enum aw_monitor_hdr_ver {
|
||||
AW_MONITOR_HDR_VER_0_1_0 = 0x00010000,
|
||||
AW_MONITOR_HDR_VER_0_1_1 = 0x00010100,
|
||||
AW_MONITOR_HDR_VER_0_1_2 = 0x00010200,
|
||||
};
|
||||
|
||||
enum aw_monitor_init {
|
||||
AW_MON_CFG_ST = 0,
|
||||
AW_MON_CFG_OK = 1,
|
||||
};
|
||||
|
||||
struct aw_monitor_hdr {
|
||||
uint32_t check_sum;
|
||||
uint32_t monitor_ver;
|
||||
char chip_type[8];
|
||||
uint32_t ui_ver;
|
||||
uint32_t monitor_switch;
|
||||
uint32_t monitor_time;
|
||||
uint32_t monitor_count;
|
||||
uint32_t ipeak_switch;
|
||||
uint32_t gain_switch;
|
||||
uint32_t vmax_switch;
|
||||
uint32_t temp_switch;
|
||||
uint32_t temp_aplha;
|
||||
uint32_t temp_num;
|
||||
uint32_t single_temp_size;
|
||||
uint32_t temp_offset;
|
||||
uint32_t vol_switch;
|
||||
uint32_t vol_aplha;
|
||||
uint32_t vol_num;
|
||||
uint32_t single_vol_size;
|
||||
uint32_t vol_offset;
|
||||
};
|
||||
|
||||
#define MONITOR_EN_MASK (0x01)
|
||||
|
||||
enum {
|
||||
MONITOR_EN_BIT = 0,
|
||||
MONITOR_LOGIC_BIT = 1,
|
||||
MONITOR_IPEAK_EN_BIT = 2,
|
||||
MONITOR_GAIN_EN_BIT = 3,
|
||||
MONITOR_VMAX_EN_BIT = 4,
|
||||
MONITOR_TEMP_EN_BIT = 5,
|
||||
MONITOR_VOL_EN_BIT = 6,
|
||||
MONITOR_TEMPERATURE_SOURCE_BIT = 7,
|
||||
MONITOR_VOLTAGE_SOURCE_BIT = 8,
|
||||
MONITOR_VOLTAGE_MODE_BIT = 9,
|
||||
};
|
||||
|
||||
struct aw_monitor_hdr_v_0_1_1 {
|
||||
uint32_t check_sum;
|
||||
uint32_t monitor_ver;
|
||||
char chip_type[16];
|
||||
uint32_t ui_ver;
|
||||
uint32_t monitor_time;
|
||||
uint32_t monitor_count;
|
||||
uint32_t enable_flag;
|
||||
/* [bit 31:7] */
|
||||
/* [bit 6: vol en] */
|
||||
/* [bit 5: temp en] */
|
||||
/* [bit 4: vmax en] */
|
||||
/* [bit 3: gain en] */
|
||||
/* [bit 2: ipeak en] */
|
||||
/* [bit 1: & or | flag] */
|
||||
/* [bit 0: monitor en] */
|
||||
uint32_t temp_aplha;
|
||||
uint32_t temp_num;
|
||||
uint32_t single_temp_size;
|
||||
uint32_t temp_offset;
|
||||
uint32_t vol_aplha;
|
||||
uint32_t vol_num;
|
||||
uint32_t single_vol_size;
|
||||
uint32_t vol_offset;
|
||||
uint32_t reserver[3];
|
||||
};
|
||||
|
||||
/* v0.1.2 */
|
||||
struct aw_monitor_hdr_v_0_1_2 {
|
||||
uint32_t check_sum;
|
||||
uint32_t monitor_ver;
|
||||
char chip_type[16];
|
||||
uint32_t ui_ver;
|
||||
uint32_t monitor_time;
|
||||
uint32_t monitor_count;
|
||||
uint32_t enable_flag;
|
||||
/* [bit 31:7]*/
|
||||
/* [bit 9: voltage mode]*/
|
||||
/* [bit 8: voltage source]*/
|
||||
/* [bit 7: temperature source]*/
|
||||
/* [bit 6: vol en]*/
|
||||
/* [bit 5: temp en]*/
|
||||
/* [bit 4: vmax en]*/
|
||||
/* [bit 3: gain en]*/
|
||||
/* [bit 2: ipeak en]*/
|
||||
/* [bit 1: & or | flag]*/
|
||||
/* [bit 0: monitor en]*/
|
||||
uint32_t temp_aplha;
|
||||
uint32_t temp_num;
|
||||
uint32_t single_temp_size;
|
||||
uint32_t temp_offset;
|
||||
uint32_t vol_aplha;
|
||||
uint32_t vol_num;
|
||||
uint32_t single_vol_size;
|
||||
uint32_t vol_offset;
|
||||
uint32_t reserver[3];
|
||||
};
|
||||
|
||||
struct aw_table {
|
||||
int16_t min_val;
|
||||
int16_t max_val;
|
||||
uint16_t ipeak;
|
||||
uint16_t gain;
|
||||
uint32_t vmax;
|
||||
};
|
||||
|
||||
struct aw_table_info {
|
||||
uint8_t table_num;
|
||||
struct aw_table *aw_table;
|
||||
};
|
||||
|
||||
struct aw_monitor_cfg {
|
||||
uint8_t monitor_status;
|
||||
uint32_t monitor_switch;
|
||||
uint32_t monitor_time;
|
||||
uint32_t monitor_count;
|
||||
uint32_t logic_switch;
|
||||
uint32_t temp_switch;
|
||||
uint32_t temp_aplha;
|
||||
uint32_t vol_switch;
|
||||
uint32_t vol_aplha;
|
||||
uint32_t ipeak_switch;
|
||||
uint32_t gain_switch;
|
||||
uint32_t vmax_switch;
|
||||
uint32_t temp_source;
|
||||
uint32_t vol_source;
|
||||
uint32_t vol_mode;
|
||||
struct aw_table_info temp_info;
|
||||
struct aw_table_info vol_info;
|
||||
};
|
||||
|
||||
struct aw_monitor_trace {
|
||||
int32_t pre_val;
|
||||
int32_t sum_val;
|
||||
struct aw_table aw_table;
|
||||
};
|
||||
|
||||
enum aw_monitor_mode {
|
||||
AW_MON_KERNEL_MODE = 0,
|
||||
AW_MON_HAL_MODE,
|
||||
};
|
||||
|
||||
/******************************************************************
|
||||
* struct aw882xx monitor
|
||||
*******************************************************************/
|
||||
struct aw_monitor_desc {
|
||||
struct delayed_work delay_work;
|
||||
struct aw_monitor_cfg monitor_cfg;
|
||||
|
||||
bool mon_start_flag;
|
||||
uint8_t first_entry;
|
||||
uint8_t samp_count;
|
||||
uint8_t db_offset;
|
||||
uint8_t monitor_mode;
|
||||
|
||||
uint32_t pre_vmax;
|
||||
struct aw_monitor_trace temp_trace;
|
||||
struct aw_monitor_trace vol_trace;
|
||||
|
||||
|
||||
#ifdef AW_DEBUG
|
||||
uint16_t test_vol;
|
||||
int16_t test_temp;
|
||||
#endif
|
||||
};
|
||||
|
||||
/******************************************************************
|
||||
* aw882xx monitor functions
|
||||
*******************************************************************/
|
||||
void aw882xx_monitor_start(struct aw_monitor_desc *monitor_desc);
|
||||
int aw882xx_monitor_stop(struct aw_monitor_desc *monitor_desc);
|
||||
void aw882xx_monitor_init(struct aw_monitor_desc *monitor_desc);
|
||||
void aw882xx_monitor_deinit(struct aw_monitor_desc *monitor_desc);
|
||||
int aw882xx_monitor_parse_fw(struct aw_monitor_desc *monitor_desc,
|
||||
uint8_t *data, uint32_t data_len);
|
||||
|
||||
void aw882xx_monitor_hal_work(struct aw_monitor_desc *monitor_desc, uint32_t *vmax);
|
||||
void aw882xx_monitor_hal_get_time(struct aw_monitor_desc *monitor_desc, uint32_t *time);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
1927
sound/soc/codecs/aw882xx/aw882xx_pid_1852_reg.h
Normal file
1927
sound/soc/codecs/aw882xx/aw882xx_pid_1852_reg.h
Normal file
File diff suppressed because it is too large
Load Diff
2158
sound/soc/codecs/aw882xx/aw882xx_pid_2013_reg.h
Normal file
2158
sound/soc/codecs/aw882xx/aw882xx_pid_2013_reg.h
Normal file
File diff suppressed because it is too large
Load Diff
2008
sound/soc/codecs/aw882xx/aw882xx_pid_2032_reg.h
Normal file
2008
sound/soc/codecs/aw882xx/aw882xx_pid_2032_reg.h
Normal file
File diff suppressed because it is too large
Load Diff
2034
sound/soc/codecs/aw882xx/aw882xx_pid_2055_reg.h
Normal file
2034
sound/soc/codecs/aw882xx/aw882xx_pid_2055_reg.h
Normal file
File diff suppressed because it is too large
Load Diff
2062
sound/soc/codecs/aw882xx/aw882xx_pid_2055a_reg.h
Normal file
2062
sound/soc/codecs/aw882xx/aw882xx_pid_2055a_reg.h
Normal file
File diff suppressed because it is too large
Load Diff
2066
sound/soc/codecs/aw882xx/aw882xx_pid_2071_reg.h
Normal file
2066
sound/soc/codecs/aw882xx/aw882xx_pid_2071_reg.h
Normal file
File diff suppressed because it is too large
Load Diff
2351
sound/soc/codecs/aw882xx/aw882xx_pid_2113_reg.h
Normal file
2351
sound/soc/codecs/aw882xx/aw882xx_pid_2113_reg.h
Normal file
File diff suppressed because it is too large
Load Diff
2397
sound/soc/codecs/aw882xx/aw882xx_pid_2308_reg.h
Normal file
2397
sound/soc/codecs/aw882xx/aw882xx_pid_2308_reg.h
Normal file
File diff suppressed because it is too large
Load Diff
247
sound/soc/codecs/aw882xx/aw882xx_spin.c
Normal file
247
sound/soc/codecs/aw882xx/aw882xx_spin.c
Normal file
@@ -0,0 +1,247 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* aw882xx_spin.c spin_module
|
||||
*
|
||||
* Copyright (c) 2019 AWINIC Technology CO., LTD
|
||||
*
|
||||
* Author: Nick Li <liweilei@awinic.com.cn>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/soc.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include "aw882xx_log.h"
|
||||
#include "aw882xx.h"
|
||||
#include "aw882xx_spin.h"
|
||||
|
||||
static unsigned int g_spin_mode;
|
||||
static unsigned int g_spin_value;
|
||||
|
||||
static DEFINE_MUTEX(g_spin_lock);
|
||||
|
||||
static int aw_dev_set_channal_mode(struct aw_device *aw_dev,
|
||||
struct aw_spin_desc spin_desc, uint32_t spin_val)
|
||||
{
|
||||
int ret;
|
||||
struct aw_reg_ch *rx_desc = &spin_desc.rx_desc;
|
||||
|
||||
ret = aw_dev->ops.aw_i2c_write_bits(aw_dev, rx_desc->reg, rx_desc->mask,
|
||||
spin_desc.spin_table[spin_val].rx_val);
|
||||
if (ret < 0) {
|
||||
aw_dev_err(aw_dev->dev, "set rx failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
aw_dev_dbg(aw_dev->dev, "set channel mode done!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw_reg_write_spin(struct aw_device *aw_dev,
|
||||
uint32_t spin_val, bool mixer_en)
|
||||
{
|
||||
int ret;
|
||||
struct aw_device *local_dev = NULL;
|
||||
struct list_head *pos = NULL;
|
||||
struct list_head *dev_list = NULL;
|
||||
|
||||
ret = aw882xx_dev_get_list_head(&dev_list);
|
||||
if (ret) {
|
||||
aw_dev_err(aw_dev->dev, "get dev list failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((g_spin_mode == AW_REG_MIXER_SPIN_MODE) && (mixer_en)) {
|
||||
list_for_each(pos, dev_list) {
|
||||
local_dev = container_of(pos, struct aw_device, list_node);
|
||||
ret = aw882xx_dsp_set_mixer_en(local_dev, AW_AUDIO_MIX_ENABLE);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
usleep_range(AW_100000_US, AW_100000_US + 10);
|
||||
|
||||
list_for_each(pos, dev_list) {
|
||||
local_dev = container_of(pos, struct aw_device, list_node);
|
||||
ret = aw_dev_set_channal_mode(local_dev, local_dev->spin_desc, spin_val);
|
||||
if (ret < 0) {
|
||||
aw_dev_err(local_dev->dev, "set channal mode failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((g_spin_mode == AW_REG_MIXER_SPIN_MODE) && (mixer_en)) {
|
||||
ret = aw882xx_dsp_set_mixer_en(aw_dev, AW_AUDIO_MIX_DSIABLE);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aw882xx_spin_set_record_val(struct aw_device *aw_dev)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
mutex_lock(&g_spin_lock);
|
||||
if (g_spin_mode == AW_ADSP_SPIN_MODE) {
|
||||
ret = aw882xx_dsp_write_spin(g_spin_value);
|
||||
if (ret) {
|
||||
mutex_unlock(&g_spin_lock);
|
||||
return ret;
|
||||
}
|
||||
} else if ((g_spin_mode == AW_REG_SPIN_MODE) ||
|
||||
(g_spin_mode == AW_REG_MIXER_SPIN_MODE)) {
|
||||
ret = aw_dev_set_channal_mode(aw_dev, aw_dev->spin_desc, g_spin_value);
|
||||
if (ret) {
|
||||
mutex_unlock(&g_spin_lock);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
aw_dev_info(aw_dev->dev, "do nothing");
|
||||
}
|
||||
mutex_unlock(&g_spin_lock);
|
||||
|
||||
aw_dev_info(aw_dev->dev, "set record spin val done");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aw882xx_spin_value_get(struct aw_device *aw_dev,
|
||||
uint32_t *spin_val, bool pstream)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (((g_spin_mode == AW_REG_SPIN_MODE) ||
|
||||
(g_spin_mode == AW_REG_MIXER_SPIN_MODE)) || (!pstream))
|
||||
*spin_val = g_spin_value;
|
||||
else if (g_spin_mode == AW_ADSP_SPIN_MODE)
|
||||
ret = aw882xx_dsp_read_spin(spin_val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int aw882xx_spin_value_set(struct aw_device *aw_dev, uint32_t spin_val, bool pstream)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&g_spin_lock);
|
||||
if (pstream) {
|
||||
if ((g_spin_mode == AW_REG_SPIN_MODE) ||
|
||||
(g_spin_mode == AW_REG_MIXER_SPIN_MODE))
|
||||
ret = aw_reg_write_spin(aw_dev, spin_val, true);
|
||||
else if (g_spin_mode == AW_ADSP_SPIN_MODE)
|
||||
ret = aw882xx_dsp_write_spin(spin_val);
|
||||
else
|
||||
aw_dev_info(aw_dev->dev, "can't set spin value");
|
||||
} else {
|
||||
if ((g_spin_mode == AW_REG_SPIN_MODE) ||
|
||||
(g_spin_mode == AW_REG_MIXER_SPIN_MODE))
|
||||
ret = aw_reg_write_spin(aw_dev, spin_val, false);
|
||||
else
|
||||
aw_dev_info(aw_dev->dev, "stream no start only record spin angle");
|
||||
}
|
||||
g_spin_value = spin_val;
|
||||
mutex_unlock(&g_spin_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aw_parse_spin_table_dt(struct aw_device *aw_dev)
|
||||
{
|
||||
int ret = -1;
|
||||
const char *str_data = NULL;
|
||||
char spin_table_str[AW_SPIN_MAX] = { 0 };
|
||||
struct aw_spin_desc *spin_desc = &aw_dev->spin_desc;
|
||||
int i;
|
||||
|
||||
ret = of_property_read_string(aw_dev->dev->of_node, "spin-data", &str_data);
|
||||
if (ret < 0) {
|
||||
aw_dev_err(aw_dev->dev, "get spin_data failed, close spin function");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sscanf(str_data, "%c %c %c %c",
|
||||
&spin_table_str[AW_SPIN_0], &spin_table_str[AW_SPIN_90],
|
||||
&spin_table_str[AW_SPIN_180], &spin_table_str[AW_SPIN_270]);
|
||||
if (ret != AW_SPIN_MAX) {
|
||||
aw_dev_err(aw_dev->dev, "unsupported str:%s, close spin function", str_data);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < AW_SPIN_MAX; i++) {
|
||||
if (spin_table_str[i] == 'l' || spin_table_str[i] == 'L') {
|
||||
spin_desc->spin_table[i].rx_val = spin_desc->rx_desc.left_val;
|
||||
} else if (spin_table_str[i] == 'r' || spin_table_str[i] == 'R') {
|
||||
spin_desc->spin_table[i].rx_val = spin_desc->rx_desc.right_val;
|
||||
} else {
|
||||
aw_dev_err(aw_dev->dev, "unsupported str:%s, close spin function", str_data);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw_parse_spin_dts(struct aw_device *aw_dev)
|
||||
{
|
||||
int ret = -1;
|
||||
const char *spin_str = NULL;
|
||||
|
||||
ret = of_property_read_string(aw_dev->dev->of_node, "spin-mode", &spin_str);
|
||||
if (ret < 0) {
|
||||
g_spin_mode = AW_SPIN_OFF_MODE;
|
||||
aw_dev_info(aw_dev->dev, "spin-mode get failed, spin switch off, spin_mode:%d", g_spin_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(spin_str, "dsp_spin"))
|
||||
g_spin_mode = AW_ADSP_SPIN_MODE;
|
||||
else if (!strcmp(spin_str, "reg_spin"))
|
||||
g_spin_mode = AW_REG_SPIN_MODE;
|
||||
else if (!strcmp(spin_str, "reg_mixer_spin"))
|
||||
g_spin_mode = AW_REG_MIXER_SPIN_MODE;
|
||||
else
|
||||
g_spin_mode = AW_SPIN_OFF_MODE;
|
||||
|
||||
if ((g_spin_mode == AW_REG_SPIN_MODE) ||
|
||||
(g_spin_mode == AW_REG_MIXER_SPIN_MODE)) {
|
||||
ret = aw_parse_spin_table_dt(aw_dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
aw_dev_info(aw_dev->dev, "spin mode is %d", g_spin_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aw882xx_spin_init(struct aw_spin_desc *spin_desc)
|
||||
{
|
||||
int ret = 0;
|
||||
struct aw_device *aw_dev =
|
||||
container_of(spin_desc, struct aw_device, spin_desc);
|
||||
|
||||
ret = aw_parse_spin_dts(aw_dev);
|
||||
|
||||
if (g_spin_mode == AW_SPIN_OFF_MODE)
|
||||
spin_desc->aw_spin_kcontrol_st = AW_SPIN_KCONTROL_DISABLE;
|
||||
else
|
||||
spin_desc->aw_spin_kcontrol_st = AW_SPIN_KCONTROL_ENABLE;
|
||||
|
||||
aw_dev_info(aw_dev->dev, "aw_spin_kcontrol_st:%d", spin_desc->aw_spin_kcontrol_st);
|
||||
|
||||
return ret;
|
||||
}
|
||||
31
sound/soc/codecs/aw882xx/aw882xx_spin.h
Normal file
31
sound/soc/codecs/aw882xx/aw882xx_spin.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
* aw882xx_spin.h spin_module
|
||||
*
|
||||
* Copyright (c) 2019 AWINIC Technology CO., LTD
|
||||
*
|
||||
* Author: Nick Li <liweilei@awinic.com.cn>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef __AW882XX_SPIN_H__
|
||||
#define __AW882XX_SPIN_H__
|
||||
|
||||
|
||||
enum {
|
||||
AW_SPIN_OFF_MODE = 0,
|
||||
AW_ADSP_SPIN_MODE,
|
||||
AW_REG_SPIN_MODE,
|
||||
AW_REG_MIXER_SPIN_MODE,
|
||||
AW_SPIN_MODE_MAX,
|
||||
};
|
||||
|
||||
int aw882xx_spin_init(struct aw_spin_desc *spin_desc);
|
||||
int aw882xx_spin_value_set(struct aw_device *aw_dev, uint32_t spin_val, bool pstream);
|
||||
int aw882xx_spin_value_get(struct aw_device *aw_dev, uint32_t *spin_val, bool pstream);
|
||||
int aw882xx_spin_set_record_val(struct aw_device *aw_dev);
|
||||
|
||||
#endif
|
||||
10
sound/soc/codecs/it6621/Kconfig
Normal file
10
sound/soc/codecs/it6621/Kconfig
Normal file
@@ -0,0 +1,10 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
config SND_SOC_IT6621
|
||||
tristate "IT6621 driver for HDMI2.1 enhanced audio return channel (eARC)"
|
||||
depends on (I2C)
|
||||
help
|
||||
Say yes here to build support for ITE IT6621 eARC.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called it6621.
|
||||
3
sound/soc/codecs/it6621/Makefile
Normal file
3
sound/soc/codecs/it6621/Makefile
Normal file
@@ -0,0 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
it6621-y := it6621-codec.o it6621-clk.o it6621-earc.o it6621-uapi.o
|
||||
obj-$(CONFIG_SND_SOC_IT6621) += it6621.o
|
||||
319
sound/soc/codecs/it6621/it6621-clk.c
Normal file
319
sound/soc/codecs/it6621/it6621-clk.c
Normal file
@@ -0,0 +1,319 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (c) 2024 Rockchip Electronics Co. Ltd.
|
||||
* Author: Jason Zhang <jason.zhang@rock-chips.com>
|
||||
*/
|
||||
|
||||
#include "it6621.h"
|
||||
#include "it6621-clk.h"
|
||||
#include "it6621-earc.h"
|
||||
#include "it6621-reg-bank0.h"
|
||||
#include "it6621-reg-bank1.h"
|
||||
|
||||
static int it6621_get_100ms_cnt(struct it6621_priv *priv, u32 *count)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
regmap_write(priv->regmap, IT6621_REG_GEN0, IT6621_100MS_CNT_EN);
|
||||
msleep(99);
|
||||
regmap_write(priv->regmap, IT6621_REG_GEN0, IT6621_100MS_CNT_DIS);
|
||||
regmap_read(priv->regmap, IT6621_REG_100MS_CNT_7_0, &val);
|
||||
*count = (u32)val;
|
||||
regmap_read(priv->regmap, IT6621_REG_100MS_CNT_15_8, &val);
|
||||
*count += ((u32)(val) << 8);
|
||||
regmap_read(priv->regmap, IT6621_REG_100MS_CNT_23_16, &val);
|
||||
*count += ((u32)(val) << 16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_get_lcf(struct it6621_priv *priv, unsigned int *lcf)
|
||||
{
|
||||
unsigned int timer_1us_flt;
|
||||
unsigned int lcf_high;
|
||||
unsigned int lcf_low;
|
||||
unsigned int tmp;
|
||||
|
||||
if (priv->fixed_lcf) {
|
||||
*lcf = priv->fixed_lcf;
|
||||
dev_info(priv->dev, "lcf: %d\n", *lcf);
|
||||
} else {
|
||||
regmap_update_bits(priv->regmap, 0xa9, 0x0f, 0x00);
|
||||
it6621_get_100ms_cnt(priv, &lcf_low);
|
||||
|
||||
regmap_update_bits(priv->regmap, 0xa9, 0x0f, 0x0f);
|
||||
it6621_get_100ms_cnt(priv, &lcf_high);
|
||||
|
||||
if (!(lcf_high - lcf_low)) {
|
||||
dev_err(priv->dev, "Invalid LCF");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Get tenths */
|
||||
tmp = (1000000 - lcf_low) * 16 * 10 / (lcf_high - lcf_low);
|
||||
timer_1us_flt = tmp % 10;
|
||||
tmp = tmp / 10;
|
||||
if (timer_1us_flt >= 5)
|
||||
*lcf = tmp + 1;
|
||||
else
|
||||
*lcf = tmp;
|
||||
|
||||
dev_info(priv->dev, "lcf low: %d, lcf high: %d, lcf: %d\n",
|
||||
lcf_low, lcf_high, *lcf);
|
||||
}
|
||||
|
||||
if (*lcf > 15)
|
||||
*lcf = 15;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_get_refclk(struct it6621_priv *priv, unsigned int *refclk)
|
||||
{
|
||||
if (priv->rclk_sel == IT6621_RCLK_FREQ_REFCLK)
|
||||
*refclk = priv->rclk / 2;
|
||||
else if (priv->rclk_sel == IT6621_RCLK_FREQ_REFCLK_DIV_2)
|
||||
*refclk = priv->rclk;
|
||||
else if (priv->rclk_sel == IT6621_RCLK_FREQ_REFCLK_DIV_4)
|
||||
*refclk = priv->rclk * 2;
|
||||
else if (priv->rclk_sel == IT6621_RCLK_FREQ_REFCLK_DIV_8)
|
||||
*refclk = priv->rclk * 4;
|
||||
else
|
||||
*refclk = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int it6621_calc_rclk(struct it6621_priv *priv)
|
||||
{
|
||||
unsigned int timer_1us;
|
||||
unsigned int timer_1us_int;
|
||||
unsigned int timer_1us_flt;
|
||||
unsigned int lcf;
|
||||
unsigned int aclk_bnd_num;
|
||||
unsigned int aclk_valid_num;
|
||||
unsigned int sum;
|
||||
int ret;
|
||||
|
||||
ret = it6621_get_lcf(priv, &lcf);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
regmap_update_bits(priv->regmap, 0xa9, 0x0f, lcf);
|
||||
|
||||
it6621_get_100ms_cnt(priv, &sum);
|
||||
priv->rclk = sum / 100;
|
||||
dev_dbg(priv->dev, "RCLK: %uMHz\n", priv->rclk / 1000);
|
||||
|
||||
/* Update 1us timer */
|
||||
timer_1us = sum / 100000;
|
||||
timer_1us_int = timer_1us;
|
||||
timer_1us_flt = sum % 100000;
|
||||
timer_1us_flt <<= 8;
|
||||
timer_1us_flt /= 100000;
|
||||
regmap_write(priv->regmap, IT6621_REG_GEN4, timer_1us_int);
|
||||
regmap_write(priv->regmap, IT6621_REG_1US_TIME_FLT, timer_1us_flt);
|
||||
|
||||
if (priv->rclk_sel == IT6621_RCLK_FREQ_REFCLK)
|
||||
sum /= 2;
|
||||
else if (priv->rclk_sel == IT6621_RCLK_FREQ_REFCLK_DIV_4)
|
||||
sum *= 2;
|
||||
else if (priv->rclk_sel == IT6621_RCLK_FREQ_REFCLK_DIV_8)
|
||||
sum *= 4;
|
||||
|
||||
aclk_bnd_num = sum * 128 / 358400;
|
||||
aclk_valid_num = sum * 128 / 200000;
|
||||
regmap_write(priv->regmap, IT6621_REG_CLK_DET0, aclk_bnd_num & 0xff);
|
||||
regmap_write(priv->regmap, IT6621_REG_CLK_DET1,
|
||||
(aclk_bnd_num & 0x100) >> 8);
|
||||
regmap_write(priv->regmap, IT6621_REG_CLK_DET2,
|
||||
aclk_valid_num & 0xff);
|
||||
regmap_write(priv->regmap, IT6621_REG_CLK_DET3,
|
||||
(aclk_valid_num & 0x300) >> 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* it6621_force_pdiv() - If auto mode error , FW force to correct PLL's setting
|
||||
* @priv: The priv device
|
||||
*
|
||||
* Returns zero if succeed.
|
||||
*/
|
||||
int it6621_force_pdiv(struct it6621_priv *priv)
|
||||
{
|
||||
unsigned int tbclk_sel;
|
||||
unsigned int xp_pdiv;
|
||||
unsigned int xp_gain;
|
||||
unsigned int val;
|
||||
unsigned int expect;
|
||||
|
||||
regmap_read(priv->regmap, IT6621_REG_CLK_CTRL1, &val);
|
||||
tbclk_sel = val & IT6621_TBCLK_SEL;
|
||||
|
||||
regmap_read(priv->regmap, IT6621_REG_TX_AFE1, &val);
|
||||
xp_pdiv = val & IT6621_TX_XP_PDIV;
|
||||
xp_gain = (val & IT6621_TX_XP_GAIN) >> 2;
|
||||
|
||||
dev_dbg(priv->dev, "ACLK: %d\n", priv->aclk);
|
||||
|
||||
expect = 0xff;
|
||||
switch (tbclk_sel) {
|
||||
case IT6621_TBCLK_AICLK_MUL_32:
|
||||
if (xp_pdiv != 0)
|
||||
expect = 0;
|
||||
break;
|
||||
case IT6621_TBCLK_AICLK_MUL_16:
|
||||
if ((priv->aclk < 3584) && (xp_pdiv != 0))
|
||||
expect = 0;
|
||||
else if ((priv->aclk > 3584) && (priv->aclk < 7168) &&
|
||||
(xp_pdiv != 1))
|
||||
expect = 1;
|
||||
break;
|
||||
case IT6621_TBCLK_AICLK_MUL_8:
|
||||
if ((priv->aclk < 3584) && (xp_pdiv != 0))
|
||||
expect = 0;
|
||||
else if ((priv->aclk > 3584) && (priv->aclk < 7168) &&
|
||||
(xp_pdiv != 1))
|
||||
expect = 1;
|
||||
else if ((priv->aclk > 7168) && (priv->aclk < 14336) &&
|
||||
(xp_pdiv != 3))
|
||||
expect = 3;
|
||||
break;
|
||||
case IT6621_TBCLK_AICLK_MUL_4:
|
||||
if ((priv->aclk < 7168) && xp_pdiv != 0)
|
||||
expect = 0;
|
||||
else if ((priv->aclk > 7168) && (priv->aclk < 14336) &&
|
||||
(xp_pdiv != 1))
|
||||
expect = 1;
|
||||
else if ((priv->aclk > 14336) && (priv->aclk < 28672) &&
|
||||
(xp_pdiv != 3))
|
||||
expect = 3;
|
||||
break;
|
||||
case IT6621_TBCLK_AICLK_MUL_2:
|
||||
if ((priv->aclk < 14336) && xp_pdiv != 0)
|
||||
expect = 0;
|
||||
else if ((priv->aclk > 14336) && (priv->aclk < 28672) &&
|
||||
(xp_pdiv != 1))
|
||||
expect = 1;
|
||||
else if ((priv->aclk > 28672) && (priv->aclk < 57334) &&
|
||||
(xp_pdiv != 3))
|
||||
expect = 3;
|
||||
break;
|
||||
case IT6621_TBCLK_AICLK:
|
||||
if ((priv->aclk < 28672) && (xp_pdiv != 0))
|
||||
expect = 0;
|
||||
else if ((priv->aclk > 28672) && (priv->aclk < 57334) &&
|
||||
(xp_pdiv != 1))
|
||||
expect = 1;
|
||||
else if ((priv->aclk > 57334) && (priv->aclk < 114668) &&
|
||||
(xp_pdiv != 3))
|
||||
expect = 3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (expect != 0xff)
|
||||
dev_warn(priv->dev, "Wrong XP PDIV, detect %d, expected %d\n",
|
||||
xp_pdiv, expect);
|
||||
|
||||
expect = 0xff;
|
||||
switch (tbclk_sel) {
|
||||
case IT6621_TBCLK_AICLK:
|
||||
if ((priv->aclk > 3584) && (priv->aclk < 7168) &&
|
||||
(xp_gain != 0))
|
||||
expect = 0;
|
||||
break;
|
||||
case IT6621_TBCLK_AICLK_MUL_2:
|
||||
if ((priv->aclk < 3584) && (xp_gain != 0))
|
||||
expect = 0;
|
||||
break;
|
||||
default:
|
||||
if (xp_gain != 1)
|
||||
expect = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (expect != 0xff)
|
||||
dev_warn(priv->dev, "Wrong XP GAIN, detect %d, expected %d\n",
|
||||
xp_gain, expect);
|
||||
|
||||
regmap_read(priv->regmap, IT6621_REG_TX_AFE1, &val);
|
||||
xp_pdiv = val & IT6621_TX_XP_PDIV;
|
||||
xp_gain = (val & IT6621_TX_XP_GAIN) >> 2;
|
||||
dev_dbg(priv->dev, "TBCLK SEL: 0x%02X, XP PDIV: %d, XP GAIN: %d\n",
|
||||
tbclk_sel, xp_pdiv, xp_gain);
|
||||
|
||||
usleep_range(10000, 11000);
|
||||
regmap_update_bits(priv->regmap, IT6621_REG_DMAC_CTRL1,
|
||||
IT6621_TX_MANUAL_RESET_EN_SEL,
|
||||
IT6621_TX_MANUAL_RESET_EN);
|
||||
regmap_update_bits(priv->regmap, IT6621_REG_DMAC_CTRL1,
|
||||
IT6621_TX_MANUAL_RESET_EN_SEL,
|
||||
IT6621_TX_MANUAL_RESET_DIS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void it6621_get_aclk(struct it6621_priv *priv)
|
||||
{
|
||||
unsigned int aclk_avg;
|
||||
unsigned int aclk_pred2;
|
||||
unsigned int aclk_pred4;
|
||||
unsigned int aclk_valid;
|
||||
unsigned int aclk_stb;
|
||||
unsigned int refclk;
|
||||
unsigned int tmp;
|
||||
|
||||
it6621_get_refclk(priv, &refclk);
|
||||
|
||||
regmap_read(priv->regmap, IT6621_REG_CLK_DET8, &aclk_avg);
|
||||
regmap_read(priv->regmap, IT6621_REG_CLK_DET9, &tmp);
|
||||
aclk_avg += ((tmp & IT6621_DET_ACLK_AVG_HIGH) << 8);
|
||||
aclk_pred2 = (tmp & IT6621_DET_ACLK_PRE_DIV_2) >> 4;
|
||||
aclk_pred4 = (tmp & IT6621_DET_ACLK_PRE_DIV_4) >> 5;
|
||||
aclk_valid = (tmp & IT6621_DET_ACLK_FREQ_VALID) >> 6;
|
||||
aclk_stb = (tmp & IT6621_DET_ACLK_FREQ_STB) >> 7;
|
||||
|
||||
priv->aclk = refclk * 128 / aclk_avg;
|
||||
|
||||
if (aclk_pred4)
|
||||
priv->aclk *= 4;
|
||||
else if (aclk_pred2)
|
||||
priv->aclk *= 2;
|
||||
|
||||
dev_dbg(priv->dev, "ACLK: %uMHz, valid: %d, stable: %d\n",
|
||||
priv->aclk / 1000, aclk_valid, aclk_stb);
|
||||
}
|
||||
|
||||
void it6621_get_bclk(struct it6621_priv *priv)
|
||||
{
|
||||
unsigned int bclk_avg;
|
||||
unsigned int bclk_pred2;
|
||||
unsigned int bclk_pred4;
|
||||
unsigned int bclk_valid;
|
||||
unsigned int bclk_stb;
|
||||
unsigned int refclk;
|
||||
unsigned int tmp;
|
||||
|
||||
it6621_get_refclk(priv, &refclk);
|
||||
|
||||
regmap_read(priv->regmap, IT6621_REG_CLK_DET10, &bclk_avg);
|
||||
regmap_read(priv->regmap, IT6621_REG_CLK_DET11, &tmp);
|
||||
bclk_avg += ((tmp & IT6621_DET_BCLK_AVG_HIGH) << 8);
|
||||
bclk_pred2 = (tmp & IT6621_DET_BCLK_PRE_DIV_2) >> 4;
|
||||
bclk_pred4 = (tmp & IT6621_DET_BCLK_PRE_DIV_4) >> 5;
|
||||
bclk_valid = (tmp & IT6621_DET_BCLK_FREQ_VALID) >> 6;
|
||||
bclk_stb = (tmp & IT6621_DET_BCLK_FREQ_STB) >> 7;
|
||||
|
||||
priv->bclk = refclk * 128 / bclk_avg;
|
||||
|
||||
if (bclk_pred4)
|
||||
priv->bclk *= 4;
|
||||
else if (bclk_pred2)
|
||||
priv->bclk *= 2;
|
||||
|
||||
dev_dbg(priv->dev, "BCLK: %uMHz, valid: %d, stable: %d\n",
|
||||
priv->bclk / 1000, bclk_valid, bclk_stb);
|
||||
}
|
||||
18
sound/soc/codecs/it6621/it6621-clk.h
Normal file
18
sound/soc/codecs/it6621/it6621-clk.h
Normal file
@@ -0,0 +1,18 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (c) 2024 Rockchip Electronics Co. Ltd.
|
||||
* Author: Jason Zhang <jason.zhang@rock-chips.com>
|
||||
*/
|
||||
|
||||
#ifndef _IT6621_CLK_H
|
||||
#define _IT6621_CLK_H
|
||||
|
||||
#include "it6621.h"
|
||||
#include "it6621-earc.h"
|
||||
|
||||
int it6621_calc_rclk(struct it6621_priv *priv);
|
||||
int it6621_force_pdiv(struct it6621_priv *priv);
|
||||
void it6621_get_aclk(struct it6621_priv *priv);
|
||||
void it6621_get_bclk(struct it6621_priv *priv);
|
||||
|
||||
#endif /* _IT6621_CLK_H */
|
||||
894
sound/soc/codecs/it6621/it6621-codec.c
Normal file
894
sound/soc/codecs/it6621/it6621-codec.c
Normal file
@@ -0,0 +1,894 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* it6621-codec.c -- IT6621 ALSA SoC audio codec driver
|
||||
*
|
||||
* Copyright (c) 2024 Rockchip Electronics Co. Ltd.
|
||||
* Author: Jason Zhang <jason.zhang@rock-chips.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/clk.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/asoundef.h>
|
||||
|
||||
#include "it6621.h"
|
||||
#include "it6621-clk.h"
|
||||
#include "it6621-earc.h"
|
||||
#include "it6621-uapi.h"
|
||||
#include "it6621-reg-bank0.h"
|
||||
#include "it6621-reg-bank1.h"
|
||||
#include "it6621-reg-cec.h"
|
||||
|
||||
#define IT6621_I2C_NAME "it6621"
|
||||
|
||||
static const struct regmap_range_cfg it6621_range = {
|
||||
.range_min = IT6621_REG_VENDOR_ID_LOW,
|
||||
.range_max = IT6621_REG_TX_PKT3_PB15,
|
||||
.selector_reg = IT6621_REG_SYS_CTRL3,
|
||||
.selector_mask = IT6621_BANK_SEL,
|
||||
.selector_shift = 0,
|
||||
.window_start = 0,
|
||||
.window_len = 256,
|
||||
};
|
||||
|
||||
static bool it6621_is_accessible_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
if (reg >= IT6621_REG_VENDOR_ID_LOW && reg <= IT6621_REG_TX_PKT3_PB15)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static const struct regmap_config it6621_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = IT6621_REG_TX_PKT3_PB15,
|
||||
.readable_reg = it6621_is_accessible_reg,
|
||||
.writeable_reg = it6621_is_accessible_reg,
|
||||
.ranges = &it6621_range,
|
||||
.num_ranges = 1,
|
||||
};
|
||||
|
||||
static int it6621_set_audio_src(struct it6621_priv *priv)
|
||||
{
|
||||
unsigned int src;
|
||||
|
||||
if (priv->audio_ch >= 15)
|
||||
src = IT6621_AUD_SRC7_SRC0_EN;
|
||||
else if (priv->audio_ch >= 13)
|
||||
src = IT6621_AUD_SRC6_SRC0_EN;
|
||||
else if (priv->audio_ch >= 11)
|
||||
src = IT6621_AUD_SRC5_SRC0_EN;
|
||||
else if (priv->audio_ch >= 9)
|
||||
src = IT6621_AUD_SRC4_SRC0_EN;
|
||||
else if (priv->audio_ch >= 7 || priv->i2s_hbr)
|
||||
src = IT6621_AUD_SRC3_SRC0_EN;
|
||||
else if (priv->audio_ch >= 5)
|
||||
src = IT6621_AUD_SRC2_SRC0_EN;
|
||||
else if (priv->audio_ch >= 3)
|
||||
src = IT6621_AUD_SRC1_SRC0_EN;
|
||||
else
|
||||
src = IT6621_AUD_SRC0_EN;
|
||||
|
||||
/* Set input audio source */
|
||||
regmap_update_bits(priv->regmap, IT6621_REG_TX_AUD_SRC_SEL,
|
||||
IT6621_TX_AUD_SRC, priv->audio_src);
|
||||
|
||||
/* Update source number */
|
||||
regmap_write(priv->regmap, IT6621_REG_TX_AUD_SRC_EN, src);
|
||||
|
||||
/* Update ACLK detect after changing source number */
|
||||
regmap_update_bits(priv->regmap, IT6621_REG_CLK_DET7,
|
||||
IT6621_ACLK_DET_EN_SEL, IT6621_ACLK_DET_DIS);
|
||||
regmap_update_bits(priv->regmap, IT6621_REG_CLK_DET7,
|
||||
IT6621_ACLK_DET_EN_SEL, IT6621_ACLK_DET_EN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_set_i2s_tdm_fmt(struct it6621_priv *priv)
|
||||
{
|
||||
unsigned int wl;
|
||||
|
||||
if ((priv->i2s_wl == IEC958_AES4_CON_WORDLEN_24_20) ||
|
||||
(priv->i2s_wl == (IEC958_AES4_CON_WORDLEN_20_16 |
|
||||
IEC958_AES4_CON_MAX_WORDLEN_24)))
|
||||
wl = IT6621_I2S_TDM_20BIT;
|
||||
else if (priv->i2s_wl == (IEC958_AES4_CON_WORDLEN_24_20 |
|
||||
IEC958_AES4_CON_MAX_WORDLEN_24))
|
||||
wl = IT6621_I2S_TDM_24BIT;
|
||||
else
|
||||
wl = IT6621_I2S_TDM_16BIT;
|
||||
|
||||
regmap_update_bits(priv->regmap, IT6621_REG_TX_I2S,
|
||||
IT6621_I2S_TDM_WORD_LEN | IT6621_I2S_FMT,
|
||||
wl | priv->i2s_fmt);
|
||||
|
||||
regmap_update_bits(priv->regmap, IT6621_REG_TX_AUD_CTRL3,
|
||||
IT6621_TX_I2S_HBR_EN_SEL | IT6621_TX_TDM_CH_NUM,
|
||||
priv->i2s_hbr | ((priv->audio_ch / 2) - 1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_set_spdif_fmt(struct it6621_priv *priv)
|
||||
{
|
||||
if (priv->audio_type == IT6621_AUD_TYPE_NLPCM)
|
||||
regmap_update_bits(priv->regmap, IT6621_REG_DMAC_CTRL1,
|
||||
IT6621_TX_V_BIT_VAL, IT6621_TX_V_BIT_NLPCM);
|
||||
else
|
||||
regmap_update_bits(priv->regmap, IT6621_REG_DMAC_CTRL1,
|
||||
IT6621_TX_V_BIT_VAL, IT6621_TX_V_BIT_LPCM);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_set_auto_audio_fmt(struct it6621_priv *priv)
|
||||
{
|
||||
unsigned int auto_fmt;
|
||||
|
||||
if ((priv->audio_type == IT6621_AUD_TYPE_NLPCM) &&
|
||||
(priv->audio_ch == 8)) {
|
||||
auto_fmt = IT6621_TX_AUTO_AUD_FMT_DIS;
|
||||
} else {
|
||||
/* NOTE: Disable auto audio format in SPDIF */
|
||||
if (priv->audio_src == IT6621_AUD_SRC_SPDIF)
|
||||
auto_fmt = IT6621_TX_AUTO_AUD_FMT_DIS;
|
||||
else
|
||||
auto_fmt = IT6621_TX_AUTO_AUD_FMT_EN;
|
||||
}
|
||||
|
||||
regmap_update_bits(priv->regmap, IT6621_REG_TX_AUD_CTRL10,
|
||||
IT6621_TX_AUTO_AUD_FMT_SEL, auto_fmt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_set_audio_fmt(struct it6621_priv *priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Set audio source */
|
||||
ret = it6621_set_audio_src(priv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* RX I2S/TDM word length */
|
||||
ret = it6621_set_i2s_tdm_fmt(priv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* SPDIF V bit */
|
||||
ret = it6621_set_spdif_fmt(priv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* For Compress audio LayoutB */
|
||||
ret = it6621_set_auto_audio_fmt(priv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* eARC TX Channel Status */
|
||||
ret = it6621_set_channel_status(priv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_update_config(struct it6621_priv *priv)
|
||||
{
|
||||
if (priv->force_16ch)
|
||||
priv->audio_ch = 16;
|
||||
|
||||
if ((priv->audio_fs == IT6621_AES3_CON_FS_256000) ||
|
||||
(priv->audio_fs == IT6621_AES3_CON_FS_352000) ||
|
||||
(priv->audio_fs == IT6621_AES3_CON_FS_384000) ||
|
||||
(priv->audio_fs == IT6621_AES3_CON_FS_512000) ||
|
||||
(priv->audio_fs == IT6621_AES3_CON_FS_705000) ||
|
||||
(priv->audio_fs == IEC958_AES3_CON_FS_768000) ||
|
||||
(priv->audio_fs == IT6621_AES3_CON_FS_1024000) ||
|
||||
(priv->audio_fs == IT6621_AES3_CON_FS_1411000) ||
|
||||
(priv->audio_fs == IT6621_AES3_CON_FS_1536000))
|
||||
priv->audio_hbr = 1;
|
||||
else
|
||||
priv->audio_hbr = 0;
|
||||
|
||||
if (priv->audio_input_hbr == 1)
|
||||
priv->audio_hbr = 1;
|
||||
|
||||
if (priv->audio_hbr)
|
||||
priv->audio_type = IT6621_AUD_TYPE_NLPCM;
|
||||
|
||||
if ((priv->audio_src == IT6621_AUD_SRC_I2S) &&
|
||||
priv->audio_hbr && priv->i2s_hbr_enabled)
|
||||
priv->i2s_hbr = IT6621_TX_I2S_HBR_EN;
|
||||
else
|
||||
priv->i2s_hbr = IT6621_TX_I2S_HBR_DIS;
|
||||
|
||||
if ((priv->audio_src == IT6621_AUD_SRC_I2S) &&
|
||||
(priv->audio_type == IT6621_AUD_TYPE_NLPCM))
|
||||
priv->i2s_nlpcm_enabled = IT6621_TX_NLPCM_I2S_EN;
|
||||
else
|
||||
priv->i2s_nlpcm_enabled = IT6621_TX_NLPCM_I2S_DIS;
|
||||
|
||||
/* NOTE: For Allion AC3 and Allion Astro VG849C test. */
|
||||
if ((priv->audio_ch > 2) &&
|
||||
(priv->audio_type == IT6621_AUD_TYPE_NLPCM))
|
||||
priv->audio_ch = 2;
|
||||
|
||||
regmap_update_bits(priv->regmap, IT6621_REG_TX_AUD_CTRL10,
|
||||
IT6621_TX_2CH_LAYOUT_SEL | IT6621_TX_NLPCM_I2S_SEL |
|
||||
IT6621_TX_MCH_LPCM_SEL | IT6621_TX_EXT_MUTE_SEL,
|
||||
IT6621_TX_2CH_LAYOUT_DIS | priv->i2s_nlpcm_enabled |
|
||||
IT6621_TX_MCH_LPCM_DIS | IT6621_TX_EXT_MUTE_EN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_reconfig_aclk(struct it6621_priv *priv)
|
||||
{
|
||||
if (((priv->audio_src == IT6621_AUD_SRC_I2S) && priv->sck_inv_enabled) ||
|
||||
((priv->audio_src == IT6621_AUD_SRC_TDM) && priv->tck_inv_enabled) ||
|
||||
((priv->audio_src == IT6621_AUD_SRC_SPDIF) && priv->mclk_inv_enabled) ||
|
||||
((priv->audio_src == IT6621_AUD_SRC_DSD) && priv->dclk_inv_enabled))
|
||||
regmap_update_bits(priv->regmap, IT6621_REG_CLK_CTRL2,
|
||||
IT6621_ACLK_INV_SEL, IT6621_ACLK_INV_EN);
|
||||
else
|
||||
regmap_update_bits(priv->regmap, IT6621_REG_CLK_CTRL2,
|
||||
IT6621_ACLK_INV_SEL, IT6621_ACLK_INV_DIS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_config_audio(struct it6621_priv *priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = it6621_update_config(priv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = it6621_reconfig_aclk(priv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = it6621_set_audio_fmt(priv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct it6621_priv *priv = snd_soc_component_get_drvdata(dai->component);
|
||||
unsigned int state;
|
||||
|
||||
if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
|
||||
return 0;
|
||||
|
||||
set_bit(IT6621_AUDIO_START, &priv->audio_flag);
|
||||
clear_bit(IT6621_AUDIO_TO_EN_DMAC, &priv->audio_flag);
|
||||
|
||||
it6621_get_ddfsm_state(priv, &state);
|
||||
|
||||
if ((state != IT6621_TX_EARC_MODE) && (state != IT6621_TX_ARC_MODE)) {
|
||||
cancel_work_sync(&priv->hpdio_work);
|
||||
schedule_work(&priv->hpdio_work);
|
||||
}
|
||||
|
||||
priv->config_audio = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_mute(struct snd_soc_dai *dai, int mute, int stream)
|
||||
{
|
||||
struct it6621_priv *priv = snd_soc_component_get_drvdata(dai->component);
|
||||
|
||||
if (stream != SNDRV_PCM_STREAM_PLAYBACK)
|
||||
return 0;
|
||||
|
||||
if (!priv->force_mute)
|
||||
return 0;
|
||||
|
||||
/* FIXME: Sometimes unmuting stream does not work */
|
||||
regmap_update_bits(priv->regmap, IT6621_REG_TX_AUD_CTRL10,
|
||||
IT6621_TX_FORCE_MUTE_SEL,
|
||||
mute ? IT6621_TX_FORCE_MUTE_EN :
|
||||
IT6621_TX_FORCE_MUTE_DIS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void it6621_shutdown(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct it6621_priv *priv = snd_soc_component_get_drvdata(dai->component);
|
||||
|
||||
clear_bit(IT6621_AUDIO_START, &priv->audio_flag);
|
||||
clear_bit(IT6621_AUDIO_TO_EN_DMAC, &priv->audio_flag);
|
||||
}
|
||||
|
||||
static int it6621_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
|
||||
unsigned int freq, int dir)
|
||||
{
|
||||
struct it6621_priv *priv = snd_soc_dai_get_drvdata(dai);
|
||||
int ret = 0;
|
||||
|
||||
if (!freq)
|
||||
return 0;
|
||||
|
||||
ret = clk_set_rate(priv->mclk, freq);
|
||||
if (ret)
|
||||
dev_err(priv->dev, "failed to set mclk\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int it6621_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct it6621_priv *priv = snd_soc_dai_get_drvdata(dai);
|
||||
unsigned int fs;
|
||||
unsigned int wl;
|
||||
unsigned int ch;
|
||||
int ret;
|
||||
|
||||
switch (snd_pcm_rate_to_rate_bit(params_rate(params))) {
|
||||
case SNDRV_PCM_RATE_32000:
|
||||
fs = IEC958_AES3_CON_FS_32000;
|
||||
break;
|
||||
case SNDRV_PCM_RATE_44100:
|
||||
fs = IEC958_AES3_CON_FS_44100;
|
||||
break;
|
||||
case SNDRV_PCM_RATE_48000:
|
||||
fs = IEC958_AES3_CON_FS_48000;
|
||||
break;
|
||||
case SNDRV_PCM_RATE_64000:
|
||||
fs = IT6621_AES3_CON_FS_64000;
|
||||
break;
|
||||
case SNDRV_PCM_RATE_88200:
|
||||
fs = IEC958_AES3_CON_FS_88200;
|
||||
break;
|
||||
case SNDRV_PCM_RATE_96000:
|
||||
fs = IEC958_AES3_CON_FS_96000;
|
||||
break;
|
||||
case SNDRV_PCM_RATE_176400:
|
||||
fs = IEC958_AES3_CON_FS_176400;
|
||||
break;
|
||||
case SNDRV_PCM_RATE_192000:
|
||||
fs = IEC958_AES3_CON_FS_192000;
|
||||
break;
|
||||
case SNDRV_PCM_RATE_352800:
|
||||
fs = IT6621_AES3_CON_FS_352000;
|
||||
break;
|
||||
case SNDRV_PCM_RATE_384000:
|
||||
fs = IT6621_AES3_CON_FS_384000;
|
||||
break;
|
||||
default:
|
||||
dev_err(priv->dev, "invalid rate: %d\n", params_rate(params));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (params_format(params)) {
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
wl = IEC958_AES4_CON_WORDLEN_20_16;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S20_3LE:
|
||||
wl = IEC958_AES4_CON_WORDLEN_24_20;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
wl = IEC958_AES4_CON_WORDLEN_24_20 |
|
||||
IEC958_AES4_CON_MAX_WORDLEN_24;
|
||||
break;
|
||||
default:
|
||||
dev_err(priv->dev, "invalid format: %d\n",
|
||||
params_format(params));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (params_channels(params)) {
|
||||
case 32:
|
||||
case 16:
|
||||
case 8:
|
||||
case 6:
|
||||
case 2:
|
||||
ch = params_channels(params);
|
||||
break;
|
||||
default:
|
||||
dev_err(priv->dev, "invalid channel: %d\n",
|
||||
params_channels(params));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (priv->config_audio || (priv->audio_fs != fs) ||
|
||||
(priv->i2s_wl != wl) || (priv->audio_ch != ch)) {
|
||||
priv->audio_fs = fs;
|
||||
priv->i2s_wl = wl;
|
||||
priv->audio_ch = ch;
|
||||
priv->config_audio = false;
|
||||
|
||||
ret = it6621_config_audio(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct it6621_priv *priv;
|
||||
|
||||
priv = snd_soc_component_get_drvdata(component);
|
||||
priv->mclk = devm_clk_get_optional(component->dev, "mclk");
|
||||
|
||||
if (IS_ERR(priv->mclk))
|
||||
return PTR_ERR(priv->mclk);
|
||||
|
||||
clk_prepare_enable(priv->mclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_suspend(struct snd_soc_component *component)
|
||||
{
|
||||
struct it6621_priv *priv = snd_soc_component_get_drvdata(component);
|
||||
|
||||
clear_bit(IT6621_ARC_START, &priv->events);
|
||||
clear_bit(IT6621_EARC_CAP_CHG, &priv->events);
|
||||
clear_bit(IT6621_EARC_EDID_OK, &priv->events);
|
||||
clear_bit(IT6621_EARC_BCLK_OK, &priv->events);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_resume(struct snd_soc_component *component)
|
||||
{
|
||||
struct it6621_priv *priv = snd_soc_component_get_drvdata(component);
|
||||
|
||||
return it6621_earc_init(priv);
|
||||
}
|
||||
|
||||
static int it6621_audio_cap_ctl_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
|
||||
uinfo->count = sizeof_field(struct it6621_priv, rxcap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_audio_cap_ctl_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct it6621_priv *priv = snd_soc_component_get_drvdata(component);
|
||||
|
||||
mutex_lock(&priv->rxcap_lock);
|
||||
memcpy(ucontrol->value.bytes.data, priv->rxcap, sizeof(priv->rxcap));
|
||||
mutex_unlock(&priv->rxcap_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *const it6621_ddfsm_enum[] = { "ARC", "eARC", "unknown" };
|
||||
|
||||
static int it6621_ddfsm_ctl_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
|
||||
uinfo->count = 1;
|
||||
uinfo->value.enumerated.items = ARRAY_SIZE(it6621_ddfsm_enum);
|
||||
|
||||
if (uinfo->value.enumerated.item >= ARRAY_SIZE(it6621_ddfsm_enum))
|
||||
uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
|
||||
|
||||
strscpy(uinfo->value.enumerated.name,
|
||||
it6621_ddfsm_enum[uinfo->value.enumerated.item],
|
||||
sizeof(uinfo->value.enumerated.name));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_ddfsm_ctl_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct it6621_priv *priv = snd_soc_component_get_drvdata(component);
|
||||
unsigned int state;
|
||||
|
||||
it6621_get_ddfsm_state(priv, &state);
|
||||
|
||||
if (state == IT6621_TX_ARC_MODE)
|
||||
ucontrol->value.enumerated.item[0] = 0;
|
||||
else if (state == IT6621_TX_EARC_MODE)
|
||||
ucontrol->value.enumerated.item[0] = 1;
|
||||
else
|
||||
ucontrol->value.enumerated.item[0] = 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_earc_switch_ctl_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
|
||||
uinfo->count = 1;
|
||||
uinfo->value.integer.min = 0;
|
||||
uinfo->value.integer.max = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_earc_switch_ctl_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct it6621_priv *priv = snd_soc_component_get_drvdata(component);
|
||||
|
||||
ucontrol->value.integer.value[0] = (priv->earc_enabled ==
|
||||
IT6621_TX_EARC_EN) ? 1 : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_earc_switch_ctl_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct it6621_priv *priv = snd_soc_component_get_drvdata(component);
|
||||
|
||||
return it6621_set_earc_enabled(priv, !!ucontrol->value.integer.value[0]);
|
||||
}
|
||||
|
||||
static int it6621_arc_switch_ctl_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
|
||||
uinfo->count = 1;
|
||||
uinfo->value.integer.min = 0;
|
||||
uinfo->value.integer.max = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_arc_switch_ctl_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct it6621_priv *priv = snd_soc_component_get_drvdata(component);
|
||||
|
||||
ucontrol->value.integer.value[0] = (priv->arc_enabled ==
|
||||
IT6621_TX_ARC_EN) ? 1 : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_arc_switch_ctl_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct it6621_priv *priv = snd_soc_component_get_drvdata(component);
|
||||
|
||||
return it6621_set_arc_enabled(priv, !!ucontrol->value.integer.value[0]);
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new it6621_controls[] = {
|
||||
{
|
||||
.access = (SNDRV_CTL_ELEM_ACCESS_READ |
|
||||
SNDRV_CTL_ELEM_ACCESS_VOLATILE),
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
||||
.name = "eARC Audio Capabilities",
|
||||
.info = it6621_audio_cap_ctl_info,
|
||||
.get = it6621_audio_cap_ctl_get,
|
||||
},
|
||||
{
|
||||
.access = (SNDRV_CTL_ELEM_ACCESS_READ |
|
||||
SNDRV_CTL_ELEM_ACCESS_VOLATILE),
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
||||
.name = "eARC DD FSM",
|
||||
.info = it6621_ddfsm_ctl_info,
|
||||
.get = it6621_ddfsm_ctl_get,
|
||||
},
|
||||
{
|
||||
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
|
||||
SNDRV_CTL_ELEM_ACCESS_VOLATILE),
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
||||
.name = "eARC Switch",
|
||||
.info = it6621_earc_switch_ctl_info,
|
||||
.get = it6621_earc_switch_ctl_get,
|
||||
.put = it6621_earc_switch_ctl_put,
|
||||
},
|
||||
{
|
||||
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
|
||||
SNDRV_CTL_ELEM_ACCESS_VOLATILE),
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
||||
.name = "ARC Switch",
|
||||
.info = it6621_arc_switch_ctl_info,
|
||||
.get = it6621_arc_switch_ctl_get,
|
||||
.put = it6621_arc_switch_ctl_put,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver it6621_component = {
|
||||
.probe = it6621_probe,
|
||||
.suspend = it6621_suspend,
|
||||
.resume = it6621_resume,
|
||||
.controls = it6621_controls,
|
||||
.num_controls = ARRAY_SIZE(it6621_controls),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dai_ops it6621_dai_ops = {
|
||||
.startup = it6621_startup,
|
||||
.set_sysclk = it6621_set_dai_sysclk,
|
||||
.hw_params = it6621_hw_params,
|
||||
.mute_stream = it6621_mute,
|
||||
.shutdown = it6621_shutdown,
|
||||
};
|
||||
|
||||
#define IT6621_RATES (SNDRV_PCM_RATE_32000 | \
|
||||
SNDRV_PCM_RATE_44100 | \
|
||||
SNDRV_PCM_RATE_48000 | \
|
||||
SNDRV_PCM_RATE_64000 | \
|
||||
SNDRV_PCM_RATE_88200 | \
|
||||
SNDRV_PCM_RATE_96000 | \
|
||||
SNDRV_PCM_RATE_176400 | \
|
||||
SNDRV_PCM_RATE_192000 | \
|
||||
SNDRV_PCM_RATE_352800 | \
|
||||
SNDRV_PCM_RATE_384000)
|
||||
|
||||
#define IT6621_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
|
||||
SNDRV_PCM_FMTBIT_S20_3LE | \
|
||||
SNDRV_PCM_FMTBIT_S24_LE)
|
||||
|
||||
static struct snd_soc_dai_driver it6621_dais[] = {
|
||||
{
|
||||
.name = "it6621-i2s",
|
||||
.playback = {
|
||||
.stream_name = "IT6621 I2S Playback",
|
||||
.channels_min = 2,
|
||||
.channels_max = 16,
|
||||
.rates = IT6621_RATES,
|
||||
.formats = IT6621_FORMATS,
|
||||
},
|
||||
.ops = &it6621_dai_ops,
|
||||
}, {
|
||||
.name = "it6621-spdif",
|
||||
.playback = {
|
||||
.stream_name = "IT6621 SPDIF Playback",
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
.rates = IT6621_RATES,
|
||||
.formats = IT6621_FORMATS,
|
||||
},
|
||||
.ops = &it6621_dai_ops,
|
||||
}, {
|
||||
.name = "it6621-dsd",
|
||||
.playback = {
|
||||
.stream_name = "IT6621 DSD Playback",
|
||||
.channels_min = 2,
|
||||
.channels_max = 12,
|
||||
.rates = IT6621_RATES,
|
||||
.formats = IT6621_FORMATS,
|
||||
},
|
||||
.ops = &it6621_dai_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static int it6621_check_dev(struct it6621_priv *priv)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
regmap_bulk_read(priv->regmap, IT6621_REG_VENDOR_ID_LOW, &val, 2);
|
||||
priv->vid = le16_to_cpu(val);
|
||||
if (priv->vid != IT6621_VENDOR_ID) {
|
||||
dev_err(priv->dev, "invalid vendor id %x\n", priv->vid);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
regmap_bulk_read(priv->regmap, IT6621_REG_DEV_ID_LOW, &val, 2);
|
||||
priv->devid = le16_to_cpu(val);
|
||||
if (priv->devid != IT6621_DEVICE_ID) {
|
||||
dev_err(priv->dev, "invalid device id %x\n", priv->devid);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
regmap_read(priv->regmap, IT6621_REG_REV_ID, &val);
|
||||
priv->revid = val;
|
||||
|
||||
if ((priv->revid != IT6621_REVISION_VARIANT_B0) &&
|
||||
(priv->revid != IT6621_REVISION_VARIANT_C0) &&
|
||||
(priv->revid != IT6621_REVISION_VARIANT_D0)) {
|
||||
dev_err(priv->dev, "invalid revision id %x\n", priv->revid);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void it6621_toggle_hpdio(struct it6621_priv *priv)
|
||||
{
|
||||
mutex_lock(&priv->hpdio_lock);
|
||||
|
||||
dev_dbg(priv->dev, "toggle hpdio\n");
|
||||
gpiod_set_value_cansleep(priv->hpdio, 0);
|
||||
/*
|
||||
* NOTE: Toggle HPD signal at least 100ms (suggestion time is about
|
||||
* 1 ~ 1.5 second).
|
||||
*/
|
||||
msleep(100);
|
||||
gpiod_set_value_cansleep(priv->hpdio, 1);
|
||||
|
||||
mutex_unlock(&priv->hpdio_lock);
|
||||
}
|
||||
|
||||
static void it6621_hpdio_work(struct work_struct *work)
|
||||
{
|
||||
struct it6621_priv *priv = container_of(work, struct it6621_priv,
|
||||
hpdio_work);
|
||||
|
||||
it6621_toggle_hpdio(priv);
|
||||
}
|
||||
|
||||
static int it6621_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct it6621_priv *priv;
|
||||
const char *source;
|
||||
int ret;
|
||||
|
||||
priv = devm_kzalloc(&client->dev, sizeof(struct it6621_priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
dev_set_drvdata(&client->dev, priv);
|
||||
|
||||
priv->client = client;
|
||||
priv->dev = &client->dev;
|
||||
priv->regmap = devm_regmap_init_i2c(client, &it6621_regmap_config);
|
||||
if (IS_ERR(priv->regmap)) {
|
||||
dev_err(priv->dev, "failed to initialize regmap\n");
|
||||
return PTR_ERR(priv->regmap);
|
||||
}
|
||||
|
||||
ret = it6621_check_dev(priv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
priv->audio_type = IT6621_AUD_TYPE_LPCM;
|
||||
priv->audio_ch = 0;
|
||||
priv->audio_fs = IEC958_AES3_CON_FS_NOTID;
|
||||
priv->i2s_wl = IEC958_AES4_CON_WORDLEN_NOTID;
|
||||
priv->mch_lpcm_enabled = IT6621_TX_MCH_LPCM_DIS;
|
||||
priv->layout_2ch_enabled = IT6621_TX_2CH_LAYOUT_DIS;
|
||||
priv->vcm_sel = IT6621_TX_VCM0;
|
||||
priv->i2s_fmt = IT6621_I2S_FMT_32BIT;
|
||||
priv->rclk_sel = IT6621_RCLK_FREQ_REFCLK_DIV_2;
|
||||
priv->update_avg_enabled = IT6621_UPDATE_AVG_EN;
|
||||
priv->sck_inv_enabled = 0;
|
||||
priv->tck_inv_enabled = 1;
|
||||
priv->mclk_inv_enabled = 1;
|
||||
priv->dclk_inv_enabled = 0;
|
||||
priv->cmo_opt = IT6621_TX_CMO_NORMAL;
|
||||
priv->force_cmo_enabled = IT6621_TX_FORCE_CMO_EN;
|
||||
priv->resync_opt = IT6621_TX_RESYNC_NEW;
|
||||
priv->pkt1_enabled = IT6621_TX_PKT1_DIS;
|
||||
priv->pkt2_enabled = IT6621_TX_PKT2_DIS;
|
||||
priv->pkt3_enabled = IT6621_TX_PKT3_DIS;
|
||||
priv->i2s_hbr_enabled = 1;
|
||||
priv->ubit_opt = IT6621_TX_U_BIT_1BIT_FRAME;
|
||||
priv->c_ch_opt = IT6621_TX_C_CH_OPT1;
|
||||
priv->ecc_opt = IT6621_TX_ECC_U_SWAP;
|
||||
priv->enc_seed = 0xa5c3;
|
||||
priv->enc_opt = IT6621_TX_ENC_OPT3;
|
||||
priv->bclk_inv_enabled = IT6621_BCLK_INV_DIS;
|
||||
priv->nxt_pkt_to_sel = IT6621_TX_NEXT_PKT_TIMEOUT_50US;
|
||||
priv->turn_over_sel = IT6621_TX_TURN_OVER_16US;
|
||||
priv->hb_retry_sel = IT6621_TX_HB_RETRY_0MS;
|
||||
priv->hb_retry_enabled = IT6621_TX_HB_RETRY_EN;
|
||||
priv->cmd_to_enabled = 0;
|
||||
priv->enter_arc_now = IT6621_TX_ARC_NOW_DIS;
|
||||
priv->arc_enabled = IT6621_TX_ARC_EN;
|
||||
priv->earc_enabled = IT6621_TX_EARC_EN;
|
||||
INIT_LIST_HEAD(&priv->fhs);
|
||||
mutex_init(&priv->fhs_lock);
|
||||
mutex_init(&priv->hpdio_lock);
|
||||
mutex_init(&priv->rxcap_lock);
|
||||
INIT_WORK(&priv->hpdio_work, it6621_hpdio_work);
|
||||
|
||||
ret = it6621_uapi_init(priv);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "failed to initialize uapi\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_add_action_or_reset(priv->dev,
|
||||
(void(*)(void *))it6621_uapi_remove,
|
||||
priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = device_property_read_string(priv->dev, "ite,audio-source",
|
||||
&source);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "no input audio source\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!strcmp(source, "i2s"))
|
||||
priv->audio_src = IT6621_AUD_SRC_I2S;
|
||||
else if (!strcmp(source, "spdif"))
|
||||
priv->audio_src = IT6621_AUD_SRC_SPDIF;
|
||||
else if (!strcmp(source, "tdm"))
|
||||
priv->audio_src = IT6621_AUD_SRC_TDM;
|
||||
else if (!strcmp(source, "dsd"))
|
||||
priv->audio_src = IT6621_AUD_SRC_DSD;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
if (device_property_read_bool(priv->dev, "ite,force-arc"))
|
||||
priv->force_arc = 1;
|
||||
|
||||
if (device_property_read_bool(priv->dev, "ite,force-earc"))
|
||||
priv->force_earc = 1;
|
||||
|
||||
if (device_property_read_u32(priv->dev, "ite,fixed-lcf",
|
||||
&priv->fixed_lcf))
|
||||
priv->fixed_lcf = 0x00;
|
||||
|
||||
priv->hpdio = devm_gpiod_get_optional(&client->dev, "hpdio",
|
||||
GPIOD_OUT_LOW);
|
||||
|
||||
ret = it6621_earc_init(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (client->irq) {
|
||||
ret = devm_request_threaded_irq(priv->dev, client->irq, NULL,
|
||||
it6621_irq,
|
||||
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
|
||||
"it6621", priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return devm_snd_soc_register_component(priv->dev, &it6621_component,
|
||||
it6621_dais,
|
||||
ARRAY_SIZE(it6621_dais));
|
||||
}
|
||||
|
||||
static const struct i2c_device_id it6621_i2c_id[] = {
|
||||
{ IT6621_I2C_NAME, 0 },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, it6621_i2c_id);
|
||||
|
||||
static const struct of_device_id it6621_dt_match[] = {
|
||||
{ .compatible = "ite,it6621" },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
static struct i2c_driver it6621_i2c_driver = {
|
||||
.driver = {
|
||||
.name = IT6621_I2C_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(it6621_dt_match),
|
||||
},
|
||||
.probe = it6621_i2c_probe,
|
||||
.id_table = it6621_i2c_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(it6621_i2c_driver);
|
||||
|
||||
MODULE_AUTHOR("Jason Zhang <jason.zhang@rock-chips.com>");
|
||||
MODULE_DESCRIPTION("ASoC IT6621 eARC Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
1092
sound/soc/codecs/it6621/it6621-earc.c
Normal file
1092
sound/soc/codecs/it6621/it6621-earc.c
Normal file
File diff suppressed because it is too large
Load Diff
62
sound/soc/codecs/it6621/it6621-earc.h
Normal file
62
sound/soc/codecs/it6621/it6621-earc.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (c) 2024 Rockchip Electronics Co. Ltd.
|
||||
* Author: Jason Zhang <jason.zhang@rock-chips.com>
|
||||
*/
|
||||
|
||||
#ifndef _IT6621_EARC_H
|
||||
#define _IT6621_EARC_H
|
||||
|
||||
#include "it6621.h"
|
||||
|
||||
#define IT6621_AES3_CON_FS_64000 0x0b
|
||||
#define IT6621_AES3_CON_FS_128000 0x2b
|
||||
#define IT6621_AES3_CON_FS_256000 0x1b
|
||||
#define IT6621_AES3_CON_FS_352000 0x0d
|
||||
#define IT6621_AES3_CON_FS_384000 0x05
|
||||
#define IT6621_AES3_CON_FS_512000 0x3b
|
||||
#define IT6621_AES3_CON_FS_705000 0x2d
|
||||
#define IT6621_AES3_CON_FS_1024000 0x35
|
||||
#define IT6621_AES3_CON_FS_1411000 0x1d
|
||||
#define IT6621_AES3_CON_FS_1536000 0x15
|
||||
|
||||
#define IT6621_AUD_TYPE_LPCM 0
|
||||
#define IT6621_AUD_TYPE_NLPCM 1
|
||||
#define IT6621_AUD_TYPE_HBR 2
|
||||
#define IT6621_AUD_TYPE_DSD 3
|
||||
|
||||
/* HDMI2.1 spec. Table 9-23: Channel Status Bits 0, 1, 3, 4, and 5 */
|
||||
#define HDMI_AUDIO_FMT_UN_2CH_LPCM 0x00 /* Unencrypted 2-channel LPCM */
|
||||
#define HDMI_AUDIO_FMT_UN_MCH_LPCM 0x10 /* Unencrypted multi-channel LPCM */
|
||||
#define HDMI_AUDIO_FMT_UN_XCH_DSD 0x18 /* Unencrypted One Bit Audio */
|
||||
#define HDMI_AUDIO_FMT_UN_2CH_NLPCM 0x02 /* Unencrypted IEC 61937 */
|
||||
#define HDMI_AUDIO_FMT_EN_2CH_NLPCM 0x06 /* Encrypted IEC 61937 */
|
||||
#define HDMI_AUDIO_FMT_EN_MCH_NLPCM 0x16 /* Encrypted multi-channel LPCM */
|
||||
#define HDMI_AUDIO_FMT_EN_XCH_DSD 0x1e /* Encrypted One Bit Audio */
|
||||
|
||||
/*
|
||||
* HDMI2.1 spec.
|
||||
* Table 9-25: Channel Status Bits 44 to 47 When Multi-Channel L-PCM is
|
||||
* Transmitted.
|
||||
* Table 9-26: Channel Status Bits 44 to 47 When One Bit Audio is Transmitted.
|
||||
* Table 9-27: Channel Status Bits 44 to 47 When IEC 61937 (Compressed) Audio
|
||||
* is Transmitted.
|
||||
*/
|
||||
#define HDMI_AUDIO_LAYOUT_LPCM_2CH 0x00
|
||||
#define HDMI_AUDIO_LAYOUT_LPCM_8CH 0x07
|
||||
#define HDMI_AUDIO_LAYOUT_LPCM_16CH 0x0b
|
||||
#define HDMI_AUDIO_LAYOUT_LPCM_32CH 0x03
|
||||
#define HDMI_AUDIO_LAYOUT_NLPCM_2CH 0x00
|
||||
#define HDMI_AUDIO_LAYOUT_NLPCM_8CH 0x07
|
||||
#define HDMI_AUDIO_LAYOUT_DSD_6CH 0x05
|
||||
#define HDMI_AUDIO_LAYOUT_DSD_12CH 0x09
|
||||
|
||||
int it6621_set_arc_enabled(struct it6621_priv *priv, bool enabled);
|
||||
int it6621_set_earc_enabled(struct it6621_priv *priv, bool enabled);
|
||||
int it6621_set_enter_arc(struct it6621_priv *priv, bool enabled);
|
||||
int it6621_get_ddfsm_state(struct it6621_priv *priv, unsigned int *state);
|
||||
int it6621_set_channel_status(struct it6621_priv *priv);
|
||||
int it6621_earc_init(struct it6621_priv *priv);
|
||||
irqreturn_t it6621_irq(int irq, void *data);
|
||||
|
||||
#endif /* _IT6621_EARC_H */
|
||||
982
sound/soc/codecs/it6621/it6621-reg-bank0.h
Normal file
982
sound/soc/codecs/it6621/it6621-reg-bank0.h
Normal file
@@ -0,0 +1,982 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (c) 2024 Rockchip Electronics Co. Ltd.
|
||||
* Author: Jason Zhang <jason.zhang@rock-chips.com>
|
||||
*/
|
||||
|
||||
#ifndef _IT6621_REG_BANK0_H
|
||||
#define _IT6621_REG_BANK0_H
|
||||
|
||||
/* Bank 0 */
|
||||
|
||||
/* General Registers */
|
||||
#define IT6621_REG_VENDOR_ID_LOW 0x00 /* Vendor ID low */
|
||||
#define IT6621_REG_VENDOR_ID_HIGH 0x01 /* Vendor ID high */
|
||||
#define IT6621_REG_DEV_ID_LOW 0x02 /* Device ID low */
|
||||
#define IT6621_REG_DEV_ID_HIGH 0x03 /* Device ID high */
|
||||
#define IT6621_REG_REV_ID 0x04 /* Revision ID */
|
||||
|
||||
/* System Reset */
|
||||
#define IT6621_REG_SYS_RESET 0x05
|
||||
#define IT6621_SW_ACLK_RESET_SEL BIT(0) /* Software ACLK clock domain reset */
|
||||
#define IT6621_SW_ACLK_RESET_DIS (0x00 << 0)
|
||||
#define IT6621_SW_ACLK_RESET_EN (0x01 << 0)
|
||||
#define IT6621_SW_BCLK_RESET_SEL BIT(1) /* Software BCLK clock domain reset */
|
||||
#define IT6621_SW_BCLK_RESET_DIS (0x00 << 1)
|
||||
#define IT6621_SW_BCLK_RESET_EN (0x01 << 1)
|
||||
#define IT6621_SW_TCCLK_RESET_SEL BIT(2) /* Software TCCLK clock domain reset */
|
||||
#define IT6621_SW_TCCLK_RESET_DIS (0x00 << 2)
|
||||
#define IT6621_SW_TCCLK_RESET_EN (0x01 << 2)
|
||||
#define IT6621_SW_RCCLK_RESET_SEL BIT(3) /* Software RCCLK clock domain reset */
|
||||
#define IT6621_SW_RCCLK_RESET_DIS (0x00 << 3)
|
||||
#define IT6621_SW_RCCLK_RESET_EN (0x01 << 3)
|
||||
#define IT6621_SW_RCLK_RESET_SEL BIT(7) /* Software RCLK clock domain reset */
|
||||
#define IT6621_SW_RCLK_RESET_DIS (0x00 << 7)
|
||||
#define IT6621_SW_RCLK_RESET_EN (0x01 << 7)
|
||||
|
||||
/* System Status */
|
||||
#define IT6621_REG_SYS_STATUS 0x07
|
||||
#define IT6621_HPDIO_STATUS BIT(0) /* eARC HPDIO status */
|
||||
#define IT6621_HPDB_STATUS BIT(1) /* eARC HPDB status */
|
||||
#define IT6621_TX_XP_LOCK BIT(2) /* eARC TX XP lock indicator of PLL, 1: locked */
|
||||
#define IT6621_TX_NO_AUDIO BIT(4) /* 1: eARC TX no input audio */
|
||||
#define IT6621_TX_MUTE BIT(6) /* eARC TX input mute status */
|
||||
|
||||
#define IT6621_REG_EARC_TX_AUD_FREQ_NUM 0x0a
|
||||
|
||||
/* System Control Registers */
|
||||
#define IT6621_REG_SYS_CTRL0 0x0c
|
||||
#define IT6621_EXT_INT_EN BIT(1) /* External INT pin, 0: Disable, 1: Enable */
|
||||
#define IT6621_INT_IO_MODE BIT(2) /* External INT pin mode selection,
|
||||
* 0: Push-Pull Mode,
|
||||
* 1: Open-Drain mode
|
||||
*/
|
||||
#define IT6621_INT_IO_POL BIT(3) /* External INT pin active selection,
|
||||
* 0: INT active low,
|
||||
* 1: INT active high
|
||||
*/
|
||||
#define IT6621_FORCE_WRITE_UPDATE BIT(4) /* 1: force write update in non-idle state */
|
||||
|
||||
#define IT6621_REG_SYS_CTRL1 0x0d
|
||||
#define IT6621_TX_AUD_FREQ_OPT BIT(0) /* eARC TX audio sampling frequency option */
|
||||
#define IT6621_TX_AUD_FREQ_DIV1 (0x00 << 0) /* div 1 */
|
||||
#define IT6621_TX_AUD_FREQ_DIV4 (0x01 << 0) /* div 4 */
|
||||
#define IT6621_TX_FORCE_HPDB_LOW_SEL BIT(4) /* eARC TX force HPDB low */
|
||||
#define IT6621_TX_FORCE_HPDB_LOW_DIS (0x00 << 4)
|
||||
#define IT6621_TX_FORCE_HPDB_LOW_EN (0x01 << 4)
|
||||
|
||||
#define IT6621_REG_SYS_CTRL3 0x0f
|
||||
#define IT6621_BANK_SEL GENMASK(1, 0) /* Bank selection */
|
||||
#define IT6621_BANK0 (0x00 << 0) /* Reg00h~ Regffh */
|
||||
#define IT6621_BANK1 (0x01 << 0) /* Reg110h ~ Reg1ffh */
|
||||
#define IT6621_BANK2 (0x02 << 0) /* Reg210h ~ Reg2ffh */
|
||||
#define IT6621_TX_INT_STATUS BIT(2) /* eARC TX interrupt status */
|
||||
#define IT6621_CEC_INT_STATUS BIT(4) /* eARC CEC interrupt status */
|
||||
|
||||
/* Interrupt Status Registers */
|
||||
#define IT6621_REG_INT_STATUS0 0x10
|
||||
#define IT6621_TX_HPDIO_ON BIT(0) /* eARC TX HPDIO on interrupt */
|
||||
#define IT6621_TX_HPDIO_OFF BIT(1) /* eARC TX HPDIO off interrupt */
|
||||
#define IT6621_TX_STATE3_CHANGE BIT(2) /* eARC TX state3 change interrupt */
|
||||
#define IT6621_TX_HB_LOST BIT(3) /* eARC TX HeartBeat lost interrupt */
|
||||
#define IT6621_TX_DISV_TIMEOUT BIT(4) /* eARC TX discovery timeout interrupt */
|
||||
#define IT6621_TX_NO_AUD_CHANGE BIT(5) /* eARC TX no audio change interrupt */
|
||||
#define IT6621_TX_XP_LOCK_CHANGE BIT(6) /* eARC TX XP_LOCK change interrupt */
|
||||
#define IT6621_TX_RESYNC_ERR BIT(7) /* eARC TX ReSync error interrupt */
|
||||
|
||||
#define IT6621_REG_INT_STATUS1 0x11
|
||||
#define IT6621_TX_CMD_DONE BIT(0) /* eARC TX command done interrupt */
|
||||
#define IT6621_TX_CMD_FAIL BIT(1) /* eARC TX command fail interrupt */
|
||||
#define IT6621_TX_HB_DONE BIT(2) /* eARC TX HeartBeat done interrupt */
|
||||
#define IT6621_TX_READ_STATE_CHANGE BIT(3) /* eARC TX read EARC_RX_STAT change interrupt */
|
||||
#define IT6621_TX_CMDC_BP_ERR BIT(4) /* eARC TX CMDC bi-phase error interrupt */
|
||||
#define IT6621_TX_WRITE_STATE_CHANGE BIT(5) /* eARC TX auto write STAT_CHNG
|
||||
* from '1' to '0' done
|
||||
*/
|
||||
#define IT6621_TX_WRITE_CAP_CHANGE BIT(6) /* eARC TX auto write CAP_CHNG
|
||||
* from '1' to '0' done
|
||||
*/
|
||||
#define IT6621_TX_HB_FAIL BIT(7) /* eARC TX HeartBeat fail interrupt */
|
||||
|
||||
#define IT6621_REG_INT_STATUS2 0x12
|
||||
#define IT6621_TX_FIFO_ERR BIT(0) /* eARC TX FIFO error interrupt */
|
||||
#define IT6621_TX_DEC_ERR BIT(1) /* eARC TX input audio decode error interrupt */
|
||||
#define IT6621_TX_SPDIF_READY BIT(2) /* eARC TX input SPDIF channel
|
||||
* status ready interrupt
|
||||
*/
|
||||
#define IT6621_TX_SPDIF_CHANGE BIT(3) /* eARC TX input SPDIF channel
|
||||
* status change interrupt
|
||||
*/
|
||||
#define IT6621_TX_MUTE_CHANGE BIT(4) /* eARC TX input MUTE change interrupt */
|
||||
|
||||
#define IT6621_REG_INT_STATUS3 0x13
|
||||
#define IT6621_TX_HPDB_ON BIT(0) /* eARC TX HPDB on interrupt */
|
||||
#define IT6621_TX_HPDB_OFF BIT(1) /* eARC TX HPDB off interrupt */
|
||||
|
||||
#define IT6621_REG_INT_STATUS4 0x19
|
||||
#define IT6621_DET_ACLK_STABLE BIT(0) /* Detect ACLK stable interrupt */
|
||||
#define IT6621_DET_ACLK_VALID BIT(1) /* Detect ACLK valid interrupt */
|
||||
#define IT6621_DET_BCLK_STABLE BIT(2) /* Detect BCLK stable interrupt */
|
||||
#define IT6621_DET_BCLK_VALID BIT(3) /* Detect BCLK valid interrupt */
|
||||
#define IT6621_DET_NO_BCLK BIT(4) /* Detect no BCLK interrupt */
|
||||
#define IT6621_DET_NO_DMAC BIT(5) /* Detect no DMAC interrupt */
|
||||
|
||||
/* Interrupt Enable Registers */
|
||||
#define IT6621_REG_INT_EN0 0x1c
|
||||
#define IT6621_TX_HPDIO_ON_EN BIT(0) /* Enable eARC TX HPDIO on interrupt */
|
||||
#define IT6621_TX_HPDIO_OFF_EN BIT(1) /* Enable eARC TX HPDIO off interrupt */
|
||||
#define IT6621_TX_STATE3_CHANGE_EN BIT(2) /* Enable eARC TX state3 change interrupt */
|
||||
#define IT6621_TX_HB_LOST_EN BIT(3) /* Enable eARC TX HeartBeat lost interrupt */
|
||||
#define IT6621_TX_DISV_TIMEOUT_EN BIT(4) /* Enable eARC TX discovery timeout interrupt */
|
||||
#define IT6621_TX_NO_AUD_CHANGE_EN BIT(5) /* Enable eARC TX no audio change interrupt */
|
||||
#define IT6621_TX_XP_LOCK_CHANGE_EN BIT(6) /* Enable eARC TX XP_LOCK change interrupt */
|
||||
#define IT6621_TX_RESYNC_ERR_EN BIT(7) /* Enable eARC TX ReSync error interrupt */
|
||||
|
||||
#define IT6621_REG_INT_EN1 0x1d
|
||||
#define IT6621_TX_CMD_DONE_SEL BIT(0) /* Enable eARC TX command done interrupt */
|
||||
#define IT6621_TX_CMD_DONE_DIS (0x00 << 0)
|
||||
#define IT6621_TX_CMD_DONE_EN (0x01 << 0)
|
||||
#define IT6621_TX_CMD_FAIL_SEL BIT(1) /* Enable eARC TX command fail interrupt */
|
||||
#define IT6621_TX_CMD_FAIL_DIS (0x00 << 1)
|
||||
#define IT6621_TX_CMD_FAIL_EN (0x01 << 1)
|
||||
#define IT6621_TX_HB_DONE_SEL BIT(2) /* Enable eARC TX HeartBeat done interrupt */
|
||||
#define IT6621_TX_HB_DONE_DIS (0x00 << 2)
|
||||
#define IT6621_TX_HB_DONE_EN (0x01 << 2)
|
||||
#define IT6621_TX_READ_STATE_CHG_SEL BIT(3) /* Enable eARC TX read
|
||||
* EARC_RX_STAT change interrupt
|
||||
*/
|
||||
#define IT6621_TX_READ_STATE_CHG_DIS (0x00 << 3)
|
||||
#define IT6621_TX_READ_STATE_CHG_EN (0x01 << 3)
|
||||
#define IT6621_TX_CMDC_BP_ERR_SEL BIT(4) /* Enable eARC TX CMDC bi-phase error interrupt */
|
||||
#define IT6621_TX_CMDC_BP_ERR_DIS (0x00 << 4)
|
||||
#define IT6621_TX_CMDC_BP_ERR_EN (0x01 << 4)
|
||||
#define IT6621_TX_WRITE_STATE_CHG_SEL BIT(5) /* Enable eARC TX auto write
|
||||
* state change interrupt
|
||||
*/
|
||||
#define IT6621_TX_WRITE_STATE_CHG_DIS (0x00 << 5)
|
||||
#define IT6621_TX_WRITE_STATE_CHG_EN (0x01 << 5)
|
||||
#define IT6621_TX_WRITE_CAP_CHG_SEL BIT(6) /* Enable eARC TX auto write cap change interrupt */
|
||||
#define IT6621_TX_WRITE_CAP_CHG_DIS (0x00 << 6)
|
||||
#define IT6621_TX_WRITE_CAP_CHG_EN (0x01 << 6)
|
||||
#define IT6621_TX_HB_FAIL_SEL BIT(7) /* Enable eARC TX HeartBeat fail interrupt */
|
||||
#define IT6621_TX_HB_FAIL_DIS (0x00 << 7)
|
||||
#define IT6621_TX_HB_FAIL_EN (0x01 << 7)
|
||||
|
||||
#define IT6621_REG_INT_EN2 0x1e
|
||||
#define IT6621_TX_FIFO_ERR_EN BIT(0) /* Enable eARC TX FIFO error interrupt */
|
||||
#define IT6621_TX_DEC_ERR_EN BIT(1) /* Enable eARC TX input audio
|
||||
* decode error interrupt
|
||||
*/
|
||||
#define IT6621_TX_SPDIF_READY_EN BIT(2) /* Enable eARC TX input SPDIF
|
||||
* channel status ready interrupt
|
||||
*/
|
||||
#define IT6621_TX_SPDIF_CHANGE_EN BIT(3) /* Enable eARC TX input SPDIF
|
||||
* channel status change interrupt
|
||||
*/
|
||||
#define IT6621_TX_MUTE_CHANGE_EN BIT(4) /* Enable eARC TX input MUTE change interrupt */
|
||||
|
||||
#define IT6621_REG_INT_EN3 0x1f
|
||||
#define IT6621_TX_HPDB_ON_EN BIT(0) /* Enable eARC TX HPDB on interrupt */
|
||||
#define IT6621_TX_HPDB_OFF_EN BIT(1) /* Enable eARC TX HPDB off interrupt */
|
||||
|
||||
#define IT6621_REG_INT_EN4 0x25
|
||||
#define IT6621_DET_ACLK_STABLE_EN BIT(0) /* Enable detect ACLK stable interrupt */
|
||||
#define IT6621_DET_ACLK_VALID_EN BIT(1) /* Enable detect ACLK valid interrupt */
|
||||
#define IT6621_DET_BCLK_STABLE_EN BIT(2) /* Enable detect BCLK stable interrupt */
|
||||
#define IT6621_DET_BCLK_VALID_EN BIT(3) /* Enable detect BCLK valid interrupt */
|
||||
#define IT6621_DET_NO_BCLK_EN BIT(4) /* Enable detect no BCLK interrupt */
|
||||
#define IT6621_DET_NO_DMAC_EN BIT(5) /* Enable detect no DMAC interrupt */
|
||||
|
||||
/* Clock Control Registers */
|
||||
#define IT6621_REG_CLK_CTRL0 0x28
|
||||
#define IT6621_RCLK_FREQ_SEL GENMASK(1, 0) /* RCLK frequency selection */
|
||||
#define IT6621_RCLK_FREQ_REFCLK (0x00 << 0) /* RCLK = REFCLK, 20MHz */
|
||||
#define IT6621_RCLK_FREQ_REFCLK_DIV_2 (0x01 << 0) /* RCLK = REFCLK/2, 10Mhz */
|
||||
#define IT6621_RCLK_FREQ_REFCLK_DIV_4 (0x02 << 0) /* RCLK = REFCLK/4, 5Mhz */
|
||||
#define IT6621_RCLK_FREQ_REFCLK_DIV_8 (0x03 << 0) /* RCLK = REFCLK/8, 2.5Mhz */
|
||||
#define IT6621_RCLK_PWD_SEL BIT(2) /* Enable RCLK power-down when IDDQ mode */
|
||||
#define IT6621_RCLK_PWD_DIS (0x00 << 2) /* disable */
|
||||
#define IT6621_RCLK_PWD_EN (0x01 << 2) /* enable */
|
||||
#define IT6621_GATE_RCLK_SEL BIT(4) /* Gating GRCLK clock domain */
|
||||
#define IT6621_GATE_RCLK_DIS (0x00 << 4) /* disable */
|
||||
#define IT6621_GATE_RCLK_EN (0x01 << 4) /* enable */
|
||||
#define IT6621_DMAC_PWD_SEL BIT(6) /* Enable DMAC power-down */
|
||||
#define IT6621_DMAC_PWD_DIS (0x00 << 6) /* disable */
|
||||
#define IT6621_DMAC_PWD_EN (0x01 << 6) /* enable */
|
||||
#define IT6621_CMDC_PWD_SEL BIT(7) /* Enable CMDC power-down */
|
||||
#define IT6621_CMDC_PWD_DIS (0x00 << 7) /* disable */
|
||||
#define IT6621_CMDC_PWD_EN (0x01 << 7) /* enable */
|
||||
|
||||
#define IT6621_REG_CLK_CTRL1 0x29
|
||||
#define IT6621_TBCLK_SEL GENMASK(2, 0) /* TBCLK selection */
|
||||
#define IT6621_TBCLK_AICLK (0x00 << 0) /* TBCLK = AICLK x 1 */
|
||||
#define IT6621_TBCLK_AICLK_MUL_2 (0x01 << 0) /* TBCLK = AICLK x 2 */
|
||||
#define IT6621_TBCLK_AICLK_MUL_4 (0x02 << 0) /* TBCLK = AICLK x 4 */
|
||||
#define IT6621_TBCLK_AICLK_MUL_8 (0x03 << 0) /* TBCLK = AICLK x 8 */
|
||||
#define IT6621_TBCLK_AICLK_MUL_16 (0x04 << 0) /* TBCLK = AICLK x 16 */
|
||||
#define IT6621_TBCLK_AICLK_MUL_32 (0x05 << 0) /* TBCLK = AICLK x 32 */
|
||||
#define IT6621_TBCLK_AUTO BIT(3) /* 1: TBCLK auto mode */
|
||||
#define IT6621_AOCLK_SEL GENMASK(6, 4) /* AOCLK selection */
|
||||
#define IT6621_AOCLK_RBCLK (0x00 << 4) /* AOCLK = RBCLK / 1 */
|
||||
#define IT6621_AOCLK_RBCLK_DIV_2 (0x01 << 4) /* AOCLK = RBCLK / 2 */
|
||||
#define IT6621_AOCLK_RBCLK_DIV_4 (0x02 << 4) /* AOCLK = RBCLK / 4 */
|
||||
#define IT6621_AOCLK_RBCLK_DIV_8 (0x03 << 4) /* AOCLK = RBCLK / 8 */
|
||||
#define IT6621_AOCLK_RBCLK_DIV_16 (0x04 << 4) /* AOCLK = RBCLK / 16 */
|
||||
#define IT6621_AOCLK_RBCLK_DIV_32 (0x05 << 4) /* AOCLK = RBCLK / 32 */
|
||||
#define IT6621_AOCLK_LCCLK (0x06 << 4) /* AOCLK = LCCLK */
|
||||
#define IT6621_AOCLK_AUTO BIT(7) /* 1: AOCLK auto mode */
|
||||
|
||||
#define IT6621_REG_CLK_CTRL2 0x2a
|
||||
#define IT6621_ACLK_INV_SEL BIT(0) /* eARC ACLK inversion */
|
||||
#define IT6621_ACLK_INV_DIS (0x00 << 0) /* disable */
|
||||
#define IT6621_ACLK_INV_EN (0x01 << 0) /* enable */
|
||||
#define IT6621_BCLK_INV_SEL BIT(1) /* eARC BCLK inversion */
|
||||
#define IT6621_BCLK_INV_DIS (0x00 << 1) /* disable */
|
||||
#define IT6621_BCLK_INV_EN (0x01 << 1) /* enable */
|
||||
#define IT6621_RCCLK_OPT BIT(2) /* RCCLK option */
|
||||
#define IT6621_MCLKX2_SEL GENMASK(6, 4) /* MCLKX2 selection */
|
||||
#define IT6621_MCLKX2_RBCLKX2 (0x00 << 4) /* MCLKX2 = RBCLKX2 / 1 */
|
||||
#define IT6621_MCLKX2_RBCLKX2_DIV_2 (0x01 << 4) /* MCLKX2 = RBCLKX2 / 2 */
|
||||
#define IT6621_MCLKX2_RBCLKX2_DIV_4 (0x02 << 4) /* MCLKX2 = RBCLKX2 / 4 */
|
||||
#define IT6621_MCLKX2_RBCLKX2_DIV_8 (0x03 << 4) /* MCLKX2 = RBCLKX2 / 8 */
|
||||
#define IT6621_MCLKX2_RBCLKX2_DIV_16 (0x04 << 4) /* MCLKX2 = RBCLKX2 / 16 */
|
||||
#define IT6621_MCLKX2_RBCLKX2_DIV_32 (0x05 << 4) /* MCLKX2 = RBCLKX2 / 32 */
|
||||
#define IT6621_MCLKX2_LCCLK (0x06 << 4) /* MCLKX2 = LCCLK */
|
||||
#define IT6621_MCLKX2_AUTO BIT(7) /* 1: MCLKX2 auto mode */
|
||||
|
||||
/* eARC TX Discovery and Disconnect Registers */
|
||||
#define IT6621_REG_TX_DD0 0x30
|
||||
#define IT6621_TX_DD_FSM_SEL BIT(0) /* 1: eARC TX enable discovery and disconnect FSM */
|
||||
#define IT6621_TX_DD_FSM_DIS (0x00 << 0)
|
||||
#define IT6621_TX_DD_FSM_EN (0x01 << 0)
|
||||
#define IT6621_TX_EARC_SEL BIT(1) /* 1: enable eARC TX function */
|
||||
#define IT6621_TX_EARC_DIS (0x00 << 1)
|
||||
#define IT6621_TX_EARC_EN (0x01 << 1)
|
||||
#define IT6621_TX_ARC_SEL BIT(2) /* 1: enable ARC TX function */
|
||||
#define IT6621_TX_ARC_DIS (0x00 << 2)
|
||||
#define IT6621_TX_ARC_EN (0x01 << 2)
|
||||
#define IT6621_TX_ARC_NOW_SEL BIT(3) /* 1: ARC TX function is enabled now */
|
||||
#define IT6621_TX_ARC_NOW_DIS (0x00 << 3)
|
||||
#define IT6621_TX_ARC_NOW_EN (0x01 << 3)
|
||||
#define IT6621_TX_DISV_TIMEOUT_SEL GENMASK(5, 4) /* eARC TX discovery
|
||||
* timeout selection
|
||||
* (No COMMA)
|
||||
*/
|
||||
#define IT6621_TX_DISV_TIMEOUT_450MS (0x00 << 4) /* 450ms */
|
||||
#define IT6621_TX_DISV_TIMEOUT_475MS (0x01 << 4) /* 475ms */
|
||||
#define IT6621_TX_DISV_TIMEOUT_500MS (0x02 << 4) /* 500ms */
|
||||
#define IT6621_TX_DISV_TIMEOUT_600MS (0x03 << 4) /* 600ms */
|
||||
#define IT6621_TX_HB_POS_SEL GENMASK(7, 6) /* eARC TX HeartBeat position selection */
|
||||
#define IT6621_TX_HB_POS_1MS (0x00 << 6) /* 1ms */
|
||||
#define IT6621_TX_HB_POS_3MS (0x01 << 6) /* 3ms */
|
||||
#define IT6621_TX_HB_POS_5MS (0x02 << 6) /* 5ms */
|
||||
#define IT6621_TX_HB_POS_7MS (0x03 << 6) /* 7ms */
|
||||
|
||||
#define IT6621_REG_TX_DD1 0x31
|
||||
#define IT6621_TX_COMMA_SEL GENMASK(1, 0) /* eARC TX valid COMMA selection */
|
||||
#define IT6621_TX_COMMA_8_12MS (0x00 << 0) /* 8~12ms */
|
||||
#define IT6621_TX_COMMA_7_13MS (0x01 << 0) /* 7~13ms */
|
||||
#define IT6621_TX_COMMA_6_14MS (0x02 << 0) /* 6~14ms */
|
||||
#define IT6621_TX_COMMA_5_15MS (0x03 << 0) /* 5~15ms */
|
||||
#define IT6621_TX_COMMA_OPT BIT(2) /* eARC TX COMMA bit error
|
||||
* tolerance, 0: no tolerance,
|
||||
* 1: 1-bit tolerance
|
||||
*/
|
||||
|
||||
#define IT6621_REG_TX_DD2 0x32
|
||||
#define IT6621_TX_DD_FSM_STATE GENMASK(5, 0) /* eARC TX discovery and
|
||||
* disconnect FSM state
|
||||
*/
|
||||
#define IT6621_TX_EARC_MODE (0x08 << 0)
|
||||
#define IT6621_TX_ARC_MODE (0x20 << 0)
|
||||
|
||||
#define IT6621_REG_TX_DD3 0x33
|
||||
#define IT6621_TX_FORCE_ARC_MODE_SEL BIT(0) /* force TX ARC mode */
|
||||
#define IT6621_TX_FORCE_ARC_MODE_DIS (0x00 << 0)
|
||||
#define IT6621_TX_FORCE_ARC_MODE_EN (0x01 << 0)
|
||||
|
||||
/* eARC TX CMDC Registers */
|
||||
#define IT6621_REG_CMDC0 0x40
|
||||
#define IT6621_TX_CMD_TIMEOUT_EN BIT(0) /* 1: eARC TX enable NACK/RETRY timeout (256-time) */
|
||||
#define IT6621_TX_NACK_DELAY_EN BIT(1) /* 1: eARC TX enable NACK delay */
|
||||
#define IT6621_TX_DEBUG_FIFO_EN BIT(2) /* 1: eARC TX enable debug FIFO */
|
||||
#define IT6621_TX_NEXT_PKT_TIMEOUT_SEL BIT(3) /* eARC TX next packet timeout selection */
|
||||
#define IT6621_TX_NEXT_PKT_TIMEOUT_30US (0x00 << 3) /* 30us */
|
||||
#define IT6621_TX_NEXT_PKT_TIMEOUT_50US (0x01 << 3) /* 50us */
|
||||
#define IT6621_TX_NACK_DELAY_SEL GENMASK(5, 4) /* eARC TX NACK packet delay time selection */
|
||||
#define IT6621_TX_NACK_DELAY_500US (0x00 << 4) /* 500us */
|
||||
#define IT6621_TX_NACK_DELAY_1MS (0x01 << 4) /* 1ms */
|
||||
#define IT6621_TX_NACK_DELAY_2MS (0x02 << 4) /* 2ms */
|
||||
#define IT6621_TX_NACK_DELAY_4MS (0x03 << 4) /* 4ms */
|
||||
#define IT6621_TX_TURN_OVER_SEL GENMASK(7, 6) /* eARC TX turn-over time
|
||||
* selection before
|
||||
* transmitting packet
|
||||
*/
|
||||
#define IT6621_TX_TURN_OVER_8US (0x00 << 6) /* 8us */
|
||||
#define IT6621_TX_TURN_OVER_16US (0x01 << 6) /* 16us */
|
||||
#define IT6621_TX_TURN_OVER_24US (0x02 << 6) /* 24us */
|
||||
|
||||
#define IT6621_REG_CMDC1 0x41
|
||||
#define IT6621_TX_CMDC_STATE GENMASK(3, 0) /* eARC TX CMDC state */
|
||||
#define IT6621_TX_CMDC_STATE_IDLE (0x00 << 0) /* IDLE */
|
||||
#define IT6621_TX_CMDC_STATE_CMD (0x01 << 0) /* TX Cmd */
|
||||
#define IT6621_TX_CMDC_STATE_DEVID (0x02 << 0) /* TX DevID */
|
||||
#define IT6621_TX_CMDC_STATE_OFFSET (0x03 << 0) /* TX Offset */
|
||||
#define IT6621_TX_CMDC_STATE_CONT1 (0x04 << 0) /* TX Cont1 */
|
||||
#define IT6621_TX_CMDC_STATE_CONT2 (0x05 << 0) /* TX Cont2 */
|
||||
#define IT6621_TX_CMDC_STATE_RETRY (0x06 << 0) /* TX Retry */
|
||||
#define IT6621_TX_CMDC_STATE_DATA1 (0x07 << 0) /* TX Data1 */
|
||||
#define IT6621_TX_CMDC_STATE_DATA2 (0x08 << 0) /* TX Data2 */
|
||||
#define IT6621_TX_CMDC_STATE_STOP (0x09 << 0) /* TX Stop */
|
||||
#define IT6621_TX_FAIL_STATE GENMASK(7, 4)
|
||||
#define IT6621_TX_FAIL_STATE_NO_RESP BIT(4) /* No response */
|
||||
#define IT6621_TX_FAIL_STATE_UNEXP_RESP BIT(5) /* Unexpected response */
|
||||
#define IT6621_TX_FAIL_STATE_ECC_ERR BIT(6) /* Uncorrectable ECC error */
|
||||
#define IT6621_TX_FAIL_STATE_TIMEOUT BIT(7) /* NACK/RETRY 256 times timeout */
|
||||
|
||||
#define IT6621_REG_TX_DEV_ID 0x42 /* eARC TX device ID */
|
||||
#define IT6621_REG_TX_OFFSET 0x43 /* eARC TX offset value */
|
||||
|
||||
#define IT6621_REG_CMDC2 0x44
|
||||
#define IT6621_TX_BYTE_NO GENMASK(4, 0) /* eARC TX byte number (1~32 bytes) */
|
||||
#define IT6621_TX_CMD_BUSY BIT(5) /* 1: eARC TX command busy */
|
||||
#define IT6621_TX_WRITE_TRIGGER BIT(6) /* eARC TX write trigger */
|
||||
#define IT6621_TX_READ_TRIGGER BIT(7) /* eARC TX read trigger */
|
||||
|
||||
#define IT6621_REG_TX_DATA_FIFO 0x45 /* eARC TX data FIFO of read/write
|
||||
* data (32-stage FIFO)
|
||||
*/
|
||||
|
||||
#define IT6621_REG_CMDC3 0x46
|
||||
#define IT6621_TX_DATA_FIFO_STAGE GENMASK(5, 0) /* eARC TX data FIFO stage */
|
||||
#define IT6621_TX_DATA_FIFO_EMPTY (0x00 << 0) /* FIFO empty */
|
||||
#define IT6621_TX_DATA_FIFO_FULL (0x20 << 0) /* FIFO full */
|
||||
#define IT6621_TX_DATA_FIFO_ERR BIT(6) /* eARC TX data FIFO error */
|
||||
#define IT6621_TX_DATA_FIFO_CLEAR BIT(7) /* eARC TX data FIFO clear */
|
||||
|
||||
#define IT6621_REG_CMDC4 0x47
|
||||
#define IT6621_TX_AUTO_HB_EN BIT(0) /* eARC TX auto HeartBeat, 0: disable, 1: enable */
|
||||
#define IT6621_TX_AUTO_HB_BUSY BIT(1) /* 1: eARC TX auto HeartBeat busy */
|
||||
#define IT6621_TX_HB_TIME_SEL GENMASK(3, 2) /* eARC TX auto HeartBeat time selection */
|
||||
#define IT6621_TX_HB_TIME_35MS (0x00 << 2) /* 35ms */
|
||||
#define IT6621_TX_HB_TIME_40MS (0x01 << 2) /* 40ms */
|
||||
#define IT6621_TX_HB_TIME_45MS (0x02 << 2) /* 45ms */
|
||||
#define IT6621_TX_HB_TIME_50MS (0x03 << 2) /* 50ms */
|
||||
#define IT6621_TX_HB_RETRY_SEL BIT(4) /* eARC TX auto HeartBeat retry,
|
||||
* 0: disable, 1: enable
|
||||
*/
|
||||
#define IT6621_TX_HB_RETRY_DIS (0x00 << 4)
|
||||
#define IT6621_TX_HB_RETRY_EN (0x01 << 4)
|
||||
#define IT6621_TX_HB_TRIGGER BIT(5) /* eARC TX HeartBeat trigger */
|
||||
#define IT6621_TX_HB_RETRY_TIME_SEL GENMASK(7, 6) /* eARC TX HeartBeat retry time selection */
|
||||
#define IT6621_TX_HB_RETRY_0MS (0x00 << 6) /* 0ms */
|
||||
#define IT6621_TX_HB_RETRY_4MS (0x01 << 6) /* 4ms */
|
||||
#define IT6621_TX_HB_RETRY_8MS (0x02 << 6) /* 8ms */
|
||||
#define IT6621_TX_HB_RETRY_16MS (0x03 << 6) /* 16ms */
|
||||
|
||||
#define IT6621_REG_TX_READ_STATE 0x48 /* eARC TX read back value of EARC_RX_STAT */
|
||||
#define IT6621_EARC_RX_STAT_EARC_HPD BIT(0)
|
||||
#define IT6621_EARC_RX_STAT_CAP_CHNG BIT(3)
|
||||
#define IT6621_EARC_RX_STAT_STAT_CHNG BIT(4)
|
||||
|
||||
#define IT6621_REG_CMDC5 0x49
|
||||
#define IT6621_TX_AUTO_WRITE_STATE_SEL BIT(0) /* 1: eARC TX auto write EARC_TX_STAT[7:1] */
|
||||
#define IT6621_TX_AUTO_WRITE_STATE_DIS (0x00 << 0) /* to pass SL-870 HFR5-1-35/36/37 */
|
||||
#define IT6621_TX_AUTO_WRITE_STATE_EN (0x01 << 0)
|
||||
#define IT6621_TX_WRITE_STATE GENMASK(7, 1) /* eARC TX write value of EARC_TX_STAT[7:1] */
|
||||
|
||||
#define IT6621_REG_CMDC6 0x4a
|
||||
#define IT6621_TX_CMO_OPT BIT(0) /* eARC TX common mode output enable option */
|
||||
#define IT6621_TX_CMO_NORMAL (0x00 << 0) /* normal */
|
||||
#define IT6621_TX_CMO_PRE_1BIT (0x01 << 0) /* 1-bit before normal */
|
||||
#define IT6621_TX_FORCE_CMO_OPT BIT(1) /* eARC TX common mode output enable option */
|
||||
#define IT6621_TX_FORCE_CMO_NORMAL (0x00 << 1) /* normal */
|
||||
#define IT6621_TX_FORCE_CMO_EN (0x01 << 1) /* force output enable */
|
||||
#define IT6621_TX_RESYNC_OPT BIT(2) /* eARC TX common mode resync option */
|
||||
#define IT6621_TX_RESYNC_OLD (0x00 << 2) /* old */
|
||||
#define IT6621_TX_RESYNC_NEW (0x01 << 2) /* new */
|
||||
|
||||
#define IT6621_REG_TX_DEBUG_FIFO0 0x4d /* eARC TX debug FIFO (32-stage
|
||||
* FIFO), Cmd[7:0]/Data[7:0]
|
||||
*/
|
||||
|
||||
#define IT6621_REG_TX_DEBUG_FIFO1 0x4e
|
||||
#define IT6621_TX_DEBUG_FIFO_CD BIT(0) /* C/D */
|
||||
#define IT6621_TX_DEBUG_FIFO_DATA (0x00 << 0) /* Data */
|
||||
#define IT6621_TX_DEBUG_FIFO_CMD (0x01 << 0) /* Cmd */
|
||||
#define IT6621_TX_DEBUG_FIFO_IO BIT(1) /* I/O */
|
||||
#define IT6621_TX_DEBUG_FIFO_INPUT_PKT (0x00 << 1) /* input packet */
|
||||
#define IT6621_TX_DEBUG_FIFO_OUTPUT_PKT (0x01 << 1) /* output packet */
|
||||
#define IT6621_TX_DEBUG_FIFO_ECC_ERR BIT(2) /* 1: ECC error */
|
||||
|
||||
#define IT6621_REG_TX_DEBUG_FIFO2 0x4f
|
||||
#define IT6621_TX_DEBUG_FIFO_STAGE GENMASK(5, 0) /* eARC TX debug FIFO stage */
|
||||
#define IT6621_TX_DEBUG_FIFO_EMPTY (0x00 << 0) /* FIFO empty */
|
||||
#define IT6621_TX_DEBUG_FIFO_FULL (0x20 << 0) /* FIFO full */
|
||||
#define IT6621_TX_DEBUG_FIFO_ERR BIT(6) /* eARC TX debug FIFO error */
|
||||
#define IT6621_TX_DEBUG_FIFO_CLEAR_SEL BIT(7) /* eARC TX debug FIFO clear */
|
||||
#define IT6621_TX_DEBUG_FIFO_CLEAR_DIS (0x00 << 7) /* FIFO empty */
|
||||
#define IT6621_TX_DEBUG_FIFO_CLEAR_EN (0x01 << 7)
|
||||
|
||||
/* eARC TX DMAC Control Registers */
|
||||
#define IT6621_REG_DMAC_CTRL0 0x60
|
||||
#define IT6621_TX_ECC_EN BIT(0) /* eARC TX ECC, 0: disable, 1: enable */
|
||||
#define IT6621_TX_AUTO_ECC BIT(1) /* 1: eARC TX auto ECC */
|
||||
#define IT6621_TX_ECC_OPT BIT(2) /* eARC TX ECC option */
|
||||
#define IT6621_TX_ECC_VC_SWAP (0x00 << 2) /* vc swap */
|
||||
#define IT6621_TX_ECC_U_SWAP (0x01 << 2) /* u swap */
|
||||
#define IT6621_TX_ENC_SEL BIT(3) /* eARC TX encryption, 0: disable, 1: enable */
|
||||
#define IT6621_TX_ENC_DIS (0x00 << 3) /* disable */
|
||||
#define IT6621_TX_ENC_EN (0x01 << 3) /* enable */
|
||||
#define IT6621_TX_ENC_OPT GENMASK(5, 4) /* eARC TX encryption option */
|
||||
#define IT6621_TX_ENC_OPT0 (0x00 << 4)
|
||||
#define IT6621_TX_ENC_OPT1 (0x01 << 4)
|
||||
#define IT6621_TX_ENC_OPT2 (0x02 << 4)
|
||||
#define IT6621_TX_ENC_OPT3 (0x03 << 4)
|
||||
|
||||
#define IT6621_REG_TX_ENC_SEED_LOW 0x61 /* eARC TX encryption seed */
|
||||
#define IT6621_REG_TX_ENC_SEED_HIGH 0x62 /* eARC TX encryption seed */
|
||||
|
||||
#define IT6621_REG_DMAC_CTRL1 0x63
|
||||
#define IT6621_TX_MANUAL_RESET_EN_SEL BIT(0) /* 1: enable eARC TX audio FIFO manual reset */
|
||||
#define IT6621_TX_MANUAL_RESET_DIS (0x00 << 0)
|
||||
#define IT6621_TX_MANUAL_RESET_EN (0x01 << 0)
|
||||
#define IT6621_TX_AUTO_RESET_EN BIT(1) /* 1: enable eARC TX audio FIFO auto reset */
|
||||
#define IT6621_TX_PKT1_EN_SEL BIT(2) /* 1: enable eARC TX packet 1 using U-bit */
|
||||
#define IT6621_TX_PKT1_DIS (0x00 << 2)
|
||||
#define IT6621_TX_PKT1_EN (0x01 << 2)
|
||||
#define IT6621_TX_PKT2_EN_SEL BIT(3) /* 1: enable eARC TX packet 2 using U-bit */
|
||||
#define IT6621_TX_PKT2_DIS (0x00 << 3)
|
||||
#define IT6621_TX_PKT2_EN (0x01 << 3)
|
||||
#define IT6621_TX_PKT3_EN_SEL BIT(4) /* 1: enable eARC TX packet 3 using U-bit */
|
||||
#define IT6621_TX_PKT3_DIS (0x00 << 4)
|
||||
#define IT6621_TX_PKT3_EN (0x01 << 4)
|
||||
#define IT6621_TX_C_CH_OPT BIT(5) /* 1: eARC TX U-bit C-Ch option */
|
||||
#define IT6621_TX_C_CH_OPT1 (0x00 << 5) /* use RegTxChSt[14:8] for
|
||||
* C-Ch[14:8] and
|
||||
* RegTxPktCH[7:0] is for
|
||||
* CH[7:0] which should be
|
||||
* set 0x00
|
||||
*/
|
||||
#define IT6621_TX_C_CH_OPT2 (0x01 << 5) /* use RegTxPktCH[6:0] for
|
||||
* C-Ch[14:8] and CH[7:0]
|
||||
* is set 0x00
|
||||
*/
|
||||
#define IT6621_TX_U_BIT_OPT BIT(6) /* U-bit option */
|
||||
#define IT6621_TX_U_BIT_1BIT_FRAME (0x00 << 6) /* 1-bit/frame */
|
||||
#define IT6621_TX_U_BIT_1BIT_SUB_FRAME (0x01 << 6) /* 1-bit/sub-frame */
|
||||
#define IT6621_TX_V_BIT_VAL BIT(7) /* V-bit value */
|
||||
#define IT6621_TX_V_BIT_LPCM (0x00 << 7) /* LPCM */
|
||||
#define IT6621_TX_V_BIT_NLPCM (0x01 << 7) /* NLPCM */
|
||||
|
||||
/* Input Audio Control Registers */
|
||||
#define IT6621_REG_TX_AUD_SRC_EN 0x80 /* Enable input audio source */
|
||||
#define IT6621_AUD_SRC0_EN BIT(0) /* for audio source 0 */
|
||||
#define IT6621_AUD_SRC1_EN BIT(1) /* for audio source 1 */
|
||||
#define IT6621_AUD_SRC2_EN BIT(2) /* for audio source 2 */
|
||||
#define IT6621_AUD_SRC3_EN BIT(3) /* for audio source 3 */
|
||||
#define IT6621_AUD_SRC4_EN BIT(4) /* for audio source 4 */
|
||||
#define IT6621_AUD_SRC5_EN BIT(5) /* for audio source 5 */
|
||||
#define IT6621_AUD_SRC6_EN BIT(6) /* for audio source 6 */
|
||||
#define IT6621_AUD_SRC7_EN BIT(7) /* for audio source 7 */
|
||||
#define IT6621_AUD_SRC7_SRC0_EN (IT6621_AUD_SRC7_EN | \
|
||||
IT6621_AUD_SRC6_EN | \
|
||||
IT6621_AUD_SRC5_EN | \
|
||||
IT6621_AUD_SRC4_EN | \
|
||||
IT6621_AUD_SRC3_EN | \
|
||||
IT6621_AUD_SRC2_EN | \
|
||||
IT6621_AUD_SRC1_EN | \
|
||||
IT6621_AUD_SRC0_EN)
|
||||
#define IT6621_AUD_SRC6_SRC0_EN (IT6621_AUD_SRC6_EN | \
|
||||
IT6621_AUD_SRC5_EN | \
|
||||
IT6621_AUD_SRC4_EN | \
|
||||
IT6621_AUD_SRC3_EN | \
|
||||
IT6621_AUD_SRC2_EN | \
|
||||
IT6621_AUD_SRC1_EN | \
|
||||
IT6621_AUD_SRC0_EN)
|
||||
#define IT6621_AUD_SRC5_SRC0_EN (IT6621_AUD_SRC5_EN | \
|
||||
IT6621_AUD_SRC4_EN | \
|
||||
IT6621_AUD_SRC3_EN | \
|
||||
IT6621_AUD_SRC2_EN | \
|
||||
IT6621_AUD_SRC1_EN | \
|
||||
IT6621_AUD_SRC0_EN)
|
||||
#define IT6621_AUD_SRC4_SRC0_EN (IT6621_AUD_SRC4_EN | \
|
||||
IT6621_AUD_SRC3_EN | \
|
||||
IT6621_AUD_SRC2_EN | \
|
||||
IT6621_AUD_SRC1_EN | \
|
||||
IT6621_AUD_SRC0_EN)
|
||||
#define IT6621_AUD_SRC3_SRC0_EN (IT6621_AUD_SRC3_EN | \
|
||||
IT6621_AUD_SRC2_EN | \
|
||||
IT6621_AUD_SRC1_EN | \
|
||||
IT6621_AUD_SRC0_EN)
|
||||
#define IT6621_AUD_SRC2_SRC0_EN (IT6621_AUD_SRC2_EN | \
|
||||
IT6621_AUD_SRC1_EN | \
|
||||
IT6621_AUD_SRC0_EN)
|
||||
#define IT6621_AUD_SRC1_SRC0_EN (IT6621_AUD_SRC1_EN | \
|
||||
IT6621_AUD_SRC0_EN)
|
||||
|
||||
#define IT6621_REG_TX_AUD_SRC_SEL 0x81 /* Input audio source selection */
|
||||
#define IT6621_TX_AUD_SRC GENMASK(1, 0) /* eARC TX encryption option */
|
||||
#define IT6621_AUD_SRC_I2S (0x00 << 0) /* I2S */
|
||||
#define IT6621_AUD_SRC_SPDIF (0x01 << 0) /* SPDIF */
|
||||
#define IT6621_AUD_SRC_TDM (0x02 << 0) /* TDM */
|
||||
#define IT6621_AUD_SRC_DSD (0x03 << 0) /* DSD */
|
||||
|
||||
#define IT6621_REG_TX_I2S 0x82
|
||||
#define IT6621_I2S_FMT GENMASK(4, 0) /* TX I2S/TDM format */
|
||||
#define IT6621_I2S_FMT_STANDARD (0x00 << 0) /* Standard I2S */
|
||||
#define IT6621_I2S_FMT_32BIT (0x01 << 0) /* 32-bit I2S */
|
||||
#define IT6621_I2S_FMT_LEFT_JUSTIFIED (0x00 << 1) /* Left-justified */
|
||||
#define IT6621_I2S_FMT_RIGHT_JUSTIFIED (0x01 << 1) /* Right-justified */
|
||||
#define IT6621_I2S_FMT_DATA_DELAY (0x00 << 2) /* Data delay 1T correspond to WS */
|
||||
#define IT6621_I2S_FMT_NO_DATA_DELAY (0x01 << 2) /* No data delay correspond to WS */
|
||||
#define IT6621_I2S_FMT_WS_0_LEFT_CH (0x00 << 3) /* WS=0 is left channel */
|
||||
#define IT6621_I2S_FMT_WS_0_RIGHT_CH (0x01 << 3) /* WS=0 is right channel */
|
||||
#define IT6621_I2S_FMT_MSB_FIRST (0x00 << 4) /* MSB shift first */
|
||||
#define IT6621_I2S_FMT_LSB_FIRST (0x01 << 4) /* LSB shift first */
|
||||
#define IT6621_I2S_TDM_WORD_LEN GENMASK(6, 5) /* TX I2S/TDM word length */
|
||||
#define IT6621_I2S_TDM_16BIT (0x00 << 5) /* 16 bits */
|
||||
#define IT6621_I2S_TDM_18BIT (0x01 << 5) /* 18 bits */
|
||||
#define IT6621_I2S_TDM_20BIT (0x02 << 5) /* 20 bits */
|
||||
#define IT6621_I2S_TDM_24BIT (0x03 << 5) /* 24 bits */
|
||||
|
||||
#define IT6621_REG_TX_AUD_CTRL3 0x83
|
||||
#define IT6621_TX_TDM_CH_NUM GENMASK(2, 0) /* TX TDM interface channel number */
|
||||
#define IT6621_TX_TDM_2CH (0x00 << 0) /* 2-ch */
|
||||
#define IT6621_TX_TDM_4CH (0x01 << 0) /* 4-ch */
|
||||
#define IT6621_TX_TDM_8CH (0x03 << 0) /* 8-ch */
|
||||
#define IT6621_TX_TDM_16CH (0x07 << 0) /* 16-ch */
|
||||
#define IT6621_TX_I2S_HBR_EN_SEL BIT(3) /* enable TX I2S HBR input */
|
||||
#define IT6621_TX_I2S_HBR_DIS (0x00 << 3)
|
||||
#define IT6621_TX_I2S_HBR_EN (0x01 << 3)
|
||||
#define IT6621_TX_DSD_MODE BIT(4) /* TX DSD mode */
|
||||
#define IT6621_TX_DSD_MODE_NORMAL (0x00 << 4) /* normal mode */
|
||||
#define IT6621_TX_DSD_MODE_PHASE (0x01 << 4) /* phase mode */
|
||||
#define IT6621_TX_DSD_BIT_INV_SEL BIT(5) /* TX DSD data inversion */
|
||||
#define IT6621_TX_DSD_BIT_NO_INV (0x00 << 5) /* not inverse */
|
||||
#define IT6621_TX_DSD_BIT_INV (0x01 << 5) /* inverse */
|
||||
#define IT6621_TX_DSD_LM_SWAP_SEL BIT(6) /* TX DSD LSB/MSB swap */
|
||||
#define IT6621_TX_DSD_LM_NO_SWAP (0x00 << 6) /* no swap */
|
||||
#define IT6621_TX_DSD_LM_SWAP (0x01 << 6) /* swap */
|
||||
#define IT6621_TX_DSD_LR_SWAP_SEL BIT(7) /* TX DSD L/R swap */
|
||||
#define IT6621_TX_DSD_LR_NO_SWAP (0x00 << 7) /* no swap */
|
||||
#define IT6621_TX_DSD_LR_SWAP (0x01 << 7) /* swap */
|
||||
|
||||
#define IT6621_REG_TX_AUD_SEL1 0x84
|
||||
#define IT6621_TX_AUD0_SEL GENMASK(2, 0) /* TX audio 0 input selection */
|
||||
#define IT6621_TX_AUD0_FROM_SRC0 (0x00 << 0) /* from audio source 0 */
|
||||
#define IT6621_TX_AUD0_FROM_SRC1 (0x01 << 0) /* from audio source 1 */
|
||||
#define IT6621_TX_AUD0_FROM_SRC2 (0x02 << 0) /* from audio source 2 */
|
||||
#define IT6621_TX_AUD0_FROM_SRC3 (0x03 << 0) /* from audio source 3 */
|
||||
#define IT6621_TX_AUD0_FROM_SRC4 (0x04 << 0) /* from audio source 4 */
|
||||
#define IT6621_TX_AUD0_FROM_SRC5 (0x05 << 0) /* from audio source 5 */
|
||||
#define IT6621_TX_AUD0_FROM_SRC6 (0x06 << 0) /* from audio source 6 */
|
||||
#define IT6621_TX_AUD0_FROM_SRC7 (0x07 << 0) /* from audio source 7 */
|
||||
#define IT6621_TX_AUD1_SEL GENMASK(6, 4) /* TX audio 1 input selection */
|
||||
#define IT6621_TX_AUD1_FROM_SRC0 (0x00 << 4) /* from audio source 0 */
|
||||
#define IT6621_TX_AUD1_FROM_SRC1 (0x01 << 4) /* from audio source 1 */
|
||||
#define IT6621_TX_AUD1_FROM_SRC2 (0x02 << 4) /* from audio source 2 */
|
||||
#define IT6621_TX_AUD1_FROM_SRC3 (0x03 << 4) /* from audio source 3 */
|
||||
#define IT6621_TX_AUD1_FROM_SRC4 (0x04 << 4) /* from audio source 4 */
|
||||
#define IT6621_TX_AUD1_FROM_SRC5 (0x05 << 4) /* from audio source 5 */
|
||||
#define IT6621_TX_AUD1_FROM_SRC6 (0x06 << 4) /* from audio source 6 */
|
||||
#define IT6621_TX_AUD1_FROM_SRC7 (0x07 << 4) /* from audio source 7 */
|
||||
|
||||
#define IT6621_REG_TX_AUD_SEL2 0x85
|
||||
#define IT6621_TX_AUD2_SEL GENMASK(2, 0) /* TX audio 2 input selection */
|
||||
#define IT6621_TX_AUD2_FROM_SRC0 (0x00 << 0) /* from audio source 0 */
|
||||
#define IT6621_TX_AUD2_FROM_SRC1 (0x01 << 0) /* from audio source 1 */
|
||||
#define IT6621_TX_AUD2_FROM_SRC2 (0x02 << 0) /* from audio source 2 */
|
||||
#define IT6621_TX_AUD2_FROM_SRC3 (0x03 << 0) /* from audio source 3 */
|
||||
#define IT6621_TX_AUD2_FROM_SRC4 (0x04 << 0) /* from audio source 4 */
|
||||
#define IT6621_TX_AUD2_FROM_SRC5 (0x05 << 0) /* from audio source 5 */
|
||||
#define IT6621_TX_AUD2_FROM_SRC6 (0x06 << 0) /* from audio source 6 */
|
||||
#define IT6621_TX_AUD2_FROM_SRC7 (0x07 << 0) /* from audio source 7 */
|
||||
#define IT6621_TX_AUD3_SEL GENMASK(6, 4) /* TX audio 3 input selection */
|
||||
#define IT6621_TX_AUD3_FROM_SRC0 (0x00 << 4) /* from audio source 0 */
|
||||
#define IT6621_TX_AUD3_FROM_SRC1 (0x01 << 4) /* from audio source 1 */
|
||||
#define IT6621_TX_AUD3_FROM_SRC2 (0x02 << 4) /* from audio source 2 */
|
||||
#define IT6621_TX_AUD3_FROM_SRC3 (0x03 << 4) /* from audio source 3 */
|
||||
#define IT6621_TX_AUD3_FROM_SRC4 (0x04 << 4) /* from audio source 4 */
|
||||
#define IT6621_TX_AUD3_FROM_SRC5 (0x05 << 4) /* from audio source 5 */
|
||||
#define IT6621_TX_AUD3_FROM_SRC6 (0x06 << 4) /* from audio source 6 */
|
||||
#define IT6621_TX_AUD3_FROM_SRC7 (0x07 << 4) /* from audio source 7 */
|
||||
|
||||
#define IT6621_REG_TX_AUD_SEL3 0x86
|
||||
#define IT6621_TX_AUD4_SEL GENMASK(2, 0) /* TX audio 4 input selection */
|
||||
#define IT6621_TX_AUD4_FROM_SRC0 (0x00 << 0) /* from audio source 0 */
|
||||
#define IT6621_TX_AUD4_FROM_SRC1 (0x01 << 0) /* from audio source 1 */
|
||||
#define IT6621_TX_AUD4_FROM_SRC2 (0x02 << 0) /* from audio source 2 */
|
||||
#define IT6621_TX_AUD4_FROM_SRC3 (0x03 << 0) /* from audio source 3 */
|
||||
#define IT6621_TX_AUD4_FROM_SRC4 (0x04 << 0) /* from audio source 4 */
|
||||
#define IT6621_TX_AUD4_FROM_SRC5 (0x05 << 0) /* from audio source 5 */
|
||||
#define IT6621_TX_AUD4_FROM_SRC6 (0x06 << 0) /* from audio source 6 */
|
||||
#define IT6621_TX_AUD4_FROM_SRC7 (0x07 << 0) /* from audio source 7 */
|
||||
#define IT6621_TX_AUD5_SEL GENMASK(6, 4) /* TX audio 5 input selection */
|
||||
#define IT6621_TX_AUD5_FROM_SRC0 (0x00 << 4) /* from audio source 0 */
|
||||
#define IT6621_TX_AUD5_FROM_SRC1 (0x01 << 4) /* from audio source 1 */
|
||||
#define IT6621_TX_AUD5_FROM_SRC2 (0x02 << 4) /* from audio source 2 */
|
||||
#define IT6621_TX_AUD5_FROM_SRC3 (0x03 << 4) /* from audio source 3 */
|
||||
#define IT6621_TX_AUD5_FROM_SRC4 (0x04 << 4) /* from audio source 4 */
|
||||
#define IT6621_TX_AUD5_FROM_SRC5 (0x05 << 4) /* from audio source 5 */
|
||||
#define IT6621_TX_AUD5_FROM_SRC6 (0x06 << 4) /* from audio source 6 */
|
||||
#define IT6621_TX_AUD5_FROM_SRC7 (0x07 << 4) /* from audio source 7 */
|
||||
|
||||
#define IT6621_REG_TX_AUD_SEL4 0x87
|
||||
#define IT6621_TX_AUD6_SEL GENMASK(2, 0) /* TX audio 6 input selection */
|
||||
#define IT6621_TX_AUD6_FROM_SRC0 (0x00 << 0) /* from audio source 0 */
|
||||
#define IT6621_TX_AUD6_FROM_SRC1 (0x01 << 0) /* from audio source 1 */
|
||||
#define IT6621_TX_AUD6_FROM_SRC2 (0x02 << 0) /* from audio source 2 */
|
||||
#define IT6621_TX_AUD6_FROM_SRC3 (0x03 << 0) /* from audio source 3 */
|
||||
#define IT6621_TX_AUD6_FROM_SRC4 (0x04 << 0) /* from audio source 4 */
|
||||
#define IT6621_TX_AUD6_FROM_SRC5 (0x05 << 0) /* from audio source 5 */
|
||||
#define IT6621_TX_AUD6_FROM_SRC6 (0x06 << 0) /* from audio source 6 */
|
||||
#define IT6621_TX_AUD6_FROM_SRC7 (0x07 << 0) /* from audio source 7 */
|
||||
#define IT6621_TX_AUD7_SEL GENMASK(6, 4) /* TX audio 7 input selection */
|
||||
#define IT6621_TX_AUD7_FROM_SRC0 (0x00 << 4) /* from audio source 0 */
|
||||
#define IT6621_TX_AUD7_FROM_SRC1 (0x01 << 4) /* from audio source 1 */
|
||||
#define IT6621_TX_AUD7_FROM_SRC2 (0x02 << 4) /* from audio source 2 */
|
||||
#define IT6621_TX_AUD7_FROM_SRC3 (0x03 << 4) /* from audio source 3 */
|
||||
#define IT6621_TX_AUD7_FROM_SRC4 (0x04 << 4) /* from audio source 4 */
|
||||
#define IT6621_TX_AUD7_FROM_SRC5 (0x05 << 4) /* from audio source 5 */
|
||||
#define IT6621_TX_AUD7_FROM_SRC6 (0x06 << 4) /* from audio source 6 */
|
||||
#define IT6621_TX_AUD7_FROM_SRC7 (0x07 << 4) /* from audio source 7 */
|
||||
|
||||
#define IT6621_REG_TX_AUD_FORCE_OUTPUT 0x88 /* 1: force output data to 24-bit '0' */
|
||||
|
||||
#define IT6621_REG_TX_AUD_CTRL9 0x89
|
||||
#define IT6621_TX_SPDIF_REC_EN BIT(0) /* 1: enable SPDIF input record channel status */
|
||||
#define IT6621_TX_SPDIF_ERR_DET_EN BIT(1) /* 1: enable SPDIF input channel
|
||||
* status error detection
|
||||
*/
|
||||
#define IT6621_TX_MCLK_FREQ GENMASK(3, 2) /* Input MCLK frequency selection */
|
||||
#define IT6621_TX_MCLK_FREQ_128FS (0x00 << 2) /* 128FS */
|
||||
#define IT6621_TX_MCLK_FREQ_256FS (0x01 << 2) /* 256FS */
|
||||
#define IT6621_TX_MCLK_FREQ_512FS (0x02 << 2) /* 512FS */
|
||||
#define IT6621_TX_MCLK_FREQ_1024FS (0x03 << 2) /* 1024FS */
|
||||
#define IT6621_TX_MUTE_TO_OFF_EN BIT(4) /* 1: enable TXMUTE to audio off */
|
||||
#define IT6621_TX_FIFO_ERR_TO_MUTE_EN BIT(5) /* 1: enable FIFO error to audio mute */
|
||||
#define IT6621_TX_NO_CLK_TO_MUTE_EN BIT(6) /* 1: enable no TBCLK to audio mute */
|
||||
#define IT6621_TX_UNSTB_CLK_TO_MUTE_EN BIT(7) /* 1: enable TBCLK unstable to audio mute */
|
||||
|
||||
#define IT6621_REG_TX_AUD_CTRL10 0x8a
|
||||
#define IT6621_TX_EXT_MUTE_SEL BIT(0) /* external MUTE input
|
||||
* RegEnTxMute=RegF0[1] at FPGA
|
||||
* register (SlvAddr=0x88)
|
||||
*/
|
||||
#define IT6621_TX_EXT_MUTE_EN (0x00 << 0) /* enable */
|
||||
#define IT6621_TX_EXT_MUTE_DIS (0x01 << 0) /* disable */
|
||||
#define IT6621_TX_AUTO_CH_STAT_MUTE_SEL BIT(1) /* eARC TX channel status MUTE auto mode */
|
||||
#define IT6621_TX_AUTO_CH_STAT_MUTE_DIS (0x00 << 1) /* disable */
|
||||
#define IT6621_TX_AUTO_CH_STAT_MUTE_EN (0x01 << 1) /* enable */
|
||||
#define IT6621_TX_AUTO_AUD_FMT_SEL BIT(2) /* eARC TX channel status audio format auto mode */
|
||||
#define IT6621_TX_AUTO_AUD_FMT_DIS (0x00 << 2) /* disable */
|
||||
#define IT6621_TX_AUTO_AUD_FMT_EN (0x01 << 2) /* enable */
|
||||
#define IT6621_TX_AUTO_LAYOUT_SEL BIT(3) /* eARC TX channel status layout auto mode */
|
||||
#define IT6621_TX_AUTO_LAYOUT_DIS (0x00 << 3) /* disable */
|
||||
#define IT6621_TX_AUTO_LAYOUT_EN (0x01 << 3) /* enable */
|
||||
#define IT6621_TX_MCH_LPCM_SEL BIT(4) /* eARC TX force multi-channel LPCM */
|
||||
#define IT6621_TX_MCH_LPCM_DIS (0x00 << 4) /* disable */
|
||||
#define IT6621_TX_MCH_LPCM_EN (0x01 << 4) /* enable */
|
||||
#define IT6621_TX_NLPCM_I2S_SEL BIT(5) /* eARC TX force NLPCM from I2S interface */
|
||||
#define IT6621_TX_NLPCM_I2S_DIS (0x00 << 5) /* disable */
|
||||
#define IT6621_TX_NLPCM_I2S_EN (0x01 << 5) /* enable */
|
||||
#define IT6621_TX_2CH_LAYOUT_SEL BIT(6) /* eARC TX force 2-channel layout */
|
||||
#define IT6621_TX_2CH_LAYOUT_DIS (0x00 << 6) /* disable */
|
||||
#define IT6621_TX_2CH_LAYOUT_EN (0x01 << 6) /* enable */
|
||||
#define IT6621_TX_FORCE_MUTE_SEL BIT(7) /* force TXMUTE */
|
||||
#define IT6621_TX_FORCE_MUTE_DIS (0x00 << 7) /* disable */
|
||||
#define IT6621_TX_FORCE_MUTE_EN (0x01 << 7) /* enable */
|
||||
|
||||
/* eARC TX AFE Registers */
|
||||
#define IT6621_REG_TX_AFE0 0xa0
|
||||
#define IT6621_TX_XP_RESET_SEL BIT(0) /* Reset PLL, low active */
|
||||
#define IT6621_TX_XP_RESET_ACTIVE (0x00 << 0) /* active */
|
||||
#define IT6621_TX_XP_RESET_INACTIVE (0x01 << 0) /* inactive */
|
||||
#define IT6621_TX_XP_PWD BIT(1) /* Power down PLL, low active */
|
||||
#define IT6621_TX_XP_IPWD BIT(2) /* Power down the bias for PLL and LC, low active */
|
||||
|
||||
#define IT6621_REG_TX_AFE1 0xa1
|
||||
#define IT6621_TX_XP_PDIV GENMASK(1, 0) /* Set PDIV[1:0] by
|
||||
* TBCLKSEL[2:0] and the
|
||||
* frequency of AICLK.
|
||||
* When TBCLKSEL=101, set 00
|
||||
* When TBCLKSEL=100
|
||||
* 2.048MHz~3.072MHz: set 00
|
||||
* 4.096MHz~6.144MHz: set 01
|
||||
* When TBCLKSEL=011
|
||||
* 2.048MHz~3.072MHz: set 00
|
||||
* 4.096MHz~6.144MHz: set 01
|
||||
* 8.192MHz~12.288MHz: set 10 or 11
|
||||
* When TBCLKSEL=010
|
||||
* 4.096MHz~6.144MHz: set 00
|
||||
* 8.192MHz~12.288MHz: set 01
|
||||
* 16.384MHz~24.576MHz: set 10 or 11
|
||||
* When TBCLKSEL=001
|
||||
* 2.048MHz~12.288MHz: set 00
|
||||
* 16.384MHz~24.576MHz: set 01
|
||||
* 32.768MHz~49.152MHz: set 10 or 11
|
||||
* When TBCLKSEL=000
|
||||
* 4.096MHz~24.576MHz: set 00
|
||||
* 32.768MHz~49.152MHz: set 01
|
||||
* 65.536MHz~98.304MHz: set 10 or 11
|
||||
*/
|
||||
#define IT6621_TX_XP_GAIN BIT(2) /* Set GAIN by TBCLKSEL[2:0] and
|
||||
* the frequency of AICLK
|
||||
* When TBCLK=000, 4.096MHz~6.144MHz: set 0
|
||||
* When TBCLK=001, 2.048MHz~3.072MHz: set 0
|
||||
* When others set1
|
||||
*/
|
||||
#define IT6621_TX_XP_DEI_SEL BIT(3)
|
||||
#define IT6621_TX_XP_DEI_DIS (0x00 << 3)
|
||||
#define IT6621_TX_XP_DEI_EN (0x01 << 3)
|
||||
#define IT6621_TX_XP_ER0_SEL BIT(4)
|
||||
#define IT6621_TX_XP_ER0_DIS (0x00 << 4)
|
||||
#define IT6621_TX_XP_ER0_EN (0x01 << 4)
|
||||
#define IT6621_TX_AUTO_XP_GAIN_SEL BIT(6) /* 1: XP_GAIN auto mode */
|
||||
#define IT6621_TX_AUTO_XP_GAIN_DIS (0x00 << 6)
|
||||
#define IT6621_TX_AUTO_XP_GAIN_EN (0x01 << 6)
|
||||
#define IT6621_TX_AUTO_XP_PDIV_SEL BIT(7) /* 1: XP_PDIV[1:0] auto mode */
|
||||
#define IT6621_TX_AUTO_XP_PDIV_DIS (0x00 << 7)
|
||||
#define IT6621_TX_AUTO_XP_PDIV_EN (0x01 << 7)
|
||||
|
||||
#define IT6621_REG_TX_AFE2 0xa2
|
||||
#define IT6621_TX_DRV_DPWD BIT(0) /* Power down the differential
|
||||
* mode driver, high active.
|
||||
* NOTE: Set 1 in ARC mode.
|
||||
*/
|
||||
#define IT6621_TX_DRV_RESET_SEL BIT(1) /* Reset the differential mode
|
||||
* driver, high active.
|
||||
* NOTE: Set 1 in ARC mode.
|
||||
*/
|
||||
#define IT6621_TX_DRV_RESET_DIS (0x00 << 1)
|
||||
#define IT6621_TX_DRV_RESET_EN (0x01 << 1)
|
||||
#define IT6621_TX_DRV_DC GENMASK(3, 2)
|
||||
#define IT6621_TX_DRV_DC_DIS (0x00 << 2)
|
||||
#define IT6621_TX_DRV_DC_EN (0x01 << 2)
|
||||
#define IT6621_TX_DRV_DC_SEL_DIS (0x00 << 3)
|
||||
#define IT6621_TX_DRV_DC_SEL_EN (0x01 << 3)
|
||||
#define IT6621_TX_DRV_DSW_SEL GENMASK(6, 4)
|
||||
#define IT6621_TX_DRV_DSW_4 (0x04 << 4)
|
||||
#define IT6621_TX_DRV_DSW_7 (0x07 << 4)
|
||||
#define IT6621_TX_DRV_OT_SEL BIT(7)
|
||||
#define IT6621_TX_DRV_OT_DIS (0x00 << 7)
|
||||
#define IT6621_TX_DRV_OT_EN (0x01 << 7)
|
||||
|
||||
#define IT6621_REG_TX_AFE3 0xa3
|
||||
#define IT6621_TX_DRV_CPWD BIT(0) /* Power down the common mode driver, high active */
|
||||
#define IT6621_TX_DRV_CSR_SEL GENMASK(3, 1) /* 0: fastest, 7: slowest */
|
||||
#define IT6621_TX_DRV_CSR_2 (0x02 << 1)
|
||||
#define IT6621_TX_DRV_CSR_4 (0x04 << 1)
|
||||
#define IT6621_TX_DRV_CSW_SEL GENMASK(6, 4) /* 0: minimum, 7: maximum */
|
||||
#define IT6621_TX_DRV_CSW_4 (0x04 << 4)
|
||||
#define IT6621_TX_DRV_CSW_7 (0x07 << 4)
|
||||
#define IT6621_TX_IN_ARC_MODE_SEL BIT(7) /* In ARC mode */
|
||||
#define IT6621_TX_IN_ARC_SIGNAL_MODE (0x00 << 7) /* signal mode */
|
||||
#define IT6621_TX_IN_ARC_COMMON_MODE (0x01 << 7) /* common mode */
|
||||
|
||||
#define IT6621_REG_TX_AFE4 0xa4
|
||||
#define IT6621_TX_RC_PWD BIT(0) /* Power down common receiver,
|
||||
* high active.
|
||||
* NOTE: Set 1 in ARC mode.
|
||||
*/
|
||||
#define IT6621_TX_RC_CK_SEL BIT(1)
|
||||
#define IT6621_TX_RC_CK_DIS (0x00 << 1)
|
||||
#define IT6621_TX_RC_CK_EN (0x01 << 1)
|
||||
#define IT6621_TX_VCM_SEL GENMASK(3, 2)
|
||||
#define IT6621_TX_VCM0 (0x00 << 2)
|
||||
#define IT6621_TX_VCM1 (0x01 << 2)
|
||||
#define IT6621_TX_VCM2 (0x02 << 2)
|
||||
#define IT6621_TX_VCM3 (0x03 << 2)
|
||||
#define IT6621_TX_HYS_SEL GENMASK(6, 4)
|
||||
#define IT6621_TX_HYS5 (0x05 << 4)
|
||||
#define IT6621_TX_HYS6 (0x06 << 4)
|
||||
|
||||
#define IT6621_REG_TX_AFE5 0xa5
|
||||
#define IT6621_TX_LC_PWD BIT(4) /* PWD=0, LCVCO is at power down */
|
||||
#define IT6621_TX_LC_ICTP_PWD BIT(5) /* ICTP_PWD=0, ICTP block is at power down */
|
||||
#define IT6621_TX_LC_RESET BIT(6) /* RESET=0, LCVCO is at reset */
|
||||
|
||||
#define IT6621_REG_TX_AFE15 0xaf
|
||||
#define IT6621_TX_AUTO_DPWD_SEL BIT(0) /* 1: enable auto power down
|
||||
* differential mode TX AFE
|
||||
*/
|
||||
#define IT6621_TX_AUTO_DPWD_DIS (0x00 << 0)
|
||||
#define IT6621_TX_AUTO_DPWD_EN (0x01 << 0)
|
||||
#define IT6621_TX_AUTO_DRST_SEL BIT(1) /* 1: enable auto reset differential mode TX AFE */
|
||||
#define IT6621_TX_AUTO_DRST_DIS (0x00 << 1)
|
||||
#define IT6621_TX_AUTO_DRST_EN (0x01 << 1)
|
||||
#define IT6621_TX_AUTO_CPWD_SEL BIT(2) /* 1: enable auto power down common mode TX AFE */
|
||||
#define IT6621_TX_AUTO_CPWD_DIS (0x00 << 2)
|
||||
#define IT6621_TX_AUTO_CPWD_EN (0x01 << 2)
|
||||
|
||||
/* eARC Clock Detection Registers */
|
||||
#define IT6621_REG_CLK_DET0 0xc0
|
||||
#define IT6621_ACLK_BND_NUM_LOW GENMASK(7, 0) /* ACLK frequency boundary
|
||||
* for XP_PDIV auto setting.
|
||||
* 128T@3.584MHz count by 10MHz RCLK.
|
||||
*/
|
||||
|
||||
#define IT6621_REG_CLK_DET1 0xc1
|
||||
#define IT6621_ACLK_BND_NUM_HIGH BIT(0)
|
||||
|
||||
#define IT6621_REG_CLK_DET2 0xc2
|
||||
#define IT6621_ACLK_VALID_NUM_LOW GENMASK(7, 0) /* ACLK frequency valid for
|
||||
* XP_PDIV auto setting.
|
||||
* 128T@2MHz count by 10MHz RCLK.
|
||||
*/
|
||||
|
||||
#define IT6621_REG_CLK_DET3 0xc3
|
||||
#define IT6621_ACLK_VALID_NUM_HIGH GENMASK(1, 0)
|
||||
|
||||
#define IT6621_REG_CLK_DET4 0xc4
|
||||
#define IT6621_BCLK_BND_NUM GENMASK(7, 0) /* BCLK frequency boundary
|
||||
* for FSEL auto setting.
|
||||
* 128T@6.25MHz count by 10MHz RCLK.
|
||||
*/
|
||||
|
||||
#define IT6621_REG_CLK_DET5 0xc5
|
||||
#define IT6621_BCLK_VALID_NUM_LOW GENMASK(7, 0) /* BCLK frequency valid for
|
||||
* FSEL auto setting.
|
||||
* 128T@4MHz count by 10MHz RCLK.
|
||||
*/
|
||||
|
||||
#define IT6621_REG_CLK_DET6 0xc6
|
||||
#define IT6621_BCLK_VALID_NUM_HIGH BIT(0)
|
||||
|
||||
#define IT6621_REG_CLK_DET7 0xc7
|
||||
#define IT6621_ACLK_DET_EN_SEL BIT(0) /* enable ACLK clock detection */
|
||||
#define IT6621_ACLK_DET_DIS (0x00 << 0)
|
||||
#define IT6621_ACLK_DET_EN (0x01 << 0)
|
||||
#define IT6621_BCLK_DET_EN_SEL BIT(1) /* 1: enable BCLK clock detection */
|
||||
#define IT6621_UPDATE_AVG_EN_SEL BIT(4) /* enable update average clock detection value */
|
||||
#define IT6621_UPDATE_AVG_DIS (0x00 << 4)
|
||||
#define IT6621_UPDATE_AVG_EN (0x01 << 4)
|
||||
#define IT6621_CLK_DIFF_MIN_EN BIT(5)
|
||||
#define IT6621_CLK_ORG_DELTA_EN (0x00 << 5) /* 0: Original delta */
|
||||
#define IT6621_CLK_FIX_MIN_DELTA_EN (0x01 << 5) /* 1: Fix minimum delta */
|
||||
#define IT6621_RCLK_DELTA_SEL GENMASK(7, 6) /* RCLK deviation selection */
|
||||
#define IT6621_RCLK_DELTA1 (0x00 << 6) /* +/-1% */
|
||||
#define IT6621_RCLK_DELTA2 (0x01 << 6) /* +/-2% */
|
||||
#define IT6621_RCLK_DELTA3 (0x02 << 6) /* +/-3% */
|
||||
#define IT6621_RCLK_DELTA5 (0x03 << 6) /* +/-5% */
|
||||
|
||||
#define IT6621_REG_CLK_DET8 0xc8
|
||||
#define IT6621_DET_ACLK_AVG_LOW GENMASK(7, 0) /* ACLK frequency detection */
|
||||
|
||||
#define IT6621_REG_CLK_DET9 0xc9
|
||||
#define IT6621_DET_ACLK_AVG_HIGH GENMASK(3, 0)
|
||||
#define IT6621_DET_ACLK_PRE_DIV_2 BIT(4) /* 1: ACLK is pre-divided by 2 */
|
||||
#define IT6621_DET_ACLK_PRE_DIV_4 BIT(5) /* 1: ACLK is pre-divided by 4 */
|
||||
#define IT6621_DET_ACLK_FREQ_VALID BIT(6) /* 1: ACLK frequency is valid */
|
||||
#define IT6621_DET_ACLK_FREQ_STB BIT(7) /* 1: ACLK frequency detection */
|
||||
|
||||
#define IT6621_REG_CLK_DET10 0xca
|
||||
#define IT6621_DET_BCLK_AVG_LOW GENMASK(7, 0) /* BCLK frequency detection */
|
||||
|
||||
#define IT6621_REG_CLK_DET11 0xcb
|
||||
#define IT6621_DET_BCLK_AVG_HIGH GENMASK(2, 0)
|
||||
#define IT6621_DET_BCLK_PRE_DIV_2 BIT(4) /* 1: BCLK is pre-divided by 2 */
|
||||
#define IT6621_DET_BCLK_PRE_DIV_4 BIT(5) /* 1: BCLK is pre-divided by 4 */
|
||||
#define IT6621_DET_BCLK_FREQ_VALID BIT(6) /* 1: BCLK frequency is valid */
|
||||
#define IT6621_DET_BCLK_FREQ_STB BIT(7) /* 1: BCLK frequency detection */
|
||||
|
||||
/* GPIO Control Registers */
|
||||
#define IT6621_REG_GPIO_CTRL0 0xe8
|
||||
#define IT6621_I2S0_GPIO_MODE_EN BIT(0) /* 1: enable I2S0 GPIO mode */
|
||||
#define IT6621_I2S0_GPIO_OUTPUT_EN BIT(1) /* 1: enable I2S0 output enable */
|
||||
#define IT6621_I2S0_GPIO_OUTPUT_VAL BIT(2) /* I2S0 GPIO output value */
|
||||
#define IT6621_I2S0_GPIO_INPUT_VAL BIT(3) /* I2S0 GPIO input value */
|
||||
#define IT6621_I2S1_GPIO_MODE_EN BIT(4) /* 1: enable I2S1 GPIO mode */
|
||||
#define IT6621_I2S1_GPIO_OUTPUT_EN BIT(5) /* 1: enable I2S1 output enable */
|
||||
#define IT6621_I2S1_GPIO_OUTPUT_VAL BIT(6) /* I2S1 GPIO output value */
|
||||
#define IT6621_I2S1_GPIO_INPUT_VAL BIT(7) /* I2S1 GPIO input value */
|
||||
|
||||
#define IT6621_REG_GPIO_CTRL1 0xe9
|
||||
#define IT6621_I2S2_GPIO_MODE_EN BIT(0) /* 1: enable I2S2 GPIO mode */
|
||||
#define IT6621_I2S2_GPIO_OUTPUT_EN BIT(1) /* 1: enable I2S2 output enable */
|
||||
#define IT6621_I2S2_GPIO_OUTPUT_VAL BIT(2) /* I2S2 GPIO output value */
|
||||
#define IT6621_I2S2_GPIO_INPUT_VAL BIT(3) /* I2S2 GPIO input value */
|
||||
#define IT6621_I2S3_GPIO_MODE_EN BIT(4) /* 1: enable I2S3 GPIO mode */
|
||||
#define IT6621_I2S3_GPIO_OUTPUT_EN BIT(5) /* 1: enable I2S3 output enable */
|
||||
#define IT6621_I2S3_GPIO_OUTPUT_VAL BIT(6) /* I2S3 GPIO output value */
|
||||
#define IT6621_I2S3_GPIO_INPUT_VAL BIT(7) /* I2S3 GPIO input value */
|
||||
|
||||
#define IT6621_REG_GPIO_CTRL2 0xea
|
||||
#define IT6621_I2S4_GPIO_MODE_EN BIT(0) /* 1: enable I2S4 GPIO mode */
|
||||
#define IT6621_I2S4_GPIO_OUTPUT_EN BIT(1) /* 1: enable I2S4 output enable */
|
||||
#define IT6621_I2S4_GPIO_OUTPUT_VAL BIT(2) /* I2S4 GPIO output value */
|
||||
#define IT6621_I2S4_GPIO_INPUT_VAL BIT(3) /* I2S4 GPIO input value */
|
||||
#define IT6621_I2S5_GPIO_MODE_EN BIT(4) /* 1: enable I2S5 GPIO mode */
|
||||
#define IT6621_I2S5_GPIO_OUTPUT_EN BIT(5) /* 1: enable I2S5 output enable */
|
||||
#define IT6621_I2S5_GPIO_OUTPUT_VAL BIT(6) /* I2S5 GPIO output value */
|
||||
#define IT6621_I2S5_GPIO_INPUT_VAL BIT(7) /* I2S5 GPIO input value */
|
||||
|
||||
#define IT6621_REG_GPIO_CTRL3 0xeb
|
||||
#define IT6621_I2S6_GPIO_MODE_EN BIT(0) /* 1: enable I2S6 GPIO mode */
|
||||
#define IT6621_I2S6_GPIO_OUTPUT_EN BIT(1) /* 1: enable I2S6 output enable */
|
||||
#define IT6621_I2S6_GPIO_OUTPUT_VAL BIT(2) /* I2S6 GPIO output value */
|
||||
#define IT6621_I2S6_GPIO_INPUT_VAL BIT(3) /* I2S6 GPIO input value */
|
||||
#define IT6621_I2S7_GPIO_MODE_EN BIT(4) /* 1: enable I2S7 GPIO mode */
|
||||
#define IT6621_I2S7_GPIO_OUTPUT_EN BIT(5) /* 1: enable I2S7 output enable */
|
||||
#define IT6621_I2S7_GPIO_OUTPUT_VAL BIT(6) /* I2S7 GPIO output value */
|
||||
#define IT6621_I2S7_GPIO_INPUT_VAL BIT(7) /* I2S7 GPIO input value */
|
||||
|
||||
#define IT6621_REG_GPIO_CTRL4 0xec
|
||||
#define IT6621_MCLK_GPIO_MODE_EN BIT(0) /* 1: enable MCLK GPIO mode */
|
||||
#define IT6621_MCLK_GPIO_OUTPUT_EN BIT(1) /* 1: enable MCLK output enable */
|
||||
#define IT6621_MCLK_GPIO_OUTPUT_VAL BIT(2) /* MCLK GPIO output value */
|
||||
#define IT6621_MCLK_GPIO_INPUT_VAL BIT(3) /* MCLK GPIO input value */
|
||||
#define IT6621_SPDIF_GPIO_MODE_EN BIT(4) /* 1: enable SPDIF GPIO mode */
|
||||
#define IT6621_SPDIF_GPIO_OUTPUT_EN BIT(5) /* 1: enable SPDIF output enable */
|
||||
#define IT6621_SPDIF_GPIO_OUTPUT_VAL BIT(6) /* SPDIF GPIO output value */
|
||||
#define IT6621_SPDIF_GPIO_INPUT_VAL BIT(7) /* SPDIF GPIO input value */
|
||||
|
||||
#define IT6621_REG_GPIO_CTRL5 0xed
|
||||
#define IT6621_MUTE_GPIO_MODE_EN BIT(0) /* 1: enable MUTE GPIO mode */
|
||||
#define IT6621_MUTE_GPIO_OUTPUT_EN BIT(1) /* 1: enable MUTE output enable */
|
||||
#define IT6621_MUTE_GPIO_OUTPUT_VAL BIT(2) /* MUTE GPIO output value */
|
||||
#define IT6621_MUTE_GPIO_INPUT_VAL BIT(3) /* MUTE GPIO input value */
|
||||
#define IT6621_HPDB_GPIO_MODE_EN BIT(4) /* 1: enable HPDB GPIO mode */
|
||||
#define IT6621_HPDB_GPIO_OUTPUT_EN BIT(5) /* 1: enable HPDB output enable */
|
||||
#define IT6621_HPDB_GPIO_OUTPUT_VAL BIT(6) /* HPDB GPIO output value */
|
||||
#define IT6621_HPDB_GPIO_INPUT_VAL BIT(7) /* HPDB GPIO input value */
|
||||
|
||||
/* Misc Registers */
|
||||
#define IT6621_REG_MISC0 0xf0
|
||||
#define IT6621_DEBUG_SEL GENMASK(2, 0) /* Select one of the 8 debug groups */
|
||||
#define IT6621_DEBUG_EN BIT(3) /* 1: enable debug output */
|
||||
#define IT6621_AUD_DEBUG_EN BIT(5) /* 1: Enable audio signal debug output */
|
||||
|
||||
#define IT6621_REG_MISC1 0xf1
|
||||
#define IT6621_HPD_DG_TIME_SEL GENMASK(1, 0) /* HPD de-glitch time selection */
|
||||
#define IT6621_HPD_DG_TIME_10US (0x00 << 0) /* 10us */
|
||||
#define IT6621_HPD_DG_TIME_100US (0x01 << 0) /* 100us */
|
||||
#define IT6621_HPD_DG_TIME_1MS (0x02 << 0) /* 1ms */
|
||||
#define IT6621_HPD_DG_TIME_10MS (0x03 << 0) /* 10ms */
|
||||
#define IT6621_CMD_HOLD_TIME GENMASK(7, 4) /* PCI2C hold time */
|
||||
|
||||
#define IT6621_REG_MISC2 0xf2
|
||||
#define IT6621_CMD_DRV GENMASK(1, 0) /* Driving setting for PCSCL and PCSDA */
|
||||
#define IT6621_HPD_DRV GENMASK(3, 2) /* Driving setting for HPD signals */
|
||||
#define IT6621_I2S_DRV GENMASK(5, 4) /* Driving setting for I2S signals */
|
||||
#define IT6621_SPDIF_DRV GENMASK(7, 6) /* Driving setting for SPDIF signals */
|
||||
|
||||
#define IT6621_REG_MISC3 0xf3
|
||||
#define IT6621_CMD_SMT BIT(0) /* PCSCL/PCSDA Schmitt trigger option */
|
||||
#define IT6621_SCK_SMT BIT(2) /* SCK/DCLK Schmitt trigger option */
|
||||
#define IT6621_MCLK_SMT BIT(3) /* MCLK Schmitt trigger option */
|
||||
#define IT6621_SPDIFSMT BIT(4) /* SPDIF Schmitt trigger option */
|
||||
|
||||
#define IT6621_REG_MISC12 0xfc
|
||||
#define IT6621_CRCLK_SEL_EN BIT(0)
|
||||
#define IT6621_PWD_CRCLK (0x00 << 0) /* power-down CRCLK and disable CEC function */
|
||||
#define IT6621_CRCLK_EN (0x01 << 0) /* enable CRCLK for CEC function */
|
||||
#define IT6621_CEC_SLAVE_ADDR GENMASK(7, 1) /* CEC slave address */
|
||||
|
||||
#define IT6621_REG_PASS_WORD 0xff /* 0xC3/0xA5 on, 0xFF off */
|
||||
#define IT6621_PASS_WORD_ON1 0xc3
|
||||
#define IT6621_PASS_WORD_ON2 0xa5
|
||||
#define IT6621_PASS_WORD_OFF 0xff
|
||||
|
||||
#endif /* _IT6621_REG_BANK0_H */
|
||||
147
sound/soc/codecs/it6621/it6621-reg-bank1.h
Normal file
147
sound/soc/codecs/it6621/it6621-reg-bank1.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (c) 2024 Rockchip Electronics Co. Ltd.
|
||||
* Author: Jason Zhang <jason.zhang@rock-chips.com>
|
||||
*/
|
||||
|
||||
#ifndef _IT6621_REG_BANK1_H
|
||||
#define _IT6621_REG_BANK1_H
|
||||
|
||||
/* Bank 1 */
|
||||
|
||||
/* General Registers */
|
||||
#define IT6621_REG_GEN0 0x110
|
||||
#define IT6621_100MS_CNT_SEL BIT(7) /* Enable 100ms calibration counter */
|
||||
#define IT6621_100MS_CNT_DIS (0x00 << 7)
|
||||
#define IT6621_100MS_CNT_EN (0x01 << 7)
|
||||
|
||||
#define IT6621_REG_100MS_CNT_7_0 0x111 /* 100ms counter value */
|
||||
#define IT6621_REG_100MS_CNT_15_8 0x112
|
||||
#define IT6621_REG_100MS_CNT_23_16 0x113
|
||||
|
||||
#define IT6621_REG_GEN4 0x114
|
||||
#define IT6621_1US_TIME_INT GENMASK(5, 0) /* 1us time base integer number.
|
||||
* Note: default value is
|
||||
* calculated by 10MHz RCLK.
|
||||
*/
|
||||
|
||||
#define IT6621_REG_1US_TIME_FLT 0x115 /* 1us time base floating number */
|
||||
|
||||
#define IT6621_REG_GEN6 0x116
|
||||
#define IT6621_TIMER_INT_NUM GENMASK(6, 0) /* User defined timer
|
||||
* interrupt count number
|
||||
*/
|
||||
#define IT6621_TIMER_INT_UNIT BIT(7)
|
||||
#define IT6621_TIMER_INT_UNIT_10MS (0x00 << 7) /* unit=10ms */
|
||||
#define IT6621_TIMER_INT_UNIT_100MS (0x01 << 7) /* unit=100ms */
|
||||
|
||||
#define IT6621_REG_GEN7 0x117
|
||||
#define IT6621_TIME_STAMP_EN_SEL GENMASK(6, 0) /* Time stamp for firmware */
|
||||
#define IT6621_TIME_STAMP_EN BIT(7) /* 1: Enable time stamp */
|
||||
|
||||
/* Input SPDIF Channel Status Registers */
|
||||
#define IT6621_REG_AI_TX_CH_ST_7_0 0x120
|
||||
#define IT6621_REG_AI_TX_CH_ST_15_8 0x121
|
||||
#define IT6621_REG_AI_TX_CH_ST_23_16 0x122
|
||||
#define IT6621_REG_AI_TX_CH_ST_31_24 0x123
|
||||
#define IT6621_REG_AI_TX_CH_ST_39_32 0x124
|
||||
|
||||
/* eARC TX Channel Status Registers */
|
||||
#define IT6621_REG_TX_CH_ST0 0x130
|
||||
#define IT6621_REG_TX_CH_ST1 0x131
|
||||
#define IT6621_REG_TX_CH_ST2 0x132
|
||||
#define IT6621_REG_TX_CH_ST3 0x133
|
||||
#define IT6621_REG_TX_CH_ST4 0x134
|
||||
#define IT6621_REG_TX_CH_ST5 0x135
|
||||
#define IT6621_REG_TX_CH_ST9 0x139
|
||||
#define IT6621_REG_TX_CH_ST10 0x13a
|
||||
#define IT6621_REG_TX_CH_ST11 0x13b
|
||||
#define IT6621_REG_TX_CH_ST12 0x13c
|
||||
#define IT6621_REG_TX_CH_ST13 0x13d
|
||||
#define IT6621_REG_TX_CH_ST14 0x13e
|
||||
#define IT6621_REG_TX_CH_ST15 0x13f
|
||||
|
||||
/* eARC TX U-bit Packet Registers */
|
||||
|
||||
/* Packet Type 1 */
|
||||
#define IT6621_REG_TX_PKT1_CRC 0x150 /* eARC TX packet CRC */
|
||||
#define IT6621_REG_TX_PKT1_CH 0x151 /* eARC TX packet CH */
|
||||
#define IT6621_REG_TX_PKT1_HB0 0x152 /* eARC TX packet HB0 */
|
||||
#define IT6621_REG_TX_PKT1_HB1 0x153 /* eARC TX packet HB1 */
|
||||
#define IT6621_REG_TX_PKT1_HB2 0x154 /* eARC TX packet HB2 */
|
||||
#define IT6621_REG_TX_PKT1_PB0 0x155 /* eARC TX packet PB0 */
|
||||
#define IT6621_REG_TX_PKT1_PB1 0x156 /* eARC TX packet PB1 */
|
||||
#define IT6621_REG_TX_PKT1_PB2 0x157 /* eARC TX packet PB2 */
|
||||
#define IT6621_REG_TX_PKT1_PB3 0x158 /* eARC TX packet PB3 */
|
||||
#define IT6621_REG_TX_PKT1_PB4 0x159 /* eARC TX packet PB4 */
|
||||
#define IT6621_REG_TX_PKT1_PB5 0x15a /* eARC TX packet PB5 */
|
||||
#define IT6621_REG_TX_PKT1_PB6 0x15b /* eARC TX packet PB6 */
|
||||
#define IT6621_REG_TX_PKT1_PB7 0x15c /* eARC TX packet PB7 */
|
||||
#define IT6621_REG_TX_PKT1_PB8 0x15d /* eARC TX packet PB8 */
|
||||
#define IT6621_REG_TX_PKT1_PB9 0x15e /* eARC TX packet PB9 */
|
||||
#define IT6621_REG_TX_PKT1_PB10 0x15f /* eARC TX packet PB10 */
|
||||
#define IT6621_REG_TX_PKT1_PB11 0x160 /* eARC TX packet PB11 */
|
||||
#define IT6621_REG_TX_PKT1_PB12 0x161 /* eARC TX packet PB12 */
|
||||
#define IT6621_REG_TX_PKT1_PB13 0x162 /* eARC TX packet PB13 */
|
||||
#define IT6621_REG_TX_PKT1_PB14 0x163 /* eARC TX packet PB14 */
|
||||
#define IT6621_REG_TX_PKT1_PB15 0x164 /* eARC TX packet PB15 */
|
||||
#define IT6621_REG_TX_PKT1_PB16 0x165 /* eARC TX packet PB16 */
|
||||
#define IT6621_REG_TX_PKT1_PB17 0x166 /* eARC TX packet PB17 */
|
||||
#define IT6621_REG_TX_PKT1_PB18 0x167 /* eARC TX packet PB18 */
|
||||
#define IT6621_REG_TX_PKT1_PB19 0x168 /* eARC TX packet PB19 */
|
||||
#define IT6621_REG_TX_PKT1_PB20 0x169 /* eARC TX packet PB20 */
|
||||
#define IT6621_REG_TX_PKT1_PB21 0x16a /* eARC TX packet PB21 */
|
||||
#define IT6621_REG_TX_PKT1_PB22 0x16b /* eARC TX packet PB22 */
|
||||
#define IT6621_REG_TX_PKT1_PB23 0x16c /* eARC TX packet PB23 */
|
||||
#define IT6621_REG_TX_PKT1_PB24 0x16d /* eARC TX packet PB24 */
|
||||
#define IT6621_REG_TX_PKT1_PB25 0x16e /* eARC TX packet PB25 */
|
||||
#define IT6621_REG_TX_PKT1_PB26 0x16f /* eARC TX packet PB26 */
|
||||
#define IT6621_REG_TX_PKT1_PB27 0x170 /* eARC TX packet PB27 */
|
||||
|
||||
/* Packet Type 2 */
|
||||
#define IT6621_REG_TX_PKT2_CRC 0x171 /* eARC TX packet CRC */
|
||||
#define IT6621_REG_TX_PKT2_CH 0x172 /* eARC TX packet CH */
|
||||
#define IT6621_REG_TX_PKT2_HB0 0x173 /* eARC TX packet HB0 */
|
||||
#define IT6621_REG_TX_PKT2_HB1 0x174 /* eARC TX packet HB1 */
|
||||
#define IT6621_REG_TX_PKT2_HB2 0x175 /* eARC TX packet HB2 */
|
||||
#define IT6621_REG_TX_PKT2_PB0 0x176 /* eARC TX packet PB0 */
|
||||
#define IT6621_REG_TX_PKT2_PB1 0x177 /* eARC TX packet PB1 */
|
||||
#define IT6621_REG_TX_PKT2_PB2 0x178 /* eARC TX packet PB2 */
|
||||
#define IT6621_REG_TX_PKT2_PB3 0x179 /* eARC TX packet PB3 */
|
||||
#define IT6621_REG_TX_PKT2_PB4 0x17a /* eARC TX packet PB4 */
|
||||
#define IT6621_REG_TX_PKT2_PB5 0x17b /* eARC TX packet PB5 */
|
||||
#define IT6621_REG_TX_PKT2_PB6 0x17c /* eARC TX packet PB6 */
|
||||
#define IT6621_REG_TX_PKT2_PB7 0x17d /* eARC TX packet PB7 */
|
||||
#define IT6621_REG_TX_PKT2_PB8 0x17e /* eARC TX packet PB8 */
|
||||
#define IT6621_REG_TX_PKT2_PB9 0x17f /* eARC TX packet PB9 */
|
||||
#define IT6621_REG_TX_PKT2_PB10 0x180 /* eARC TX packet PB10 */
|
||||
#define IT6621_REG_TX_PKT2_PB11 0x181 /* eARC TX packet PB11 */
|
||||
#define IT6621_REG_TX_PKT2_PB12 0x182 /* eARC TX packet PB12 */
|
||||
#define IT6621_REG_TX_PKT2_PB13 0x183 /* eARC TX packet PB13 */
|
||||
#define IT6621_REG_TX_PKT2_PB14 0x184 /* eARC TX packet PB14 */
|
||||
#define IT6621_REG_TX_PKT2_PB15 0x185 /* eARC TX packet PB15 */
|
||||
|
||||
/* Packet Type 3 */
|
||||
#define IT6621_REG_TX_PKT3_CRC 0x186 /* eARC TX packet CRC */
|
||||
#define IT6621_REG_TX_PKT3_CH 0x187 /* eARC TX packet CH */
|
||||
#define IT6621_REG_TX_PKT3_HB0 0x188 /* eARC TX packet HB0 */
|
||||
#define IT6621_REG_TX_PKT3_HB1 0x189 /* eARC TX packet HB1 */
|
||||
#define IT6621_REG_TX_PKT3_HB2 0x18a /* eARC TX packet HB2 */
|
||||
#define IT6621_REG_TX_PKT3_PB0 0x18b /* eARC TX packet PB0 */
|
||||
#define IT6621_REG_TX_PKT3_PB1 0x18c /* eARC TX packet PB1 */
|
||||
#define IT6621_REG_TX_PKT3_PB2 0x18d /* eARC TX packet PB2 */
|
||||
#define IT6621_REG_TX_PKT3_PB3 0x18e /* eARC TX packet PB3 */
|
||||
#define IT6621_REG_TX_PKT3_PB4 0x18f /* eARC TX packet PB4 */
|
||||
#define IT6621_REG_TX_PKT3_PB5 0x190 /* eARC TX packet PB5 */
|
||||
#define IT6621_REG_TX_PKT3_PB6 0x191 /* eARC TX packet PB6 */
|
||||
#define IT6621_REG_TX_PKT3_PB7 0x192 /* eARC TX packet PB7 */
|
||||
#define IT6621_REG_TX_PKT3_PB8 0x193 /* eARC TX packet PB8 */
|
||||
#define IT6621_REG_TX_PKT3_PB9 0x194 /* eARC TX packet PB9 */
|
||||
#define IT6621_REG_TX_PKT3_PB10 0x195 /* eARC TX packet PB10 */
|
||||
#define IT6621_REG_TX_PKT3_PB11 0x196 /* eARC TX packet PB11 */
|
||||
#define IT6621_REG_TX_PKT3_PB12 0x197 /* eARC TX packet PB12 */
|
||||
#define IT6621_REG_TX_PKT3_PB13 0x198 /* eARC TX packet PB13 */
|
||||
#define IT6621_REG_TX_PKT3_PB14 0x199 /* eARC TX packet PB14 */
|
||||
#define IT6621_REG_TX_PKT3_PB15 0x19a /* eARC TX packet PB15 */
|
||||
|
||||
#endif /* _IT6621_REG_BANK1_H */
|
||||
246
sound/soc/codecs/it6621/it6621-reg-cec.h
Normal file
246
sound/soc/codecs/it6621/it6621-reg-cec.h
Normal file
@@ -0,0 +1,246 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (c) 2024 Rockchip Electronics Co. Ltd.
|
||||
* Author: Jason Zhang <jason.zhang@rock-chips.com>
|
||||
*/
|
||||
|
||||
#ifndef _IT6621_REG_CEC_H
|
||||
#define _IT6621_REG_CEC_H
|
||||
|
||||
/* CEC Control Registers */
|
||||
#define IT6621_REG_CEC_CTRL6 0x06 /* 0: Interrupt Enable, 1: Interrupt Mask */
|
||||
#define IT6621_TX_INT_MASK BIT(0)
|
||||
#define IT6621_RX_INT_MASK BIT(1)
|
||||
#define IT6621_RX_FAIL_INT_MASK BIT(2)
|
||||
#define IT6621_TX_DONE_INT_MASK BIT(3)
|
||||
#define IT6621_RX_DONE_INT_MASK BIT(4)
|
||||
#define IT6621_TX_FAIL_INT_MASK BIT(5)
|
||||
#define IT6621_CMD_OVERFLOW_INT_MASK BIT(6)
|
||||
#define IT6621_DATA_OVERFLOW_INT_MASK BIT(7)
|
||||
|
||||
#define IT6621_REG_CEC_CTRL7 0x07
|
||||
#define IT6621_DBG_CEC_SEL GENMASK(4, 2)
|
||||
#define IT6621_CEC_INT_STS_SEL BIT(5)
|
||||
|
||||
#define IT6621_REG_CEC_CTRL8 0x08
|
||||
#define IT6621_CEC_INT_SEL BIT(0) /* CEC interrupt enable,
|
||||
* 1: Enable, 0: Disable
|
||||
*/
|
||||
#define IT6621_CEC_INT_DIS (0x00 << 0)
|
||||
#define IT6621_CEC_INT_EN (0x01 << 0)
|
||||
#define IT6621_CEC_RESET_SEL BIT(2) /* Reset CEC block,
|
||||
* 1: Enable, 0: Disable
|
||||
*/
|
||||
#define IT6621_CEC_RESET_DIS (0x00 << 2)
|
||||
#define IT6621_CEC_RESET_EN (0x01 << 2)
|
||||
#define IT6621_CEC_SMT BIT(3) /* Schmitt trigger of CEC IO,
|
||||
* 1: Enable, 0: Disable
|
||||
*/
|
||||
#define IT6621_CEC_FORCE BIT(4) /* Force CEC output regardless of normal function */
|
||||
#define IT6621_CEC_OE BIT(5) /* Force CEC output value */
|
||||
#define IT6621_DBG_CEC_CLR BIT(6) /* For debug only */
|
||||
#define IT6621_FIRE_FRAME BIT(7) /* 1: Fire CEC command out */
|
||||
|
||||
#define IT6621_REG_CEC_CTRL9 0x09
|
||||
#define IT6621_EN_100MS_CNT BIT(0) /* Used as a reference 100ms
|
||||
* time interval for CEC calibration
|
||||
*/
|
||||
#define IT6621_NACK_SEL BIT(1) /* Acknowledge from follower to initiator */
|
||||
#define IT6621_ACK_EN (0x00 << 1) /* ACK */
|
||||
#define IT6621_NACK_EN (0x01 << 1) /* NACK */
|
||||
#define IT6621_PULSE_SEL BIT(2) /* Select illegal bit as error bit */
|
||||
#define IT6621_PULSE_DIS (0x00 << 2) /* Disable */
|
||||
#define IT6621_PULSE_EN (0x01 << 2) /* Enable */
|
||||
#define IT6621_ACK_TRIG_SEL BIT(3) /* Acknowledge for broadcast mode */
|
||||
#define IT6621_ACK_TRIG_NACK (0x00 << 3) /* NACK */
|
||||
#define IT6621_ACK_TRIG_ACK (0x01 << 3) /* ACK */
|
||||
#define IT6621_REFIRE_SEL BIT(4) /* Retry to fire CEC command */
|
||||
#define IT6621_REFIRE_DIS (0x00 << 4) /* Disable */
|
||||
#define IT6621_REFIRE_EN (0x01 << 4) /* Enable */
|
||||
#define IT6621_RX_SELF_SEL BIT(5) /* Initiator received CEC bus data */
|
||||
#define IT6621_RX_SELF_EN (0x00 << 5) /* Enable */
|
||||
#define IT6621_RX_SELF_DIS (0x01 << 5) /* Disable */
|
||||
#define IT6621_REGION_SEL BIT(6) /* Select region for error bit */
|
||||
#define IT6621_REGION_START_TO_IDLE (0x00 << 6) /* Region form state Start to IDLE */
|
||||
#define IT6621_REGION_WHOLE (0x01 << 6) /* Whole region */
|
||||
#define IT6621_DATA_BIT_SEL BIT(7) /* Select data bit */
|
||||
#define IT6621_DATA_BIT_NORMAL (0x00 << 7) /* Normal */
|
||||
#define IT6621_DATA_BIT_INC_0P1MS (0x01 << 7) /* Increase 0.1ms */
|
||||
|
||||
#define IT6621_REG_CEC_CTRL10 0x0a
|
||||
#define IT6621_BUS_FREE_SEL GENMASK(1, 0) /* Select bus free bit time */
|
||||
#define IT6621_BUS_FREE_AUTO (0x00 << 0) /* Automatic */
|
||||
#define IT6621_BUS_FREE_3BIT_TIME (0x01 << 0) /* 3 bit time */
|
||||
#define IT6621_BUS_FREE_5BIT_TIME (0x02 << 0) /* 5 bit time */
|
||||
#define IT6621_BUS_FREE_7BIT_TIME (0x03 << 0) /* 7 bit time */
|
||||
#define IT6621_BIT_END_SEL GENMASK(3, 2) /* Select logic 0 and
|
||||
* logic 1 output bit time
|
||||
*/
|
||||
#define IT6621_BIT_END_STD (0x00 << 2) /* Standard */
|
||||
#define IT6621_BIT_END_MAX0_MIN1 (0x01 << 2) /* Logic 0 maximum and logic 1 minimum */
|
||||
#define IT6621_BIT_END_MAX1_MIN0 (0x02 << 2) /* Logic 1 maximum and logic 0 minimum */
|
||||
#define IT6621_AR_BIT_SEL BIT(4) /* Select bit time for arbitration lose */
|
||||
#define IT6621_AR_BIT_5BIT_TIME (0x00 << 4) /* 5 bit time */
|
||||
#define IT6621_AR_BIT_3BIT_TIME (0x01 << 4) /* 3 bit time */
|
||||
#define IT6621_HW_RTY_SEL BIT(5) /* HW 5 times Retry of TX */
|
||||
#define IT6621_HW_RTY_EN (0x00 << 5)
|
||||
#define IT6621_HW_RTY_DIS (0x01 << 5)
|
||||
#define IT6621_CEC_RX_EN_SEL BIT(6) /* CEC RX function */
|
||||
#define IT6621_CEC_RX_DIS (0x00 << 6)
|
||||
#define IT6621_CEC_RX_EN (0x01 << 6)
|
||||
|
||||
#define IT6621_REG_DATA_MIN 0x0b /* Minimum data bit time */
|
||||
#define IT6621_REG_TIMER_UNIT 0x0c /* CEC timer unit, nominally
|
||||
* 100us. This value should be
|
||||
* decided from MS_Count.
|
||||
*/
|
||||
|
||||
#define IT6621_REG_CEC_CTRL13 0x0d
|
||||
#define IT6621_CEC_IO_PU_SEL BIT(4)
|
||||
#define IT6621_CEC_IO_NORMAL (0x00 << 4) /* Normal */
|
||||
#define IT6621_CEC_IO_PU (0x01 << 4) /* Pull-up */
|
||||
#define IT6621_CEC_IO_SR BIT(5) /* CEC IO slew rate control */
|
||||
#define IT6621_CEC_IO_DRV GENMASK(7, 6)
|
||||
#define IT6621_CEC_IO_DRV_2P5MA (0x00 << 6) /* 2.5mA */
|
||||
#define IT6621_CEC_IO_DRV_5MA (0x01 << 6) /* 5mA */
|
||||
#define IT6621_CEC_IO_DRV_7P5MA (0x02 << 6) /* 7.5mA */
|
||||
#define IT6621_CEC_IO_DRV_10MA (0x03 << 6) /* 10mA */
|
||||
|
||||
/* CEC Initiator Registers */
|
||||
#define IT6621_REG_TX_HEADER 0x10 /* CEC initiator command header */
|
||||
#define IT6621_REG_TX_OPCODE 0x11 /* CEC initiator command Opcode */
|
||||
#define IT6621_REG_TX_OPERAND1 0x12 /* CEC initiator command Operand1 */
|
||||
#define IT6621_REG_TX_OPERAND2 0x13 /* CEC initiator command Operand2 */
|
||||
#define IT6621_REG_TX_OPERAND3 0x14 /* CEC initiator command Operand3 */
|
||||
#define IT6621_REG_TX_OPERAND4 0x15 /* CEC initiator command Operand4 */
|
||||
#define IT6621_REG_TX_OPERAND5 0x16 /* CEC initiator command Operand5 */
|
||||
#define IT6621_REG_TX_OPERAND6 0x17 /* CEC initiator command Operand6 */
|
||||
#define IT6621_REG_TX_OPERAND7 0x18 /* CEC initiator command Operand7 */
|
||||
#define IT6621_REG_TX_OPERAND8 0x19 /* CEC initiator command Operand8 */
|
||||
#define IT6621_REG_TX_OPERAND9 0x1a /* CEC initiator command Operand9 */
|
||||
#define IT6621_REG_TX_OPERAND10 0x1b /* CEC initiator command Operand10 */
|
||||
#define IT6621_REG_TX_OPERAND11 0x1c /* CEC initiator command Operand11 */
|
||||
#define IT6621_REG_TX_OPERAND12 0x1d /* CEC initiator command Operand12 */
|
||||
#define IT6621_REG_TX_OPERAND13 0x1e /* CEC initiator command Operand13 */
|
||||
#define IT6621_REG_TX_OPERAND14 0x1f /* CEC initiator command Operand14 */
|
||||
#define IT6621_REG_TX_OPERAND15 0x20 /* CEC initiator command Operand15 */
|
||||
#define IT6621_REG_TX_OPERAND16 0x21 /* CEC initiator command Operand16 */
|
||||
|
||||
#define IT6621_REG_CEC_INIT22 0x22
|
||||
#define IT6621_LOG_ADDR GENMASK(3, 0) /* CEC target logical address */
|
||||
|
||||
#define IT6621_REG_CEC_INIT23 0x23
|
||||
#define IT6621_OUT_NUM GENMASK(4, 0) /* CEC output byte size in a frame */
|
||||
|
||||
/* CEC Follower Registers */
|
||||
#define IT6621_REG_RX_HEADER 0x30 /* CEC Follower command header */
|
||||
#define IT6621_REG_RX_OPCODE 0x31 /* CEC Follower command Opcode */
|
||||
#define IT6621_REG_RX_OPERAND1 0x32 /* CEC Follower command Operand1 */
|
||||
#define IT6621_REG_RX_OPERAND2 0x33 /* CEC Follower command Operand2 */
|
||||
#define IT6621_REG_RX_OPERAND3 0x34 /* CEC Follower command Operand3 */
|
||||
#define IT6621_REG_RX_OPERAND4 0x35 /* CEC Follower command Operand4 */
|
||||
#define IT6621_REG_RX_OPERAND5 0x36 /* CEC Follower command Operand5 */
|
||||
#define IT6621_REG_RX_OPERAND6 0x37 /* CEC Follower command Operand6 */
|
||||
#define IT6621_REG_RX_OPERAND7 0x38 /* CEC Follower command Operand7 */
|
||||
#define IT6621_REG_RX_OPERAND8 0x39 /* CEC Follower command Operand8 */
|
||||
#define IT6621_REG_RX_OPERAND9 0x3a /* CEC Follower command Operand9 */
|
||||
#define IT6621_REG_RX_OPERAND10 0x3b /* CEC Follower command Operand10 */
|
||||
#define IT6621_REG_RX_OPERAND11 0x3c /* CEC Follower command Operand11 */
|
||||
#define IT6621_REG_RX_OPERAND12 0x3d /* CEC Follower command Operand12 */
|
||||
#define IT6621_REG_RX_OPERAND13 0x3e /* CEC Follower command Operand13 */
|
||||
#define IT6621_REG_RX_OPERAND14 0x3f /* CEC Follower command Operand14 */
|
||||
#define IT6621_REG_RX_OPERAND15 0x40 /* CEC Follower command Operand15 */
|
||||
#define IT6621_REG_RX_OPERAND16 0x41 /* CEC Follower command Operand16 */
|
||||
|
||||
#define IT6621_REG_CEC_FOL22 0x42
|
||||
#define IT6621_IN_CNT GENMASK(4, 0) /* CEC follower received bytes */
|
||||
|
||||
/* CEC Misc. Registers */
|
||||
#define IT6621_REG_CEC_MSIC0 0x43
|
||||
#define IT6621_OUT_CNT GENMASK(4, 0) /* CEC initiator output bytes */
|
||||
|
||||
#define IT6621_REG_CEC_MSIC1 0x44
|
||||
#define IT6621_BUS_STATUS BIT(1)
|
||||
#define IT6621_BUS_STATUS_BUSY (0x00 << 1) /* Busy */
|
||||
#define IT6621_BUS_STATUS_FREE (0x01 << 1) /* Busy */
|
||||
#define IT6621_OUT_STATUS GENMASK(3, 2) /* Output status */
|
||||
#define IT6621_OUT_STATUS_RCV_ACK (0x00 << 2) /* Received ACK */
|
||||
#define IT6621_OUT_STATUS_RCV_NACK (0x01 << 2) /* Received NACK */
|
||||
#define IT6621_OUT_STATUS_RTY (0x02 << 2) /* Retry, if no ACK, NACK
|
||||
* or arbitration lose
|
||||
*/
|
||||
#define IT6621_OUT_STATUS_FAIL (0x03 << 2) /* Fail */
|
||||
#define IT6621_ERR_STATUS GENMASK(5, 4) /* Output status */
|
||||
#define IT6621_ERR_STATUS_NO_ERR (0x00 << 4) /* No error occurs */
|
||||
#define IT6621_ERR_STATUS_MDBP (0x01 << 4) /* Received data period < minimum
|
||||
* data bit period
|
||||
*/
|
||||
#define IT6621_ERR_STATUS_IHLP (0x02 << 4) /* Illegal high-low period */
|
||||
#define IT6621_ERR_STATUS_BOTH (0x03 << 4) /* Both */
|
||||
#define IT6621_READY_FIRE BIT(6) /* Bus ready for firing a CEC command */
|
||||
|
||||
#define IT6621_REG_CEC_MS_COUNT_7_0 0x45
|
||||
#define IT6621_REG_CEC_MS_COUNT_15_8 0x46
|
||||
#define IT6621_REG_CEC_MS_COUNT_19_16 0x47
|
||||
|
||||
#define IT6621_REG_CEC_MSIC5 0x48
|
||||
#define IT6621_DBG_STATE GENMASK(3, 0) /* Debug CEC error state */
|
||||
#define IT6621_DBG_INT BIT(4) /* CEC interrupt for debug */
|
||||
#define IT6621_CEC_INT BIT(5) /* CEC interrupt status */
|
||||
|
||||
#define IT6621_REG_CEC_MSIC6 0x49
|
||||
#define IT6621_DBG_BLOCK GENMASK(4, 0) /* Debug CEC error block number */
|
||||
|
||||
#define IT6621_REG_CEC_MSIC7 0x4a
|
||||
#define IT6621_DBG_BIT GENMASK(3, 0) /* Debug CEC error bit number */
|
||||
|
||||
#define IT6621_REG_DBG_TIMING 0x4b /* Debug CEC error data bit time */
|
||||
|
||||
#define IT6621_REG_CEC_MSIC8 0x4c
|
||||
#define IT6621_TX_INT BIT(0) /* CEC initiator output byte interrupt */
|
||||
#define IT6621_RX_INT BIT(1) /* CEC follower received byte interrupt */
|
||||
#define IT6621_RX_FAIL_INT BIT(2) /* CEC received fail interrupt */
|
||||
#define IT6621_TX_DONE_INT BIT(3) /* CEC output finish interrupt */
|
||||
#define IT6621_RX_DONE_INT BIT(4) /* CEC received finish interrupt */
|
||||
#define IT6621_TX_FAIL_INT BIT(5) /* CEC initiator output fail interrupt */
|
||||
#define IT6621_CMD_OVERFLOW_INT BIT(6) /* CEC command FIFO over flow interrupt */
|
||||
#define IT6621_DATA_OVERFLOW_INT BIT(7) /* CEC data FIFO over flow interrupt */
|
||||
|
||||
#define IT6621_REG_RX_CMD_RX_HEADER 0x4d /* Command FIFO Rx_Header */
|
||||
#define IT6621_REG_RX_CMD_RX_OPCODE 0x4e /* Command FIFO Rx_Opcode */
|
||||
|
||||
#define IT6621_REG_RX_CMD_BYTE2 0x4f
|
||||
#define IT6621_RX_CMD_IN_CNT GENMASK(4, 0) /* Command FIFO In_Cnt */
|
||||
#define IT6621_RX_CMD_ERR_STATUS GENMASK(6, 5) /* Command FIFO Error_Status */
|
||||
#define IT6621_RX_CMD_CEC_RX_FAIL BIT(7) /* Command FIFO CEC Rx_Fail */
|
||||
|
||||
#define IT6621_REG_RX_DATA 0x50 /* Data FIFO Rx_Operand */
|
||||
|
||||
#define IT6621_REG_CEC_MSIC12 0x51
|
||||
#define IT6621_RX_CMD_VALID BIT(0) /* Read command FIFO valid */
|
||||
#define IT6621_RX_CMD_FULL BIT(1) /* Command FIFO full */
|
||||
#define IT6621_RX_CMD_WRITE_OVERFLOW BIT(2) /* Write command FIFO over flow */
|
||||
#define IT6621_RX_CMD_READ_OVERFLOW BIT(3) /* Read command FIFO over flow */
|
||||
#define IT6621_RX_DATA_VALID BIT(4) /* Read data FIFO valid */
|
||||
#define IT6621_RX_DATA_FULL BIT(5) /* Data FIFO full */
|
||||
#define IT6621_RX_DATA_WRITE_OVERFLOW BIT(6) /* Write data FIFO over flow */
|
||||
#define IT6621_RX_DATA_READ_OVERFLOW BIT(7) /* Read data FIFO over flow */
|
||||
|
||||
#define IT6621_REG_CEC_MSIC13 0x52
|
||||
#define IT6621_RX_CMD_STG GENMASK(3, 0) /* Rx command FIFO stage */
|
||||
#define IT6621_RX_CMD_FIFO_RST BIT(5) /* CEC command FIFO reset 1:Reset */
|
||||
#define IT6621_RX_DATA_FIFO_RST BIT(6) /* CEC data FIFO reset 1:Reset */
|
||||
#define IT6621_RX_CEC_FIFO_EN_SEL BIT(7) /* CEC FIFO enable */
|
||||
#define IT6621_RX_CEC_FIFO_DIS (0x00 << 7) /* Disable */
|
||||
#define IT6621_RX_CEC_FIFO_EN (0x01 << 7) /* Enable */
|
||||
|
||||
#define IT6621_REG_CEC_MSIC14 0x53
|
||||
#define IT6621_RX_DATA_STG GENMASK(3, 0) /* Rx data FIFO stage */
|
||||
|
||||
#define IT6621_REG_CEC_MSIC15 0x54
|
||||
#define IT6621_TX_FAIL_STATUS GENMASK(2, 0)
|
||||
#define IT6621_TX_FAIL_STATUS_RCV_ACK BIT(0) /* receive ACK */
|
||||
#define IT6621_TX_FAIL_STATUS_RCV_NACK BIT(1) /* receive NACK */
|
||||
#define IT6621_TX_FAIL_STATUS_RTY BIT(2) /* retry */
|
||||
|
||||
#endif /* _IT6621_REG_CEC_H */
|
||||
364
sound/soc/codecs/it6621/it6621-uapi.c
Normal file
364
sound/soc/codecs/it6621/it6621-uapi.c
Normal file
@@ -0,0 +1,364 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (c) 2024 Rockchip Electronics Co. Ltd.
|
||||
* Author: Jason Zhang <jason.zhang@rock-chips.com>
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/poll.h>
|
||||
|
||||
#include "it6621.h"
|
||||
#include "it6621-earc.h"
|
||||
#include "it6621-uapi.h"
|
||||
|
||||
#define IT6621_MAX_MSGS 18
|
||||
#define IT6621_MAX_MSG_LEN 256
|
||||
|
||||
struct it6621_msg {
|
||||
u8 event;
|
||||
u8 data[IT6621_MAX_MSG_LEN];
|
||||
} __packed;
|
||||
|
||||
/* Command */
|
||||
#define IT6621_EARC_SET_ENABLED _IOW('a', 0x01, unsigned int)
|
||||
#define IT6621_EARC_GET_STATE _IOR('a', 0x02, unsigned int)
|
||||
#define IT6621_EARC_GET_AUDIO_CAP _IOR('a', 0x03, u8[IT6621_MAX_MSG_LEN])
|
||||
#define IT6621_EARC_GET_EVENT _IOR('a', 0x04, struct it6621_msg)
|
||||
#define IT6621_EARC_SET_ENTER_ARC _IOW('a', 0x05, unsigned int)
|
||||
|
||||
struct it6621_msg_entry {
|
||||
struct list_head list;
|
||||
struct it6621_msg msg;
|
||||
};
|
||||
|
||||
struct it6621_fh {
|
||||
struct list_head list;
|
||||
struct list_head msgs;
|
||||
unsigned int msgs_num;
|
||||
struct mutex msgs_lock;
|
||||
wait_queue_head_t wait;
|
||||
struct it6621_priv *priv;
|
||||
struct mutex valid_lock;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
static int minor;
|
||||
|
||||
static bool it6621_fh_get_valid(struct it6621_fh *fh)
|
||||
{
|
||||
bool valid;
|
||||
|
||||
mutex_lock(&fh->valid_lock);
|
||||
valid = fh->valid;
|
||||
mutex_unlock(&fh->valid_lock);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
static void it6621_fh_set_valid(struct it6621_fh *fh, bool valid)
|
||||
{
|
||||
mutex_lock(&fh->valid_lock);
|
||||
fh->valid = valid;
|
||||
mutex_unlock(&fh->valid_lock);
|
||||
}
|
||||
|
||||
static int it6621_fh_set_earc_enabled(struct it6621_fh *fh,
|
||||
unsigned int __user *argp)
|
||||
{
|
||||
struct it6621_priv *priv = fh->priv;
|
||||
unsigned int enabled;
|
||||
int ret;
|
||||
|
||||
ret = copy_from_user(&enabled, argp, sizeof(enabled));
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
|
||||
return it6621_set_earc_enabled(priv, !!enabled);
|
||||
}
|
||||
|
||||
static int it6621_fh_get_earc_state(struct it6621_fh *fh,
|
||||
unsigned int __user *argp)
|
||||
{
|
||||
struct it6621_priv *priv = fh->priv;
|
||||
int ret;
|
||||
|
||||
ret = copy_to_user(argp, &priv->state, sizeof(priv->state));
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_fh_get_earc_audio_cap(struct it6621_fh *fh, u8 __user *argp)
|
||||
{
|
||||
struct it6621_priv *priv = fh->priv;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&priv->rxcap_lock);
|
||||
ret = copy_to_user(argp, priv->rxcap, sizeof(priv->rxcap));
|
||||
mutex_unlock(&priv->rxcap_lock);
|
||||
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_fh_get_msg(struct it6621_fh *fh,
|
||||
struct it6621_msg __user *argp,
|
||||
bool block)
|
||||
{
|
||||
struct it6621_msg_entry *entry;
|
||||
int ret = 0;
|
||||
|
||||
do {
|
||||
mutex_lock(&fh->msgs_lock);
|
||||
|
||||
if (fh->msgs_num) {
|
||||
entry = list_first_entry(&fh->msgs,
|
||||
struct it6621_msg_entry,
|
||||
list);
|
||||
list_del(&entry->list);
|
||||
ret = copy_to_user(argp, &entry->msg, sizeof(entry->msg));
|
||||
kfree(entry);
|
||||
fh->msgs_num--;
|
||||
mutex_unlock(&fh->msgs_lock);
|
||||
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_unlock(&fh->msgs_lock);
|
||||
|
||||
if (!block)
|
||||
return -EAGAIN;
|
||||
|
||||
ret = wait_event_interruptible(fh->wait, fh->msgs_num);
|
||||
|
||||
if (!it6621_fh_get_valid(fh))
|
||||
return -ENXIO;
|
||||
/* Exit on error, otherwise loop to get the new message */
|
||||
} while (!ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int it6621_fh_push_msg(struct it6621_fh *fh, u8 event, void *data,
|
||||
size_t len)
|
||||
{
|
||||
struct it6621_msg_entry *entry;
|
||||
|
||||
mutex_lock(&fh->msgs_lock);
|
||||
|
||||
if (fh->msgs_num <= IT6621_MAX_MSGS) {
|
||||
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
|
||||
if (!entry) {
|
||||
mutex_unlock(&fh->msgs_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
entry->msg.event = event;
|
||||
memcpy(entry->msg.data, data, len);
|
||||
list_add_tail(&entry->list, &fh->msgs);
|
||||
fh->msgs_num++;
|
||||
} else {
|
||||
dev_warn(fh->priv->dev, "queue is full for fh: %p", fh);
|
||||
}
|
||||
|
||||
mutex_unlock(&fh->msgs_lock);
|
||||
|
||||
wake_up_interruptible(&fh->wait);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it6621_fh_set_enter_arc(struct it6621_fh *fh,
|
||||
unsigned int __user *argp)
|
||||
{
|
||||
struct it6621_priv *priv = fh->priv;
|
||||
int enabled;
|
||||
int ret;
|
||||
|
||||
ret = copy_from_user(&enabled, argp, sizeof(enabled));
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
|
||||
return it6621_set_enter_arc(priv, !!enabled);
|
||||
}
|
||||
|
||||
static int it6621_uapi_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct miscdevice *mdev = file->private_data;
|
||||
struct it6621_priv *priv = container_of(mdev, struct it6621_priv, mdev);
|
||||
struct it6621_fh *fh;
|
||||
|
||||
if (!priv->uapi_registered)
|
||||
return -ENXIO;
|
||||
|
||||
fh = kzalloc(sizeof(*fh), GFP_KERNEL);
|
||||
if (!fh)
|
||||
return -ENOMEM;
|
||||
|
||||
fh->priv = priv;
|
||||
fh->valid = true;
|
||||
fh->msgs_num = 0;
|
||||
INIT_LIST_HEAD(&fh->msgs);
|
||||
mutex_init(&fh->msgs_lock);
|
||||
mutex_init(&fh->valid_lock);
|
||||
init_waitqueue_head(&fh->wait);
|
||||
|
||||
mutex_lock(&priv->fhs_lock);
|
||||
list_add(&fh->list, &priv->fhs);
|
||||
mutex_unlock(&priv->fhs_lock);
|
||||
|
||||
file->private_data = fh;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long it6621_uapi_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct it6621_fh *fh = file->private_data;
|
||||
bool block = !(file->f_flags & O_NONBLOCK);
|
||||
void __user *argp = (void __user *)arg;
|
||||
|
||||
if (!it6621_fh_get_valid(fh))
|
||||
return -ENODEV;
|
||||
|
||||
switch (cmd) {
|
||||
case IT6621_EARC_SET_ENABLED:
|
||||
return it6621_fh_set_earc_enabled(fh, argp);
|
||||
case IT6621_EARC_GET_STATE:
|
||||
return it6621_fh_get_earc_state(fh, argp);
|
||||
case IT6621_EARC_GET_AUDIO_CAP:
|
||||
return it6621_fh_get_earc_audio_cap(fh, argp);
|
||||
case IT6621_EARC_GET_EVENT:
|
||||
return it6621_fh_get_msg(fh, argp, block);
|
||||
case IT6621_EARC_SET_ENTER_ARC:
|
||||
return it6621_fh_set_enter_arc(fh, argp);
|
||||
default:
|
||||
return -ENOTTY;
|
||||
}
|
||||
}
|
||||
|
||||
static int it6621_uapi_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct it6621_fh *fh = file->private_data;
|
||||
struct it6621_priv *priv = fh->priv;
|
||||
struct it6621_msg_entry *entry;
|
||||
|
||||
if (it6621_fh_get_valid(fh)) {
|
||||
mutex_lock(&priv->fhs_lock);
|
||||
list_del(&fh->list);
|
||||
mutex_unlock(&priv->fhs_lock);
|
||||
}
|
||||
|
||||
mutex_lock(&fh->msgs_lock);
|
||||
|
||||
while (!list_empty(&fh->msgs)) {
|
||||
entry = list_first_entry(&fh->msgs, struct it6621_msg_entry,
|
||||
list);
|
||||
list_del(&entry->list);
|
||||
kfree(entry);
|
||||
}
|
||||
|
||||
mutex_unlock(&fh->msgs_lock);
|
||||
|
||||
kfree(fh);
|
||||
file->private_data = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __poll_t it6621_uapi_poll(struct file *file,
|
||||
struct poll_table_struct *poll)
|
||||
{
|
||||
struct it6621_fh *fh = file->private_data;
|
||||
__poll_t ret = 0;
|
||||
|
||||
poll_wait(file, &fh->wait, poll);
|
||||
if (!it6621_fh_get_valid(fh))
|
||||
ret = EPOLLERR | EPOLLHUP;
|
||||
else
|
||||
ret = EPOLLIN | EPOLLRDNORM;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const struct file_operations it6621_uapi_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = it6621_uapi_open,
|
||||
.unlocked_ioctl = it6621_uapi_ioctl,
|
||||
.compat_ioctl = it6621_uapi_ioctl,
|
||||
.release = it6621_uapi_release,
|
||||
.poll = it6621_uapi_poll,
|
||||
.llseek = no_llseek,
|
||||
};
|
||||
|
||||
int it6621_uapi_init(struct it6621_priv *priv)
|
||||
{
|
||||
char *name;
|
||||
int ret;
|
||||
|
||||
name = kzalloc(NAME_MAX, GFP_KERNEL);
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
snprintf(name, NAME_MAX, "ite-earc%d", minor++);
|
||||
priv->mdev.minor = MISC_DYNAMIC_MINOR;
|
||||
priv->mdev.name = name;
|
||||
priv->mdev.fops = &it6621_uapi_fops;
|
||||
|
||||
ret = misc_register(&priv->mdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->uapi_registered = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void it6621_uapi_remove(struct it6621_priv *priv)
|
||||
{
|
||||
struct it6621_fh *fh;
|
||||
|
||||
mutex_lock(&priv->fhs_lock);
|
||||
|
||||
priv->uapi_registered = false;
|
||||
|
||||
list_for_each_entry(fh, &priv->fhs, list)
|
||||
it6621_fh_set_valid(fh, false);
|
||||
|
||||
list_for_each_entry(fh, &priv->fhs, list)
|
||||
wake_up_interruptible(&fh->wait);
|
||||
|
||||
mutex_unlock(&priv->fhs_lock);
|
||||
|
||||
misc_deregister(&priv->mdev);
|
||||
kfree(priv->mdev.name);
|
||||
}
|
||||
|
||||
int it6621_uapi_msg(struct it6621_priv *priv, u8 event, void *data, size_t len)
|
||||
{
|
||||
struct it6621_fh *fh;
|
||||
int ret = 0;
|
||||
|
||||
if (!priv->uapi_registered)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&priv->fhs_lock);
|
||||
|
||||
list_for_each_entry(fh, &priv->fhs, list) {
|
||||
ret = it6621_fh_push_msg(fh, event, data, len);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_unlock(&priv->fhs_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
30
sound/soc/codecs/it6621/it6621-uapi.h
Normal file
30
sound/soc/codecs/it6621/it6621-uapi.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (c) 2024 Rockchip Electronics Co. Ltd.
|
||||
* Author: Jason Zhang <jason.zhang@rock-chips.com>
|
||||
*/
|
||||
|
||||
#ifndef _IT6621_UAPI_H
|
||||
#define _IT6621_UAPI_H
|
||||
|
||||
/* States */
|
||||
#define IT6621_EARC_IDLE 0x01
|
||||
#define IT6621_EARC_PENDING 0x02
|
||||
#define IT6621_ARC_PENDING 0x03
|
||||
#define IT6621_EARC_CONNECTED 0x04
|
||||
|
||||
/* Events */
|
||||
#define IT6621_EVENT_STATE_CHANGE 0x01 /* Event of state change, with a
|
||||
* state following up.
|
||||
*/
|
||||
|
||||
#define IT6621_EVENT_AUDIO_CAP_CHANGE 0x02 /* Event of capabilities change,
|
||||
* with a audio capabilities
|
||||
* following up.
|
||||
*/
|
||||
|
||||
int it6621_uapi_init(struct it6621_priv *priv);
|
||||
void it6621_uapi_remove(struct it6621_priv *priv);
|
||||
int it6621_uapi_msg(struct it6621_priv *priv, u8 event, void *data, size_t len);
|
||||
|
||||
#endif /* _IT6621_UAPI_H */
|
||||
210
sound/soc/codecs/it6621/it6621.h
Normal file
210
sound/soc/codecs/it6621/it6621.h
Normal file
@@ -0,0 +1,210 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (c) 2024 Rockchip Electronics Co. Ltd.
|
||||
* Author: Jason Zhang <jason.zhang@rock-chips.com>
|
||||
*/
|
||||
|
||||
#ifndef _IT6621_H
|
||||
#define _IT6621_H
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <sound/asoundef.h>
|
||||
|
||||
#define IT6621_VENDOR_ID 0x4954
|
||||
#define IT6621_DEVICE_ID 0x6621
|
||||
#define IT6621_REVISION_VARIANT_B0 0xb0
|
||||
#define IT6621_REVISION_VARIANT_C0 0xc0
|
||||
#define IT6621_REVISION_VARIANT_D0 0xd0
|
||||
|
||||
#define IT6621_ARC_START 0
|
||||
#define IT6621_EARC_CAP_CHG 1
|
||||
#define IT6621_EARC_EDID_OK 2
|
||||
#define IT6621_EARC_BCLK_OK 3
|
||||
|
||||
#define IT6621_AUDIO_START 0
|
||||
#define IT6621_AUDIO_TO_EN_DMAC 7
|
||||
|
||||
#define IT6621_CMD_WAIT_TIME_MS 1
|
||||
#define IT6621_CMD_WAIT_COUNT 10
|
||||
#define IT6621_RXCAP_BULK_LEN 16
|
||||
#define IT6621_RX_CAP_MAX_LEN 256
|
||||
#define IT6621_ADB_MAX_LEN 32
|
||||
|
||||
/**
|
||||
* struct it6621_priv - IT6621 device
|
||||
* @client: the i2c client used by the driver.
|
||||
* @dev: i2c device.
|
||||
* @mclk: master clock.
|
||||
* @hpdio: Input Hot Plus Detection.
|
||||
* @hpdio_lock: hpdio lock to protect hpdio access.
|
||||
* @rxcap_lock: rxcap lock to protect rxcap access.
|
||||
* @state: the state of IT6621 device.
|
||||
* @vid: vendor ID.
|
||||
* @devid: device ID.
|
||||
* @revid: revision ID.
|
||||
* @audio_enc: LPCM 2-ch do not support encryption.
|
||||
* @audio_src: I2S, SPDIF, TDM, DSD (DSD: EnAudGen must be TRUE for
|
||||
* Internal AudGen).
|
||||
* @audio_ch: channel number.
|
||||
* @audio_fs: sample frequency.
|
||||
* @audio_type: LPCM, NLPCM.
|
||||
* @audio_hbr: HBR.
|
||||
* @audio_input_hbr: input audio HBR.
|
||||
* @i2s_wl: 0 for 16-bit, 1 for 18-bit, 2 for 20-bit, 3 for 24-bit.
|
||||
* @i2s_hbr: I2S HBR.
|
||||
* @i2s_fmt: I2S format.
|
||||
* @i2s_nlpcm_enabled: auto by input setting.
|
||||
* @i2s_hbr_enabled: enable eARC TX I2S hbr.
|
||||
* @hbr_layb_enabled: QD980 HFR5-1-40.
|
||||
* @mch_lpcm_enabled: SL-870 5-1-30 [Multi-channel 2-ch layout] has audio output
|
||||
* @layout_2ch_enabled: use for SL-870 5-1-29 [Multi-channel 2-ch layout] =>
|
||||
* fixed by SL-870 @ FW Ver1.11 => (always FALSE)
|
||||
* @vcm_sel: tx VCM selection.
|
||||
* @force_ca: force channel allocation.
|
||||
* @force_16ch: force to 16 channels.
|
||||
* @toggle_by_edid: indicate whether HPD is toggled by EDID.
|
||||
* @rclk: RCLK frequency.
|
||||
* @aclk: ACLK frequency.
|
||||
* @bclk: BCLK frequency.
|
||||
* @rclk_sel: RCLK frequency selection.
|
||||
* @update_avg_enabled: enable update average clock detection value.
|
||||
* @cmo_opt: eARC TX common mode output enable option.
|
||||
* @force_cmo_enabled: force eARC TX common mode enable.
|
||||
* @resync_opt: eARC TX common mode resync option.
|
||||
* @ubit_opt: U-bit option.
|
||||
* @c_ch_opt: eARC TX U-bit C-Ch option.
|
||||
* @ecc_opt: eARC TX ECC option.
|
||||
* @enc_seed: eARC TX encryption seed.
|
||||
* @enc_opt: eARC TX encryption option.
|
||||
* @fixed_lcf: fixed LC frequency.
|
||||
* @bclk_inv_enabled: enable eARC BCLK inversion.
|
||||
* @sck_inv_enabled: enable I2S serial clock inversion.
|
||||
* @tck_inv_enabled: enable TDM clock inversion.
|
||||
* @mclk_inv_enabled: enable SPDIF master clock inversion.
|
||||
* @dclk_inv_enabled: enable DSD clock inversion.
|
||||
* @nxt_pkt_to_sel: eARC TX next packet timeout selection.
|
||||
* @turn_over_sel: eARC TX turn-over time selection before
|
||||
* transmitting packet, set 24 us for QD980 HFR5-1-21.
|
||||
* @hb_retry_sel: eARC TX HeartBeat retry time selection.
|
||||
* @hb_retry_enabled: enable eARC TX auto HeartBeat retry.
|
||||
* @cmd_to_enabled: indicate whether command timeout is enabled.
|
||||
* @force_arc: force TX ARC mode.
|
||||
* @enter_arc_now: enter ARC mode when initiate IT6621 device,
|
||||
* enable for standalone ARC mode.
|
||||
* @arc_enabled: enable ARC mode.
|
||||
* @earc_enabled: enable eARC mode, disable for standalone ARC mode.
|
||||
* @pkt1_enabled: enable eARC TX packet 1 using U-bit.
|
||||
* @pkt2_enabled: enable eARC TX packet 2 using U-bit.
|
||||
* @pkt3_enabled: enable eARC TX packet 3 using U-bit.
|
||||
* @events: eARC events.
|
||||
* @audio_flag: upstream's audio state, if upstream is audio on, set to 1 at
|
||||
* upstream, extern to upstream's function.
|
||||
* @hpdio_work: work to toggle hpdio.
|
||||
* @config_audio: indicate whether audio is need to be configured.
|
||||
* @force_mute: force mute.
|
||||
* @uapi_registered: indicate whether uapi is registered.
|
||||
* @rxcap: capabilities from the ARC device.
|
||||
* @adb: audio data block.
|
||||
*/
|
||||
struct it6621_priv {
|
||||
struct i2c_client *client;
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct miscdevice mdev;
|
||||
struct clk *mclk;
|
||||
struct gpio_desc *hpdio;
|
||||
struct list_head fhs;
|
||||
struct mutex fhs_lock;
|
||||
struct mutex hpdio_lock;
|
||||
struct mutex rxcap_lock;
|
||||
unsigned int state;
|
||||
unsigned int vid;
|
||||
unsigned int devid;
|
||||
unsigned int revid;
|
||||
|
||||
/* Tx Audio Option */
|
||||
unsigned int audio_enc;
|
||||
unsigned int audio_src;
|
||||
unsigned int audio_ch;
|
||||
unsigned int audio_fs;
|
||||
unsigned int audio_type;
|
||||
unsigned int audio_hbr;
|
||||
unsigned int audio_input_hbr;
|
||||
unsigned int i2s_wl;
|
||||
unsigned int i2s_hbr;
|
||||
unsigned int i2s_fmt;
|
||||
unsigned int i2s_nlpcm_enabled;
|
||||
unsigned int i2s_hbr_enabled;
|
||||
unsigned int hbr_layb_enabled;
|
||||
unsigned int mch_lpcm_enabled;
|
||||
unsigned int layout_2ch_enabled;
|
||||
unsigned int vcm_sel;
|
||||
unsigned int force_ca;
|
||||
unsigned int force_16ch;
|
||||
|
||||
/* FIXME: Need to toggle by edid? */
|
||||
unsigned int toggle_by_edid;
|
||||
unsigned int rclk;
|
||||
unsigned int aclk;
|
||||
unsigned int bclk;
|
||||
|
||||
/* Clock configurations */
|
||||
unsigned int rclk_sel;
|
||||
unsigned int update_avg_enabled;
|
||||
|
||||
unsigned int cmo_opt;
|
||||
unsigned int force_cmo_enabled;
|
||||
unsigned int resync_opt;
|
||||
unsigned int ubit_opt;
|
||||
unsigned int c_ch_opt;
|
||||
unsigned int ecc_opt;
|
||||
unsigned int enc_seed;
|
||||
unsigned int enc_opt;
|
||||
unsigned int fixed_lcf;
|
||||
|
||||
/* Clock inversion option */
|
||||
unsigned int bclk_inv_enabled;
|
||||
unsigned int sck_inv_enabled;
|
||||
unsigned int tck_inv_enabled;
|
||||
unsigned int mclk_inv_enabled;
|
||||
unsigned int dclk_inv_enabled;
|
||||
|
||||
/* DMCD option */
|
||||
unsigned int nxt_pkt_to_sel;
|
||||
unsigned int turn_over_sel;
|
||||
|
||||
/* TX CMDC option */
|
||||
unsigned int hb_retry_sel;
|
||||
unsigned int hb_retry_enabled;
|
||||
unsigned int cmd_to_enabled;
|
||||
|
||||
/* Discovery option */
|
||||
unsigned int force_arc;
|
||||
unsigned int force_earc;
|
||||
unsigned int enter_arc_now;
|
||||
unsigned int arc_enabled;
|
||||
unsigned int earc_enabled;
|
||||
|
||||
/* Loop Test option */
|
||||
unsigned int pkt1_enabled;
|
||||
unsigned int pkt2_enabled;
|
||||
unsigned int pkt3_enabled;
|
||||
|
||||
unsigned long events;
|
||||
unsigned long audio_flag;
|
||||
|
||||
struct work_struct hpdio_work;
|
||||
struct class class;
|
||||
bool config_audio;
|
||||
bool force_mute;
|
||||
bool uapi_registered;
|
||||
u8 rxcap[IT6621_RX_CAP_MAX_LEN];
|
||||
u8 adb[IT6621_ADB_MAX_LEN];
|
||||
};
|
||||
|
||||
#endif /* _IT6621_H */
|
||||
Reference in New Issue
Block a user