All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: Jeff Chang <richtek.jeff.chang@gmail.com>
Cc: lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz,
	tiwai@suse.com, matthias.bgg@gmail.com,
	alsa-devel@alsa-project.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, jeff_chang@richtek.com
Subject: Re: [PATCH v6] ASoC: Add MediaTek MT6660 Speaker Amp Driver
Date: Tue, 14 Jan 2020 08:44:22 +0100	[thread overview]
Message-ID: <s5htv4yfpnt.wl-tiwai@suse.de> (raw)
In-Reply-To: <1578968526-13191-1-git-send-email-richtek.jeff.chang@gmail.com>

On Tue, 14 Jan 2020 03:22:06 +0100,
Jeff Chang wrote:
> diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
> index 229cc89..f135fbb 100644
> --- a/sound/soc/codecs/Kconfig
> +++ b/sound/soc/codecs/Kconfig
> @@ -1465,6 +1466,16 @@ config SND_SOC_MT6358
>  	  Enable support for the platform which uses MT6358 as
>  	  external codec device.
>  
> +config SND_SOC_MT6660
> +	tristate "Mediatek MT6660 Speaker Amplifier"
> +	depends on I2C
> +	help
> +	  MediaTek MT6660 is a smart power amplifier which contain
> +	  speaker protection, multi-band DRC, equalizer functions.
> +	  Select N if you don't have MT6660 on board.
> +	  Select M to build this as module.
> +
> +

One blank line too much here.

> --- /dev/null
> +++ b/sound/soc/codecs/mt6660.c
> @@ -0,0 +1,533 @@
> +// SPDX-License-Identifier: GPL-2.0 //
> +
> +// Copyright (c) 2019 MediaTek Inc.
> +
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/version.h>
> +#include <linux/err.h>
> +#include <linux/i2c.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/delay.h>
> +#include <sound/soc.h>
> +#include <sound/tlv.h>
> +#include <sound/pcm_params.h>
> +#include <linux/debugfs.h>

Move linux/*.h above sound/*.h inclusion.

> +
> +#include "mt6660.h"
> +
> +#pragma pack(push, 1)

Actually packing makes little sense for those use cases.
As I mentioned earlier, packing is useful only for either saving some
memory (e.g. for a large array) or a strict size definition like ABI.

> +struct codec_reg_val {
> +	u32 addr;
> +	u32 mask;
> +	u32 data;
> +};

Is this struct used anywhere?  If not, kill it.

> +static struct regmap_config mt6660_regmap_config = {

This can be const.

> +static int mt6660_codec_dac_event(struct snd_soc_dapm_widget *w,
> +	struct snd_kcontrol *kcontrol, int event)
> +{
> +

A superfluous blank line.

> +static int mt6660_component_get_volsw(struct snd_kcontrol *kcontrol,
> +				  struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *component =
> +		snd_soc_kcontrol_component(kcontrol);
> +	struct mt6660_chip *chip = (struct mt6660_chip *)
> +		snd_soc_component_get_drvdata(component);
> +	int ret = -EINVAL;
> +
> +	if (!strcmp(kcontrol->id.name, "Chip Rev")) {
> +		ucontrol->value.integer.value[0] = chip->chip_rev & 0x0f;
> +		ret = 0;
> +	}
> +	return ret;

So, "T0 SEL" control gets always an error when reading?
Then can't we pass simply NULL for get ops instead?

> +static int _mt6660_chip_power_on(struct mt6660_chip *chip, int on_off)
> +{
> +	u8 reg_data;
> +	int ret;
> +
> +	ret = i2c_smbus_read_byte_data(chip->i2c, MT6660_REG_SYSTEM_CTRL);
> +	if (ret < 0)
> +		return ret;
> +	reg_data = (u8)ret;
> +	if (on_off)
> +		reg_data &= (~0x01);
> +	else
> +		reg_data |= 0x01;
> +	return regmap_write(chip->regmap, MT6660_REG_SYSTEM_CTRL, reg_data);

Hm, this looks like an open-code of forced update bits via regmap.
But interestingly there is no corresponding standard helper for that.
Essentially it should be regmap_update_bits_base() with force=1.

Mark?

> +static int mt6660_component_aif_hw_params(struct snd_pcm_substream *substream,
> +	struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
> +{
> +	int word_len = params_physical_width(hw_params);
> +	int aud_bit = params_width(hw_params);
....
> +	switch (aud_bit) {
> +	case 16:
> +		reg_data = 3;
> +		break;
> +	case 18:
> +		reg_data = 2;
> +		break;
> +	case 20:
> +		reg_data = 1;
> +		break;
> +	case 24:
> +	case 32:
> +		reg_data = 0;
> +		break;

So here both 24 and 32 bits data are handled equally, and...

....
> +	ret = snd_soc_component_update_bits(dai->component,
> +		MT6660_REG_TDM_CFG3, 0x3f0, word_len << 4);

... word_len is same for both S32 and S24 formats, so there can be no
difference between S24 and S32 format handling in the code.
Meanwhile, the supported formats are:

> +#define STUB_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | \
> +			SNDRV_PCM_FMTBIT_U16_LE | \
> +			SNDRV_PCM_FMTBIT_S24_LE | \
> +			SNDRV_PCM_FMTBIT_U24_LE | \
> +			SNDRV_PCM_FMTBIT_S32_LE | \
> +			SNDRV_PCM_FMTBIT_U32_LE)

Are you sure that S24_* formats really work properly?

Also, the code has no check / setup of the format signedness.
Do unsigned formats (U16, U24, etc) really work as expected, too?

> +static inline int _mt6660_chip_id_check(struct mt6660_chip *chip)

Drop unnecessary inline (here and other places).
Compiler optimizes well by itself.

> +static inline int _mt6660_chip_sw_reset(struct mt6660_chip *chip)
> +{
> +	int ret;
> +
> +	/* turn on main pll first, then trigger reset */
> +	ret = regmap_write(chip->regmap, 0x03, 0x00);

