Loading sound/soc/codecs/rt9120.c +48 −10 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0 #include <linux/bits.h> #include <linux/bitfield.h> #include <linux/delay.h> #include <linux/gpio/consumer.h> #include <linux/i2c.h> Loading @@ -23,9 +24,11 @@ #define RT9120_REG_ERRRPT 0x10 #define RT9120_REG_MSVOL 0x20 #define RT9120_REG_SWRESET 0x40 #define RT9120_REG_INTERCFG 0x63 #define RT9120_REG_INTERNAL0 0x65 #define RT9120_REG_INTERNAL1 0x69 #define RT9120_REG_UVPOPT 0x6C #define RT9120_REG_DIGCFG 0xF8 #define RT9120_VID_MASK GENMASK(15, 8) #define RT9120_SWRST_MASK BIT(7) Loading @@ -46,8 +49,10 @@ #define RT9120_CFG_WORDLEN_24 24 #define RT9120_CFG_WORDLEN_32 32 #define RT9120_DVDD_UVSEL_MASK GENMASK(5, 4) #define RT9120_AUTOSYNC_MASK BIT(6) #define RT9120_VENDOR_ID 0x4200 #define RT9120_VENDOR_ID 0x42 #define RT9120S_VENDOR_ID 0x43 #define RT9120_RESET_WAITMS 20 #define RT9120_CHIPON_WAITMS 20 #define RT9120_AMPON_WAITMS 50 Loading @@ -61,9 +66,16 @@ SNDRV_PCM_FMTBIT_S24_LE |\ SNDRV_PCM_FMTBIT_S32_LE) enum { CHIP_IDX_RT9120 = 0, CHIP_IDX_RT9120S, CHIP_IDX_MAX }; struct rt9120_data { struct device *dev; struct regmap *regmap; int chip_idx; }; /* 11bit [min,max,step] = [-103.9375dB, 24dB, 0.0625dB] */ Loading Loading @@ -149,8 +161,12 @@ static int rt9120_codec_probe(struct snd_soc_component *comp) snd_soc_component_init_regmap(comp, data->regmap); /* Internal setting */ snd_soc_component_write(comp, RT9120_REG_INTERNAL1, 0x03); snd_soc_component_write(comp, RT9120_REG_INTERNAL0, 0x69); if (data->chip_idx == CHIP_IDX_RT9120S) { snd_soc_component_write(comp, RT9120_REG_INTERCFG, 0xde); snd_soc_component_write(comp, RT9120_REG_INTERNAL0, 0x66); } else snd_soc_component_write(comp, RT9120_REG_INTERNAL0, 0x04); return 0; } Loading Loading @@ -201,8 +217,8 @@ static int rt9120_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *comp = dai->component; unsigned int param_width, param_slot_width; int width; unsigned int param_width, param_slot_width, auto_sync; int width, fs; switch (width = params_width(param)) { case 16: Loading Loading @@ -240,6 +256,16 @@ static int rt9120_hw_params(struct snd_pcm_substream *substream, snd_soc_component_update_bits(comp, RT9120_REG_I2SWL, RT9120_AUDWL_MASK, param_slot_width); fs = width * params_channels(param); /* If fs is divided by 48, disable auto sync */ if (fs % 48 == 0) auto_sync = 0; else auto_sync = RT9120_AUTOSYNC_MASK; snd_soc_component_update_bits(comp, RT9120_REG_DIGCFG, RT9120_AUTOSYNC_MASK, auto_sync); return 0; } Loading Loading @@ -279,9 +305,11 @@ static const struct regmap_range rt9120_rd_yes_ranges[] = { regmap_reg_range(0x20, 0x27), regmap_reg_range(0x30, 0x38), regmap_reg_range(0x3A, 0x40), regmap_reg_range(0x63, 0x63), regmap_reg_range(0x65, 0x65), regmap_reg_range(0x69, 0x69), regmap_reg_range(0x6C, 0x6C) regmap_reg_range(0x6C, 0x6C), regmap_reg_range(0xF8, 0xF8) }; static const struct regmap_access_table rt9120_rd_table = { Loading @@ -297,9 +325,11 @@ static const struct regmap_range rt9120_wr_yes_ranges[] = { regmap_reg_range(0x30, 0x38), regmap_reg_range(0x3A, 0x3D), regmap_reg_range(0x40, 0x40), regmap_reg_range(0x63, 0x63), regmap_reg_range(0x65, 0x65), regmap_reg_range(0x69, 0x69), regmap_reg_range(0x6C, 0x6C) regmap_reg_range(0x6C, 0x6C), regmap_reg_range(0xF8, 0xF8) }; static const struct regmap_access_table rt9120_wr_table = { Loading Loading @@ -370,7 +400,7 @@ static int rt9120_reg_write(void *context, unsigned int reg, unsigned int val) static const struct regmap_config rt9120_regmap_config = { .reg_bits = 8, .val_bits = 32, .max_register = RT9120_REG_UVPOPT, .max_register = RT9120_REG_DIGCFG, .reg_read = rt9120_reg_read, .reg_write = rt9120_reg_write, Loading @@ -388,8 +418,16 @@ static int rt9120_check_vendor_info(struct rt9120_data *data) if (ret) return ret; if ((devid & RT9120_VID_MASK) != RT9120_VENDOR_ID) { dev_err(data->dev, "DEVID not correct [0x%04x]\n", devid); devid = FIELD_GET(RT9120_VID_MASK, devid); switch (devid) { case RT9120_VENDOR_ID: data->chip_idx = CHIP_IDX_RT9120; break; case RT9120S_VENDOR_ID: data->chip_idx = CHIP_IDX_RT9120S; break; default: dev_err(data->dev, "DEVID not correct [0x%0x]\n", devid); return -ENODEV; } Loading Loading
sound/soc/codecs/rt9120.c +48 −10 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0 #include <linux/bits.h> #include <linux/bitfield.h> #include <linux/delay.h> #include <linux/gpio/consumer.h> #include <linux/i2c.h> Loading @@ -23,9 +24,11 @@ #define RT9120_REG_ERRRPT 0x10 #define RT9120_REG_MSVOL 0x20 #define RT9120_REG_SWRESET 0x40 #define RT9120_REG_INTERCFG 0x63 #define RT9120_REG_INTERNAL0 0x65 #define RT9120_REG_INTERNAL1 0x69 #define RT9120_REG_UVPOPT 0x6C #define RT9120_REG_DIGCFG 0xF8 #define RT9120_VID_MASK GENMASK(15, 8) #define RT9120_SWRST_MASK BIT(7) Loading @@ -46,8 +49,10 @@ #define RT9120_CFG_WORDLEN_24 24 #define RT9120_CFG_WORDLEN_32 32 #define RT9120_DVDD_UVSEL_MASK GENMASK(5, 4) #define RT9120_AUTOSYNC_MASK BIT(6) #define RT9120_VENDOR_ID 0x4200 #define RT9120_VENDOR_ID 0x42 #define RT9120S_VENDOR_ID 0x43 #define RT9120_RESET_WAITMS 20 #define RT9120_CHIPON_WAITMS 20 #define RT9120_AMPON_WAITMS 50 Loading @@ -61,9 +66,16 @@ SNDRV_PCM_FMTBIT_S24_LE |\ SNDRV_PCM_FMTBIT_S32_LE) enum { CHIP_IDX_RT9120 = 0, CHIP_IDX_RT9120S, CHIP_IDX_MAX }; struct rt9120_data { struct device *dev; struct regmap *regmap; int chip_idx; }; /* 11bit [min,max,step] = [-103.9375dB, 24dB, 0.0625dB] */ Loading Loading @@ -149,8 +161,12 @@ static int rt9120_codec_probe(struct snd_soc_component *comp) snd_soc_component_init_regmap(comp, data->regmap); /* Internal setting */ snd_soc_component_write(comp, RT9120_REG_INTERNAL1, 0x03); snd_soc_component_write(comp, RT9120_REG_INTERNAL0, 0x69); if (data->chip_idx == CHIP_IDX_RT9120S) { snd_soc_component_write(comp, RT9120_REG_INTERCFG, 0xde); snd_soc_component_write(comp, RT9120_REG_INTERNAL0, 0x66); } else snd_soc_component_write(comp, RT9120_REG_INTERNAL0, 0x04); return 0; } Loading Loading @@ -201,8 +217,8 @@ static int rt9120_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *comp = dai->component; unsigned int param_width, param_slot_width; int width; unsigned int param_width, param_slot_width, auto_sync; int width, fs; switch (width = params_width(param)) { case 16: Loading Loading @@ -240,6 +256,16 @@ static int rt9120_hw_params(struct snd_pcm_substream *substream, snd_soc_component_update_bits(comp, RT9120_REG_I2SWL, RT9120_AUDWL_MASK, param_slot_width); fs = width * params_channels(param); /* If fs is divided by 48, disable auto sync */ if (fs % 48 == 0) auto_sync = 0; else auto_sync = RT9120_AUTOSYNC_MASK; snd_soc_component_update_bits(comp, RT9120_REG_DIGCFG, RT9120_AUTOSYNC_MASK, auto_sync); return 0; } Loading Loading @@ -279,9 +305,11 @@ static const struct regmap_range rt9120_rd_yes_ranges[] = { regmap_reg_range(0x20, 0x27), regmap_reg_range(0x30, 0x38), regmap_reg_range(0x3A, 0x40), regmap_reg_range(0x63, 0x63), regmap_reg_range(0x65, 0x65), regmap_reg_range(0x69, 0x69), regmap_reg_range(0x6C, 0x6C) regmap_reg_range(0x6C, 0x6C), regmap_reg_range(0xF8, 0xF8) }; static const struct regmap_access_table rt9120_rd_table = { Loading @@ -297,9 +325,11 @@ static const struct regmap_range rt9120_wr_yes_ranges[] = { regmap_reg_range(0x30, 0x38), regmap_reg_range(0x3A, 0x3D), regmap_reg_range(0x40, 0x40), regmap_reg_range(0x63, 0x63), regmap_reg_range(0x65, 0x65), regmap_reg_range(0x69, 0x69), regmap_reg_range(0x6C, 0x6C) regmap_reg_range(0x6C, 0x6C), regmap_reg_range(0xF8, 0xF8) }; static const struct regmap_access_table rt9120_wr_table = { Loading Loading @@ -370,7 +400,7 @@ static int rt9120_reg_write(void *context, unsigned int reg, unsigned int val) static const struct regmap_config rt9120_regmap_config = { .reg_bits = 8, .val_bits = 32, .max_register = RT9120_REG_UVPOPT, .max_register = RT9120_REG_DIGCFG, .reg_read = rt9120_reg_read, .reg_write = rt9120_reg_write, Loading @@ -388,8 +418,16 @@ static int rt9120_check_vendor_info(struct rt9120_data *data) if (ret) return ret; if ((devid & RT9120_VID_MASK) != RT9120_VENDOR_ID) { dev_err(data->dev, "DEVID not correct [0x%04x]\n", devid); devid = FIELD_GET(RT9120_VID_MASK, devid); switch (devid) { case RT9120_VENDOR_ID: data->chip_idx = CHIP_IDX_RT9120; break; case RT9120S_VENDOR_ID: data->chip_idx = CHIP_IDX_RT9120S; break; default: dev_err(data->dev, "DEVID not correct [0x%0x]\n", devid); return -ENODEV; } Loading