Dear Mark Brown, Thank you for your detailed feedback. I will apply what you told me as soon as possible and request it again. I'll ask you again if there's anything wrong with the correction. I appreciate your quick response. Thank you very much for your time Best Regards, Kiseok Jo Iron Device Corporation Tel.: +82-2-541-2896 Mobile: +82-10-3320-0376 Email: kiseok.jo@xxxxxxxxxxxxxx The information in this email and any attachment is confidential and may be legally protected. It is intended solely for the addressee. Access to this email by anyone else is unauthorised. If you are not the intended recipient, any disclosure or actions taken as a result of the information in this email is prohibited and may be unlawful. If you are not the intended recipient, please notify us immediately and then delete this e-mail and any attachment. Thank you. -----Original Message----- From: Mark Brown <broonie@xxxxxxxxxx> Sent: Wednesday, August 17, 2022 9:09 PM To: Ki-Seok Jo <kiseok.jo@xxxxxxxxxxxxxx> Cc: Gyu-Hwa Park <gyuhwa.park@xxxxxxxxxxxxxx>; alsa-devel@xxxxxxxxxxxxxxxx; Suk-Min Kang <sukmin.kang@xxxxxxxxxxxxxx> Subject: Re: [PATCH 1/2] ASoC: sma1303: Add driver for Iron Device SMA1303 Amp On Wed, Aug 17, 2022 at 12:29:37PM +0900, Kiseok Jo wrote: I got part way through reviewing this driver. The top level feedback here is that the driver appears to be exposing everything in the device to userspace as enumeration controls rather than using standard features like DAPM, or appropriate other control types where there's something that's a better fit than an enum. If there's a strong reason for the driver to do something so unusual then theere should be something in here which explains what's going on. > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* sma1303.c -- sma1303 ALSA SoC Audio driver > + * > + * Copyright 2019 Iron Device Corporation 2019? Please make the entire block a C++ one so things look more intentional. > +static int power_up_down_control_put(struct snd_kcontrol *kcontrol, > + struct snd_ctl_elem_value *ucontrol) { > + struct snd_soc_component *component = > + snd_soc_kcontrol_component(kcontrol); > + struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); > + int sel = (int)ucontrol->value.integer.value[0]; > + > + if (sel && !(sma1303->force_amp_power_down)) > + sma1303_startup(component); > + else > + sma1303_shutdown(component); > + > + return 0; > +} This and all the other controls need to return 1 on change, please make sure a card with your driver your driver passes mixer-test cleanly - it will spot this and other problems. However I wouldn't expect the power controls to exist at all, generally power is managed via DAPM rather than userspace. > +static int force_sdo_bypass_put(struct snd_kcontrol *kcontrol, > + struct snd_ctl_elem_value *ucontrol) { > + struct snd_soc_component *component = > + snd_soc_kcontrol_component(kcontrol); > + struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); > + int sel = (int)ucontrol->value.integer.value[0]; > + > + sma1303->sdo_bypass_flag = (bool)sel; > + > + return 0; > +} What is this bypassing? > +static const char * const sma1303_input_format_text[] = { > + "I2S", "LJ", "Reserved", "Reserved", > + "RJ_16", "RJ_18", "RJ_20", "RJ_24"}; > + > +static const struct soc_enum sma1303_input_format_enum = > +SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1303_input_format_text), > + sma1303_input_format_text); This should be controlled by the machine driver through set_dai_fmt() and hw_params(). > +static const char * const sma1303_pcm_n_slot_text[] = { > + "Slot_1", "Slot_2", "Slot_3", "Slot_4", "Slot_5", "Slot_6", > + "Slot_7", "Slot_8", "Slot_9", "Slot_10", "Slot_11", "Slot_12", > + "Slot_13", "Slot_14", "Slot_15", "Slot_16"}; > + > +static const struct soc_enum sma1303_pcm_n_slot_enum = > +SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1303_pcm_n_slot_text), > + sma1303_pcm_n_slot_text); set_tdm_slot() > +static const char * const sma1303_port_config_text[] = { > + "IN_Port", "Reserved", "OUT_Port", "Reserved"}; This should be DT properties, possibly using the pinctrl schema depending on what's actually going on. > +static const char * const sma1303_port_out_sel_text[] = { > + "Disable", "Format_C", "Mixer_out", "After_DSP", > + "Postscaler", "Reserved", "Reserved", "Reserved"}; > + > +static const struct soc_enum sma1303_port_out_sel_enum = > + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1303_port_out_sel_text), > + sma1303_port_out_sel_text); This looks like it should be a DAPM routing control. > +static const char * const sma1303_spk_off_slope_text[] = { > + "00", "01", "10", "11"}; > + > +static const struct soc_enum sma1303_spk_off_slope_enum = > + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1303_spk_off_slope_text), > + sma1303_spk_off_slope_text); Why make this an enum and not just a numerical control with values 0-3? > +static const char * const sma1303_spkmode_text[] = { > + "Off", "Mono", "Reserved", "Reserved", > + "Stereo", "Reserved", "Reserved", "Reserved"}; > + > +static const struct soc_enum sma1303_spkmode_enum = > + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1303_spkmode_text), > + sma1303_spkmode_text); Use a value enum to eliminate the reserved values from user selection, however if this is controlling if the device has mono or stereo speakers it should be a DT property since that's unlikely to change at runtime. > +static const char * const sma1303_input_gain_text[] = { > + "Gain_0dB", "Gain_M6dB", "Gain_M12dB", "Gain_MInf"}; > + > +static const struct soc_enum sma1303_input_gain_enum = > +SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1303_input_gain_text), > + sma1303_input_gain_text); This should just be a normal volume control. I've stopped reviewing at this point.