It's MT6660_REG_SYSTEM_CTRL, right?

> +	if (ret < 0)
> +		return ret;
> +	ret = regmap_write(chip->regmap, MT6660_REG_SYSTEM_CTRL, 0x80);
> +	if (ret < 0)
> +		return ret;
> +	msleep(30);
> +	return 0;
> +}
> +
> +static inline int _mt6660_read_chip_revision(struct mt6660_chip *chip)
> +{
> +	u8 reg_data[2];
> +	int ret;
> +
> +	ret = i2c_smbus_read_i2c_block_data(
> +		chip->i2c, MT6660_REG_DEVID, 2, reg_data);

Why avoiding regmap here?  This and chip_id_check() use the raw access
by some reason...


thanks,

Takashi

WARNING: multiple messages have this Message-ID (diff)
From: Takashi Iwai <tiwai@suse.de>
To: Jeff Chang <richtek.jeff.chang@gmail.com>
Cc: alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org,
	tiwai@suse.com, lgirdwood@gmail.com, jeff_chang@richtek.com,
	broonie@kernel.org, matthias.bgg@gmail.com,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [alsa-devel] [PATCH v6] ASoC: Add MediaTek MT6660 Speaker Amp Driver
Date: Tue, 14 Jan 2020 08:44:22 +0100	[thread overview]
Message-ID: <s5htv4yfpnt.wl-tiwai@suse.de> (raw)
In-Reply-To: <1578968526-13191-1-git-send-email-richtek.jeff.chang@gmail.com>

On Tue, 14 Jan 2020 03:22:06 +0100,
Jeff Chang wrote:
> diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
> index 229cc89..f135fbb 100644
> --- a/sound/soc/codecs/Kconfig
> +++ b/sound/soc/codecs/Kconfig
> @@ -1465,6 +1466,16 @@ config SND_SOC_MT6358
>  	  Enable support for the platform which uses MT6358 as
>  	  external codec device.
>  
> +config SND_SOC_MT6660
> +	tristate "Mediatek MT6660 Speaker Amplifier"
> +	depends on I2C
> +	help
> +	  MediaTek MT6660 is a smart power amplifier which contain
> +	  speaker protection, multi-band DRC, equalizer functions.
> +	  Select N if you don't have MT6660 on board.
> +	  Select M to build this as module.
> +
> +

One blank line too much here.

> --- /dev/null
> +++ b/sound/soc/codecs/mt6660.c
> @@ -0,0 +1,533 @@
> +// SPDX-License-Identifier: GPL-2.0 //
> +
> +// Copyright (c) 2019 MediaTek Inc.
> +
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/version.h>
> +#include <linux/err.h>
> +#include <linux/i2c.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/delay.h>
> +#include <sound/soc.h>
> +#include <sound/tlv.h>
> +#include <sound/pcm_params.h>
> +#include <linux/debugfs.h>

Move linux/*.h above sound/*.h inclusion.

> +
> +#include "mt6660.h"
> +
> +#pragma pack(push, 1)

Actually packing makes little sense for those use cases.
As I mentioned earlier, packing is useful only for either saving some
memory (e.g. for a large array) or a strict size definition like ABI.

> +struct codec_reg_val {
> +	u32 addr;
> +	u32 mask;
> +	u32 data;
> +};

Is this struct used anywhere?  If not, kill it.

> +static struct regmap_config mt6660_regmap_config = {

This can be const.

> +static int mt6660_codec_dac_event(struct snd_soc_dapm_widget *w,
> +	struct snd_kcontrol *kcontrol, int event)
> +{
> +

A superfluous blank line.

> +static int mt6660_component_get_volsw(struct snd_kcontrol *kcontrol,
> +				  struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *component =
> +		snd_soc_kcontrol_component(kcontrol);
> +	struct mt6660_chip *chip = (struct mt6660_chip *)
> +		snd_soc_component_get_drvdata(component);
> +	int ret = -EINVAL;
> +
> +	if (!strcmp(kcontrol->id.name, "Chip Rev")) {
> +		ucontrol->value.integer.value[0] = chip->chip_rev & 0x0f;
> +		ret = 0;
> +	}
> +	return ret;

So, "T0 SEL" control gets always an error when reading?
Then can't we pass simply NULL for get ops instead?

> +static int _mt6660_chip_power_on(struct mt6660_chip *chip, int on_off)
> +{
> +	u8 reg_data;
> +	int ret;
> +
> +	ret = i2c_smbus_read_byte_data(chip->i2c, MT6660_REG_SYSTEM_CTRL);
> +	if (ret < 0)
> +		return ret;
> +	reg_data = (u8)ret;
> +	if (on_off)
> +		reg_data &= (~0x01);
> +	else
> +		reg_data |= 0x01;
> +	return regmap_write(chip->regmap, MT6660_REG_SYSTEM_CTRL, reg_data);

Hm, this looks like an open-code of forced update bits via regmap.
But interestingly there is no corresponding standard helper for that.
Essentially it should be regmap_update_bits_base() with force=1.

Mark?

> +static int mt6660_component_aif_hw_params(struct snd_pcm_substream *substream,
> +	struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
> +{
> +	int word_len = params_physical_width(hw_params);
> +	int aud_bit = params_width(hw_params);
....
> +	switch (aud_bit) {
> +	case 16:
> +		reg_data = 3;
> +		break;
> +	case 18:
> +		reg_data = 2;
> +		break;
> +	case 20:
> +		reg_data = 1;
> +		break;
> +	case 24:
> +	case 32:
> +		reg_data = 0;
> +		break;

So here both 24 and 32 bits data are handled equally, and...

....
> +	ret = snd_soc_component_update_bits(dai->component,
> +		MT6660_REG_TDM_CFG3, 0x3f0, word_len << 4);

... word_len is same for both S32 and S24 formats, so there can be no
difference between S24 and S32 format handling in the code.
Meanwhile, the supported formats are:

> +#define STUB_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | \
> +			SNDRV_PCM_FMTBIT_U16_LE | \
> +			SNDRV_PCM_FMTBIT_S24_LE | \
> +			SNDRV_PCM_FMTBIT_U24_LE | \
> +			SNDRV_PCM_FMTBIT_S32_LE | \
> +			SNDRV_PCM_FMTBIT_U32_LE)

Are you sure that S24_* formats really work properly?

Also, the code has no check / setup of the format signedness.
Do unsigned formats (U16, U24, etc) really work as expected, too?

> +static inline int _mt6660_chip_id_check(struct mt6660_chip *chip)

Drop unnecessary inline (here and other places).
Compiler optimizes well by itself.

> +static inline int _mt6660_chip_sw_reset(struct mt6660_chip *chip)
> +{
> +	int ret;
> +
> +	/* turn on main pll first, then trigger reset */
> +	ret = regmap_write(chip->regmap, 0x03, 0x00);

It's MT6660_REG_SYSTEM_CTRL, right?

> +	if (ret < 0)
> +		return ret;
> +	ret = regmap_write(chip->regmap, MT6660_REG_SYSTEM_CTRL, 0x80);
> +	if (ret < 0)
> +		return ret;
> +	msleep(30);
> +	return 0;
> +}
> +
> +static inline int _mt6660_read_chip_revision(struct mt6660_chip *chip)
> +{
> +	u8 reg_data[2];
> +	int ret;
> +
> +	ret = i2c_smbus_read_i2c_block_data(
> +		chip->i2c, MT6660_REG_DEVID, 2, reg_data);

Why avoiding regmap here?  This and chip_id_check() use the raw access
by some reason...


thanks,

Takashi
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

WARNING: multiple messages have this Message-ID (diff)
From: Takashi Iwai <tiwai@suse.de>
To: Jeff Chang <richtek.jeff.chang@gmail.com>
Cc: alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org,
	tiwai@suse.com, lgirdwood@gmail.com, jeff_chang@richtek.com,
	broonie@kernel.org, matthias.bgg@gmail.com, perex@perex.cz,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v6] ASoC: Add MediaTek MT6660 Speaker Amp Driver
