drm/i2c: tda998x ASoC hdmi-codec support + BeagleBoneBlack audio support
Subsystems (5)
v2 cover drm/i2c: tda998x ASoC hdmi-codec support + BeagleBoneBlack audio support
Changes since first version [1] of this series:
- "drm/i2c: tda998x: Improve tda998x_configure_audio() audio related pdata"
- Change audio in tda998x pdata to audio_params to match the naming in private data struct
- Skip IEC958_AES2 byte when writing status bytes to registers
- Turn AFMT-macros to enum
- include linux/hdmi.h in drm/i2c/tda998x.h
- "drm/i2c: tda998x: Register ASoC hdmi-codec and add audio DT binding"
- Fix macronaming naming in dt-bindings/display/tda998x.h
- Turn AFMT-macros to enum
- Add locking to protect access to audio registers from ASoC thread
- "dts/am335x-boneblack: SQUASH"
- Use corrected macros from dt-bindings/display/tda998x.h
[1] https://lists.freedesktop.org/archives/dri-devel/2016-August/114491.html
Jyri Sarha (3):
drm/i2c: tda998x: Improve tda998x_configure_audio() audio related
pdata
drm/i2c: tda998x: Register ASoC hdmi-codec and add audio DT binding
ARM: dts: am335x-boneblack: Add HDMI audio support
.../devicetree/bindings/display/bridge/tda998x.txt | 18 ++ arch/arm/boot/dts/am335x-boneblack.dts | 71 ++++- drivers/gpu/drm/i2c/Kconfig | 1 + drivers/gpu/drm/i2c/tda998x_drv.c | 297 ++++++++++++++++++--- include/drm/i2c/tda998x.h | 29 +- include/dt-bindings/display/tda998x.h | 7 + 6 files changed, 368 insertions(+), 55 deletions(-) create mode 100644 include/dt-bindings/display/tda998x.h
Signature · 1 line
1.9.1
PATCH v2 1/3 drm/i2c: tda998x: Improve tda998x_configure_audio() audio related pdata
Define struct tda998x_audio_params in include/drm/i2c/tda998x.h and use it in pdata and for tda998x_configure_audio() parameters. Also updates tda998x_write_aif() to take struct hdmi_audio_infoframe * directly as a parameter.
--- drivers/gpu/drm/i2c/tda998x_drv.c | 84 +++++++++++++++++++++------------------ include/drm/i2c/tda998x.h | 28 ++++++++----- 2 files changed, 64 insertions(+), 48 deletions(-)
drivers/gpu/drm/i2c/tda998x_drv.c +46 -38
@@ -41,7 +41,7 @@ struct tda998x_priv {u8 vip_cntrl_0;u8 vip_cntrl_1;u8 vip_cntrl_2; -struct tda998x_encoder_params params; +struct tda998x_audio_params audio_params;wait_queue_head_t wq_edid;volatile int wq_edid_wait;
@@ -666,26 +666,16 @@ tda998x_write_if(struct tda998x_priv *priv, u8 bit, u16 addr,reg_set (priv,REG_DIP_IF_FLAGS , bit); } -static void -tda998x_write_aif (struct tda998x_priv *priv,struct tda998x_encoder_params *p) +static int tda998x_write_aif (struct tda998x_priv *priv, +struct hdmi_audio_infoframe *cea) {union hdmi_infoframe frame; -hdmi_audio_infoframe_init (&frame.audio); - - frame.audio.channels = p->audio_frame[1 ] &0x07 ; - frame.audio.channel_allocation = p->audio_frame[4 ]; - frame.audio.level_shift_value = (p->audio_frame[5 ] &0x78 ) >>3 ; - frame.audio.downmix_inhibit = (p->audio_frame[5 ] &0x80 ) >>7 ; - -/* -* L-PCM and IEC61937 compressed audio shall always set sample -* frequency to "refer to stream". For others, see the HDMI -* specification. -*/ - frame.audio.sample_frequency = (p->audio_frame[2 ] &0x1c ) >>2 ; + frame.audio = *cea;tda998x_write_if (priv,DIP_IF_FLAGS_IF4 ,REG_IF4_HB0 , &frame); + +return 0 ; } static void
@@ -710,20 +700,21 @@ static void tda998x_audio_mute(struct tda998x_priv *priv, bool on) } } -static void +static int tda998x_configure_audio (struct tda998x_priv *priv, -struct drm_display_mode *mode,struct tda998x_encoder_params *p) +struct tda998x_audio_params *params, +unsigned mode_clock) {u8 buf[6 ], clksel_aip, clksel_fs, cts_n, adiv;u32 n;/* Enable audio ports */ -reg_write (priv,REG_ENA_AP , p->audio_cfg); -reg_write (priv,REG_ENA_ACLK , p->audio_clk_cfg); +reg_write (priv,REG_ENA_AP , params->config);/* Set audio input source */ -switch (p->audio_format) { +switch (params->format) {case AFMT_SPDIF : +reg_write (priv,REG_ENA_ACLK ,0 );reg_write (priv,REG_MUX_AP ,MUX_AP_SELECT_SPDIF ); clksel_aip =AIP_CLKSEL_AIP_SPDIF ; clksel_fs =AIP_CLKSEL_FS_FS64SPDIF ;
@@ -731,15 +722,29 @@ tda998x_configure_audio(struct tda998x_priv *priv,break ;case AFMT_I2S : +reg_write (priv,REG_ENA_ACLK ,1 );reg_write (priv,REG_MUX_AP ,MUX_AP_SELECT_I2S ); clksel_aip =AIP_CLKSEL_AIP_I2S ; clksel_fs =AIP_CLKSEL_FS_ACLK ; - cts_n =CTS_N_M (3 ) |CTS_N_K (3 ); +switch (params->sample_width) { +case 16 : + cts_n =CTS_N_M (3 ) |CTS_N_K (1 ); +break ; +case 18 : +case 20 : +case 24 : + cts_n =CTS_N_M (3 ) |CTS_N_K (2 ); +break ; +default : +case 32 : + cts_n =CTS_N_M (3 ) |CTS_N_K (3 ); +break ; + }break ;default :BUG (); -return ; +return -EINVAL ; }reg_write (priv,REG_AIP_CLKSEL , clksel_aip);
@@ -755,11 +760,11 @@ tda998x_configure_audio(struct tda998x_priv *priv,* assume 100MHz requires larger divider. */ adiv =AUDIO_DIV_SERCLK_8 ; -if (mode->clock >100000 ) +if (mode_clock >100000 ) adiv++;/* AUDIO_DIV_SERCLK_16 */ /* S/PDIF asks for a larger divider */ -if (p->audio_format ==AFMT_SPDIF ) +if (params->format ==AFMT_SPDIF ) adiv++;/* AUDIO_DIV_SERCLK_16 or _32 */ reg_write (priv,REG_AUDIO_DIV , adiv);
@@ -768,7 +773,7 @@ tda998x_configure_audio(struct tda998x_priv *priv,* This is the approximate value of N, which happens to be * the recommended values for non-coherent clocks. */ - n =128 * p->audio_sample_rate /1000 ; + n =128 * params->sample_rate /1000 ;/* Write the CTS and N values */ buf[0 ] =0x44 ;
@@ -786,20 +791,21 @@ tda998x_configure_audio(struct tda998x_priv *priv,reg_set (priv,REG_AIP_CNTRL_0 ,AIP_CNTRL_0_RST_CTS );reg_clear (priv,REG_AIP_CNTRL_0 ,AIP_CNTRL_0_RST_CTS ); -/* Write the channel status */ - buf[0 ] =IEC958_AES0_CON_NOT_COPYRIGHT ; - buf[1 ] =0x00 ; - buf[2 ] =IEC958_AES3_CON_FS_NOTID ; - buf[3 ] =IEC958_AES4_CON_ORIGFS_NOTID | -IEC958_AES4_CON_MAX_WORDLEN_24 ; +/* Write the channel status +* The REG_CH_STAT_B-registers skip IEC958 AES2 byte, because +* there is a separate register for each I2S wire. +*/ + buf[0 ] = params->status[0 ]; + buf[1 ] = params->status[1 ]; + buf[2 ] = params->status[3 ]; + buf[3 ] = params->status[4 ];reg_write_range (priv,REG_CH_STAT_B (0 ), buf,4 );tda998x_audio_mute (priv, true);msleep (20 );tda998x_audio_mute (priv, false); -/* Write the audio information packet */ -tda998x_write_aif (priv, p); +return tda998x_write_aif (priv, ¶ms->cea); }/* DRM encoder functions */
@@ -820,7 +826,7 @@ static void tda998x_encoder_set_config(struct tda998x_priv *priv,VIP_CNTRL_2_SWAP_F (p->swap_f) | (p->mirr_f ?VIP_CNTRL_2_MIRR_F :0 ); - priv->params = *p; + priv->audio_params = p->audio_params; }static void tda998x_encoder_dpms (struct drm_encoder *encoder,int mode)
@@ -1057,9 +1063,11 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder,tda998x_write_avi (priv, adjusted_mode); -if (priv->params.audio_cfg) -tda998x_configure_audio (priv, adjusted_mode, - &priv->params); +if (priv->audio_params.format !=AFMT_UNUSED ) { +tda998x_configure_audio (priv, + &priv->audio_params, + adjusted_mode->clock); + } } }
include/drm/i2c/tda998x.h +18 -10
@@ -1,6 +1,23 @@ #ifndef __DRM_I2C_TDA998X_H__ #define __DRM_I2C_TDA998X_H__ +#include <linux/hdmi.h> + +enum { + AFMT_UNUSED = 0, + AFMT_SPDIF = 1, + AFMT_I2S = 2, +}; + +struct tda998x_audio_params { + u8 config; + u8 format; + unsigned sample_width; + unsigned sample_rate; + struct hdmi_audio_infoframe cea; + u8 status[5]; +}; + struct tda998x_encoder_params { u8 swap_b:3; u8 mirr_b:1;
@@ -15,16 +32,7 @@ struct tda998x_encoder_params { u8 swap_e:3; u8 mirr_e:1; -u8 audio_cfg; -u8 audio_clk_cfg; -u8 audio_frame[6 ]; - -enum { -AFMT_SPDIF , -AFMT_I2S - } audio_format; - - unsigned audio_sample_rate; + struct tda998x_audio_params audio_params; };#endif
Signature · 6 lines
1.9.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH v2 2/3 drm/i2c: tda998x: Register ASoC hdmi-codec and add audio DT binding
In reply to Jyri SarhaRegister ASoC HDMI codec for audio functionality and adds device tree binding for audio configuration.
With the registered HDMI codec the tda998x node can be used like a regular codec node in ASoC card configurations. HDMI audio info-frame and audio stream header is generated by the ASoC HDMI codec. The codec also applies constraints for available sample-rates based on Edid Like Data from the display. The device tree binding document has been updated [1].
Part of this patch has been inspired by Jean Francoise's "drm/i2c: tda998x:
Add support of a DT graph of ports"-patch [2]. There may still be some identical lines left from the original patch and some of the ideas have come from there.
[1] Documentation/devicetree/bindings/display/bridge/tda998x.txt
[2] http://mailman.alsa-project.org/pipermail/alsa-devel/2015-July/095255.html
--- .../devicetree/bindings/display/bridge/tda998x.txt | 18 ++ drivers/gpu/drm/i2c/Kconfig | 1 + drivers/gpu/drm/i2c/tda998x_drv.c | 213 ++++++++++++++++++++- include/drm/i2c/tda998x.h | 5 +- include/dt-bindings/display/tda998x.h | 7 + 5 files changed, 239 insertions(+), 5 deletions(-) create mode 100644 include/dt-bindings/display/tda998x.h
Documentation/devicetree/bindings/display/bridge/tda998x.txt +18 -0
@@ -21,8 +21,19 @@ Optional properties: - video-ports: 24 bits value which defines how the video controller output is wired to the TDA998x input - default: <0x230145> + - audio-ports: array of 8-bit values, 2 values per one DAI[1]. + The first value defines the DAI type: TDA998x_SPDIF or TDA998x_I2S[2]. + The second value defines the tda998x AP_ENA reg content when the DAI + in question is used. The implementation allows one or two DAIs. If two + DAIs are defined, they must be of different type. + +[1] Documentation/sound/alsa/soc/DAI.txt +[2] include/dt-bindings/display/tda998x.h + Example: +#include <dt-bindings/display/tda998x.h> + tda998x: hdmi-encoder { compatible = "nxp,tda998x"; reg = <0x70>;
@@ -30,4 +41,11 @@ Example: interrupts = <27 2>; /* falling edge */ pinctrl-0 = <&pmx_camera>; pinctrl-names = "default"; + video-ports = <0x230145>; + + #sound-dai-cells = <2>; + /* DAI-format AP_ENA reg value */ + audio-ports = < TDA998x_SPDIF 0x04 + TDA998x_I2S 0x03>; + };
drivers/gpu/drm/i2c/Kconfig +1 -0
@@ -22,6 +22,7 @@ config DRM_I2C_SIL164 config DRM_I2C_NXP_TDA998X tristate "NXP Semiconductors TDA998X HDMI encoder" default m if DRM_TILCDC + select SND_SOC_HDMI_CODEC if SND_SOC help Support for NXP Semiconductors TDA998X HDMI encoders.
drivers/gpu/drm/i2c/tda998x_drv.c +210 -3
285 lines not on this page · raw message
include/drm/i2c/tda998x.h +3 -2
@@ -2,11 +2,12 @@#define __DRM_I2C_TDA998X_H__#include <linux/hdmi.h> +#include <dt-bindings/display/tda998x.h> enum {AFMT_UNUSED =0 , -AFMT_SPDIF =1 , -AFMT_I2S =2 , +AFMT_SPDIF = TDA998x_SPDIF, +AFMT_I2S = TDA998x_I2S, };struct tda998x_audio_params {
include/dt-bindings/display/tda998x.h new file +7 -0
@@ -0,0 +1,7 @@ +#ifndef _DT_BINDINGS_TDA998X_H +#define _DT_BINDINGS_TDA998X_H + +#define TDA998x_SPDIF 1 +#define TDA998x_I2S 2 + +#endif /*_DT_BINDINGS_TDA998X_H */
Signature · 6 lines
1.9.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH v2 3/3 ARM: dts: am335x-boneblack: Add HDMI audio support
In reply to Jyri SarhaAdd HDMI audio support. Adds mcasp0_pins, clk_mcasp0_fixed, clk_mcasp0, mcasp0, sound node, and updates the tda19988 node to follow the new binding.
--- arch/arm/boot/dts/am335x-boneblack.dts | 71 ++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 4 deletions(-)
arch/arm/boot/dts/am335x-boneblack.dts +67 -4
@@ -9,6 +9,7 @@ #include "am33xx.dtsi" #include "am335x-bone-common.dtsi" +#include <dt-bindings/display/tda998x.h> / { model = "TI AM335x BeagleBone Black";
@@ -75,6 +76,16 @@ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */ >; }; + + mcasp0_pins: mcasp0_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLUP | MUX_MODE0) /* mcasp0_ahcklx.mcasp0_ahclkx */ + AM33XX_IOPAD(0x99c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2*/ + AM33XX_IOPAD(0x994, PIN_OUTPUT_PULLUP | MUX_MODE0) /* mcasp0_fsx.mcasp0_fsx */ + AM33XX_IOPAD(0x990, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp0_aclkx.mcasp0_aclkx */ + AM33XX_IOPAD(0x86c, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a11.GPIO1_27 */ + >; + }; }; &lcdc {
@@ -87,16 +98,22 @@ }; &i2c0 { - tda19988 { + tda19988: tda19988 { compatible = "nxp,tda998x"; reg = <0x70>; + pinctrl-names = "default", "off"; pinctrl-0 = <&nxp_hdmi_bonelt_pins>; pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>; - port { - hdmi_0: endpoint@0 { - remote-endpoint = <&lcdc_0>; + #sound-dai-cells = <0>; + audio-ports = < TDA998x_I2S 0x03>; + + ports { + port@0 { + hdmi_0: endpoint@0 { + remote-endpoint = <&lcdc_0>; + }; }; }; };
@@ -105,3 +122,49 @@ &rtc { system-power-controller; }; + +&mcasp0 { + #sound-dai-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&mcasp0_pins>; + status = "okay"; + op-mode = <0>; /* MCASP_IIS_MODE */ + tdm-slots = <2>; + serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ + 0 0 1 0 + >; + tx-num-evt = <32>; + rx-num-evt = <32>; +}; + +/ { + clk_mcasp0_fixed: clk_mcasp0_fixed { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <24576000>; + }; + + clk_mcasp0: clk_mcasp0 { + #clock-cells = <0>; + compatible = "gpio-gate-clock"; + clocks = <&clk_mcasp0_fixed>; + enable-gpios = <&gpio1 27 0>; /* BeagleBone Black Clk enable on GPIO1_27 */ + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "TI BeagleBone Black"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&dailink0_master>; + simple-audio-card,frame-master = <&dailink0_master>; + + dailink0_master: simple-audio-card,cpu { + sound-dai = <&mcasp0>; + clocks = <&clk_mcasp0>; + }; + + simple-audio-card,codec { + sound-dai = <&tda19988>; + }; + }; +};
Signature · 6 lines
1.9.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 5 lines · Jyri Sarha
Changes since first version [1] of this series:
- "drm/i2c: tda998x: Improvetda998x_configure_audio()audio related pdata"
- Change audio in tda998x pdata toaudio_paramsto match the naming in private data struct
- SkipIEC958_AES2byte when writing status bytes to registers
Quoted 8 lines
- Turn AFMT-macros to enum
- includelinux/hdmi.hindrm/i2c/tda998x.h
- "drm/i2c: tda998x: Register ASoC hdmi-codec and add audio DT binding"
- Fix macronaming naming indt-bindings/display/tda998x.h
- Turn AFMT-macros to enum
- Add locking to protect access to audio registers from ASoC thread
- "dts/am335x-boneblack: SQUASH"
- Use corrected macros fromdt-bindings/display/tda998x.h
Thanks, series queued.
Signature · 7 lines
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up according to speedtest.net. -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html