audio: codec: Add driver for MAX98091 codec
This patch adds a minimal driver for the MAX98091 audio codec. Currently, playback functionality is supported. Co-developed-by: Rutvij Trivedi <rutvij.trivedi@siliconsignals.io> Signed-off-by: Rutvij Trivedi <rutvij.trivedi@siliconsignals.io> Co-developed-by: Tarang Raval <tarang.raval@siliconsignals.io> Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io> Signed-off-by: Silicon Signals <siliconsignalsforgit@gmail.com>
This commit is contained in:
parent
6231b43435
commit
ba36bf6c0a
6 changed files with 567 additions and 0 deletions
|
@ -14,3 +14,4 @@ zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_WM8904 wm8904.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_WM8962 wm8962.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_CS43L22 cs43l22.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_PCM1681 pcm1681.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_MAX98091 max98091.c)
|
||||
|
|
|
@ -36,6 +36,7 @@ module-str = audio codec
|
|||
source "subsys/logging/Kconfig.template.log_config"
|
||||
|
||||
source "drivers/audio/Kconfig.cs43l22"
|
||||
source "drivers/audio/Kconfig.max98091"
|
||||
source "drivers/audio/Kconfig.pcm1681"
|
||||
source "drivers/audio/Kconfig.tas6422dac"
|
||||
source "drivers/audio/Kconfig.tlv320aic3110"
|
||||
|
|
10
drivers/audio/Kconfig.max98091
Normal file
10
drivers/audio/Kconfig.max98091
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Copyright (c) 2025 Silicon Signals Pvt. Ltd.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config AUDIO_CODEC_MAX98091
|
||||
bool "Maxim MAX98091 codec support"
|
||||
default y
|
||||
select I2C
|
||||
depends on DT_HAS_MAXIM_MAX98091_ENABLED
|
||||
help
|
||||
Enable support for the MAX98091 I2S codec via I2C.
|
326
drivers/audio/max98091.c
Normal file
326
drivers/audio/max98091.c
Normal file
|
@ -0,0 +1,326 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright (c) 2025 Silicon Signals Pvt. Ltd.
|
||||
* Author: Rutvij Trivedi <rutvij.trivedi@siliconsignals.io>
|
||||
* Author: Tarang Raval <tarang.raval@siliconsignals.io>
|
||||
*/
|
||||
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
#include <zephyr/audio/codec.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include "max98091.h"
|
||||
|
||||
LOG_MODULE_REGISTER(maxim_max98091);
|
||||
|
||||
#define DT_DRV_COMPAT maxim_max98091
|
||||
|
||||
struct max98091_config {
|
||||
struct i2c_dt_spec i2c;
|
||||
uint32_t mclk_freq;
|
||||
};
|
||||
|
||||
static void max98091_write_reg(const struct device *dev, uint8_t reg, uint8_t val)
|
||||
{
|
||||
const struct max98091_config *const dev_cfg = dev->config;
|
||||
|
||||
i2c_reg_write_byte_dt(&dev_cfg->i2c, reg, val);
|
||||
}
|
||||
|
||||
static void max98091_read_reg(const struct device *dev, uint8_t reg, uint8_t *val)
|
||||
{
|
||||
const struct max98091_config *const dev_cfg = dev->config;
|
||||
|
||||
i2c_reg_read_byte_dt(&dev_cfg->i2c, reg, val);
|
||||
}
|
||||
|
||||
static void max98091_update_reg(const struct device *dev, uint8_t reg, uint8_t mask, uint8_t val)
|
||||
{
|
||||
const struct max98091_config *const dev_cfg = dev->config;
|
||||
|
||||
i2c_reg_update_byte_dt(&dev_cfg->i2c, reg, mask, val);
|
||||
}
|
||||
|
||||
static void max98091_soft_reset(const struct device *dev)
|
||||
{
|
||||
max98091_write_reg(dev, M98091_REG_SOFTWARE_RESET, 0x01);
|
||||
k_msleep(20);
|
||||
}
|
||||
|
||||
/* Configuration Functions */
|
||||
static int max98091_protocol_config(const struct device *dev, audio_dai_type_t dai_type)
|
||||
{
|
||||
uint8_t fmt_reg = 0;
|
||||
|
||||
switch (dai_type) {
|
||||
case AUDIO_DAI_TYPE_I2S:
|
||||
fmt_reg |= M98091_I2S_S_MASK;
|
||||
break;
|
||||
case AUDIO_DAI_TYPE_LEFT_JUSTIFIED:
|
||||
fmt_reg |= M98091_LJ_S_MASK;
|
||||
break;
|
||||
case AUDIO_DAI_TYPE_RIGHT_JUSTIFIED:
|
||||
fmt_reg |= M98091_RJ_S_MASK;
|
||||
break;
|
||||
default:
|
||||
LOG_ERR("Unsupported DAI type: %d", dai_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
max98091_write_reg(dev, M98091_REG_DAI_INTERFACE, fmt_reg);
|
||||
LOG_DBG("Protocol configured: 0x%02x", fmt_reg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max98091_audio_fmt_config(const struct device *dev, audio_dai_cfg_t *cfg)
|
||||
{
|
||||
uint8_t sample_rate;
|
||||
uint8_t channels;
|
||||
uint8_t word_size;
|
||||
|
||||
switch (cfg->i2s.frame_clk_freq) {
|
||||
case 8000:
|
||||
sample_rate = M98091_SR_8K_MASK;
|
||||
break;
|
||||
case 16000:
|
||||
sample_rate = M98091_SR_16K_MASK;
|
||||
break;
|
||||
case 32000:
|
||||
sample_rate = M98091_SR_32K_MASK;
|
||||
break;
|
||||
case 44100:
|
||||
sample_rate = M98091_SR_44K1_MASK;
|
||||
break;
|
||||
case 48000:
|
||||
sample_rate = M98091_SR_48K_MASK;
|
||||
break;
|
||||
case 96000:
|
||||
sample_rate = M98091_SR_96K_MASK;
|
||||
break;
|
||||
default:
|
||||
LOG_ERR("Unsupported sample rate: %d", cfg->i2s.frame_clk_freq);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
max98091_write_reg(dev, M98091_REG_QUICK_SAMPLE_RATE, sample_rate);
|
||||
|
||||
switch (cfg->i2s.channels) {
|
||||
case 1: /* Mono */
|
||||
channels = 1;
|
||||
break;
|
||||
case 2: /* Stereo */
|
||||
channels = 0;
|
||||
break;
|
||||
default:
|
||||
LOG_ERR("Unsupported channels: %d", cfg->i2s.channels);
|
||||
return -EINVAL;
|
||||
}
|
||||
max98091_update_reg(dev, M98091_REG_IO_CONFIGURATION, M98091_DMONO_MASK, channels);
|
||||
|
||||
switch (cfg->i2s.word_size) {
|
||||
case 16:
|
||||
word_size = M98091_16B_WS;
|
||||
break;
|
||||
default:
|
||||
LOG_ERR("Word size %d bits not supported; falling back to 16 bits",
|
||||
cfg->i2s.word_size);
|
||||
word_size = M98091_16B_WS;
|
||||
break;
|
||||
}
|
||||
max98091_update_reg(dev, M98091_REG_INTERFACE_FORMAT, M98091_WS_MASK, word_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void max98091_set_system_clock(const struct device *dev, uint32_t mclk_freq)
|
||||
{
|
||||
uint8_t psclk;
|
||||
|
||||
if (mclk_freq >= 10000000 && mclk_freq <= 20000000) {
|
||||
psclk = M98091_PSCLK_DIV1;
|
||||
} else if (mclk_freq > 20000000 && mclk_freq <= 40000000) {
|
||||
psclk = M98091_PSCLK_DIV2;
|
||||
} else if (mclk_freq > 40000000 && mclk_freq <= 60000000) {
|
||||
psclk = M98091_PSCLK_DIV4;
|
||||
} else {
|
||||
LOG_ERR("Invalid MCLK frequency: %u", mclk_freq);
|
||||
return;
|
||||
}
|
||||
max98091_write_reg(dev, M98091_REG_SYSTEM_CLOCK, psclk);
|
||||
LOG_DBG("System clock set: PSCLK=0x%02x", psclk);
|
||||
|
||||
max98091_update_reg(dev, M98091_REG_MASTER_MODE, M98091_MAS_MASK, 0);
|
||||
}
|
||||
|
||||
static int max98091_set_volume_or_mute(const struct device *dev, audio_channel_t channel, int value,
|
||||
bool is_volume)
|
||||
{
|
||||
uint8_t hp_mask = is_volume ? M98091_HPVOLL_MASK : M98091_HPLM_MASK;
|
||||
uint8_t spk_mask = is_volume ? M98091_SPVOLL_MASK : M98091_SPLM_MASK;
|
||||
|
||||
switch (channel) {
|
||||
case AUDIO_CHANNEL_FRONT_LEFT:
|
||||
max98091_update_reg(dev, M98091_REG_LEFT_SPK_VOLUME, spk_mask, value);
|
||||
return 0;
|
||||
|
||||
case AUDIO_CHANNEL_FRONT_RIGHT:
|
||||
max98091_update_reg(dev, M98091_REG_RIGHT_SPK_VOLUME, spk_mask, value);
|
||||
return 0;
|
||||
|
||||
case AUDIO_CHANNEL_HEADPHONE_LEFT:
|
||||
max98091_update_reg(dev, M98091_REG_LEFT_HP_VOLUME, hp_mask, value);
|
||||
return 0;
|
||||
|
||||
case AUDIO_CHANNEL_HEADPHONE_RIGHT:
|
||||
max98091_update_reg(dev, M98091_REG_RIGHT_HP_VOLUME, hp_mask, value);
|
||||
return 0;
|
||||
|
||||
case AUDIO_CHANNEL_ALL:
|
||||
max98091_update_reg(dev, M98091_REG_LEFT_SPK_VOLUME, spk_mask, value);
|
||||
max98091_update_reg(dev, M98091_REG_RIGHT_SPK_VOLUME, spk_mask, value);
|
||||
max98091_update_reg(dev, M98091_REG_LEFT_HP_VOLUME, hp_mask, value);
|
||||
max98091_update_reg(dev, M98091_REG_RIGHT_HP_VOLUME, hp_mask, value);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int max98091_out_volume_config(const struct device *dev, audio_channel_t channel, int volume)
|
||||
{
|
||||
return max98091_set_volume_or_mute(dev, channel, volume, true);
|
||||
}
|
||||
|
||||
static int max98091_out_mute_config(const struct device *dev, audio_channel_t channel, bool mute)
|
||||
{
|
||||
return max98091_set_volume_or_mute(dev, channel, mute, false);
|
||||
}
|
||||
|
||||
/* Audio Path Configuration */
|
||||
static void max98091_configure_output(const struct device *dev)
|
||||
{
|
||||
max98091_update_reg(dev, M98091_REG_IO_CONFIGURATION, M98091_SDIEN_MASK, M98091_SDIEN_MASK);
|
||||
|
||||
max98091_write_reg(dev, M98091_REG_LEFT_SPK_MIXER, M98091_MIXSPL_DACL_MASK);
|
||||
max98091_write_reg(dev, M98091_REG_RIGHT_SPK_MIXER, M98091_MIXSPR_DACR_MASK);
|
||||
|
||||
/* select DAC only source */
|
||||
max98091_write_reg(dev, M98091_REG_HP_CONTROL, 0x00);
|
||||
|
||||
/* M98091_HPREN_MASK, M98091_HPLEN_MASK, M98091_SPREN_MASK,
|
||||
* M98091_SPLEN_MASK, M98091_DAREN_MASK, M98091_DALEN_MASK
|
||||
*/
|
||||
max98091_write_reg(dev, M98091_REG_OUTPUT_ENABLE, 0xf3);
|
||||
|
||||
max98091_out_volume_config(dev, AUDIO_CHANNEL_ALL, M98091_DEFAULT_VOLUME);
|
||||
max98091_out_mute_config(dev, AUDIO_CHANNEL_ALL, false);
|
||||
}
|
||||
|
||||
static void max98091_start_output(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
}
|
||||
|
||||
static void max98091_stop_output(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
}
|
||||
|
||||
static int max98091_set_property(const struct device *dev, audio_property_t property,
|
||||
audio_channel_t channel, audio_property_value_t val)
|
||||
{
|
||||
switch (property) {
|
||||
case AUDIO_PROPERTY_OUTPUT_VOLUME:
|
||||
max98091_out_volume_config(dev, channel, val.vol);
|
||||
case AUDIO_PROPERTY_OUTPUT_MUTE:
|
||||
max98091_out_mute_config(dev, channel, val.mute);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int max98091_configure(const struct device *dev, struct audio_codec_cfg *cfg)
|
||||
{
|
||||
const struct max98091_config *const dev_cfg = dev->config;
|
||||
|
||||
if (cfg->dai_type >= AUDIO_DAI_TYPE_INVALID) {
|
||||
LOG_ERR("dai_type not supported");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
max98091_soft_reset(dev);
|
||||
|
||||
if (cfg->dai_route == AUDIO_ROUTE_BYPASS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Put the audio codec into shutdown mode */
|
||||
max98091_write_reg(dev, M98091_REG_DEVICE_SHUTDOWN, 0x00);
|
||||
|
||||
max98091_write_reg(dev, M98091_REG_DAC_CONTROL, 0x00);
|
||||
|
||||
max98091_write_reg(dev, M98091_REG_TDM_CONTROL, 0x00);
|
||||
|
||||
/* Set DLY = 1 to conform to the I2S standard.
|
||||
* DLY is only effective when TDM = 0
|
||||
*/
|
||||
max98091_write_reg(dev, M98091_REG_INTERFACE_FORMAT, M98091_DLY_MASK);
|
||||
|
||||
/* Configure system clock */
|
||||
max98091_set_system_clock(dev, dev_cfg->mclk_freq);
|
||||
|
||||
max98091_protocol_config(dev, cfg->dai_type);
|
||||
max98091_audio_fmt_config(dev, &cfg->dai_cfg);
|
||||
|
||||
/* Configure audio paths based on route */
|
||||
switch (cfg->dai_route) {
|
||||
case AUDIO_ROUTE_PLAYBACK:
|
||||
max98091_configure_output(dev);
|
||||
break;
|
||||
default:
|
||||
LOG_DBG("Unsupported audio route selected");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Bring the audio codec out of shutdown mode */
|
||||
max98091_write_reg(dev, M98091_REG_DEVICE_SHUTDOWN, M98091_SHDNN_MASK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct audio_codec_api max98091_api = {
|
||||
.configure = max98091_configure,
|
||||
.start_output = max98091_start_output,
|
||||
.stop_output = max98091_stop_output,
|
||||
.set_property = max98091_set_property,
|
||||
};
|
||||
|
||||
static int max98091_init(const struct device *dev)
|
||||
{
|
||||
const struct max98091_config *cfg_tan = dev->config;
|
||||
uint8_t device_id;
|
||||
|
||||
if (!i2c_is_ready_dt(&cfg_tan->i2c)) {
|
||||
LOG_ERR("I2C bus not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
max98091_read_reg(dev, M98091_REG_REVISION_ID, &device_id);
|
||||
if (device_id >= M98091_REVA && (device_id <= M98091_REVA + 0x0f)) {
|
||||
LOG_INF("MAX98091 Device ID: 0x%02X", device_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOG_ERR("Invalid MAX98091 Device ID: 0x%02X", device_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#define MAX98091_INIT(inst) \
|
||||
static const struct max98091_config max98091_config_##inst = { \
|
||||
.i2c = I2C_DT_SPEC_INST_GET(inst), \
|
||||
.mclk_freq = DT_INST_PROP(inst, mclk_frequency)}; \
|
||||
DEVICE_DT_INST_DEFINE(inst, max98091_init, NULL, NULL, &max98091_config_##inst, \
|
||||
POST_KERNEL, CONFIG_AUDIO_CODEC_INIT_PRIORITY, &max98091_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(MAX98091_INIT)
|
213
drivers/audio/max98091.h
Normal file
213
drivers/audio/max98091.h
Normal file
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright (c) 2025 Silicon Signals Pvt. Ltd.
|
||||
* Author: Rutvij Trivedi <rutvij.trivedi@siliconsignals.io>
|
||||
* Author: Tarang Raval <tarang.raval@siliconsignals.io>
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_CODEC_MAX98091_H_
|
||||
#define ZEPHYR_INCLUDE_CODEC_MAX98091_H_
|
||||
|
||||
/*
|
||||
* MAX98091 Register Definitions
|
||||
*/
|
||||
|
||||
#define M98091_REG_SOFTWARE_RESET 0x00
|
||||
#define M98091_REG_DEVICE_STATUS 0x01
|
||||
#define M98091_REG_JACK_STATUS 0x02
|
||||
#define M98091_REG_INTERRUPT_S 0x03
|
||||
#define M98091_REG_MASTER_CLOCK 0x04
|
||||
#define M98091_REG_QUICK_SAMPLE_RATE 0x05
|
||||
#define M98091_REG_DAI_INTERFACE 0x06
|
||||
#define M98091_REG_DAC_PATH 0x07
|
||||
#define M98091_REG_MIC_DIRECT_TO_ADC 0x08
|
||||
#define M98091_REG_LINE_TO_ADC 0x09
|
||||
#define M98091_REG_ANALOG_MIC_LOOP 0x0A
|
||||
#define M98091_REG_ANALOG_LINE_LOOP 0x0B
|
||||
#define M98091_REG_RESERVED 0x0C
|
||||
#define M98091_REG_LINE_INPUT_CONFIG 0x0D
|
||||
#define M98091_REG_LINE_INPUT_LEVEL 0x0E
|
||||
#define M98091_REG_INPUT_MODE 0x0F
|
||||
#define M98091_REG_MIC1_INPUT_LEVEL 0x10
|
||||
#define M98091_REG_MIC2_INPUT_LEVEL 0x11
|
||||
#define M98091_REG_MIC_BIAS_VOLTAGE 0x12
|
||||
#define M98091_REG_DIGITAL_MIC_ENABLE 0x13
|
||||
#define M98091_REG_DIGITAL_MIC_CONFIG 0x14
|
||||
#define M98091_REG_LEFT_ADC_MIXER 0x15
|
||||
#define M98091_REG_RIGHT_ADC_MIXER 0x16
|
||||
#define M98091_REG_LEFT_ADC_LEVEL 0x17
|
||||
#define M98091_REG_RIGHT_ADC_LEVEL 0x18
|
||||
#define M98091_REG_ADC_BIQUAD_LEVEL 0x19
|
||||
#define M98091_REG_ADC_SIDETONE 0x1A
|
||||
#define M98091_REG_SYSTEM_CLOCK 0x1B
|
||||
#define M98091_REG_CLOCK_MODE 0x1C
|
||||
#define M98091_REG_CLOCK_RATIO_NI_MSB 0x1D
|
||||
#define M98091_REG_CLOCK_RATIO_NI_LSB 0x1E
|
||||
#define M98091_REG_CLOCK_RATIO_MI_MSB 0x1F
|
||||
#define M98091_REG_CLOCK_RATIO_MI_LSB 0x20
|
||||
#define M98091_REG_MASTER_MODE 0x21
|
||||
#define M98091_REG_INTERFACE_FORMAT 0x22
|
||||
#define M98091_REG_TDM_CONTROL 0x23
|
||||
#define M98091_REG_TDM_FORMAT 0x24
|
||||
#define M98091_REG_IO_CONFIGURATION 0x25
|
||||
#define M98091_REG_FILTER_CONFIG 0x26
|
||||
#define M98091_REG_DAI_PLAYBACK_LEVEL 0x27
|
||||
#define M98091_REG_DAI_PLAYBACK_LEVEL_EQ 0x28
|
||||
#define M98091_REG_LEFT_HP_MIXER 0x29
|
||||
#define M98091_REG_RIGHT_HP_MIXER 0x2A
|
||||
#define M98091_REG_HP_CONTROL 0x2B
|
||||
#define M98091_REG_LEFT_HP_VOLUME 0x2C
|
||||
#define M98091_REG_RIGHT_HP_VOLUME 0x2D
|
||||
#define M98091_REG_LEFT_SPK_MIXER 0x2E
|
||||
#define M98091_REG_RIGHT_SPK_MIXER 0x2F
|
||||
#define M98091_REG_SPK_CONTROL 0x30
|
||||
#define M98091_REG_LEFT_SPK_VOLUME 0x31
|
||||
#define M98091_REG_RIGHT_SPK_VOLUME 0x32
|
||||
#define M98091_REG_DRC_TIMING 0x33
|
||||
#define M98091_REG_DRC_COMPRESSOR 0x34
|
||||
#define M98091_REG_DRC_EXPANDER 0x35
|
||||
#define M98091_REG_DRC_GAIN 0x36
|
||||
#define M98091_REG_RCV_LOUTL_MIXER 0x37
|
||||
#define M98091_REG_RCV_LOUTL_CONTROL 0x38
|
||||
#define M98091_REG_RCV_LOUTL_VOLUME 0x39
|
||||
#define M98091_REG_LOUTR_MIXER 0x3A
|
||||
#define M98091_REG_LOUTR_CONTROL 0x3B
|
||||
#define M98091_REG_LOUTR_VOLUME 0x3C
|
||||
#define M98091_REG_JACK_DETECT 0x3D
|
||||
#define M98091_REG_INPUT_ENABLE 0x3E
|
||||
#define M98091_REG_OUTPUT_ENABLE 0x3F
|
||||
#define M98091_REG_LEVEL_CONTROL 0x40
|
||||
#define M98091_REG_DSP_FILTER_ENABLE 0x41
|
||||
#define M98091_REG_BIAS_CONTROL 0x42
|
||||
#define M98091_REG_DAC_CONTROL 0x43
|
||||
#define M98091_REG_ADC_CONTROL 0x44
|
||||
#define M98091_REG_DEVICE_SHUTDOWN 0x45
|
||||
#define M98091_REG_EQUALIZER_BASE 0x46
|
||||
#define M98091_REG_RECORD_BIQUAD_BASE 0xAF
|
||||
#define M98091_REG_DMIC3_VOLUME 0xBE
|
||||
#define M98091_REG_DMIC4_VOLUME 0xBF
|
||||
#define M98091_REG_DMIC34_BQ_PREATTEN 0xC0
|
||||
#define M98091_REG_RECORD_TDM_SLOT 0xC1
|
||||
#define M98091_REG_SAMPLE_RATE 0xC2
|
||||
#define M98091_REG_DMIC34_BIQUAD_BASE 0xC3
|
||||
#define M98091_REG_REVISION_ID 0xFF
|
||||
|
||||
/* MAX98090 Register Bit Fields */
|
||||
|
||||
/* M98091_REG_SOFTWARE_RESET */
|
||||
#define M98091_SWRESET_MASK BIT(7)
|
||||
|
||||
/* M98091_REG_QUICK_SAMPLE_RATE */
|
||||
#define M98091_SR_96K_MASK BIT(5)
|
||||
#define M98091_SR_32K_MASK BIT(4)
|
||||
#define M98091_SR_48K_MASK BIT(3)
|
||||
#define M98091_SR_44K1_MASK BIT(2)
|
||||
#define M98091_SR_16K_MASK BIT(1)
|
||||
#define M98091_SR_8K_MASK BIT(0)
|
||||
|
||||
/* M98091_REG_DAI_INTERFACE */
|
||||
#define M98091_RJ_M_MASK BIT(5)
|
||||
#define M98091_RJ_S_MASK BIT(4)
|
||||
#define M98091_LJ_M_MASK BIT(3)
|
||||
#define M98091_LJ_S_MASK BIT(2)
|
||||
#define M98091_I2S_M_MASK BIT(1)
|
||||
#define M98091_I2S_S_MASK BIT(0)
|
||||
|
||||
/* M98091_REG_SYSTEM_CLOCK */
|
||||
#define M98091_PSCLK_DISABLED (0 << 4)
|
||||
#define M98091_PSCLK_DIV1 BIT(4)
|
||||
#define M98091_PSCLK_DIV2 (2 << 4)
|
||||
#define M98091_PSCLK_DIV4 (3 << 4)
|
||||
|
||||
/* M98091_REG_MASTER_MODE */
|
||||
#define M98091_MAS_MASK BIT(7)
|
||||
|
||||
/* M98091_REG_INTERFACE_FORMAT */
|
||||
#define M98091_RJ_MASK BIT(5)
|
||||
#define M98091_WCI_MASK BIT(4)
|
||||
#define M98091_BCI_MASK BIT(3)
|
||||
#define M98091_DLY_MASK BIT(2)
|
||||
#define M98091_WS_MASK (3 << 0)
|
||||
#define M98091_16B_WS (0 << 0)
|
||||
|
||||
/* M98091_REG_IO_CONFIGURATION */
|
||||
#define M98091_LTEN_MASK BIT(5)
|
||||
#define M98091_LBEN_MASK BIT(4)
|
||||
#define M98091_DMONO_MASK BIT(3)
|
||||
#define M98091_HIZOFF_MASK BIT(2)
|
||||
#define M98091_SDOEN_MASK BIT(1)
|
||||
#define M98091_SDIEN_MASK BIT(0)
|
||||
|
||||
/* M98091_REG_LEFT_HP_MIXER */
|
||||
#define M98091_MIXHPL_MIC2_MASK BIT(5)
|
||||
#define M98091_MIXHPL_MIC1_MASK BIT(4)
|
||||
#define M98091_MIXHPL_LINEB_MASK BIT(3)
|
||||
#define M98091_MIXHPL_LINEA_MASK BIT(2)
|
||||
#define M98091_MIXHPL_DACR_MASK BIT(1)
|
||||
#define M98091_MIXHPL_DACL_MASK BIT(0)
|
||||
#define M98091_MIXHPL_MASK (63 << 0)
|
||||
|
||||
/* M98091_REG_RIGHT_HP_MIXER */
|
||||
#define M98091_MIXHPR_MIC2_MASK BIT(5)
|
||||
#define M98091_MIXHPR_MIC1_MASK BIT(4)
|
||||
#define M98091_MIXHPR_LINEB_MASK BIT(3)
|
||||
#define M98091_MIXHPR_LINEA_MASK BIT(2)
|
||||
#define M98091_MIXHPR_DACR_MASK BIT(1)
|
||||
#define M98091_MIXHPR_DACL_MASK BIT(0)
|
||||
#define M98091_MIXHPR_MASK (63 << 0)
|
||||
|
||||
/* M98091_REG_HP_CONTROL */
|
||||
#define M98091_MIXHPRSEL_MASK BIT(5)
|
||||
#define M98091_MIXHPLSEL_MASK BIT(4)
|
||||
#define M98091_MIXHPRG_MASK (3 << 2)
|
||||
#define M98091_MIXHPLG_MASK (3 << 0)
|
||||
|
||||
/* M98091_REG_LEFT_HP_VOLUME */
|
||||
#define M98091_HPLM_MASK BIT(7)
|
||||
#define M98091_HPVOLL_MASK (31 << 0)
|
||||
|
||||
/* M98091_REG_LEFT_SPK_MIXER */
|
||||
#define M98091_MIXSPL_MIC2_MASK BIT(5)
|
||||
#define M98091_MIXSPL_MIC1_MASK BIT(4)
|
||||
#define M98091_MIXSPL_LINEB_MASK BIT(3)
|
||||
#define M98091_MIXSPL_LINEA_MASK BIT(2)
|
||||
#define M98091_MIXSPL_DACR_MASK BIT(1)
|
||||
#define M98091_MIXSPL_DACL_MASK BIT(0)
|
||||
#define M98091_MIXSPL_MASK (63 << 0)
|
||||
|
||||
/* M98091_REG_RIGHT_SPK_MIXER */
|
||||
#define M98091_SPK_SLAVE_MASK BIT(6)
|
||||
#define M98091_MIXSPR_MIC2_MASK BIT(5)
|
||||
#define M98091_MIXSPR_MIC1_MASK BIT(4)
|
||||
#define M98091_MIXSPR_LINEB_MASK BIT(3)
|
||||
#define M98091_MIXSPR_LINEA_MASK BIT(2)
|
||||
#define M98091_MIXSPR_DACR_MASK BIT(1)
|
||||
#define M98091_MIXSPR_DACL_MASK BIT(0)
|
||||
#define M98091_MIXSPR_MASK (63 << 0)
|
||||
|
||||
/* M98091_REG_SPK_CONTROL */
|
||||
#define M98091_MIXSPRG_MASK (3 << 2)
|
||||
#define M98091_MIXSPLG_MASK (3 << 0)
|
||||
|
||||
/* M98091_REG_LEFT_SPK_VOLUME */
|
||||
#define M98091_SPLM_MASK BIT(7)
|
||||
#define M98091_SPVOLL_MASK (63 << 0)
|
||||
|
||||
/* M98091_REG_OUTPUT_ENABLE */
|
||||
#define M98091_HPREN_MASK BIT(7)
|
||||
#define M98091_HPLEN_MASK BIT(6)
|
||||
#define M98091_SPREN_MASK BIT(5)
|
||||
#define M98091_SPLEN_MASK BIT(4)
|
||||
#define M98091_RCVLEN_MASK BIT(3)
|
||||
#define M98091_RCVREN_MASK BIT(2)
|
||||
#define M98091_DAREN_MASK BIT(1)
|
||||
#define M98091_DALEN_MASK BIT(0)
|
||||
|
||||
/* M98091_REG_DEVICE_SHUTDOWN */
|
||||
#define M98091_SHDNN_MASK BIT(7)
|
||||
|
||||
#define M98091_DEFAULT_VOLUME 0x2A
|
||||
#define M98091_REVA 0x50
|
||||
|
||||
#endif
|
16
dts/bindings/audio/maxim,max98091.yaml
Normal file
16
dts/bindings/audio/maxim,max98091.yaml
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Copyright (c) 2025 Silicon Signals Pvt. Ltd.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: MAX98091 I2S Audio Codec
|
||||
|
||||
compatible: "maxim,max98091"
|
||||
|
||||
include: [i2c-device.yaml]
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
||||
mclk-frequency:
|
||||
type: int
|
||||
required: true
|
||||
description: External MCLK frequency in Hz
|
Loading…
Add table
Add a link
Reference in a new issue