Date: Tue, 14 Jan 2020 08:44:22 +0100	[thread overview]
Message-ID: <s5htv4yfpnt.wl-tiwai@suse.de> (raw)
In-Reply-To: <1578968526-13191-1-git-send-email-richtek.jeff.chang@gmail.com>

On Tue, 14 Jan 2020 03:22:06 +0100,
Jeff Chang wrote:
> diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
> index 229cc89..f135fbb 100644
> --- a/sound/soc/codecs/Kconfig
> +++ b/sound/soc/codecs/Kconfig
> @@ -1465,6 +1466,16 @@ config SND_SOC_MT6358
>  	  Enable support for the platform which uses MT6358 as
>  	  external codec device.
>  
> +config SND_SOC_MT6660
> +	tristate "Mediatek MT6660 Speaker Amplifier"
> +	depends on I2C
> +	help
> +	  MediaTek MT6660 is a smart power amplifier which contain
> +	  speaker protection, multi-band DRC, equalizer functions.
> +	  Select N if you don't have MT6660 on board.
> +	  Select M to build this as module.
> +
> +

One blank line too much here.

> --- /dev/null
> +++ b/sound/soc/codecs/mt6660.c
> @@ -0,0 +1,533 @@
> +// SPDX-License-Identifier: GPL-2.0 //
> +
> +// Copyright (c) 2019 MediaTek Inc.
> +
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/version.h>
> +#include <linux/err.h>
> +#include <linux/i2c.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/delay.h>
> +#include <sound/soc.h>
> +#include <sound/tlv.h>
> +#include <sound/pcm_params.h>
> +#include <linux/debugfs.h>

