From: Peter Ujfalusi <hidden> Date: 2012-08-14 14:22:36
Hello,
Changes since v1:
- Get the MCLK frequencey from twl-core driver (via new API)
- hs_extmute_disable_level parameter has been removed
- empty of_find_node_by_name() in of.h for !CONFIG_OF builds
Mark: the extmute GPIO handling (when it is used) remained in the codec driver
for now. I can think more on how to add support for this type of mute control.
If you can point me to other codec needing this it would help on designing
something which is common enough for other users.
As for now I have a separate series to add GPIO controlled output amps (hp/spk).
I will send that to review soon.
Introl mail from v1:
The following series adds DT support for the twl4030 audio submodule which
provides audio codec and vibra functionality.
The MFD core driver is probed via DT, it will create the needed child devices
based on the provided information in the DT blob.
Child drivers (vibra, ASoC codec) will parse the core's node if needed to get
the needed parameters for their configuration.
In the ASoC codec driver the hs_extmute callback (which was used to toggle a
GPIO line) has been removed. The codec driver will receive the GPIO number
(if it is needed on the platform).
If the series is OK (and no objections from the maintainers), it would be good
if this can go via audio. Changed files are well contained within the
twl4030-audio stack so I do not expect merge issues later.
The series has been tested on BeagleBoard (with the McBSP DT series, and with
the upcoming DT audio support for BeagleBoard).
Regards,
Peter
---
Peter Ujfalusi (14):
MFD: twl4030-audio: Clean up MODULE_* and platform_driver part
MFD: twl4030-audio: Convert to use devm_kzalloc
MFD: twl4030-audio: Rearange and clean-up the probe function
MFD: twl-core: Add API to query the HFCLK rate
MFD: twl4030-audio: Get audio MCLK via twl-core API instead of pdata
dt: Add empty of_find_node_by_name() function
MFD: twl4030-audio: Add DT support
Input: twl4030-vibra: Support for DT booted kernel
ASoC: twl4030: Move hs_extmute GPIO handling to driver
ARM: OMAP/ASoC: Zoom2: Let the codec to handle the hs_extmute GPIO
ASoC/MFD: twl4030: Remove set_hs_extmute callback from platform data
ASoC: twl4030: Convert to use devm_kzalloc
ASoC: twl4030: Add pointer to pdata within the private data
ASoC: twl4030: Support for DT booted kernel
.../devicetree/bindings/mfd/twl4030-audio.txt | 46 +++++++++
arch/arm/mach-omap2/board-zoom-peripherals.c | 9 +--
arch/arm/mach-omap2/include/mach/board-zoom.h | 2 -
drivers/input/misc/twl4030-vibra.c | 20 ++++-
drivers/mfd/twl-core.c | 32 ++++++
drivers/mfd/twl4030-audio.c | 107 +++++++++++++-------
include/linux/i2c/twl.h | 3 +-
include/linux/of.h | 6 +
sound/soc/codecs/twl4030.c | 103 +++++++++++++++----
sound/soc/omap/zoom2.c | 4 -
10 files changed, 261 insertions(+), 71 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mfd/twl4030-audio.txt
--
1.7.8.6
From: Peter Ujfalusi <hidden> Date: 2012-08-14 14:22:40
Place the MODULE_* lines in the same block and add MODULE_DESCRIPTION.
Rearange the platform_driver structure at the same time.
Signed-off-by: Peter Ujfalusi <redacted>
---
drivers/mfd/twl4030-audio.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
From: Peter Ujfalusi <hidden> Date: 2012-08-14 14:22:53
CFG_BOOT register's HFCLK_FREQ field hold information about the used HFCLK
frequency.
Add possibility for users to get the configured rate based on this
register.
This register was configured during boot, without it the chip would not
operate correctly, so we can trust on this information.
Signed-off-by: Peter Ujfalusi <redacted>
---
drivers/mfd/twl-core.c | 32 ++++++++++++++++++++++++++++++++
include/linux/i2c/twl.h | 1 +
2 files changed, 33 insertions(+), 0 deletions(-)
@@ -552,6 +552,38 @@ int twl_get_version(void)}EXPORT_SYMBOL_GPL(twl_get_version);+/**+*twl_get_hfclk_rate-APItogetTWLexternalHFCLKclockrate.+*+*ApitogettheTWLHFCLKratebasedonBOOT_CFGregister.+*/+inttwl_get_hfclk_rate(void)+{+u8ctrl;+intrate;++twl_i2c_read_u8(TWL_MODULE_PM_MASTER,&ctrl,R_CFG_BOOT);++switch(ctrl&0x3){+caseHFCLK_FREQ_19p2_MHZ:+rate=19200000;+break;+caseHFCLK_FREQ_26_MHZ:+rate=26000000;+break;+caseHFCLK_FREQ_38p4_MHZ:+rate=38400000;+break;+default:+pr_err("TWL4030: HFCLK is not configured\n");+rate=-EINVAL;+break;+}++returnrate;+}+EXPORT_SYMBOL_GPL(twl_get_hfclk_rate);+staticstructdevice*add_numbered_child(unsignedchip,constchar*name,intnum,void*pdata,unsignedpdata_len,
From: Peter Ujfalusi <hidden> Date: 2012-08-14 14:23:05
Support for loading the twl4030 audio module via devicetree.
Sub devices for codec and vibra will be created as mfd devices once the
core MFD driver is loaded when the kernel is booted with a DT blob.
Signed-off-by: Peter Ujfalusi <redacted>
---
.../devicetree/bindings/mfd/twl4030-audio.txt | 46 ++++++++++++++++
drivers/mfd/twl4030-audio.c | 56 +++++++++++++++++---
2 files changed, 95 insertions(+), 7 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mfd/twl4030-audio.txt
@@ -0,0 +1,46 @@+Texas Instruments TWL family (twl4030) audio module++The audio module inside the TWL family consist of an audio codec and a vibra+driver.++Required properties:+- compatible : must be "ti,twl4030-audio"++Optional properties, nodes:++Audio functionality:+- codec { }: Need to be present if the audio functionality is used. Within this+ section the following options can be used:+- ti,digimic_delay: Delay need after enabling the digimic to reduce artifacts+ from the start of the recorded sample (in ms)+-ti,ramp_delay_value: HS ramp delay configuration to reduce pop noise+-ti,hs_extmute: Use external mute for HS pop reduction+-ti,hs_extmute_gpio: Use external GPIO to control the external mute+-ti,offset_cncl_path: Offset cancellation path selection, refer to TRM for the+ valid values.++Vibra functionality+- ti,enable-vibra: Need to be set to <1> if the vibra functionality is used. if+ missing or it is 0, the vibra functionality is disabled.++Example:+&i2c1 {+ clock-frequency = <2600000>;++ twl: twl at 48 {+ reg = <0x48>;+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */+ interrupt-parent = <&intc>;++ twl_audio: audio {+ compatible = "ti,twl4030-audio";++ ti,enable-vibra = <1>;++ codec {+ ti,ramp_delay_value = <3>;+ };++ };+ };+};
@@ -156,15 +158,44 @@ unsigned int twl4030_audio_get_mclk(void)}EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk);+staticbooltwl4030_audio_has_codec(structtwl4030_audio_data*pdata,+structdevice_node*node)+{+if(pdata&&pdata->codec)+returntrue;++#ifdef CONFIG_OF+if(of_find_node_by_name(node,"codec"))+returntrue;+#endif++returnfalse;+}++staticbooltwl4030_audio_has_vibra(structtwl4030_audio_data*pdata,+structdevice_node*node)+{+intvibra;++if(pdata&&pdata->vibra)+returntrue;++if(!of_property_read_u32(node,"ti,enable-vibra",&vibra)&&vibra)+returntrue;++returnfalse;+}+staticint__devinittwl4030_audio_probe(structplatform_device*pdev){structtwl4030_audio*audio;structtwl4030_audio_data*pdata=pdev->dev.platform_data;+structdevice_node*node=pdev->dev.of_node;structmfd_cell*cell=NULL;intret,childs=0;u8val;-if(!pdata){+if(!pdata&&!node){dev_err(&pdev->dev,"Platform data is missing\n");return-EINVAL;}
@@ -202,18 +233,22 @@ static int __devinit twl4030_audio_probe(struct platform_device *pdev)audio->resource[TWL4030_AUDIO_RES_APLL].reg=TWL4030_REG_APLL_CTL;audio->resource[TWL4030_AUDIO_RES_APLL].mask=TWL4030_APLL_EN;-if(pdata->codec){+if(twl4030_audio_has_codec(pdata,node)){cell=&audio->cells[childs];cell->name="twl4030-codec";-cell->platform_data=pdata->codec;-cell->pdata_size=sizeof(*pdata->codec);+if(pdata){+cell->platform_data=pdata->codec;+cell->pdata_size=sizeof(*pdata->codec);+}childs++;}-if(pdata->vibra){+if(twl4030_audio_has_vibra(pdata,node)){cell=&audio->cells[childs];cell->name="twl4030-vibra";-cell->platform_data=pdata->vibra;-cell->pdata_size=sizeof(*pdata->vibra);+if(pdata){+cell->platform_data=pdata->vibra;+cell->pdata_size=sizeof(*pdata->vibra);+}childs++;}
@@ -245,10 +280,17 @@ static int __devexit twl4030_audio_remove(struct platform_device *pdev)return0;}+staticconststructof_device_idtwl4030_audio_of_match[]={+{.compatible="ti,twl4030-audio",},+{},+};+MODULE_DEVICE_TABLE(of,twl4030_audio_of_match);+staticstructplatform_drivertwl4030_audio_driver={.driver={.owner=THIS_MODULE,.name="twl4030-audio",+.of_match_table=twl4030_audio_of_match,},.probe=twl4030_audio_probe,.remove=__devexit_p(twl4030_audio_remove),
From: Peter Ujfalusi <hidden> Date: 2012-08-14 14:23:10
Add support when the kernel has been booted with DT blob. In this case the
pdata is NULL, we need to reach up to the core node and check if the codec
part has been enabled to determine if we need to coexist with the codec or
not.
Signed-off-by: Peter Ujfalusi <redacted>
---
drivers/input/misc/twl4030-vibra.c | 20 ++++++++++++++++++--
1 files changed, 18 insertions(+), 2 deletions(-)
From: Peter Ujfalusi <hidden> Date: 2012-08-14 14:23:14
Remove the use of set_hs_extmute callback and let the codec driver to
handle the extmute GPIO.
Signed-off-by: Peter Ujfalusi <redacted>
---
arch/arm/mach-omap2/board-zoom-peripherals.c | 9 ++-------
arch/arm/mach-omap2/include/mach/board-zoom.h | 2 --
sound/soc/omap/zoom2.c | 4 ----
3 files changed, 2 insertions(+), 13 deletions(-)
From: Peter Ujfalusi <hidden> Date: 2012-08-14 14:23:21
We no longer have users for the set_hs_extmute callback which has been
replaced by hs_extmute_gpio so the codec driver can handle the external
mute if it is needed by the board.
Signed-off-by: Peter Ujfalusi <redacted>
---
include/linux/i2c/twl.h | 2 --
sound/soc/codecs/twl4030.c | 6 ------
2 files changed, 0 insertions(+), 8 deletions(-)
From: Peter Ujfalusi <hidden> Date: 2012-08-14 14:23:48
When the kernel has been booted with DT blob the platform data is NULL for
the driver.
We need to construct the pdata based on the DT information for runtime use.
Signed-off-by: Peter Ujfalusi <redacted>
---
sound/soc/codecs/twl4030.c | 57 +++++++++++++++++++++++++++++++++++++------
1 files changed, 49 insertions(+), 8 deletions(-)
From: Peter Ujfalusi <hidden> Date: 2012-08-14 14:25:02
Access the pdata via a pointer within the twl4030_priv structure.
In preparation for DeviceTree support.
Signed-off-by: Peter Ujfalusi <redacted>
---
sound/soc/codecs/twl4030.c | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)
@@ -749,9 +748,9 @@ static int aif_event(struct snd_soc_dapm_widget *w,staticvoidheadset_ramp(structsnd_soc_codec*codec,intramp){-structtwl4030_codec_data*pdata=codec->dev->platform_data;unsignedcharhs_gain,hs_pop;structtwl4030_priv*twl4030=snd_soc_codec_get_drvdata(codec);+structtwl4030_codec_data*pdata=twl4030->pdata;/* Base values for ramp delay calculation: 2^19 - 2^26 */unsignedintramp_base[]={524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864};
@@ -864,9 +863,10 @@ static int digimic_event(struct snd_soc_dapm_widget *w,structsnd_kcontrol*kcontrol,intevent){structtwl4030_priv*twl4030=snd_soc_codec_get_drvdata(w->codec);+structtwl4030_codec_data*pdata=twl4030->pdata;-if(twl4030->digimic_delay)-twl4030_wait_ms(twl4030->digimic_delay);+if(pdata&&pdata->digimic_delay)+twl4030_wait_ms(pdata->digimic_delay);return0;}
@@ -2248,8 +2248,8 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)staticinttwl4030_soc_remove(structsnd_soc_codec*codec){-structtwl4030_codec_data*pdata=dev_get_platdata(codec->dev);structtwl4030_priv*twl4030=snd_soc_codec_get_drvdata(codec);+structtwl4030_codec_data*pdata=twl4030->pdata;/* Reset registers to their chip default before leaving */twl4030_reset_registers(codec);
@@ -2231,7 +2231,8 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec){structtwl4030_priv*twl4030;-twl4030=kzalloc(sizeof(structtwl4030_priv),GFP_KERNEL);+twl4030=devm_kzalloc(codec->dev,sizeof(structtwl4030_priv),+GFP_KERNEL);if(twl4030==NULL){dev_err(codec->dev,"Can not allocate memory\n");return-ENOMEM;
@@ -2253,7 +2254,6 @@ static int twl4030_soc_remove(struct snd_soc_codec *codec)/* Reset registers to their chip default before leaving */twl4030_reset_registers(codec);twl4030_set_bias_level(codec,SND_SOC_BIAS_OFF);-kfree(twl4030);if(pdata&&pdata->hs_extmute&&gpio_is_valid(pdata->hs_extmute_gpio))gpio_free(pdata->hs_extmute_gpio);
From: Peter Ujfalusi <hidden> Date: 2012-08-14 14:26:51
The external mute (if it is in use) is handled by a GPIO line. Prepare to
remove the set_hs_extmute callback and replace it with:
hs_extmute_gpio: the GPIO number to use for external mute
When the users of set_hs_extmute has been converted the callback can be removed.
Signed-off-by: Peter Ujfalusi <redacted>
---
include/linux/i2c/twl.h | 4 +++-
sound/soc/codecs/twl4030.c | 32 ++++++++++++++++++++++++++++++--
2 files changed, 33 insertions(+), 3 deletions(-)
@@ -302,6 +303,22 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)u8reg,byte;inti=0;+if(pdata&&pdata->hs_extmute&&+gpio_is_valid(pdata->hs_extmute_gpio)){+intret;++if(!pdata->hs_extmute_gpio)+dev_warn(codec->dev,+"Extmute GPIO is 0 is this correct?\n");++ret=gpio_request_one(pdata->hs_extmute_gpio,+GPIOF_OUT_INIT_LOW,"hs_extmute");+if(ret){+dev_err(codec->dev,"Failed to get hs_extmute GPIO\n");+pdata->hs_extmute_gpio=-1;+}+}+/* Check defaults, if instructed before anything else */if(pdata&&pdata->check_defaults)twl4030_check_defaults(codec);
@@ -748,7 +765,10 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)/* Enable external mute control, this dramatically reduces*thepop-noise*/if(pdata&&pdata->hs_extmute){-if(pdata->set_hs_extmute){+if(gpio_is_valid(pdata->hs_extmute_gpio)){+gpio_set_value(pdata->hs_extmute_gpio,1);+}elseif(pdata->set_hs_extmute){+dev_warn(codec->dev,"set_hs_extmute is deprecated\n");pdata->set_hs_extmute(1);}else{hs_pop|=TWL4030_EXTMUTE;
@@ -786,7 +806,10 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)/* Disable external mute */if(pdata&&pdata->hs_extmute){-if(pdata->set_hs_extmute){+if(gpio_is_valid(pdata->hs_extmute_gpio)){+gpio_set_value(pdata->hs_extmute_gpio,0);+}elseif(pdata->set_hs_extmute){+dev_warn(codec->dev,"set_hs_extmute is deprecated\n");pdata->set_hs_extmute(0);}else{hs_pop&=~TWL4030_EXTMUTE;
@@ -2230,12 +2253,17 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)staticinttwl4030_soc_remove(structsnd_soc_codec*codec){+structtwl4030_codec_data*pdata=dev_get_platdata(codec->dev);structtwl4030_priv*twl4030=snd_soc_codec_get_drvdata(codec);/* Reset registers to their chip default before leaving */twl4030_reset_registers(codec);twl4030_set_bias_level(codec,SND_SOC_BIAS_OFF);kfree(twl4030);++if(pdata&&pdata->hs_extmute&&gpio_is_valid(pdata->hs_extmute_gpio))+gpio_free(pdata->hs_extmute_gpio);+return0;}
From: Peter Ujfalusi <hidden> Date: 2012-08-14 14:28:50
twl-core has API to get the boot time configured HFCLK rate which has the
same rate as the audio MCLK.
Signed-off-by: Peter Ujfalusi <redacted>
---
drivers/mfd/twl4030-audio.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
From: Peter Ujfalusi <hidden> Date: 2012-08-14 14:29:12
To facilitate the device tree support the probe function need to be rearanged.
Small cleanup in the APLL frequency selection part as well.
Signed-off-by: Peter Ujfalusi <redacted>
---
drivers/mfd/twl4030-audio.c | 34 ++++++++++++++++------------------
1 files changed, 16 insertions(+), 18 deletions(-)
From: Tero Kristo <hidden> Date: 2012-08-28 09:52:06
Hi Peter,
The MFD patches in this set look good to me except for the minor comment
on patch 2 I just sent. That is with my limited knowledge of DT
though...
-Tero