18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * TDA7419 audio processor driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright 2018 Konsulko Group 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Author: Matt Porter <mporter@konsulko.com> 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/i2c.h> 118c2ecf20Sopenharmony_ci#include <linux/init.h> 128c2ecf20Sopenharmony_ci#include <linux/module.h> 138c2ecf20Sopenharmony_ci#include <linux/regmap.h> 148c2ecf20Sopenharmony_ci#include <sound/core.h> 158c2ecf20Sopenharmony_ci#include <sound/control.h> 168c2ecf20Sopenharmony_ci#include <sound/soc.h> 178c2ecf20Sopenharmony_ci#include <sound/tlv.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define TDA7419_MAIN_SRC_REG 0x00 208c2ecf20Sopenharmony_ci#define TDA7419_LOUDNESS_REG 0x01 218c2ecf20Sopenharmony_ci#define TDA7419_MUTE_CLK_REG 0x02 228c2ecf20Sopenharmony_ci#define TDA7419_VOLUME_REG 0x03 238c2ecf20Sopenharmony_ci#define TDA7419_TREBLE_REG 0x04 248c2ecf20Sopenharmony_ci#define TDA7419_MIDDLE_REG 0x05 258c2ecf20Sopenharmony_ci#define TDA7419_BASS_REG 0x06 268c2ecf20Sopenharmony_ci#define TDA7419_SECOND_SRC_REG 0x07 278c2ecf20Sopenharmony_ci#define TDA7419_SUB_MID_BASS_REG 0x08 288c2ecf20Sopenharmony_ci#define TDA7419_MIXING_GAIN_REG 0x09 298c2ecf20Sopenharmony_ci#define TDA7419_ATTENUATOR_LF_REG 0x0a 308c2ecf20Sopenharmony_ci#define TDA7419_ATTENUATOR_RF_REG 0x0b 318c2ecf20Sopenharmony_ci#define TDA7419_ATTENUATOR_LR_REG 0x0c 328c2ecf20Sopenharmony_ci#define TDA7419_ATTENUATOR_RR_REG 0x0d 338c2ecf20Sopenharmony_ci#define TDA7419_MIXING_LEVEL_REG 0x0e 348c2ecf20Sopenharmony_ci#define TDA7419_ATTENUATOR_SUB_REG 0x0f 358c2ecf20Sopenharmony_ci#define TDA7419_SA_CLK_AC_REG 0x10 368c2ecf20Sopenharmony_ci#define TDA7419_TESTING_REG 0x11 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci#define TDA7419_MAIN_SRC_SEL 0 398c2ecf20Sopenharmony_ci#define TDA7419_MAIN_SRC_GAIN 3 408c2ecf20Sopenharmony_ci#define TDA7419_MAIN_SRC_AUTOZERO 7 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci#define TDA7419_LOUDNESS_ATTEN 0 438c2ecf20Sopenharmony_ci#define TDA7419_LOUDNESS_CENTER_FREQ 4 448c2ecf20Sopenharmony_ci#define TDA7419_LOUDNESS_BOOST 6 458c2ecf20Sopenharmony_ci#define TDA7419_LOUDNESS_SOFT_STEP 7 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#define TDA7419_VOLUME_SOFT_STEP 7 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci#define TDA7419_SOFT_MUTE 0 508c2ecf20Sopenharmony_ci#define TDA7419_MUTE_INFLUENCE 1 518c2ecf20Sopenharmony_ci#define TDA7419_SOFT_MUTE_TIME 2 528c2ecf20Sopenharmony_ci#define TDA7419_SOFT_STEP_TIME 4 538c2ecf20Sopenharmony_ci#define TDA7419_CLK_FAST_MODE 7 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci#define TDA7419_TREBLE_CENTER_FREQ 5 568c2ecf20Sopenharmony_ci#define TDA7419_REF_OUT_SELECT 7 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci#define TDA7419_MIDDLE_Q_FACTOR 5 598c2ecf20Sopenharmony_ci#define TDA7419_MIDDLE_SOFT_STEP 7 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci#define TDA7419_BASS_Q_FACTOR 5 628c2ecf20Sopenharmony_ci#define TDA7419_BASS_SOFT_STEP 7 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci#define TDA7419_SECOND_SRC_SEL 0 658c2ecf20Sopenharmony_ci#define TDA7419_SECOND_SRC_GAIN 3 668c2ecf20Sopenharmony_ci#define TDA7419_REAR_SPKR_SRC 7 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci#define TDA7419_SUB_CUT_OFF_FREQ 0 698c2ecf20Sopenharmony_ci#define TDA7419_MIDDLE_CENTER_FREQ 2 708c2ecf20Sopenharmony_ci#define TDA7419_BASS_CENTER_FREQ 4 718c2ecf20Sopenharmony_ci#define TDA7419_BASS_DC_MODE 6 728c2ecf20Sopenharmony_ci#define TDA7419_SMOOTHING_FILTER 7 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci#define TDA7419_MIX_LF 0 758c2ecf20Sopenharmony_ci#define TDA7419_MIX_RF 1 768c2ecf20Sopenharmony_ci#define TDA7419_MIX_ENABLE 2 778c2ecf20Sopenharmony_ci#define TDA7419_SUB_ENABLE 3 788c2ecf20Sopenharmony_ci#define TDA7419_HPF_GAIN 4 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci#define TDA7419_SA_Q_FACTOR 0 818c2ecf20Sopenharmony_ci#define TDA7419_RESET_MODE 1 828c2ecf20Sopenharmony_ci#define TDA7419_SA_SOURCE 2 838c2ecf20Sopenharmony_ci#define TDA7419_SA_RUN 3 848c2ecf20Sopenharmony_ci#define TDA7419_RESET 4 858c2ecf20Sopenharmony_ci#define TDA7419_CLK_SOURCE 5 868c2ecf20Sopenharmony_ci#define TDA7419_COUPLING_MODE 6 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cistruct tda7419_data { 898c2ecf20Sopenharmony_ci struct regmap *regmap; 908c2ecf20Sopenharmony_ci}; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_cistatic bool tda7419_readable_reg(struct device *dev, unsigned int reg) 938c2ecf20Sopenharmony_ci{ 948c2ecf20Sopenharmony_ci return false; 958c2ecf20Sopenharmony_ci} 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_cistatic const struct reg_default tda7419_regmap_defaults[] = { 988c2ecf20Sopenharmony_ci { TDA7419_MAIN_SRC_REG, 0xfe }, 998c2ecf20Sopenharmony_ci { TDA7419_LOUDNESS_REG, 0xfe }, 1008c2ecf20Sopenharmony_ci { TDA7419_MUTE_CLK_REG, 0xfe }, 1018c2ecf20Sopenharmony_ci { TDA7419_VOLUME_REG, 0xfe }, 1028c2ecf20Sopenharmony_ci { TDA7419_TREBLE_REG, 0xfe }, 1038c2ecf20Sopenharmony_ci { TDA7419_MIDDLE_REG, 0xfe }, 1048c2ecf20Sopenharmony_ci { TDA7419_BASS_REG, 0xfe }, 1058c2ecf20Sopenharmony_ci { TDA7419_SECOND_SRC_REG, 0xfe }, 1068c2ecf20Sopenharmony_ci { TDA7419_SUB_MID_BASS_REG, 0xfe }, 1078c2ecf20Sopenharmony_ci { TDA7419_MIXING_GAIN_REG, 0xfe }, 1088c2ecf20Sopenharmony_ci { TDA7419_ATTENUATOR_LF_REG, 0xfe }, 1098c2ecf20Sopenharmony_ci { TDA7419_ATTENUATOR_RF_REG, 0xfe }, 1108c2ecf20Sopenharmony_ci { TDA7419_ATTENUATOR_LR_REG, 0xfe }, 1118c2ecf20Sopenharmony_ci { TDA7419_ATTENUATOR_RR_REG, 0xfe }, 1128c2ecf20Sopenharmony_ci { TDA7419_MIXING_LEVEL_REG, 0xfe }, 1138c2ecf20Sopenharmony_ci { TDA7419_ATTENUATOR_SUB_REG, 0xfe }, 1148c2ecf20Sopenharmony_ci { TDA7419_SA_CLK_AC_REG, 0xfe }, 1158c2ecf20Sopenharmony_ci { TDA7419_TESTING_REG, 0xfe }, 1168c2ecf20Sopenharmony_ci}; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_cistatic const struct regmap_config tda7419_regmap_config = { 1198c2ecf20Sopenharmony_ci .reg_bits = 8, 1208c2ecf20Sopenharmony_ci .val_bits = 8, 1218c2ecf20Sopenharmony_ci .max_register = TDA7419_TESTING_REG, 1228c2ecf20Sopenharmony_ci .cache_type = REGCACHE_RBTREE, 1238c2ecf20Sopenharmony_ci .readable_reg = tda7419_readable_reg, 1248c2ecf20Sopenharmony_ci .reg_defaults = tda7419_regmap_defaults, 1258c2ecf20Sopenharmony_ci .num_reg_defaults = ARRAY_SIZE(tda7419_regmap_defaults), 1268c2ecf20Sopenharmony_ci}; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_cistruct tda7419_vol_control { 1298c2ecf20Sopenharmony_ci int min, max; 1308c2ecf20Sopenharmony_ci unsigned int reg, rreg, mask, thresh; 1318c2ecf20Sopenharmony_ci unsigned int invert:1; 1328c2ecf20Sopenharmony_ci}; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistatic inline bool tda7419_vol_is_stereo(struct tda7419_vol_control *tvc) 1358c2ecf20Sopenharmony_ci{ 1368c2ecf20Sopenharmony_ci if (tvc->reg == tvc->rreg) 1378c2ecf20Sopenharmony_ci return false; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci return true; 1408c2ecf20Sopenharmony_ci} 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_cistatic int tda7419_vol_info(struct snd_kcontrol *kcontrol, 1438c2ecf20Sopenharmony_ci struct snd_ctl_elem_info *uinfo) 1448c2ecf20Sopenharmony_ci{ 1458c2ecf20Sopenharmony_ci struct tda7419_vol_control *tvc = 1468c2ecf20Sopenharmony_ci (struct tda7419_vol_control *)kcontrol->private_value; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 1498c2ecf20Sopenharmony_ci uinfo->count = tda7419_vol_is_stereo(tvc) ? 2 : 1; 1508c2ecf20Sopenharmony_ci uinfo->value.integer.min = tvc->min; 1518c2ecf20Sopenharmony_ci uinfo->value.integer.max = tvc->max; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci return 0; 1548c2ecf20Sopenharmony_ci} 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_cistatic inline int tda7419_vol_get_value(int val, unsigned int mask, 1578c2ecf20Sopenharmony_ci int min, int thresh, 1588c2ecf20Sopenharmony_ci unsigned int invert) 1598c2ecf20Sopenharmony_ci{ 1608c2ecf20Sopenharmony_ci val &= mask; 1618c2ecf20Sopenharmony_ci if (val < thresh) { 1628c2ecf20Sopenharmony_ci if (invert) 1638c2ecf20Sopenharmony_ci val = 0 - val; 1648c2ecf20Sopenharmony_ci } else if (val > thresh) { 1658c2ecf20Sopenharmony_ci if (invert) 1668c2ecf20Sopenharmony_ci val = val - thresh; 1678c2ecf20Sopenharmony_ci else 1688c2ecf20Sopenharmony_ci val = thresh - val; 1698c2ecf20Sopenharmony_ci } 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci if (val < min) 1728c2ecf20Sopenharmony_ci val = min; 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci return val; 1758c2ecf20Sopenharmony_ci} 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_cistatic int tda7419_vol_get(struct snd_kcontrol *kcontrol, 1788c2ecf20Sopenharmony_ci struct snd_ctl_elem_value *ucontrol) 1798c2ecf20Sopenharmony_ci{ 1808c2ecf20Sopenharmony_ci struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 1818c2ecf20Sopenharmony_ci struct tda7419_vol_control *tvc = 1828c2ecf20Sopenharmony_ci (struct tda7419_vol_control *)kcontrol->private_value; 1838c2ecf20Sopenharmony_ci unsigned int reg = tvc->reg; 1848c2ecf20Sopenharmony_ci unsigned int rreg = tvc->rreg; 1858c2ecf20Sopenharmony_ci unsigned int mask = tvc->mask; 1868c2ecf20Sopenharmony_ci int min = tvc->min; 1878c2ecf20Sopenharmony_ci int thresh = tvc->thresh; 1888c2ecf20Sopenharmony_ci unsigned int invert = tvc->invert; 1898c2ecf20Sopenharmony_ci int val; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci val = snd_soc_component_read(component, reg); 1928c2ecf20Sopenharmony_ci ucontrol->value.integer.value[0] = 1938c2ecf20Sopenharmony_ci tda7419_vol_get_value(val, mask, min, thresh, invert); 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci if (tda7419_vol_is_stereo(tvc)) { 1968c2ecf20Sopenharmony_ci val = snd_soc_component_read(component, rreg); 1978c2ecf20Sopenharmony_ci ucontrol->value.integer.value[1] = 1988c2ecf20Sopenharmony_ci tda7419_vol_get_value(val, mask, min, thresh, invert); 1998c2ecf20Sopenharmony_ci } 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci return 0; 2028c2ecf20Sopenharmony_ci} 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_cistatic inline int tda7419_vol_put_value(int val, int thresh, 2058c2ecf20Sopenharmony_ci unsigned int invert) 2068c2ecf20Sopenharmony_ci{ 2078c2ecf20Sopenharmony_ci if (val < 0) { 2088c2ecf20Sopenharmony_ci if (invert) 2098c2ecf20Sopenharmony_ci val = abs(val); 2108c2ecf20Sopenharmony_ci else 2118c2ecf20Sopenharmony_ci val = thresh - val; 2128c2ecf20Sopenharmony_ci } else if ((val > 0) && invert) { 2138c2ecf20Sopenharmony_ci val += thresh; 2148c2ecf20Sopenharmony_ci } 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci return val; 2178c2ecf20Sopenharmony_ci} 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_cistatic int tda7419_vol_put(struct snd_kcontrol *kcontrol, 2208c2ecf20Sopenharmony_ci struct snd_ctl_elem_value *ucontrol) 2218c2ecf20Sopenharmony_ci{ 2228c2ecf20Sopenharmony_ci struct snd_soc_component *component = 2238c2ecf20Sopenharmony_ci snd_kcontrol_chip(kcontrol); 2248c2ecf20Sopenharmony_ci struct tda7419_vol_control *tvc = 2258c2ecf20Sopenharmony_ci (struct tda7419_vol_control *)kcontrol->private_value; 2268c2ecf20Sopenharmony_ci unsigned int reg = tvc->reg; 2278c2ecf20Sopenharmony_ci unsigned int rreg = tvc->rreg; 2288c2ecf20Sopenharmony_ci unsigned int mask = tvc->mask; 2298c2ecf20Sopenharmony_ci int thresh = tvc->thresh; 2308c2ecf20Sopenharmony_ci unsigned int invert = tvc->invert; 2318c2ecf20Sopenharmony_ci int val; 2328c2ecf20Sopenharmony_ci int ret; 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci val = tda7419_vol_put_value(ucontrol->value.integer.value[0], 2358c2ecf20Sopenharmony_ci thresh, invert); 2368c2ecf20Sopenharmony_ci ret = snd_soc_component_update_bits(component, reg, 2378c2ecf20Sopenharmony_ci mask, val); 2388c2ecf20Sopenharmony_ci if (ret < 0) 2398c2ecf20Sopenharmony_ci return ret; 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci if (tda7419_vol_is_stereo(tvc)) { 2428c2ecf20Sopenharmony_ci val = tda7419_vol_put_value(ucontrol->value.integer.value[1], 2438c2ecf20Sopenharmony_ci thresh, invert); 2448c2ecf20Sopenharmony_ci ret = snd_soc_component_update_bits(component, rreg, 2458c2ecf20Sopenharmony_ci mask, val); 2468c2ecf20Sopenharmony_ci } 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci return ret; 2498c2ecf20Sopenharmony_ci} 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci#define TDA7419_SINGLE_VALUE(xreg, xmask, xmin, xmax, xthresh, xinvert) \ 2528c2ecf20Sopenharmony_ci ((unsigned long)&(struct tda7419_vol_control) \ 2538c2ecf20Sopenharmony_ci {.reg = xreg, .rreg = xreg, .mask = xmask, .min = xmin, \ 2548c2ecf20Sopenharmony_ci .max = xmax, .thresh = xthresh, .invert = xinvert}) 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci#define TDA7419_DOUBLE_R_VALUE(xregl, xregr, xmask, xmin, xmax, xthresh, \ 2578c2ecf20Sopenharmony_ci xinvert) \ 2588c2ecf20Sopenharmony_ci ((unsigned long)&(struct tda7419_vol_control) \ 2598c2ecf20Sopenharmony_ci {.reg = xregl, .rreg = xregr, .mask = xmask, .min = xmin, \ 2608c2ecf20Sopenharmony_ci .max = xmax, .thresh = xthresh, .invert = xinvert}) 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci#define TDA7419_SINGLE_TLV(xname, xreg, xmask, xmin, xmax, xthresh, \ 2638c2ecf20Sopenharmony_ci xinvert, xtlv_array) \ 2648c2ecf20Sopenharmony_ci{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2658c2ecf20Sopenharmony_ci .name = xname, \ 2668c2ecf20Sopenharmony_ci .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 2678c2ecf20Sopenharmony_ci SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 2688c2ecf20Sopenharmony_ci .tlv.p = (xtlv_array), \ 2698c2ecf20Sopenharmony_ci .info = tda7419_vol_info, \ 2708c2ecf20Sopenharmony_ci .get = tda7419_vol_get, \ 2718c2ecf20Sopenharmony_ci .put = tda7419_vol_put, \ 2728c2ecf20Sopenharmony_ci .private_value = TDA7419_SINGLE_VALUE(xreg, xmask, xmin, \ 2738c2ecf20Sopenharmony_ci xmax, xthresh, xinvert), \ 2748c2ecf20Sopenharmony_ci} 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci#define TDA7419_DOUBLE_R_TLV(xname, xregl, xregr, xmask, xmin, xmax, \ 2778c2ecf20Sopenharmony_ci xthresh, xinvert, xtlv_array) \ 2788c2ecf20Sopenharmony_ci{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2798c2ecf20Sopenharmony_ci .name = xname, \ 2808c2ecf20Sopenharmony_ci .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 2818c2ecf20Sopenharmony_ci SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 2828c2ecf20Sopenharmony_ci .tlv.p = (xtlv_array), \ 2838c2ecf20Sopenharmony_ci .info = tda7419_vol_info, \ 2848c2ecf20Sopenharmony_ci .get = tda7419_vol_get, \ 2858c2ecf20Sopenharmony_ci .put = tda7419_vol_put, \ 2868c2ecf20Sopenharmony_ci .private_value = TDA7419_DOUBLE_R_VALUE(xregl, xregr, xmask, \ 2878c2ecf20Sopenharmony_ci xmin, xmax, xthresh, \ 2888c2ecf20Sopenharmony_ci xinvert), \ 2898c2ecf20Sopenharmony_ci} 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_cistatic const char * const enum_src_sel[] = { 2928c2ecf20Sopenharmony_ci "QD", "SE1", "SE2", "SE3", "SE", "Mute", "Mute", "Mute"}; 2938c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(soc_enum_main_src_sel, 2948c2ecf20Sopenharmony_ci TDA7419_MAIN_SRC_REG, TDA7419_MAIN_SRC_SEL, enum_src_sel); 2958c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new soc_mux_main_src_sel = 2968c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Main Source Select", soc_enum_main_src_sel); 2978c2ecf20Sopenharmony_cistatic DECLARE_TLV_DB_SCALE(tlv_src_gain, 0, 100, 0); 2988c2ecf20Sopenharmony_cistatic DECLARE_TLV_DB_SCALE(tlv_loudness_atten, -1500, 100, 0); 2998c2ecf20Sopenharmony_cistatic const char * const enum_loudness_center_freq[] = { 3008c2ecf20Sopenharmony_ci "Flat", "400 Hz", "800 Hz", "2400 Hz"}; 3018c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(soc_enum_loudness_center_freq, 3028c2ecf20Sopenharmony_ci TDA7419_LOUDNESS_REG, TDA7419_LOUDNESS_CENTER_FREQ, 3038c2ecf20Sopenharmony_ci enum_loudness_center_freq); 3048c2ecf20Sopenharmony_cistatic const char * const enum_mute_influence[] = { 3058c2ecf20Sopenharmony_ci "Pin and IIC", "IIC"}; 3068c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(soc_enum_mute_influence, 3078c2ecf20Sopenharmony_ci TDA7419_MUTE_CLK_REG, TDA7419_MUTE_INFLUENCE, enum_mute_influence); 3088c2ecf20Sopenharmony_cistatic const char * const enum_soft_mute_time[] = { 3098c2ecf20Sopenharmony_ci "0.48 ms", "0.96 ms", "123 ms", "123 ms"}; 3108c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(soc_enum_soft_mute_time, 3118c2ecf20Sopenharmony_ci TDA7419_MUTE_CLK_REG, TDA7419_SOFT_MUTE_TIME, enum_soft_mute_time); 3128c2ecf20Sopenharmony_cistatic const char * const enum_soft_step_time[] = { 3138c2ecf20Sopenharmony_ci "0.160 ms", "0.321 ms", "0.642 ms", "1.28 ms", 3148c2ecf20Sopenharmony_ci "2.56 ms", "5.12 ms", "10.24 ms", "20.48 ms"}; 3158c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(soc_enum_soft_step_time, 3168c2ecf20Sopenharmony_ci TDA7419_MUTE_CLK_REG, TDA7419_SOFT_STEP_TIME, enum_soft_step_time); 3178c2ecf20Sopenharmony_cistatic DECLARE_TLV_DB_SCALE(tlv_volume, -8000, 100, 1); 3188c2ecf20Sopenharmony_cistatic const char * const enum_treble_center_freq[] = { 3198c2ecf20Sopenharmony_ci "10.0 kHz", "12.5 kHz", "15.0 kHz", "17.5 kHz"}; 3208c2ecf20Sopenharmony_cistatic DECLARE_TLV_DB_SCALE(tlv_filter, -1500, 100, 0); 3218c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(soc_enum_treble_center_freq, 3228c2ecf20Sopenharmony_ci TDA7419_TREBLE_REG, TDA7419_TREBLE_CENTER_FREQ, 3238c2ecf20Sopenharmony_ci enum_treble_center_freq); 3248c2ecf20Sopenharmony_cistatic const char * const enum_ref_out_select[] = { 3258c2ecf20Sopenharmony_ci "External Vref (4 V)", "Internal Vref (3.3 V)"}; 3268c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(soc_enum_ref_out_select, 3278c2ecf20Sopenharmony_ci TDA7419_TREBLE_REG, TDA7419_REF_OUT_SELECT, enum_ref_out_select); 3288c2ecf20Sopenharmony_cistatic const char * const enum_middle_q_factor[] = { 3298c2ecf20Sopenharmony_ci "0.5", "0.75", "1.0", "1.25"}; 3308c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(soc_enum_middle_q_factor, 3318c2ecf20Sopenharmony_ci TDA7419_MIDDLE_REG, TDA7419_MIDDLE_Q_FACTOR, enum_middle_q_factor); 3328c2ecf20Sopenharmony_cistatic const char * const enum_bass_q_factor[] = { 3338c2ecf20Sopenharmony_ci "1.0", "1.25", "1.5", "2.0"}; 3348c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(soc_enum_bass_q_factor, 3358c2ecf20Sopenharmony_ci TDA7419_BASS_REG, TDA7419_BASS_Q_FACTOR, enum_bass_q_factor); 3368c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(soc_enum_second_src_sel, 3378c2ecf20Sopenharmony_ci TDA7419_SECOND_SRC_REG, TDA7419_SECOND_SRC_SEL, enum_src_sel); 3388c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new soc_mux_second_src_sel = 3398c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Second Source Select", soc_enum_second_src_sel); 3408c2ecf20Sopenharmony_cistatic const char * const enum_rear_spkr_src[] = { 3418c2ecf20Sopenharmony_ci "Main", "Second"}; 3428c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(soc_enum_rear_spkr_src, 3438c2ecf20Sopenharmony_ci TDA7419_SECOND_SRC_REG, TDA7419_REAR_SPKR_SRC, enum_rear_spkr_src); 3448c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new soc_mux_rear_spkr_src = 3458c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Rear Speaker Source", soc_enum_rear_spkr_src); 3468c2ecf20Sopenharmony_cistatic const char * const enum_sub_cut_off_freq[] = { 3478c2ecf20Sopenharmony_ci "Flat", "80 Hz", "120 Hz", "160 Hz"}; 3488c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(soc_enum_sub_cut_off_freq, 3498c2ecf20Sopenharmony_ci TDA7419_SUB_MID_BASS_REG, TDA7419_SUB_CUT_OFF_FREQ, 3508c2ecf20Sopenharmony_ci enum_sub_cut_off_freq); 3518c2ecf20Sopenharmony_cistatic const char * const enum_middle_center_freq[] = { 3528c2ecf20Sopenharmony_ci "500 Hz", "1000 Hz", "1500 Hz", "2500 Hz"}; 3538c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(soc_enum_middle_center_freq, 3548c2ecf20Sopenharmony_ci TDA7419_SUB_MID_BASS_REG, TDA7419_MIDDLE_CENTER_FREQ, 3558c2ecf20Sopenharmony_ci enum_middle_center_freq); 3568c2ecf20Sopenharmony_cistatic const char * const enum_bass_center_freq[] = { 3578c2ecf20Sopenharmony_ci "60 Hz", "80 Hz", "100 Hz", "200 Hz"}; 3588c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(soc_enum_bass_center_freq, 3598c2ecf20Sopenharmony_ci TDA7419_SUB_MID_BASS_REG, TDA7419_BASS_CENTER_FREQ, 3608c2ecf20Sopenharmony_ci enum_bass_center_freq); 3618c2ecf20Sopenharmony_cistatic const char * const enum_sa_q_factor[] = { 3628c2ecf20Sopenharmony_ci "3.5", "1.75" }; 3638c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(soc_enum_sa_q_factor, 3648c2ecf20Sopenharmony_ci TDA7419_SA_CLK_AC_REG, TDA7419_SA_Q_FACTOR, enum_sa_q_factor); 3658c2ecf20Sopenharmony_cistatic const char * const enum_reset_mode[] = { 3668c2ecf20Sopenharmony_ci "IIC", "Auto" }; 3678c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(soc_enum_reset_mode, 3688c2ecf20Sopenharmony_ci TDA7419_SA_CLK_AC_REG, TDA7419_RESET_MODE, enum_reset_mode); 3698c2ecf20Sopenharmony_cistatic const char * const enum_sa_src[] = { 3708c2ecf20Sopenharmony_ci "Bass", "In Gain" }; 3718c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(soc_enum_sa_src, 3728c2ecf20Sopenharmony_ci TDA7419_SA_CLK_AC_REG, TDA7419_SA_SOURCE, enum_sa_src); 3738c2ecf20Sopenharmony_cistatic const char * const enum_clk_src[] = { 3748c2ecf20Sopenharmony_ci "Internal", "External" }; 3758c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(soc_enum_clk_src, 3768c2ecf20Sopenharmony_ci TDA7419_SA_CLK_AC_REG, TDA7419_CLK_SOURCE, enum_clk_src); 3778c2ecf20Sopenharmony_cistatic const char * const enum_coupling_mode[] = { 3788c2ecf20Sopenharmony_ci "DC Coupling (without HPF)", "AC Coupling after In Gain", 3798c2ecf20Sopenharmony_ci "DC Coupling (with HPF)", "AC Coupling after Bass" }; 3808c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(soc_enum_coupling_mode, 3818c2ecf20Sopenharmony_ci TDA7419_SA_CLK_AC_REG, TDA7419_COUPLING_MODE, enum_coupling_mode); 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci/* ASoC Controls */ 3848c2ecf20Sopenharmony_cistatic struct snd_kcontrol_new tda7419_controls[] = { 3858c2ecf20Sopenharmony_ciSOC_SINGLE_TLV("Main Source Capture Volume", TDA7419_MAIN_SRC_REG, 3868c2ecf20Sopenharmony_ci TDA7419_MAIN_SRC_GAIN, 15, 0, tlv_src_gain), 3878c2ecf20Sopenharmony_ciSOC_SINGLE("Main Source AutoZero Switch", TDA7419_MAIN_SRC_REG, 3888c2ecf20Sopenharmony_ci TDA7419_MAIN_SRC_AUTOZERO, 1, 1), 3898c2ecf20Sopenharmony_ciSOC_SINGLE_TLV("Loudness Playback Volume", TDA7419_LOUDNESS_REG, 3908c2ecf20Sopenharmony_ci TDA7419_LOUDNESS_ATTEN, 15, 1, tlv_loudness_atten), 3918c2ecf20Sopenharmony_ciSOC_ENUM("Loudness Center Frequency", soc_enum_loudness_center_freq), 3928c2ecf20Sopenharmony_ciSOC_SINGLE("Loudness High Boost Switch", TDA7419_LOUDNESS_REG, 3938c2ecf20Sopenharmony_ci TDA7419_LOUDNESS_BOOST, 1, 1), 3948c2ecf20Sopenharmony_ciSOC_SINGLE("Loudness Soft Step Switch", TDA7419_LOUDNESS_REG, 3958c2ecf20Sopenharmony_ci TDA7419_LOUDNESS_SOFT_STEP, 1, 1), 3968c2ecf20Sopenharmony_ciSOC_SINGLE("Soft Mute Switch", TDA7419_MUTE_CLK_REG, TDA7419_SOFT_MUTE, 1, 1), 3978c2ecf20Sopenharmony_ciSOC_ENUM("Mute Influence", soc_enum_mute_influence), 3988c2ecf20Sopenharmony_ciSOC_ENUM("Soft Mute Time", soc_enum_soft_mute_time), 3998c2ecf20Sopenharmony_ciSOC_ENUM("Soft Step Time", soc_enum_soft_step_time), 4008c2ecf20Sopenharmony_ciSOC_SINGLE("Clock Fast Mode Switch", TDA7419_MUTE_CLK_REG, 4018c2ecf20Sopenharmony_ci TDA7419_CLK_FAST_MODE, 1, 1), 4028c2ecf20Sopenharmony_ciTDA7419_SINGLE_TLV("Master Playback Volume", TDA7419_VOLUME_REG, 4038c2ecf20Sopenharmony_ci 0x7f, -80, 15, 0x10, 0, tlv_volume), 4048c2ecf20Sopenharmony_ciSOC_SINGLE("Volume Soft Step Switch", TDA7419_VOLUME_REG, 4058c2ecf20Sopenharmony_ci TDA7419_VOLUME_SOFT_STEP, 1, 1), 4068c2ecf20Sopenharmony_ciTDA7419_SINGLE_TLV("Treble Playback Volume", TDA7419_TREBLE_REG, 4078c2ecf20Sopenharmony_ci 0x1f, -15, 15, 0x10, 1, tlv_filter), 4088c2ecf20Sopenharmony_ciSOC_ENUM("Treble Center Frequency", soc_enum_treble_center_freq), 4098c2ecf20Sopenharmony_ciSOC_ENUM("Reference Output Select", soc_enum_ref_out_select), 4108c2ecf20Sopenharmony_ciTDA7419_SINGLE_TLV("Middle Playback Volume", TDA7419_MIDDLE_REG, 4118c2ecf20Sopenharmony_ci 0x1f, -15, 15, 0x10, 1, tlv_filter), 4128c2ecf20Sopenharmony_ciSOC_ENUM("Middle Q Factor", soc_enum_middle_q_factor), 4138c2ecf20Sopenharmony_ciSOC_SINGLE("Middle Soft Step Switch", TDA7419_MIDDLE_REG, 4148c2ecf20Sopenharmony_ci TDA7419_MIDDLE_SOFT_STEP, 1, 1), 4158c2ecf20Sopenharmony_ciTDA7419_SINGLE_TLV("Bass Playback Volume", TDA7419_BASS_REG, 4168c2ecf20Sopenharmony_ci 0x1f, -15, 15, 0x10, 1, tlv_filter), 4178c2ecf20Sopenharmony_ciSOC_ENUM("Bass Q Factor", soc_enum_bass_q_factor), 4188c2ecf20Sopenharmony_ciSOC_SINGLE("Bass Soft Step Switch", TDA7419_BASS_REG, 4198c2ecf20Sopenharmony_ci TDA7419_BASS_SOFT_STEP, 1, 1), 4208c2ecf20Sopenharmony_ciSOC_SINGLE_TLV("Second Source Capture Volume", TDA7419_SECOND_SRC_REG, 4218c2ecf20Sopenharmony_ci TDA7419_SECOND_SRC_GAIN, 15, 0, tlv_src_gain), 4228c2ecf20Sopenharmony_ciSOC_ENUM("Subwoofer Cut-off Frequency", soc_enum_sub_cut_off_freq), 4238c2ecf20Sopenharmony_ciSOC_ENUM("Middle Center Frequency", soc_enum_middle_center_freq), 4248c2ecf20Sopenharmony_ciSOC_ENUM("Bass Center Frequency", soc_enum_bass_center_freq), 4258c2ecf20Sopenharmony_ciSOC_SINGLE("Bass DC Mode Switch", TDA7419_SUB_MID_BASS_REG, 4268c2ecf20Sopenharmony_ci TDA7419_BASS_DC_MODE, 1, 1), 4278c2ecf20Sopenharmony_ciSOC_SINGLE("Smoothing Filter Switch", TDA7419_SUB_MID_BASS_REG, 4288c2ecf20Sopenharmony_ci TDA7419_SMOOTHING_FILTER, 1, 1), 4298c2ecf20Sopenharmony_ciTDA7419_DOUBLE_R_TLV("Front Speaker Playback Volume", TDA7419_ATTENUATOR_LF_REG, 4308c2ecf20Sopenharmony_ci TDA7419_ATTENUATOR_RF_REG, 0x7f, -80, 15, 0x10, 0, 4318c2ecf20Sopenharmony_ci tlv_volume), 4328c2ecf20Sopenharmony_ciSOC_SINGLE("Left Front Soft Step Switch", TDA7419_ATTENUATOR_LF_REG, 4338c2ecf20Sopenharmony_ci TDA7419_VOLUME_SOFT_STEP, 1, 1), 4348c2ecf20Sopenharmony_ciSOC_SINGLE("Right Front Soft Step Switch", TDA7419_ATTENUATOR_RF_REG, 4358c2ecf20Sopenharmony_ci TDA7419_VOLUME_SOFT_STEP, 1, 1), 4368c2ecf20Sopenharmony_ciTDA7419_DOUBLE_R_TLV("Rear Speaker Playback Volume", TDA7419_ATTENUATOR_LR_REG, 4378c2ecf20Sopenharmony_ci TDA7419_ATTENUATOR_RR_REG, 0x7f, -80, 15, 0x10, 0, 4388c2ecf20Sopenharmony_ci tlv_volume), 4398c2ecf20Sopenharmony_ciSOC_SINGLE("Left Rear Soft Step Switch", TDA7419_ATTENUATOR_LR_REG, 4408c2ecf20Sopenharmony_ci TDA7419_VOLUME_SOFT_STEP, 1, 1), 4418c2ecf20Sopenharmony_ciSOC_SINGLE("Right Rear Soft Step Switch", TDA7419_ATTENUATOR_RR_REG, 4428c2ecf20Sopenharmony_ci TDA7419_VOLUME_SOFT_STEP, 1, 1), 4438c2ecf20Sopenharmony_ciTDA7419_SINGLE_TLV("Mixing Capture Volume", TDA7419_MIXING_LEVEL_REG, 4448c2ecf20Sopenharmony_ci 0x7f, -80, 15, 0x10, 0, tlv_volume), 4458c2ecf20Sopenharmony_ciSOC_SINGLE("Mixing Level Soft Step Switch", TDA7419_MIXING_LEVEL_REG, 4468c2ecf20Sopenharmony_ci TDA7419_VOLUME_SOFT_STEP, 1, 1), 4478c2ecf20Sopenharmony_ciTDA7419_SINGLE_TLV("Subwoofer Playback Volume", TDA7419_ATTENUATOR_SUB_REG, 4488c2ecf20Sopenharmony_ci 0x7f, -80, 15, 0x10, 0, tlv_volume), 4498c2ecf20Sopenharmony_ciSOC_SINGLE("Subwoofer Soft Step Switch", TDA7419_ATTENUATOR_SUB_REG, 4508c2ecf20Sopenharmony_ci TDA7419_VOLUME_SOFT_STEP, 1, 1), 4518c2ecf20Sopenharmony_ciSOC_ENUM("Spectrum Analyzer Q Factor", soc_enum_sa_q_factor), 4528c2ecf20Sopenharmony_ciSOC_ENUM("Spectrum Analyzer Reset Mode", soc_enum_reset_mode), 4538c2ecf20Sopenharmony_ciSOC_ENUM("Spectrum Analyzer Source", soc_enum_sa_src), 4548c2ecf20Sopenharmony_ciSOC_SINGLE("Spectrum Analyzer Run Switch", TDA7419_SA_CLK_AC_REG, 4558c2ecf20Sopenharmony_ci TDA7419_SA_RUN, 1, 1), 4568c2ecf20Sopenharmony_ciSOC_SINGLE("Spectrum Analyzer Reset Switch", TDA7419_SA_CLK_AC_REG, 4578c2ecf20Sopenharmony_ci TDA7419_RESET, 1, 1), 4588c2ecf20Sopenharmony_ciSOC_ENUM("Clock Source", soc_enum_clk_src), 4598c2ecf20Sopenharmony_ciSOC_ENUM("Coupling Mode", soc_enum_coupling_mode), 4608c2ecf20Sopenharmony_ci}; 4618c2ecf20Sopenharmony_ci 4628c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new soc_mixer_lf_output_controls[] = { 4638c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("Mix to LF Speaker Switch", 4648c2ecf20Sopenharmony_ci TDA7419_MIXING_GAIN_REG, 4658c2ecf20Sopenharmony_ci TDA7419_MIX_LF, 1, 1), 4668c2ecf20Sopenharmony_ci}; 4678c2ecf20Sopenharmony_ci 4688c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new soc_mixer_rf_output_controls[] = { 4698c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("Mix to RF Speaker Switch", 4708c2ecf20Sopenharmony_ci TDA7419_MIXING_GAIN_REG, 4718c2ecf20Sopenharmony_ci TDA7419_MIX_RF, 1, 1), 4728c2ecf20Sopenharmony_ci}; 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new soc_mix_enable_switch_controls[] = { 4758c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("Switch", TDA7419_MIXING_GAIN_REG, 4768c2ecf20Sopenharmony_ci TDA7419_MIX_ENABLE, 1, 1), 4778c2ecf20Sopenharmony_ci}; 4788c2ecf20Sopenharmony_ci 4798c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new soc_sub_enable_switch_controls[] = { 4808c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("Switch", TDA7419_MIXING_GAIN_REG, 4818c2ecf20Sopenharmony_ci TDA7419_MIX_ENABLE, 1, 1), 4828c2ecf20Sopenharmony_ci}; 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_widget tda7419_dapm_widgets[] = { 4858c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("SE3L"), 4868c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("SE3R"), 4878c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("SE2L"), 4888c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("SE2R"), 4898c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("SE1L"), 4908c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("SE1R"), 4918c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("DIFFL"), 4928c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("DIFFR"), 4938c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("MIX"), 4948c2ecf20Sopenharmony_ci 4958c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("Main Source Select", SND_SOC_NOPM, 4968c2ecf20Sopenharmony_ci 0, 0, &soc_mux_main_src_sel), 4978c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("Second Source Select", SND_SOC_NOPM, 4988c2ecf20Sopenharmony_ci 0, 0, &soc_mux_second_src_sel), 4998c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("Rear Speaker Source", SND_SOC_NOPM, 5008c2ecf20Sopenharmony_ci 0, 0, &soc_mux_rear_spkr_src), 5018c2ecf20Sopenharmony_ci 5028c2ecf20Sopenharmony_ci SND_SOC_DAPM_SWITCH("Mix Enable", SND_SOC_NOPM, 5038c2ecf20Sopenharmony_ci 0, 0, &soc_mix_enable_switch_controls[0]), 5048c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER_NAMED_CTL("LF Output Mixer", SND_SOC_NOPM, 5058c2ecf20Sopenharmony_ci 0, 0, &soc_mixer_lf_output_controls[0], 5068c2ecf20Sopenharmony_ci ARRAY_SIZE(soc_mixer_lf_output_controls)), 5078c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER_NAMED_CTL("RF Output Mixer", SND_SOC_NOPM, 5088c2ecf20Sopenharmony_ci 0, 0, &soc_mixer_rf_output_controls[0], 5098c2ecf20Sopenharmony_ci ARRAY_SIZE(soc_mixer_rf_output_controls)), 5108c2ecf20Sopenharmony_ci 5118c2ecf20Sopenharmony_ci SND_SOC_DAPM_SWITCH("Subwoofer Enable", 5128c2ecf20Sopenharmony_ci SND_SOC_NOPM, 0, 0, 5138c2ecf20Sopenharmony_ci &soc_sub_enable_switch_controls[0]), 5148c2ecf20Sopenharmony_ci 5158c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUTPUT("OUTLF"), 5168c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUTPUT("OUTRF"), 5178c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUTPUT("OUTLR"), 5188c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUTPUT("OUTRR"), 5198c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUTPUT("OUTSW"), 5208c2ecf20Sopenharmony_ci}; 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_route tda7419_dapm_routes[] = { 5238c2ecf20Sopenharmony_ci {"Main Source Select", "SE3", "SE3L"}, 5248c2ecf20Sopenharmony_ci {"Main Source Select", "SE3", "SE3R"}, 5258c2ecf20Sopenharmony_ci {"Main Source Select", "SE2", "SE2L"}, 5268c2ecf20Sopenharmony_ci {"Main Source Select", "SE2", "SE2R"}, 5278c2ecf20Sopenharmony_ci {"Main Source Select", "SE1", "SE1L"}, 5288c2ecf20Sopenharmony_ci {"Main Source Select", "SE1", "SE1R"}, 5298c2ecf20Sopenharmony_ci {"Main Source Select", "SE", "DIFFL"}, 5308c2ecf20Sopenharmony_ci {"Main Source Select", "SE", "DIFFR"}, 5318c2ecf20Sopenharmony_ci {"Main Source Select", "QD", "DIFFL"}, 5328c2ecf20Sopenharmony_ci {"Main Source Select", "QD", "DIFFR"}, 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_ci {"Second Source Select", "SE3", "SE3L"}, 5358c2ecf20Sopenharmony_ci {"Second Source Select", "SE3", "SE3R"}, 5368c2ecf20Sopenharmony_ci {"Second Source Select", "SE2", "SE2L"}, 5378c2ecf20Sopenharmony_ci {"Second Source Select", "SE2", "SE2R"}, 5388c2ecf20Sopenharmony_ci {"Second Source Select", "SE1", "SE1L"}, 5398c2ecf20Sopenharmony_ci {"Second Source Select", "SE1", "SE1R"}, 5408c2ecf20Sopenharmony_ci {"Second Source Select", "SE", "DIFFL"}, 5418c2ecf20Sopenharmony_ci {"Second Source Select", "SE", "DIFFR"}, 5428c2ecf20Sopenharmony_ci {"Second Source Select", "QD", "DIFFL"}, 5438c2ecf20Sopenharmony_ci {"Second Source Select", "QD", "DIFFR"}, 5448c2ecf20Sopenharmony_ci 5458c2ecf20Sopenharmony_ci {"Rear Speaker Source", "Main", "Main Source Select"}, 5468c2ecf20Sopenharmony_ci {"Rear Speaker Source", "Second", "Second Source Select"}, 5478c2ecf20Sopenharmony_ci 5488c2ecf20Sopenharmony_ci {"Subwoofer Enable", "Switch", "Main Source Select"}, 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_ci {"Mix Enable", "Switch", "MIX"}, 5518c2ecf20Sopenharmony_ci 5528c2ecf20Sopenharmony_ci {"LF Output Mixer", NULL, "Main Source Select"}, 5538c2ecf20Sopenharmony_ci {"LF Output Mixer", "Mix to LF Speaker Switch", "Mix Enable"}, 5548c2ecf20Sopenharmony_ci {"RF Output Mixer", NULL, "Main Source Select"}, 5558c2ecf20Sopenharmony_ci {"RF Output Mixer", "Mix to RF Speaker Switch", "Mix Enable"}, 5568c2ecf20Sopenharmony_ci 5578c2ecf20Sopenharmony_ci {"OUTLF", NULL, "LF Output Mixer"}, 5588c2ecf20Sopenharmony_ci {"OUTRF", NULL, "RF Output Mixer"}, 5598c2ecf20Sopenharmony_ci {"OUTLR", NULL, "Rear Speaker Source"}, 5608c2ecf20Sopenharmony_ci {"OUTRR", NULL, "Rear Speaker Source"}, 5618c2ecf20Sopenharmony_ci {"OUTSW", NULL, "Subwoofer Enable"}, 5628c2ecf20Sopenharmony_ci}; 5638c2ecf20Sopenharmony_ci 5648c2ecf20Sopenharmony_cistatic const struct snd_soc_component_driver tda7419_component_driver = { 5658c2ecf20Sopenharmony_ci .name = "tda7419", 5668c2ecf20Sopenharmony_ci .controls = tda7419_controls, 5678c2ecf20Sopenharmony_ci .num_controls = ARRAY_SIZE(tda7419_controls), 5688c2ecf20Sopenharmony_ci .dapm_widgets = tda7419_dapm_widgets, 5698c2ecf20Sopenharmony_ci .num_dapm_widgets = ARRAY_SIZE(tda7419_dapm_widgets), 5708c2ecf20Sopenharmony_ci .dapm_routes = tda7419_dapm_routes, 5718c2ecf20Sopenharmony_ci .num_dapm_routes = ARRAY_SIZE(tda7419_dapm_routes), 5728c2ecf20Sopenharmony_ci}; 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_cistatic int tda7419_probe(struct i2c_client *i2c, 5758c2ecf20Sopenharmony_ci const struct i2c_device_id *id) 5768c2ecf20Sopenharmony_ci{ 5778c2ecf20Sopenharmony_ci struct tda7419_data *tda7419; 5788c2ecf20Sopenharmony_ci int i, ret; 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci tda7419 = devm_kzalloc(&i2c->dev, 5818c2ecf20Sopenharmony_ci sizeof(struct tda7419_data), 5828c2ecf20Sopenharmony_ci GFP_KERNEL); 5838c2ecf20Sopenharmony_ci if (tda7419 == NULL) 5848c2ecf20Sopenharmony_ci return -ENOMEM; 5858c2ecf20Sopenharmony_ci 5868c2ecf20Sopenharmony_ci i2c_set_clientdata(i2c, tda7419); 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_ci tda7419->regmap = devm_regmap_init_i2c(i2c, &tda7419_regmap_config); 5898c2ecf20Sopenharmony_ci if (IS_ERR(tda7419->regmap)) { 5908c2ecf20Sopenharmony_ci ret = PTR_ERR(tda7419->regmap); 5918c2ecf20Sopenharmony_ci dev_err(&i2c->dev, "error initializing regmap: %d\n", 5928c2ecf20Sopenharmony_ci ret); 5938c2ecf20Sopenharmony_ci return ret; 5948c2ecf20Sopenharmony_ci } 5958c2ecf20Sopenharmony_ci 5968c2ecf20Sopenharmony_ci /* 5978c2ecf20Sopenharmony_ci * Reset registers to power-on defaults. The part does not provide a 5988c2ecf20Sopenharmony_ci * soft-reset function and the registers are not readable. This ensures 5998c2ecf20Sopenharmony_ci * that the cache matches register contents even if the registers have 6008c2ecf20Sopenharmony_ci * been previously initialized and not power cycled before probe. 6018c2ecf20Sopenharmony_ci */ 6028c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(tda7419_regmap_defaults); i++) 6038c2ecf20Sopenharmony_ci regmap_write(tda7419->regmap, 6048c2ecf20Sopenharmony_ci tda7419_regmap_defaults[i].reg, 6058c2ecf20Sopenharmony_ci tda7419_regmap_defaults[i].def); 6068c2ecf20Sopenharmony_ci 6078c2ecf20Sopenharmony_ci ret = devm_snd_soc_register_component(&i2c->dev, 6088c2ecf20Sopenharmony_ci &tda7419_component_driver, NULL, 0); 6098c2ecf20Sopenharmony_ci if (ret < 0) { 6108c2ecf20Sopenharmony_ci dev_err(&i2c->dev, "error registering component: %d\n", 6118c2ecf20Sopenharmony_ci ret); 6128c2ecf20Sopenharmony_ci } 6138c2ecf20Sopenharmony_ci 6148c2ecf20Sopenharmony_ci return ret; 6158c2ecf20Sopenharmony_ci} 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_cistatic const struct i2c_device_id tda7419_i2c_id[] = { 6188c2ecf20Sopenharmony_ci { "tda7419", 0 }, 6198c2ecf20Sopenharmony_ci { } 6208c2ecf20Sopenharmony_ci}; 6218c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, tda7419_i2c_id); 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_cistatic const struct of_device_id tda7419_of_match[] = { 6248c2ecf20Sopenharmony_ci { .compatible = "st,tda7419" }, 6258c2ecf20Sopenharmony_ci { }, 6268c2ecf20Sopenharmony_ci}; 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_cistatic struct i2c_driver tda7419_driver = { 6298c2ecf20Sopenharmony_ci .driver = { 6308c2ecf20Sopenharmony_ci .name = "tda7419", 6318c2ecf20Sopenharmony_ci .of_match_table = tda7419_of_match, 6328c2ecf20Sopenharmony_ci }, 6338c2ecf20Sopenharmony_ci .probe = tda7419_probe, 6348c2ecf20Sopenharmony_ci .id_table = tda7419_i2c_id, 6358c2ecf20Sopenharmony_ci}; 6368c2ecf20Sopenharmony_ci 6378c2ecf20Sopenharmony_cimodule_i2c_driver(tda7419_driver); 6388c2ecf20Sopenharmony_ci 6398c2ecf20Sopenharmony_ciMODULE_AUTHOR("Matt Porter <mporter@konsulko.com>"); 6408c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("TDA7419 audio processor driver"); 6418c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 642