Move linux/*.h above sound/*.h inclusion.

> +
> +#include "mt6660.h"
> +
> +#pragma pack(push, 1)

Actually packing makes little sense for those use cases.
As I mentioned earlier, packing is useful only for either saving some
memory (e.g. for a large array) or a strict size definition like ABI.

> +struct codec_reg_val {
> +	u32 addr;
> +	u32 mask;
> +	u32 data;
> +};

Is this struct used anywhere?  If not, kill it.

> +static struct regmap_config mt6660_regmap_config = {

This can be const.

> +static int mt6660_codec_dac_event(struct snd_soc_dapm_widget *w,
> +	struct snd_kcontrol *kcontrol, int event)
> +{
> +

A superfluous blank line.

> +static int mt6660_component_get_volsw(struct snd_kcontrol *kcontrol,
> +				  struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *component =
> +		snd_soc_kcontrol_component(kcontrol);
> +	struct mt6660_chip *chip = (struct mt6660_chip *)
> +		snd_soc_component_get_drvdata(component);
> +	int ret = -EINVAL;
> +
> +	if (!strcmp(kcontrol->id.name, "Chip Rev")) {
> +		ucontrol->value.integer.value[0] = chip->chip_rev & 0x0f;
> +		ret = 0;
> +	}
> +	return ret;

So, "T0 SEL" control gets always an error when reading?
Then can't we pass simply NULL for get ops instead?

> +static int _mt6660_chip_power_on(struct mt6660_chip *chip, int on_off)
> +{
> +	u8 reg_data;
> +	int ret;
> +
> +	ret = i2c_smbus_read_byte_data(chip->i2c, MT6660_REG_SYSTEM_CTRL);
> +	if (ret < 0)
> +		return ret;
> +	reg_data = (u8)ret;
> +	if (on_off)
> +		reg_data &= (~0x01);
> +	else
> +		reg_data |= 0x01;
> +	return regmap_write(chip->regmap, MT6660_REG_SYSTEM_CTRL, reg_data);

Hm, this looks like an open-code of forced update bits via regmap.
But interestingly there is no corresponding standard helper for that.
Essentially it should be regmap_update_bits_base() with force=1.

Mark?

> +static int mt6660_component_aif_hw_params(struct snd_pcm_substream *substream,
> +	struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
> +{
> +	int word_len = params_physical_width(hw_params);
> +	int aud_bit = params_width(hw_params);
....
> +	switch (aud_bit) {
> +	case 16:
> +		reg_data = 3;
> +		break;
> +	case 18:
> +		reg_data = 2;
> +		break;
> +	case 20:
> +		reg_data = 1;
> +		break;
> +	case 24:
> +	case 32:
> +		reg_data = 0;
> +		break;

So here both 24 and 32 bits data are handled equally, and...

....
> +	ret = snd_soc_component_update_bits(dai->component,
> +		MT6660_REG_TDM_CFG3, 0x3f0, word_len << 4);

... word_len is same for both S32 and S24 formats, so there can be no
difference between S24 and S32 format handling in the code.
Meanwhile, the supported formats are:

> +#define STUB_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | \
> +			SNDRV_PCM_FMTBIT_U16_LE | \
> +			SNDRV_PCM_FMTBIT_S24_LE | \
> +			SNDRV_PCM_FMTBIT_U24_LE | \
> +			SNDRV_PCM_FMTBIT_S32_LE | \
> +			SNDRV_PCM_FMTBIT_U32_LE)

Are you sure that S24_* formats really work properly?

Also, the code has no check / setup of the format signedness.
Do unsigned formats (U16, U24, etc) really work as expected, too?

> +static inline int _mt6660_chip_id_check(struct mt6660_chip *chip)

Drop unnecessary inline (here and other places).
Compiler optimizes well by itself.

> +static inline int _mt6660_chip_sw_reset(struct mt6660_chip *chip)
> +{
> +	int ret;
> +
> +	/* turn on main pll first, then trigger reset */
> +	ret = regmap_write(chip->regmap, 0x03, 0x00);

