On Tue, Sep 03, 2019 at 03:08:21PM +0800, richtek.jeff.chang@gmail.com wrote:
--- /dev/null +++ b/sound/soc/codecs/mt6660.c @@ -0,0 +1,802 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- Copyright (c) 2019 MediaTek Inc.
- */
Please make the entire comment block a C++ comment so things look more consistent.
+struct reg_size_table {
- u32 addr;
- u8 size;
+};
+static const struct reg_size_table mt6660_reg_size_table[] = {
- { MT6660_REG_HPF1_COEF, 4 },
- { MT6660_REG_HPF2_COEF, 4 },
- { MT6660_REG_TDM_CFG3, 2 },
- { MT6660_REG_RESV17, 2 },
- { MT6660_REG_RESV23, 2 },
- { MT6660_REG_SIGMAX, 2 },
- { MT6660_REG_DEVID, 2},
- { MT6660_REG_TDM_CFG3, 2},
- { MT6660_REG_HCLIP_CTRL, 2},
- { MT6660_REG_DA_GAIN, 2},
+};
Please talk to your hardware designers about the benefits of consistent register sizes :/
+static int32_t mt6660_i2c_update_bits(struct mt6660_chip *chip,
- uint32_t addr, uint32_t mask, uint32_t data)
+{
It would be good to implement a regmap rather than open coding *everything* - it'd give you things like this without needing to open code them. Providing you don't use the cache code it should cope fine with variable register sizes.
+static int mt6660_i2c_init_setting(struct mt6660_chip *chip) +{
- int i, len, ret;
- const struct codec_reg_val *init_table;
- init_table = e4_reg_inits;
- len = ARRAY_SIZE(e4_reg_inits);
- for (i = 0; i < len; i++) {
ret = mt6660_i2c_update_bits(chip, init_table[i].addr,
init_table[i].mask, init_table[i].data);
if (ret < 0)
return ret;
Why are we not using the chip defaults here?
+static int mt6660_chip_power_on(
- struct snd_soc_component *component, int on_off)
+{
- struct mt6660_chip *chip = (struct mt6660_chip *)
snd_soc_component_get_drvdata(component);
- int ret = 0;
- unsigned int val;
- dev_dbg(component->dev, "%s: on_off = %d\n", __func__, on_off);
- mutex_lock(&chip->var_lock);
- if (on_off) {
if (chip->pwr_cnt == 0) {
ret = mt6660_i2c_update_bits(chip,
MT6660_REG_SYSTEM_CTRL, 0x01, 0x00);
val = mt6660_i2c_read(chip, MT6660_REG_IRQ_STATUS1);
dev_info(chip->dev,
"%s reg0x05 = 0x%x\n", __func__, val);
}
chip->pwr_cnt++;
This looks like you're open coding runtime PM stuff? AFAICT the issue is that you need to write to this register to do any I/O. Just implement this via the standard runtime PM framework, you'll need to do something about the register I/O in the controls (ideally in the framework, it'd be a lot easier if you did have a cache) but you could cut out this bit.
+static int mt6660_component_set_bias_level(struct snd_soc_component *component,
- enum snd_soc_bias_level level)
+{
- struct snd_soc_dapm_context *dapm =
snd_soc_component_get_dapm(component);
- int ret;
- unsigned int val;
- struct mt6660_chip *chip = snd_soc_component_get_drvdata(component);
- if (dapm->bias_level == level) {
dev_warn(component->dev, "%s: repeat level change\n", __func__);
This shouldn't be a warning.
+static const struct snd_kcontrol_new mt6660_component_snd_controls[] = {
- SOC_SINGLE_EXT_TLV("Volume_Ctrl", MT6660_REG_VOL_CTRL, 0, 255,
1, snd_soc_get_volsw, mt6660_component_put_volsw,
vol_ctl_tlv),
- SOC_SINGLE_EXT("WDT_Enable", MT6660_REG_WDT_CTRL, 7, 1, 0,
snd_soc_get_volsw, mt6660_component_put_volsw),
These control names should all use standard ALSA control names - on/off switches should end in Switch, volume controls in Volume.
- SOC_SINGLE_EXT("I2SLRS", MT6660_REG_DATAO_SEL, 6, 3, 0,
snd_soc_get_volsw, mt6660_component_put_volsw),
- SOC_SINGLE_EXT("I2SDOLS", MT6660_REG_DATAO_SEL, 3, 7, 0,
snd_soc_get_volsw, mt6660_component_put_volsw),
- SOC_SINGLE_EXT("I2SDORS", MT6660_REG_DATAO_SEL, 0, 7, 0,
snd_soc_get_volsw, mt6660_component_put_volsw),
What do these controls do?