drivers: audio: tas6422dac: add driver
Add Texas Instruments TAS6422 DAC driver. Signed-off-by: Benjamin Lemouzy <blemouzy@centralp.fr>
This commit is contained in:
parent
cb76aab9d3
commit
75bc80d86f
|
@ -6,3 +6,4 @@ zephyr_library_sources_ifdef(CONFIG_AUDIO_TLV320DAC tlv320dac310x.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_AUDIO_MPXXDTYY mpxxdtyy.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_AUDIO_MPXXDTYY mpxxdtyy-i2s.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_AUDIO_DMIC_NRFX_PDM dmic_nrfx_pdm.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_AUDIO_TAS6422DAC tas6422dac.c)
|
||||
|
|
|
@ -29,6 +29,7 @@ module = AUDIO_CODEC
|
|||
module-str = audio codec
|
||||
source "subsys/logging/Kconfig.template.log_config"
|
||||
|
||||
source "drivers/audio/Kconfig.tas6422dac"
|
||||
source "drivers/audio/Kconfig.tlv320dac"
|
||||
|
||||
endif # AUDIO_CODEC
|
||||
|
|
11
drivers/audio/Kconfig.tas6422dac
Normal file
11
drivers/audio/Kconfig.tas6422dac
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Copyright (c) 2023 Centralp
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config AUDIO_TAS6422DAC
|
||||
bool "TAS6422 audio amplifier support"
|
||||
default y
|
||||
depends on DT_HAS_TI_TAS6422DAC_ENABLED
|
||||
select I2C
|
||||
depends on GPIO
|
||||
help
|
||||
Enable TAS6422 support on the selected board
|
379
drivers/audio/tas6422dac.c
Normal file
379
drivers/audio/tas6422dac.c
Normal file
|
@ -0,0 +1,379 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Centralp
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT ti_tas6422dac
|
||||
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
#include <zephyr/audio/codec.h>
|
||||
|
||||
#include "tas6422dac.h"
|
||||
|
||||
#define LOG_LEVEL CONFIG_AUDIO_CODEC_LOG_LEVEL
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(tas6422dac);
|
||||
|
||||
#define TAS6422DAC_MUTE_GPIO_SUPPORT DT_ANY_INST_HAS_PROP_STATUS_OKAY(mute_gpios)
|
||||
|
||||
#define CODEC_OUTPUT_VOLUME_MAX (24 * 2)
|
||||
#define CODEC_OUTPUT_VOLUME_MIN (-100 * 2)
|
||||
|
||||
struct codec_driver_config {
|
||||
struct i2c_dt_spec bus;
|
||||
#if TAS6422DAC_MUTE_GPIO_SUPPORT
|
||||
struct gpio_dt_spec mute_gpio;
|
||||
#endif /* TAS6422DAC_MUTE_GPIO_SUPPORT */
|
||||
};
|
||||
|
||||
struct codec_driver_data {
|
||||
};
|
||||
|
||||
enum tas6422dac_channel_t {
|
||||
TAS6422DAC_CHANNEL_1,
|
||||
TAS6422DAC_CHANNEL_2,
|
||||
TAS6422DAC_CHANNEL_ALL,
|
||||
TAS6422DAC_CHANNEL_UNKNOWN,
|
||||
};
|
||||
|
||||
static enum tas6422dac_channel_t audio_to_tas6422dac_channel[] = {
|
||||
[AUDIO_CHANNEL_FRONT_LEFT] = TAS6422DAC_CHANNEL_1,
|
||||
[AUDIO_CHANNEL_FRONT_RIGHT] = TAS6422DAC_CHANNEL_2,
|
||||
[AUDIO_CHANNEL_LFE] = TAS6422DAC_CHANNEL_UNKNOWN,
|
||||
[AUDIO_CHANNEL_FRONT_CENTER] = TAS6422DAC_CHANNEL_UNKNOWN,
|
||||
[AUDIO_CHANNEL_REAR_LEFT] = TAS6422DAC_CHANNEL_1,
|
||||
[AUDIO_CHANNEL_REAR_RIGHT] = TAS6422DAC_CHANNEL_2,
|
||||
[AUDIO_CHANNEL_REAR_CENTER] = TAS6422DAC_CHANNEL_UNKNOWN,
|
||||
[AUDIO_CHANNEL_SIDE_LEFT] = TAS6422DAC_CHANNEL_1,
|
||||
[AUDIO_CHANNEL_SIDE_RIGHT] = TAS6422DAC_CHANNEL_2,
|
||||
[AUDIO_CHANNEL_ALL] = TAS6422DAC_CHANNEL_ALL,
|
||||
};
|
||||
|
||||
static void codec_mute_output(const struct device *dev, enum tas6422dac_channel_t channel);
|
||||
static void codec_unmute_output(const struct device *dev, enum tas6422dac_channel_t channel);
|
||||
static void codec_write_reg(const struct device *dev, uint8_t reg, uint8_t val);
|
||||
static void codec_read_reg(const struct device *dev, uint8_t reg, uint8_t *val);
|
||||
static void codec_soft_reset(const struct device *dev);
|
||||
static int codec_configure_dai(const struct device *dev, audio_dai_cfg_t *cfg);
|
||||
static void codec_configure_output(const struct device *dev);
|
||||
static int codec_set_output_volume(const struct device *dev, enum tas6422dac_channel_t channel,
|
||||
int vol);
|
||||
|
||||
#if (LOG_LEVEL >= LOG_LEVEL_DEBUG)
|
||||
static void codec_read_all_regs(const struct device *dev);
|
||||
#define CODEC_DUMP_REGS(dev) codec_read_all_regs((dev))
|
||||
#else
|
||||
#define CODEC_DUMP_REGS(dev)
|
||||
#endif
|
||||
|
||||
static int codec_initialize(const struct device *dev)
|
||||
{
|
||||
const struct codec_driver_config *const dev_cfg = dev->config;
|
||||
|
||||
if (!device_is_ready(dev_cfg->bus.bus)) {
|
||||
LOG_ERR("I2C device not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#if TAS6422DAC_MUTE_GPIO_SUPPORT
|
||||
if (!device_is_ready(dev_cfg->mute_gpio.port)) {
|
||||
LOG_ERR("GPIO device not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif /* TAS6422DAC_MUTE_GPIO_SUPPORT */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codec_configure(const struct device *dev, struct audio_codec_cfg *cfg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (cfg->dai_type != AUDIO_DAI_TYPE_I2S) {
|
||||
LOG_ERR("dai_type must be AUDIO_DAI_TYPE_I2S");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
codec_soft_reset(dev);
|
||||
ret = codec_configure_dai(dev, &cfg->dai_cfg);
|
||||
codec_configure_output(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void codec_start_output(const struct device *dev)
|
||||
{
|
||||
codec_unmute_output(dev, TAS6422DAC_CHANNEL_ALL);
|
||||
|
||||
CODEC_DUMP_REGS(dev);
|
||||
}
|
||||
|
||||
static void codec_stop_output(const struct device *dev)
|
||||
{
|
||||
codec_mute_output(dev, TAS6422DAC_CHANNEL_ALL);
|
||||
}
|
||||
|
||||
static void codec_mute_output(const struct device *dev, enum tas6422dac_channel_t channel)
|
||||
{
|
||||
uint8_t val;
|
||||
|
||||
#if TAS6422DAC_MUTE_GPIO_SUPPORT
|
||||
const struct codec_driver_config *const dev_cfg = dev->config;
|
||||
|
||||
gpio_pin_configure_dt(&dev_cfg->mute_gpio, GPIO_OUTPUT_ACTIVE);
|
||||
#endif
|
||||
|
||||
codec_read_reg(dev, CH_STATE_CTRL_ADDR, &val);
|
||||
switch (channel) {
|
||||
case TAS6422DAC_CHANNEL_1:
|
||||
val &= ~CH_STATE_CTRL_CH1_STATE_CTRL_MASK;
|
||||
val |= CH_STATE_CTRL_CH1_STATE_CTRL(CH_STATE_CTRL_MUTE);
|
||||
break;
|
||||
case TAS6422DAC_CHANNEL_2:
|
||||
val &= ~CH_STATE_CTRL_CH2_STATE_CTRL_MASK;
|
||||
val |= CH_STATE_CTRL_CH2_STATE_CTRL(CH_STATE_CTRL_MUTE);
|
||||
break;
|
||||
case TAS6422DAC_CHANNEL_ALL:
|
||||
val &= ~(CH_STATE_CTRL_CH1_STATE_CTRL_MASK | CH_STATE_CTRL_CH2_STATE_CTRL_MASK);
|
||||
val |= CH_STATE_CTRL_CH1_STATE_CTRL(CH_STATE_CTRL_MUTE) |
|
||||
CH_STATE_CTRL_CH2_STATE_CTRL(CH_STATE_CTRL_MUTE);
|
||||
break;
|
||||
case TAS6422DAC_CHANNEL_UNKNOWN:
|
||||
default:
|
||||
LOG_ERR("Invalid codec channel %u", channel);
|
||||
return;
|
||||
}
|
||||
codec_write_reg(dev, CH_STATE_CTRL_ADDR, val);
|
||||
}
|
||||
|
||||
static void codec_unmute_output(const struct device *dev, enum tas6422dac_channel_t channel)
|
||||
{
|
||||
uint8_t val;
|
||||
|
||||
#if TAS6422DAC_MUTE_GPIO_SUPPORT
|
||||
const struct codec_driver_config *const dev_cfg = dev->config;
|
||||
|
||||
gpio_pin_configure_dt(&dev_cfg->mute_gpio, GPIO_OUTPUT_INACTIVE);
|
||||
#endif
|
||||
|
||||
codec_read_reg(dev, CH_STATE_CTRL_ADDR, &val);
|
||||
switch (channel) {
|
||||
case TAS6422DAC_CHANNEL_1:
|
||||
val &= ~CH_STATE_CTRL_CH1_STATE_CTRL_MASK;
|
||||
val |= CH_STATE_CTRL_CH1_STATE_CTRL(CH_STATE_CTRL_PLAY);
|
||||
break;
|
||||
case TAS6422DAC_CHANNEL_2:
|
||||
val &= ~CH_STATE_CTRL_CH2_STATE_CTRL_MASK;
|
||||
val |= CH_STATE_CTRL_CH2_STATE_CTRL(CH_STATE_CTRL_PLAY);
|
||||
break;
|
||||
case TAS6422DAC_CHANNEL_ALL:
|
||||
val &= ~(CH_STATE_CTRL_CH1_STATE_CTRL_MASK | CH_STATE_CTRL_CH2_STATE_CTRL_MASK);
|
||||
val |= CH_STATE_CTRL_CH1_STATE_CTRL(CH_STATE_CTRL_PLAY) |
|
||||
CH_STATE_CTRL_CH2_STATE_CTRL(CH_STATE_CTRL_PLAY);
|
||||
break;
|
||||
case TAS6422DAC_CHANNEL_UNKNOWN:
|
||||
default:
|
||||
LOG_ERR("Invalid codec channel %u", channel);
|
||||
return;
|
||||
}
|
||||
codec_write_reg(dev, CH_STATE_CTRL_ADDR, val);
|
||||
}
|
||||
|
||||
static int codec_set_property(const struct device *dev, audio_property_t property,
|
||||
audio_channel_t channel, audio_property_value_t val)
|
||||
{
|
||||
enum tas6422dac_channel_t codec_channel = audio_to_tas6422dac_channel[channel];
|
||||
|
||||
if (codec_channel == TAS6422DAC_CHANNEL_UNKNOWN) {
|
||||
LOG_ERR("Invalid channel %u", channel);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (property) {
|
||||
case AUDIO_PROPERTY_OUTPUT_VOLUME:
|
||||
return codec_set_output_volume(dev, codec_channel, val.vol);
|
||||
|
||||
case AUDIO_PROPERTY_OUTPUT_MUTE:
|
||||
if (val.mute) {
|
||||
codec_mute_output(dev, codec_channel);
|
||||
} else {
|
||||
codec_unmute_output(dev, codec_channel);
|
||||
}
|
||||
return 0;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int codec_apply_properties(const struct device *dev)
|
||||
{
|
||||
/* nothing to do because there is nothing cached */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void codec_write_reg(const struct device *dev, uint8_t reg, uint8_t val)
|
||||
{
|
||||
const struct codec_driver_config *const dev_cfg = dev->config;
|
||||
|
||||
i2c_reg_write_byte_dt(&dev_cfg->bus, reg, val);
|
||||
LOG_DBG("%s WR REG:0x%02x VAL:0x%02x", dev->name, reg, val);
|
||||
}
|
||||
|
||||
static void codec_read_reg(const struct device *dev, uint8_t reg, uint8_t *val)
|
||||
{
|
||||
const struct codec_driver_config *const dev_cfg = dev->config;
|
||||
|
||||
i2c_reg_read_byte_dt(&dev_cfg->bus, reg, val);
|
||||
LOG_DBG("%s RD REG:0x%02x VAL:0x%02x", dev->name, reg, *val);
|
||||
}
|
||||
|
||||
static void codec_soft_reset(const struct device *dev)
|
||||
{
|
||||
uint8_t val;
|
||||
|
||||
codec_read_reg(dev, MODE_CTRL_ADDR, &val);
|
||||
val |= MODE_CTRL_RESET;
|
||||
codec_write_reg(dev, MODE_CTRL_ADDR, val);
|
||||
}
|
||||
|
||||
static int codec_configure_dai(const struct device *dev, audio_dai_cfg_t *cfg)
|
||||
{
|
||||
uint8_t val;
|
||||
|
||||
codec_read_reg(dev, SAP_CTRL_ADDR, &val);
|
||||
|
||||
/* I2S mode */
|
||||
val &= ~SAP_CTRL_INPUT_FORMAT_MASK;
|
||||
val |= SAP_CTRL_INPUT_FORMAT(SAP_CTRL_INPUT_FORMAT_I2S);
|
||||
|
||||
/* Input sampling rate */
|
||||
val &= ~SAP_CTRL_INPUT_SAMPLING_RATE_MASK;
|
||||
switch (cfg->i2s.frame_clk_freq) {
|
||||
case AUDIO_PCM_RATE_44P1K:
|
||||
val |= SAP_CTRL_INPUT_SAMPLING_RATE(SAP_CTRL_INPUT_SAMPLING_RATE_44_1_KHZ);
|
||||
break;
|
||||
case AUDIO_PCM_RATE_48K:
|
||||
val |= SAP_CTRL_INPUT_SAMPLING_RATE(SAP_CTRL_INPUT_SAMPLING_RATE_48_KHZ);
|
||||
break;
|
||||
case AUDIO_PCM_RATE_96K:
|
||||
val |= SAP_CTRL_INPUT_SAMPLING_RATE(SAP_CTRL_INPUT_SAMPLING_RATE_96_KHZ);
|
||||
break;
|
||||
default:
|
||||
LOG_ERR("Invalid sampling rate %zu", cfg->i2s.frame_clk_freq);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
codec_write_reg(dev, SAP_CTRL_ADDR, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void codec_configure_output(const struct device *dev)
|
||||
{
|
||||
uint8_t val;
|
||||
|
||||
/* Overcurrent level = 1 */
|
||||
codec_read_reg(dev, MISC_CTRL_1_ADDR, &val);
|
||||
val &= ~MISC_CTRL_1_OC_CONTROL_MASK;
|
||||
codec_write_reg(dev, MISC_CTRL_1_ADDR, val);
|
||||
|
||||
/*
|
||||
* PWM frequency = 10 fs
|
||||
* Reduce PWM frequency to prevent component overtemperature
|
||||
*/
|
||||
codec_read_reg(dev, MISC_CTRL_2_ADDR, &val);
|
||||
val &= ~MISC_CTRL_2_PWM_FREQUENCY_MASK;
|
||||
val |= MISC_CTRL_2_PWM_FREQUENCY(MISC_CTRL_2_PWM_FREQUENCY_10_FS);
|
||||
codec_write_reg(dev, MISC_CTRL_2_ADDR, val);
|
||||
}
|
||||
|
||||
static int codec_set_output_volume(const struct device *dev, enum tas6422dac_channel_t channel,
|
||||
int vol)
|
||||
{
|
||||
uint8_t vol_val;
|
||||
|
||||
if ((vol > CODEC_OUTPUT_VOLUME_MAX) || (vol < CODEC_OUTPUT_VOLUME_MIN)) {
|
||||
LOG_ERR("Invalid volume %d.%d dB", vol >> 1, ((uint32_t)vol & 1) ? 5 : 0);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vol_val = vol + 0xcf;
|
||||
switch (channel) {
|
||||
case TAS6422DAC_CHANNEL_1:
|
||||
codec_write_reg(dev, CH1_VOLUME_CTRL_ADDR, CH_VOLUME_CTRL_VOLUME(vol_val));
|
||||
break;
|
||||
case TAS6422DAC_CHANNEL_2:
|
||||
codec_write_reg(dev, CH2_VOLUME_CTRL_ADDR, CH_VOLUME_CTRL_VOLUME(vol_val));
|
||||
break;
|
||||
case TAS6422DAC_CHANNEL_ALL:
|
||||
codec_write_reg(dev, CH1_VOLUME_CTRL_ADDR, CH_VOLUME_CTRL_VOLUME(vol_val));
|
||||
codec_write_reg(dev, CH2_VOLUME_CTRL_ADDR, CH_VOLUME_CTRL_VOLUME(vol_val));
|
||||
break;
|
||||
case TAS6422DAC_CHANNEL_UNKNOWN:
|
||||
default:
|
||||
LOG_ERR("Invalid codec channel %u", channel);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (LOG_LEVEL >= LOG_LEVEL_DEBUG)
|
||||
static void codec_read_all_regs(const struct device *dev)
|
||||
{
|
||||
uint8_t val;
|
||||
|
||||
codec_read_reg(dev, MODE_CTRL_ADDR, &val);
|
||||
codec_read_reg(dev, MISC_CTRL_1_ADDR, &val);
|
||||
codec_read_reg(dev, MISC_CTRL_2_ADDR, &val);
|
||||
codec_read_reg(dev, SAP_CTRL_ADDR, &val);
|
||||
codec_read_reg(dev, CH_STATE_CTRL_ADDR, &val);
|
||||
codec_read_reg(dev, CH1_VOLUME_CTRL_ADDR, &val);
|
||||
codec_read_reg(dev, CH2_VOLUME_CTRL_ADDR, &val);
|
||||
codec_read_reg(dev, DC_LDG_CTRL_1_ADDR, &val);
|
||||
codec_read_reg(dev, DC_LDG_CTRL_2_ADDR, &val);
|
||||
codec_read_reg(dev, DC_LDG_REPORT_1_ADDR, &val);
|
||||
codec_read_reg(dev, DC_LDG_REPORT_3_ADDR, &val);
|
||||
codec_read_reg(dev, CH_FAULTS_ADDR, &val);
|
||||
codec_read_reg(dev, GLOBAL_FAULTS_1_ADDR, &val);
|
||||
codec_read_reg(dev, GLOBAL_FAULTS_2_ADDR, &val);
|
||||
codec_read_reg(dev, WARNINGS_ADDR, &val);
|
||||
codec_read_reg(dev, PIN_CTRL_ADDR, &val);
|
||||
codec_read_reg(dev, MISC_CTRL_3_ADDR, &val);
|
||||
codec_read_reg(dev, ILIMIT_STATUS_ADDR, &val);
|
||||
codec_read_reg(dev, MISC_CTRL_4_ADDR, &val);
|
||||
codec_read_reg(dev, MISC_CTRL_5_ADDR, &val);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct audio_codec_api codec_driver_api = {
|
||||
.configure = codec_configure,
|
||||
.start_output = codec_start_output,
|
||||
.stop_output = codec_stop_output,
|
||||
.set_property = codec_set_property,
|
||||
.apply_properties = codec_apply_properties,
|
||||
};
|
||||
|
||||
#if TAS6422DAC_MUTE_GPIO_SUPPORT
|
||||
#define TAS6422DAC_MUTE_GPIO_INIT(n) .mute_gpio = GPIO_DT_SPEC_INST_GET(n, mute_gpios)
|
||||
#else
|
||||
#define TAS6422DAC_MUTE_GPIO_INIT(n)
|
||||
#endif /* TAS6422DAC_MUTE_GPIO_SUPPORT */
|
||||
|
||||
#define TAS6422DAC_INIT(n) \
|
||||
static struct codec_driver_data codec_device_data_##n; \
|
||||
\
|
||||
static struct codec_driver_config codec_device_config_##n = { \
|
||||
.bus = I2C_DT_SPEC_INST_GET(n), TAS6422DAC_MUTE_GPIO_INIT(n)}; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(n, codec_initialize, NULL, &codec_device_data_##n, \
|
||||
&codec_device_config_##n, POST_KERNEL, \
|
||||
CONFIG_AUDIO_CODEC_INIT_PRIORITY, &codec_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(TAS6422DAC_INIT)
|
262
drivers/audio/tas6422dac.h
Normal file
262
drivers/audio/tas6422dac.h
Normal file
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Centralp
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_DRIVERS_AUDIO_TAS6422DAC_H_
|
||||
#define ZEPHYR_DRIVERS_AUDIO_TAS6422DAC_H_
|
||||
|
||||
#include <zephyr/sys/util_macro.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Mode Control Register */
|
||||
#define MODE_CTRL_ADDR 0x00
|
||||
#define MODE_CTRL_RESET BIT(7)
|
||||
#define MODE_CTRL_RESET_MASK BIT(7)
|
||||
#define MODE_CTRL_PBTL_CH12 BIT(4)
|
||||
#define MODE_CTRL_PBTL_CH12_MASK BIT(4)
|
||||
#define MODE_CTRL_CH1_LO_MODE BIT(3)
|
||||
#define MODE_CTRL_CH1_LO_MODE_MASK BIT(3)
|
||||
#define MODE_CTRL_CH2_LO_MODE BIT(2)
|
||||
#define MODE_CTRL_CH2_LO_MODE_MASK BIT(2)
|
||||
|
||||
/* Miscellaneous Control 1 Register */
|
||||
#define MISC_CTRL_1_ADDR 0x01
|
||||
#define MISC_CTRL_1_HPF_BYPASS BIT(7)
|
||||
#define MISC_CTRL_1_HPF_BYPASS_MASK BIT(7)
|
||||
#define MISC_CTRL_1_OTW_CONTROL_MASK (BIT_MASK(2) << 5)
|
||||
#define MISC_CTRL_1_OTW_CONTROL(val) (((val) << 5) & MISC_CTRL_1_OTW_CONTROL_MASK)
|
||||
#define MISC_CTRL_1_OTW_CONTROL_140_DEGREE 0
|
||||
#define MISC_CTRL_1_OTW_CONTROL_130_DEGREE 1
|
||||
#define MISC_CTRL_1_OTW_CONTROL_120_DEGREE 2
|
||||
#define MISC_CTRL_1_OTW_CONTROL_110_DEGREE 3
|
||||
#define MISC_CTRL_1_OC_CONTROL BIT(4)
|
||||
#define MISC_CTRL_1_OC_CONTROL_MASK BIT(4)
|
||||
#define MISC_CTRL_1_VOLUME_RATE_MASK (BIT_MASK(2) << 2)
|
||||
#define MISC_CTRL_1_VOLUME_RATE(val) (((val) << 2) & MISC_CTRL_1_VOLUME_RATE_MASK)
|
||||
#define MISC_CTRL_1_VOLUME_RATE_1_STEP_EVERY_1_FSYNC 0
|
||||
#define MISC_CTRL_1_VOLUME_RATE_1_STEP_EVERY_2_FSYNC 1
|
||||
#define MISC_CTRL_1_VOLUME_RATE_1_STEP_EVERY_4_FSYNC 2
|
||||
#define MISC_CTRL_1_VOLUME_RATE_1_STEP_EVERY_8_FSYNC 3
|
||||
#define MISC_CTRL_1_GAIN_MASK BIT_MASK(2)
|
||||
#define MISC_CTRL_1_GAIN(val) ((val) & MISC_CTRL_1_GAIN_MASK)
|
||||
#define MISC_CTRL_1_GAIN_7_5_V_PEAK_OUTPUT 0
|
||||
#define MISC_CTRL_1_GAIN_15_V_PEAK_OUTPUT 1
|
||||
#define MISC_CTRL_1_GAIN_21_V_PEAK_OUTPUT 2
|
||||
#define MISC_CTRL_1_GAIN_29_V_PEAK_OUTPUT 3
|
||||
|
||||
/* Miscellaneous Control 2 Register */
|
||||
#define MISC_CTRL_2_ADDR 0x02
|
||||
#define MISC_CTRL_2_PWM_FREQUENCY_MASK (BIT_MASK(3) << 4)
|
||||
#define MISC_CTRL_2_PWM_FREQUENCY(val) (((val) << 4) & MISC_CTRL_2_PWM_FREQUENCY_MASK)
|
||||
#define MISC_CTRL_2_PWM_FREQUENCY_8_FS 0
|
||||
#define MISC_CTRL_2_PWM_FREQUENCY_10_FS 1
|
||||
#define MISC_CTRL_2_PWM_FREQUENCY_38_FS 5
|
||||
#define MISC_CTRL_2_PWM_FREQUENCY_44_FS 6
|
||||
#define MISC_CTRL_2_PWM_FREQUENCY_48_FS 7
|
||||
#define MISC_CTRL_2_SDM_OSR BIT(2)
|
||||
#define MISC_CTRL_2_SDM_OSR_MASK BIT(2)
|
||||
#define MISC_CTRL_2_OUTPUT_PHASE_MASK BIT_MASK(2)
|
||||
#define MISC_CTRL_2_OUTPUT_PHASE(val) ((val) & MISC_CTRL_2_OUTPUT_PHASE_MASK)
|
||||
#define MISC_CTRL_2_OUTPUT_PHASE_210_DEGREES 1
|
||||
#define MISC_CTRL_2_OUTPUT_PHASE_225_DEGREES 2
|
||||
#define MISC_CTRL_2_OUTPUT_PHASE_240_DEGREES 3
|
||||
|
||||
/* Serial Audio-Port Control Register */
|
||||
#define SAP_CTRL_ADDR 0x03
|
||||
#define SAP_CTRL_INPUT_SAMPLING_RATE_MASK (BIT_MASK(2) << 6)
|
||||
#define SAP_CTRL_INPUT_SAMPLING_RATE(val) (((val) << 6) & SAP_CTRL_INPUT_SAMPLING_RATE_MASK)
|
||||
#define SAP_CTRL_INPUT_SAMPLING_RATE_44_1_KHZ 0
|
||||
#define SAP_CTRL_INPUT_SAMPLING_RATE_48_KHZ 1
|
||||
#define SAP_CTRL_INPUT_SAMPLING_RATE_96_KHZ 2
|
||||
#define SAP_CTRL_TDM_SLOT_SELECT BIT(5)
|
||||
#define SAP_CTRL_TDM_SLOT_SELECT_MASK BIT(5)
|
||||
#define SAP_CTRL_TDM_SLOT_SIZE BIT(4)
|
||||
#define SAP_CTRL_TDM_SLOT_SIZE_MASK BIT(4)
|
||||
#define SAP_CTRL_TDM_SLOT_SELECT_2 BIT(3)
|
||||
#define SAP_CTRL_TDM_SLOT_SELECT_2_MASK BIT(3)
|
||||
#define SAP_CTRL_INPUT_FORMAT_MASK BIT_MASK(3)
|
||||
#define SAP_CTRL_INPUT_FORMAT(val) ((val) & SAP_CTRL_INPUT_FORMAT_MASK)
|
||||
#define SAP_CTRL_INPUT_FORMAT_24_BITS_RIGHT 0
|
||||
#define SAP_CTRL_INPUT_FORMAT_20_BITS_RIGHT 1
|
||||
#define SAP_CTRL_INPUT_FORMAT_18_BITS_RIGHT 2
|
||||
#define SAP_CTRL_INPUT_FORMAT_16_BITS_RIGHT 3
|
||||
#define SAP_CTRL_INPUT_FORMAT_I2S 4
|
||||
#define SAP_CTRL_INPUT_FORMAT_LEFT 5
|
||||
#define SAP_CTRL_INPUT_FORMAT_DSP 6
|
||||
|
||||
/* Channel State Control Register */
|
||||
#define CH_STATE_CTRL_ADDR 0x04
|
||||
#define CH_STATE_CTRL_CH1_STATE_CTRL_MASK (BIT_MASK(2) << 6)
|
||||
#define CH_STATE_CTRL_CH1_STATE_CTRL(val) (((val) << 6) & CH_STATE_CTRL_CH1_STATE_CTRL_MASK)
|
||||
#define CH_STATE_CTRL_CH2_STATE_CTRL_MASK (BIT_MASK(2) << 4)
|
||||
#define CH_STATE_CTRL_CH2_STATE_CTRL(val) (((val) << 4) & CH_STATE_CTRL_CH2_STATE_CTRL_MASK)
|
||||
#define CH_STATE_CTRL_PLAY 0
|
||||
#define CH_STATE_CTRL_HIZ 1
|
||||
#define CH_STATE_CTRL_MUTE 2
|
||||
#define CH_STATE_CTRL_DC_LOAD 3
|
||||
|
||||
/* Channel 1 and 2 Volume Control Registers */
|
||||
#define CH1_VOLUME_CTRL_ADDR 0x05
|
||||
#define CH2_VOLUME_CTRL_ADDR 0x06
|
||||
#define CH_VOLUME_CTRL_VOLUME_MASK BIT_MASK(8)
|
||||
#define CH_VOLUME_CTRL_VOLUME(val) ((val) & CH_VOLUME_CTRL_VOLUME_MASK)
|
||||
|
||||
/* DC Load Diagnostic Control 1 Register */
|
||||
#define DC_LDG_CTRL_1_ADDR 0x09
|
||||
#define DC_LDG_CTRL_1_ABORT BIT(7)
|
||||
#define DC_LDG_CTRL_1_ABORT_MASK BIT(7)
|
||||
#define DC_LDG_CTRL_1_DOUBLE_RAMP BIT(6)
|
||||
#define DC_LDG_CTRL_1_DOUBLE_RAMP_MASK BIT(6)
|
||||
#define DC_LDG_CTRL_1_DOUBLE_SETTLE BIT(5)
|
||||
#define DC_LDG_CTRL_1_DOUBLE_SETTLE_MASK BIT(5)
|
||||
#define DC_LDG_CTRL_1_LO_ENABLE BIT(1)
|
||||
#define DC_LDG_CTRL_1_LO_ENABLE_MASK BIT(1)
|
||||
#define DC_LDG_CTRL_1_BYPASS BIT(0)
|
||||
#define DC_LDG_CTRL_1_BYPASS_MASK BIT(0)
|
||||
|
||||
/* DC Load Diagnostic Control 2 Register */
|
||||
#define DC_LDG_CTRL_2_ADDR 0x0A
|
||||
#define DC_LDG_CTRL_2_CH1_SL_MASK (BIT_MASK(4) << 4)
|
||||
#define DC_LDG_CTRL_2_CH1_SL(val) (((val) << 4) & DC_LDG_CTRL_2_CH1_SL_MASK)
|
||||
#define DC_LDG_CTRL_2_CH2_SL_MASK BIT_MASK(4)
|
||||
#define DC_LDG_CTRL_2_CH2_SL(val) ((val) & DC_LDG_CTRL_2_CH2_SL_MASK)
|
||||
|
||||
/* DC Load Diagnostics Report 1 */
|
||||
#define DC_LDG_REPORT_1_ADDR 0x0C
|
||||
#define DC_LDG_REPORT_1_CH1_S2G BIT(7)
|
||||
#define DC_LDG_REPORT_1_CH1_S2G_MASK BIT(7)
|
||||
#define DC_LDG_REPORT_1_CH1_S2P BIT(6)
|
||||
#define DC_LDG_REPORT_1_CH1_S2P_MASK BIT(6)
|
||||
#define DC_LDG_REPORT_1_CH1_OL BIT(5)
|
||||
#define DC_LDG_REPORT_1_CH1_OL_MASK BIT(5)
|
||||
#define DC_LDG_REPORT_1_CH1_SL BIT(4)
|
||||
#define DC_LDG_REPORT_1_CH1_SL_MASK BIT(4)
|
||||
#define DC_LDG_REPORT_1_CH2_S2G BIT(3)
|
||||
#define DC_LDG_REPORT_1_CH2_S2G_MASK BIT(3)
|
||||
#define DC_LDG_REPORT_1_CH2_S2P BIT(2)
|
||||
#define DC_LDG_REPORT_1_CH2_S2P_MASK BIT(2)
|
||||
#define DC_LDG_REPORT_1_CH2_OL BIT(1)
|
||||
#define DC_LDG_REPORT_1_CH2_OL_MASK BIT(1)
|
||||
#define DC_LDG_REPORT_1_CH2_SL BIT(0)
|
||||
#define DC_LDG_REPORT_1_CH2_SL_MASK BIT(0)
|
||||
|
||||
/* DC Load Diagnostics Report 3 */
|
||||
#define DC_LDG_REPORT_3_ADDR 0x0E
|
||||
#define DC_LDG_REPORT_3_CH1_LO BIT(3)
|
||||
#define DC_LDG_REPORT_3_CH1_LO_MASK BIT(3)
|
||||
#define DC_LDG_REPORT_3_CH2_LO BIT(2)
|
||||
#define DC_LDG_REPORT_3_CH2_LO_MASK BIT(2)
|
||||
|
||||
/* Channel Faults Register */
|
||||
#define CH_FAULTS_ADDR 0x10
|
||||
#define CH_FAULTS_CH1_OC BIT(7)
|
||||
#define CH_FAULTS_CH1_OC_MASK BIT(7)
|
||||
#define CH_FAULTS_CH2_OC BIT(6)
|
||||
#define CH_FAULTS_CH2_OC_MASK BIT(6)
|
||||
#define CH_FAULTS_CH1_DC BIT(3)
|
||||
#define CH_FAULTS_CH1_DC_MASK BIT(3)
|
||||
#define CH_FAULTS_CH2_DC BIT(2)
|
||||
#define CH_FAULTS_CH2_DC_MASK BIT(2)
|
||||
|
||||
/* Global Faults 1 Register */
|
||||
#define GLOBAL_FAULTS_1_ADDR 0x11
|
||||
#define GLOBAL_FAULTS_1_INVALID_CLOCK BIT(4)
|
||||
#define GLOBAL_FAULTS_1_INVALID_CLOCK_MASK BIT(4)
|
||||
#define GLOBAL_FAULTS_1_PVDD_OV BIT(3)
|
||||
#define GLOBAL_FAULTS_1_PVDD_OV_MASK BIT(3)
|
||||
#define GLOBAL_FAULTS_1_VBAT_OV BIT(2)
|
||||
#define GLOBAL_FAULTS_1_VBAT_OV_MASK BIT(2)
|
||||
#define GLOBAL_FAULTS_1_PVDD_UV BIT(1)
|
||||
#define GLOBAL_FAULTS_1_PVDD_UV_MASK BIT(1)
|
||||
#define GLOBAL_FAULTS_1_VBAT_UV BIT(0)
|
||||
#define GLOBAL_FAULTS_1_VBAT_UV_MASK BIT(0)
|
||||
|
||||
/* Global Faults 2 Register */
|
||||
#define GLOBAL_FAULTS_2_ADDR 0x12
|
||||
#define GLOBAL_FAULTS_2_OTSD BIT(4)
|
||||
#define GLOBAL_FAULTS_2_OTSD_MASK BIT(4)
|
||||
#define GLOBAL_FAULTS_2_CH1_OTSD BIT(3)
|
||||
#define GLOBAL_FAULTS_2_CH1_OTSD_MASK BIT(3)
|
||||
#define GLOBAL_FAULTS_2_CH2_OTSD BIT(2)
|
||||
#define GLOBAL_FAULTS_2_CH2_OTSD_MASK BIT(2)
|
||||
|
||||
/* Warnings Register */
|
||||
#define WARNINGS_ADDR 0x13
|
||||
#define WARNINGS_VDD_POR BIT(5)
|
||||
#define WARNINGS_VDD_POR_MASK BIT(5)
|
||||
#define WARNINGS_OTW BIT(4)
|
||||
#define WARNINGS_OTW_MASK BIT(4)
|
||||
#define WARNINGS_OTW_CH1 BIT(3)
|
||||
#define WARNINGS_OTW_CH1_MASK BIT(3)
|
||||
#define WARNINGS_OTW_CH2 BIT(2)
|
||||
#define WARNINGS_OTW_CH2_MASK BIT(2)
|
||||
|
||||
/* Pin Control Register */
|
||||
#define PIN_CTRL_ADDR 0x14
|
||||
#define PIN_CTRL_MASK_OC BIT(7)
|
||||
#define PIN_CTRL_MASK_OC_MASK BIT(7)
|
||||
#define PIN_CTRL_MASK_OTSD BIT(6)
|
||||
#define PIN_CTRL_MASK_OTSD_MASK BIT(6)
|
||||
#define PIN_CTRL_MASK_UV BIT(5)
|
||||
#define PIN_CTRL_MASK_UV_MASK BIT(5)
|
||||
#define PIN_CTRL_MASK_OV BIT(4)
|
||||
#define PIN_CTRL_MASK_OV_MASK BIT(4)
|
||||
#define PIN_CTRL_MASK_DC BIT(3)
|
||||
#define PIN_CTRL_MASK_DC_MASK BIT(3)
|
||||
#define PIN_CTRL_MASK_ILIMIT BIT(2)
|
||||
#define PIN_CTRL_MASK_ILIMIT_MASK BIT(2)
|
||||
#define PIN_CTRL_MASK_CLIP BIT(1)
|
||||
#define PIN_CTRL_MASK_CLIP_MASK BIT(1)
|
||||
#define PIN_CTRL_MASK_OTW BIT(0)
|
||||
#define PIN_CTRL_MASK_OTW_MASK BIT(0)
|
||||
|
||||
/* Miscellaneous Control 3 Register */
|
||||
#define MISC_CTRL_3_ADDR 0x21
|
||||
#define MISC_CTRL_3_CLEAR_FAULT BIT(7)
|
||||
#define MISC_CTRL_3_CLEAR_FAULT_MASK BIT(7)
|
||||
#define MISC_CTRL_3_PBTL_CH_SEL BIT(6)
|
||||
#define MISC_CTRL_3_PBTL_CH_SEL_MASK BIT(6)
|
||||
#define MISC_CTRL_3_MASK_ILIMIT BIT(5)
|
||||
#define MISC_CTRL_3_MASK_ILIMIT_MASK BIT(5)
|
||||
#define MISC_CTRL_3_OTSD_AUTO_RECOVERY BIT(3)
|
||||
#define MISC_CTRL_3_OTSD_AUTO_RECOVERY_MASK BIT(3)
|
||||
|
||||
/* ILIMIT Status Register */
|
||||
#define ILIMIT_STATUS_ADDR 0x25
|
||||
#define ILIMIT_STATUS_CH2_ILIMIT_WARN BIT(1)
|
||||
#define ILIMIT_STATUS_CH2_ILIMIT_WARN_MASK BIT(1)
|
||||
#define ILIMIT_STATUS_CH1_ILIMIT_WARN BIT(0)
|
||||
#define ILIMIT_STATUS_CH1_ILIMIT_WARN_MASK BIT(0)
|
||||
|
||||
/* Miscellaneous Control 4 Register */
|
||||
#define MISC_CTRL_4_ADDR 0x26
|
||||
#define MISC_CTRL_4_HPF_CORNER_MASK BIT_MASK(3)
|
||||
#define MISC_CTRL_4_HPF_CORNER(val) ((val) & MISC_CTRL_4_HPF_CORNER_MASK)
|
||||
#define MISC_CTRL_4_HPF_CORNER_3_7_HZ 0
|
||||
#define MISC_CTRL_4_HPF_CORNER_7_4_HZ 1
|
||||
#define MISC_CTRL_4_HPF_CORNER_15_HZ 2
|
||||
#define MISC_CTRL_4_HPF_CORNER_30_HZ 3
|
||||
#define MISC_CTRL_4_HPF_CORNER_59_HZ 4
|
||||
#define MISC_CTRL_4_HPF_CORNER_118_HZ 5
|
||||
#define MISC_CTRL_4_HPF_CORNER_235_HZ 6
|
||||
#define MISC_CTRL_4_HPF_CORNER_463_HZ 7
|
||||
|
||||
/* Miscellaneous Control 5 Register */
|
||||
#define MISC_CTRL_5_ADDR 0x28
|
||||
#define MISC_CTRL_5_SS_BW_SEL BIT(7)
|
||||
#define MISC_CTRL_5_SS_BW_SEL_MASK BIT(7)
|
||||
#define MISC_CTRL_5_SS_DIV2 BIT(6)
|
||||
#define MISC_CTRL_5_SS_DIV2_MASK BIT(6)
|
||||
#define MISC_CTRL_5_PHASE_SEL_MSB BIT(5)
|
||||
#define MISC_CTRL_5_PHASE_SEL_MSB_MASK BIT(5)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_AUDIO_TAS6422DAC_H_ */
|
12
dts/bindings/audio/ti,tas6422dac.yaml
Normal file
12
dts/bindings/audio/ti,tas6422dac.yaml
Normal file
|
@ -0,0 +1,12 @@
|
|||
# Copyright (c) 2023 Centralp
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: Texas Instruments TAS6422 Audio Amplifier
|
||||
|
||||
compatible: "ti,tas6422dac"
|
||||
|
||||
include: i2c-device.yaml
|
||||
|
||||
properties:
|
||||
mute-gpios:
|
||||
type: phandle-array
|
Loading…
Reference in a new issue