It's MT6660_REG_SYSTEM_CTRL, right?

> +	if (ret < 0)
> +		return ret;
> +	ret = regmap_write(chip->regmap, MT6660_REG_SYSTEM_CTRL, 0x80);
> +	if (ret < 0)
> +		return ret;
> +	msleep(30);
> +	return 0;
> +}
> +
> +static inline int _mt6660_read_chip_revision(struct mt6660_chip *chip)
> +{
> +	u8 reg_data[2];
> +	int ret;
> +
> +	ret = i2c_smbus_read_i2c_block_data(
> +		chip->i2c, MT6660_REG_DEVID, 2, reg_data);

Why avoiding regmap here?  This and chip_id_check() use the raw access
by some reason...


thanks,

Takashi

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2020-01-14  7:44 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-14  2:22 [PATCH v6] ASoC: Add MediaTek MT6660 Speaker Amp Driver Jeff Chang
2020-01-14  2:22 ` Jeff Chang
2020-01-14  2:22 ` [alsa-devel] " Jeff Chang
2020-01-14  7:44 ` Takashi Iwai [this message]
2020-01-14  7:44   ` Takashi Iwai
2020-01-14  7:44   ` [alsa-devel] " Takashi Iwai
2020-01-14  9:48   ` jeff_chang(張世佳)
2020-01-14 10:12     ` Takashi Iwai
2020-01-14 10:12       ` Takashi Iwai
2020-01-14 10:12       ` [alsa-devel] " Takashi Iwai
2020-01-14 14:49       ` Mark Brown
2020-01-14 14:49         ` Mark Brown
2020-01-14 14:49         ` [alsa-devel] " Mark Brown
2020-01-14 12:47   ` Mark Brown
2020-01-14 12:47     ` Mark Brown
2020-01-14 12:47     ` [alsa-devel] " Mark Brown
2020-01-14 13:27     ` Takashi Iwai
2020-01-14 13:27       ` Takashi Iwai
2020-01-14 13:27       ` [alsa-devel] " Takashi Iwai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=s5htv4yfpnt.wl-tiwai@suse.de \
    --to=tiwai@suse.de \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=jeff_chang@richtek.com \
    --cc=lgirdwood@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=matthias.bgg@gmail.com \
    --cc=perex@perex.cz \
    --cc=richtek.jeff.chang@gmail.com \
    --cc=tiwai@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.