[alsa-devel] [PATCH resend 0/4] ASoC: omap-mcpdm/twl6040: Offset cancellation
Hello,
The following series adds support for the McPDM offset cancellation feature. It provides the needed functionality to: - read the HSTRIM values from the twl6040 codec - configure the offset cancellation registers in OMAP-McPDM
Rebased batches on top of: git://opensource.wolfsonmicro.com/linux-2.6-asoc, for-3.2 branch
No other changes.
Mark: I have not added you acks to the patches, since you will be signing them off anyways.
Regards, Peter --- Peter Ujfalusi (4): ASoC: twl6040: Read the TRIM values from the chip ASoC: twl6040: Function to fetch the TRIM values ASoC: omap-mcpdm: API to configure offset cancellation ASoC: sdp4430: Configure McPDM offset cancellation
sound/soc/codecs/twl6040.c | 16 ++++++++++++++++ sound/soc/codecs/twl6040.h | 13 +++++++++++++ sound/soc/omap/omap-mcpdm.c | 25 +++++++++++++++++++++++++ sound/soc/omap/omap-mcpdm.h | 12 ++++++++++++ sound/soc/omap/sdp4430.c | 10 +++++++++- 5 files changed, 75 insertions(+), 1 deletions(-)
Update the reg_cache with values from chip regarding to TRIM.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com --- sound/soc/codecs/twl6040.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index dabf37b..26c06ff 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -278,9 +278,16 @@ static void twl6040_init_chip(struct snd_soc_codec *codec) struct twl6040 *twl6040 = codec->control_data; u8 val;
+ /* Update reg_cache: ASICREV, and TRIM values */ val = twl6040_get_revid(twl6040); twl6040_write_reg_cache(codec, TWL6040_REG_ASICREV, val);
+ twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM1); + twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM2); + twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM3); + twl6040_read_reg_volatile(codec, TWL6040_REG_HSOTRIM); + twl6040_read_reg_volatile(codec, TWL6040_REG_HFOTRIM); + /* Change chip defaults */ /* No imput selected for microphone amplifiers */ twl6040_write_reg_cache(codec, TWL6040_REG_MICLCTL, 0x18);
Provide API to fetch the TRIM values (for machine drivers)
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com --- sound/soc/codecs/twl6040.c | 9 +++++++++ sound/soc/codecs/twl6040.h | 13 +++++++++++++ 2 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 26c06ff..d5c4bb4 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1113,6 +1113,15 @@ int twl6040_get_clk_id(struct snd_soc_codec *codec) } EXPORT_SYMBOL_GPL(twl6040_get_clk_id);
+int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim) +{ + if (unlikely(trim >= TWL6040_TRIM_INVAL)) + return -EINVAL; + + return twl6040_read_reg_cache(codec, TWL6040_REG_TRIM1 + trim); +} +EXPORT_SYMBOL_GPL(twl6040_get_trim_value); + static const struct snd_kcontrol_new twl6040_snd_controls[] = { /* Capture gains */ SOC_DOUBLE_TLV("Capture Preamplifier Volume", diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h index d8de678..a83277b 100644 --- a/sound/soc/codecs/twl6040.h +++ b/sound/soc/codecs/twl6040.h @@ -22,8 +22,21 @@ #ifndef __TWL6040_H__ #define __TWL6040_H__
+enum twl6040_trim { + TWL6040_TRIM_TRIM1 = 0, + TWL6040_TRIM_TRIM2, + TWL6040_TRIM_TRIM3, + TWL6040_TRIM_HSOTRIM, + TWL6040_TRIM_HFOTRIM, + TWL6040_TRIM_INVAL, +}; + +#define TWL6040_HSF_TRIM_LEFT(x) (x & 0x0f) +#define TWL6040_HSF_TRIM_RIGHT(x) ((x >> 4) & 0x0f) + void twl6040_hs_jack_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, int report); int twl6040_get_clk_id(struct snd_soc_codec *codec); +int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim);
#endif /* End of __TWL6040_H__ */
The offset cancellation values can be different from board to board, even on the same HW platform. Provide a way for the machine drivers to configure the McPDM offset cancellation.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com --- sound/soc/omap/omap-mcpdm.c | 25 +++++++++++++++++++++++++ sound/soc/omap/omap-mcpdm.h | 12 ++++++++++++ 2 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 2c9fa51..41d1706 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -59,6 +59,9 @@ struct omap_mcpdm { /* McPDM FIFO thresholds */ u32 dn_threshold; u32 up_threshold; + + /* McPDM dn offsets for rx1, and 2 channels */ + u32 dn_rx_offset; };
/* @@ -183,6 +186,15 @@ static void omap_mcpdm_open_streams(struct omap_mcpdm *mcpdm) MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL | MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL);
+ /* Enable DN RX1/2 offset cancellation feature, if configured */ + if (mcpdm->dn_rx_offset) { + u32 dn_offset = mcpdm->dn_rx_offset; + + omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset); + dn_offset |= (MCPDM_DN_OFST_RX1_EN | MCPDM_DN_OFST_RX2_EN); + omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset); + } + omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN, mcpdm->dn_threshold); omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP, mcpdm->up_threshold);
@@ -209,6 +221,10 @@ static void omap_mcpdm_close_streams(struct omap_mcpdm *mcpdm)
/* Disable DMA request generation for uplink */ omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_CLR, MCPDM_DMA_UP_ENABLE); + + /* Disable RX1/2 offset cancellation */ + if (mcpdm->dn_rx_offset) + omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, 0); }
static irqreturn_t omap_mcpdm_irq_handler(int irq, void *dev_id) @@ -418,6 +434,15 @@ static struct snd_soc_dai_driver omap_mcpdm_dai = { .ops = &omap_mcpdm_dai_ops, };
+void omap_mcpdm_configure_dn_offsets(struct snd_soc_pcm_runtime *rtd, + u8 rx1, u8 rx2) +{ + struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(rtd->cpu_dai); + + mcpdm->dn_rx_offset = MCPDM_DNOFST_RX1(rx1) | MCPDM_DNOFST_RX2(rx2); +} +EXPORT_SYMBOL_GPL(omap_mcpdm_configure_dn_offsets); + static __devinit int asoc_mcpdm_probe(struct platform_device *pdev) { struct omap_mcpdm *mcpdm; diff --git a/sound/soc/omap/omap-mcpdm.h b/sound/soc/omap/omap-mcpdm.h index d23122a..de8cf26 100644 --- a/sound/soc/omap/omap-mcpdm.h +++ b/sound/soc/omap/omap-mcpdm.h @@ -92,4 +92,16 @@ #define MCPDM_UP_THRES_MAX 0xF #define MCPDM_DN_THRES_MAX 0xF
+/* + * MCPDM_DN_OFFSET bit fields + */ + +#define MCPDM_DN_OFST_RX1_EN (1 << 0) +#define MCPDM_DNOFST_RX1(x) ((x & 0x1f) << 1) +#define MCPDM_DN_OFST_RX2_EN (1 << 8) +#define MCPDM_DNOFST_RX2(x) ((x & 0x1f) << 9) + +void omap_mcpdm_configure_dn_offsets(struct snd_soc_pcm_runtime *rtd, + u8 rx1, u8 rx2); + #endif /* End of __OMAP_MCPDM_H__ */
Based on the values from twl6040 codec (HSOTRIM L/R) we can configure the McPDM offset cancellation.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com --- sound/soc/omap/sdp4430.c | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c index 4200eb4..249d84b 100644 --- a/sound/soc/omap/sdp4430.c +++ b/sound/soc/omap/sdp4430.c @@ -121,7 +121,7 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; - int ret; + int ret, hs_trim;
/* Add SDP4430 specific widgets */ ret = snd_soc_dapm_new_controls(dapm, sdp4430_twl6040_dapm_widgets, @@ -144,6 +144,14 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) if (ret) return ret;
+ /* + * Configure McPDM offset cancellation based on the HSOTRIM value from + * twl6040. + */ + hs_trim = twl6040_get_trim_value(codec, TWL6040_TRIM_HSOTRIM); + omap_mcpdm_configure_dn_offsets(rtd, TWL6040_HSF_TRIM_LEFT(hs_trim), + TWL6040_HSF_TRIM_RIGHT(hs_trim)); + /* Headset jack detection */ ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, &hs_jack);
participants (1)
-
Peter Ujfalusi