* [PATCH v3 0/2] sti: add audio interface to the hdmi driver
@ 2016-04-21 8:07 Arnaud Pouliquen
2016-04-21 8:07 ` [PATCH v3 1/2] video: hdmi: add helper function for N and CTS Arnaud Pouliquen
2016-04-21 8:07 ` [PATCH v3 2/2] drm: sti: Add ASoC generic hdmi codec support Arnaud Pouliquen
0 siblings, 2 replies; 6+ messages in thread
From: Arnaud Pouliquen @ 2016-04-21 8:07 UTC (permalink / raw)
To: alsa-devel, dri-devel
Cc: Jean-Francois Moine, Lars-Peter Clausen, Russell King - ARM Linux,
Philipp Zabel, David Airlie, arnaud.pouliquen, Liam Girdwood,
Jyri Sarha, Takashi Iwai, Mark Brown, Benjamin Gaignard
This patchset implements audio interface in HDMI drm driver. Implementation is based on
ASoC generic hdmi codec driver( https://patchwork.kernel.org/patch/8713141/).
It also proposes helper functions to compute N and CTS parameters
according to HDMI 1.4b specification.
V3:
- video: hdmi: add helper function for N and CTS
Also used on Mediatek platform (https://patchwork.kernel.org/patch/8887341)
delta vs V2:
- typo fixes
- if/else code optimisation
- drm: sti: Add ASoC generic hdmi codec support.
- typo fixes
- add audio registers in debugfs information
V2: RFC
https://patchwork.kernel.org/patch/8091531/("video: hdmi: add helper function for N and CTS")
https://patchwork.kernel.org/patch/8091561/("ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders")
- patch: video: hdmi: add helper function for N and CTS
Fixes based on Russel King remarks
- Duplicate function to have a separte treatment for coherent and
non-coherent clocks
- Add ratio field for alternate CTS value
- Clock frequency in Hz for TMDS and audio clocks
- Add information concerning clocks and CTS calculation.
V1:
This RFC is the implementation of audio HDMI on sti platform based on generic hdmi-codec driver:
https://patchwork.kernel.org/patch/7215271/ ("ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders")
https://patchwork.kernel.org/patch/8062611/ ("video: hdmi: add helper function for N and CTS")
Arnaud Pouliquen (2):
drm: sti: Add ASoC generic hdmi codec support.
video: hdmi: add helper function for N and CTS
drivers/gpu/drm/sti/Kconfig | 1 +
drivers/gpu/drm/sti/sti_hdmi.c | 248 ++++++++++++++++++++++++++++++++++++++---
drivers/gpu/drm/sti/sti_hdmi.h | 13 +++
drivers/video/hdmi.c | 202 +++++++++++++++++++++++++++++++++
include/linux/hdmi.h | 22 ++++
5 files changed, 469 insertions(+), 17 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH v3 1/2] video: hdmi: add helper function for N and CTS 2016-04-21 8:07 [PATCH v3 0/2] sti: add audio interface to the hdmi driver Arnaud Pouliquen @ 2016-04-21 8:07 ` Arnaud Pouliquen 2016-04-21 9:24 ` [alsa-devel] " kbuild test robot 2016-04-21 12:39 ` Philipp Zabel 2016-04-21 8:07 ` [PATCH v3 2/2] drm: sti: Add ASoC generic hdmi codec support Arnaud Pouliquen 1 sibling, 2 replies; 6+ messages in thread From: Arnaud Pouliquen @ 2016-04-21 8:07 UTC (permalink / raw) To: alsa-devel, dri-devel Cc: Jean-Francois Moine, Lars-Peter Clausen, Russell King - ARM Linux, Philipp Zabel, David Airlie, arnaud.pouliquen, Liam Girdwood, Jyri Sarha, Takashi Iwai, Mark Brown, Benjamin Gaignard Add helper function to compute HDMI CTS and N parameters Implementation is based on HDMI 1.4b specification. Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com> Acked-by: Benjamin Gaignard <benjamin.gaignard@linaro.org> Acked-by: Vincent ABRIOU <vincent.abriou@st.com> --- drivers/video/hdmi.c | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/hdmi.h | 22 ++++++ 2 files changed, 224 insertions(+) diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c index 1626892..6381ce0 100644 --- a/drivers/video/hdmi.c +++ b/drivers/video/hdmi.c @@ -1242,3 +1242,205 @@ int hdmi_infoframe_unpack(union hdmi_infoframe *frame, void *buffer) return ret; } EXPORT_SYMBOL(hdmi_infoframe_unpack); + +/** + * audio clock regeneration (acr) parameters + * N and CTS computation are based on HDMI specification 1.4b + */ +enum audio_rate { + HDMI_AUDIO_N_CTS_32KHZ, + HDMI_AUDIO_N_CTS_44_1KHZ, + HDMI_AUDIO_N_CTS_48KHZ, +}; + +struct hdmi_audio_acr { + unsigned int tmds_clk; + struct hdmi_audio_n_cts n_cts; +}; + +static const struct hdmi_audio_acr hdmi_audio_standard_acr[3][12] = { + { /*32 kHz*/ + { 25174825, { 4576, 28125, 0 } }, /* 25,20/1.001 MHz */ + { 25200000, { 4096, 25200, 0 } }, /* 25.20 MHz */ + { 27000000, { 4096, 27000, 0 } }, /* 27.00 MHz */ + { 27027000, { 4096, 27027, 0 } }, /* 27.00*1.001 MHz */ + { 54000000, { 4096, 54000, 0 } }, /* 54.00 MHz */ + { 54054000, { 4096, 54054, 0 } }, /* 54.00*1.001 MHz */ + { 74175824, { 11648, 210937, 50 } }, /* 74.25/1.001 MHz */ + { 74250000, { 4096, 74250, 0 } }, /* 74.25 MHz */ + { 148351648, { 11648, 421875, 0 } }, /* 148.50/1.001 MHz */ + { 148500000, { 4096, 148500, 0 } }, /* 148.50 MHz */ + { 296703296, { 5824, 421875, 0 } }, /* 297/1.001 MHz */ + { 297000000, { 3072, 222750, 0 } }, /* 297 MHz */ + }, + { /*44.1 kHz, 88.2 kHz 176.4 kHz*/ + { 25174825, { 7007, 31250, 0 } }, /* 25,20/1.001 MHz */ + { 25200000, { 6272, 28000, 0 } }, /* 25.20 MHz */ + { 27000000, { 6272, 30000, 0 } }, /* 27.00 MHz */ + { 27027000, { 6272, 30030, 0 } }, /* 27.00*1.001 MHz */ + { 54000000, { 6272, 60000, 0 } }, /* 54.00 MHz */ + { 54054000, { 6272, 60060, 0 } }, /* 54.00*1.001 MHz */ + { 74175824, { 17836, 234375, 0 } }, /* 74.25/1.001 MHz */ + { 74250000, { 6272, 82500, 0 } }, /* 74.25 MHz */ + { 148351648, { 8918, 234375, 0 } }, /* 148.50/1.001 MHz */ + { 148500000, { 6272, 165000, 0 } }, /* 148.50 MHz */ + { 296703296, { 4459, 234375, 0 } }, /* 297/1.001 MHz */ + { 297000000, { 4704, 247500, 0 } }, /* 297 MHz */ + }, + { /*48 kHz, 96 kHz 192 kHz*/ + { 25174825, { 6864, 28125, 0 } }, /* 25,20/1.001 MHz */ + { 25200000, { 6144, 25200, 0 } }, /* 25.20 MHz */ + { 27000000, { 6144, 27000, 0 } }, /* 27.00 MHz */ + { 27027000, { 6144, 27027, 0 } }, /* 27.00*1.001 MHz */ + { 54000000, { 6144, 54000, 0 } }, /* 54.00 MHz */ + { 54054000, { 6144, 54054, 0 } }, /* 54.00*1.001 MHz */ + { 74175824, { 11648, 140625, 0 } }, /* 74.25/1.001 MHz */ + { 74250000, { 6144, 74250, 0 } }, /* 74.25 MHz */ + { 148351648, { 5824, 140625, 0 } }, /* 148.50/1.001 MHz */ + { 148500000, { 6144, 148500, 0 } }, /* 148.50 MHz */ + { 296703296, { 5824, 281250, 0 } }, /* 297/1.001 MHz */ + { 297000000, { 5120, 247500, 0 } }, /* 297 MHz */ + } +}; + +/** + * hdmi_audio_get_coherent_n_cts() - compute N and CTS parameters for coherent + * clocks. Coherent clock means that audio and TMDS clocks have the same + * source (no drifts between clocks). + * + * @audio_fs: audio frame clock frequency in Hz + * @tmds_clk: HDMI TMDS clock frequency in Hz + * @n_cts: N and CTS parameter returned to user + * + * Values computed are based on table described in HDMI specification 1.4b + * + * Returns 0 on success or a negative error code on failure. + */ +int hdmi_audio_get_coherent_n_cts(unsigned int audio_fs, + unsigned int tmds_clk, + struct hdmi_audio_n_cts *n_cts) +{ + int audio_freq_id, i; + int rate_coeff = 1; + u64 val, min; + const struct hdmi_audio_acr *acr_table; + const struct hdmi_audio_n_cts *predef_n_cts = NULL; + + switch (audio_fs) { + case 32000: + audio_freq_id = HDMI_AUDIO_N_CTS_32KHZ; + n_cts->n = 4096; + break; + case 44100: + audio_freq_id = HDMI_AUDIO_N_CTS_44_1KHZ; + n_cts->n = 6272; + break; + case 48000: + audio_freq_id = HDMI_AUDIO_N_CTS_48KHZ; + n_cts->n = 6144; + break; + case 88200: + audio_freq_id = HDMI_AUDIO_N_CTS_44_1KHZ; + rate_coeff = 2; + n_cts->n = 6272 * 2; + break; + case 96000: + audio_freq_id = HDMI_AUDIO_N_CTS_48KHZ; + rate_coeff = 2; + n_cts->n = 6144 * 2; + break; + case 176400: + audio_freq_id = HDMI_AUDIO_N_CTS_44_1KHZ; + rate_coeff = 4; + n_cts->n = 6272 * 4; + break; + case 192000: + audio_freq_id = HDMI_AUDIO_N_CTS_48KHZ; + rate_coeff = 4; + n_cts->n = 6144 * 4; + break; + default: + return -EINVAL; + } + + acr_table = hdmi_audio_standard_acr[audio_freq_id]; + for (i = 0; i < ARRAY_SIZE(hdmi_audio_standard_acr[0]); i++) { + if (tmds_clk == acr_table[i].tmds_clk) { + predef_n_cts = &acr_table[i].n_cts; + n_cts->n = predef_n_cts->n * rate_coeff; + n_cts->cts = predef_n_cts->cts; + n_cts->cts_1_ratio = predef_n_cts->cts_1_ratio; + return 0; + } + } + + /* + * predefined frequency not found. Compute CTS using formula: + * CTS = (Ftdms_clk * N) / (128* audio_fs) + */ + val = (u64)tmds_clk * n_cts->n; + n_cts->cts = div64_u64(val, 128UL * audio_fs); + + n_cts->cts_1_ratio = 0; + min = (u64)n_cts->cts * 128UL * audio_fs; + if (min < (val)) { + /* + * non-accurate value for CTS + * compute ratio, needed by user to alternate in ACR + * between CTS and CTS + 1 value. + */ + n_cts->cts_1_ratio = 100 - ((u32)(val - min)) * 100 / + (128 * audio_fs); + } + + return 0; +} +EXPORT_SYMBOL(hdmi_audio_get_coherent_n_cts); + +/** + * hdmi_audio_get_non_coherent_n() - get N parameter for non-coherent + * clocks. None-coherent clocks means that audio and TMDS clocks have not the + * same source (drifts between clocks). In this case assumption is that CTS is + * automatically calculated by hardware. + * + * @audio_fs: audio frame clock frequency in Hz + * + * Values computed are based on table described in HDMI specification 1.4b + * + * Returns n value. + */ +int hdmi_audio_get_non_coherent_n(unsigned int audio_fs) +{ + unsigned int n; + + switch (audio_fs) { + case 32000: + n = 4096; + break; + case 44100: + n = 6272; + break; + case 48000: + n = 6144; + break; + case 88200: + n = 6272 * 2; + break; + case 96000: + n = 6144 * 2; + break; + case 176400: + n = 6272 * 4; + break; + case 192000: + n = 6144 * 4; + break; + default: + /* Not pre-defined, recommended value: 128 * fs / 1000 */ + n = (audio_fs * 128) / 1000; + } + + return n; +} +EXPORT_SYMBOL(hdmi_audio_get_non_coherent_n); + diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h index e974420..28b6794 100644 --- a/include/linux/hdmi.h +++ b/include/linux/hdmi.h @@ -333,4 +333,26 @@ int hdmi_infoframe_unpack(union hdmi_infoframe *frame, void *buffer); void hdmi_infoframe_log(const char *level, struct device *dev, union hdmi_infoframe *frame); +/** + * struct hdmi_audio_n_cts - n and cts parameter for ACR packets + * @n: N parameter + * @cts: CTS parameter + * @cts_1_ratio: ratio from 0 to 99 to alternate "CTS" and "CTS + 1" values + * ratio = 0: CTS parameter is accurate, no need to alternate with "CTS + 1" + * value + * ratio = x: Need to alternate with ACR "CTS + 1" value x% of the time to + * generate accurate audio clock + */ +struct hdmi_audio_n_cts { + unsigned int n; + unsigned int cts; + unsigned int cts_1_ratio; +}; + +int hdmi_audio_get_coherent_n_cts(unsigned int audio_fs, + unsigned int tmds_clk, + struct hdmi_audio_n_cts *n_cts); + +int hdmi_audio_get_non_coherent_n(unsigned int audio_fs); + #endif /* _DRM_HDMI_H */ -- 1.9.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [alsa-devel] [PATCH v3 1/2] video: hdmi: add helper function for N and CTS 2016-04-21 8:07 ` [PATCH v3 1/2] video: hdmi: add helper function for N and CTS Arnaud Pouliquen @ 2016-04-21 9:24 ` kbuild test robot 2016-04-21 12:39 ` Philipp Zabel 1 sibling, 0 replies; 6+ messages in thread From: kbuild test robot @ 2016-04-21 9:24 UTC (permalink / raw) Cc: alsa-devel, Russell King - ARM Linux, Benjamin Gaignard, arnaud.pouliquen, Liam Girdwood, dri-devel, Mark Brown, kbuild-all, Jyri Sarha [-- Attachment #1: Type: text/plain, Size: 19061 bytes --] Hi, [auto build test WARNING on drm/drm-next] [also build test WARNING on v4.6-rc4 next-20160420] [if your patch is applied to the wrong git tree, please drop us a note to help improving the system] url: https://github.com/0day-ci/linux/commits/Arnaud-Pouliquen/sti-add-audio-interface-to-the-hdmi-driver/20160421-161330 base: git://people.freedesktop.org/~airlied/linux.git drm-next reproduce: make htmldocs All warnings (new ones prefixed by >>): drivers/gpu/drm/i915/i915_irq.c:2663: warning: No description found for parameter 'fmt' include/drm/drm_crtc.h:364: warning: No description found for parameter 'mode_blob' include/drm/drm_crtc.h:779: warning: No description found for parameter 'name' include/drm/drm_crtc.h:1238: warning: No description found for parameter 'connector_id' include/drm/drm_crtc.h:1238: warning: No description found for parameter 'tile_blob_ptr' include/drm/drm_crtc.h:1277: warning: No description found for parameter 'rotation' include/drm/drm_crtc.h:1539: warning: No description found for parameter 'name' include/drm/drm_crtc.h:1539: warning: No description found for parameter 'mutex' include/drm/drm_crtc.h:1539: warning: No description found for parameter 'helper_private' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'tile_idr' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'connector_ida' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'delayed_event' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'edid_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'dpms_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'path_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'tile_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'plane_type_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'rotation_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'prop_src_x' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'prop_src_y' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'prop_src_w' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'prop_src_h' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'prop_crtc_x' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'prop_crtc_y' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'prop_crtc_w' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'prop_crtc_h' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'prop_fb_id' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'prop_crtc_id' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'prop_active' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'prop_mode_id' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'dvi_i_subconnector_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'dvi_i_select_subconnector_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'tv_subconnector_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'tv_select_subconnector_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'tv_mode_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'tv_left_margin_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'tv_right_margin_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'tv_top_margin_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'tv_bottom_margin_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'tv_brightness_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'tv_contrast_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'tv_flicker_reduction_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'tv_overscan_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'tv_saturation_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'tv_hue_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'scaling_mode_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'aspect_ratio_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'dirty_info_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'suggested_x_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'suggested_y_property' include/drm/drm_crtc.h:2175: warning: No description found for parameter 'allow_fb_modifiers' drivers/gpu/drm/drm_atomic_helper.c:2924: warning: No description found for parameter 'start' drivers/gpu/drm/drm_atomic_helper.c:2924: warning: No description found for parameter 'start' drivers/gpu/drm/drm_atomic_helper.c:2924: warning: No description found for parameter 'start' drivers/gpu/drm/drm_atomic_helper.c:2924: warning: No description found for parameter 'start' include/drm/drm_dp_helper.h:749: warning: No description found for parameter 'i2c_nack_count' include/drm/drm_dp_helper.h:749: warning: No description found for parameter 'i2c_defer_count' drivers/gpu/drm/drm_dp_mst_topology.c:2356: warning: No description found for parameter 'connector' include/drm/drm_dp_mst_helper.h:92: warning: No description found for parameter 'cached_edid' include/drm/drm_dp_mst_helper.h:92: warning: No description found for parameter 'has_audio' include/drm/drm_dp_mst_helper.h:466: warning: No description found for parameter 'max_dpcd_transaction_bytes' include/drm/drm_dp_mst_helper.h:466: warning: No description found for parameter 'sink_count' include/drm/drm_dp_mst_helper.h:466: warning: No description found for parameter 'total_slots' include/drm/drm_dp_mst_helper.h:466: warning: No description found for parameter 'avail_slots' include/drm/drm_dp_mst_helper.h:466: warning: No description found for parameter 'total_pbn' include/drm/drm_dp_mst_helper.h:466: warning: No description found for parameter 'qlock' include/drm/drm_dp_mst_helper.h:466: warning: No description found for parameter 'tx_msg_downq' include/drm/drm_dp_mst_helper.h:466: warning: No description found for parameter 'tx_down_in_progress' include/drm/drm_dp_mst_helper.h:466: warning: No description found for parameter 'payload_lock' include/drm/drm_dp_mst_helper.h:466: warning: No description found for parameter 'proposed_vcpis' include/drm/drm_dp_mst_helper.h:466: warning: No description found for parameter 'payloads' include/drm/drm_dp_mst_helper.h:466: warning: No description found for parameter 'payload_mask' include/drm/drm_dp_mst_helper.h:466: warning: No description found for parameter 'vcpi_mask' include/drm/drm_dp_mst_helper.h:466: warning: No description found for parameter 'tx_waitq' include/drm/drm_dp_mst_helper.h:466: warning: No description found for parameter 'work' include/drm/drm_dp_mst_helper.h:466: warning: No description found for parameter 'tx_work' include/drm/drm_dp_mst_helper.h:466: warning: No description found for parameter 'destroy_connector_list' include/drm/drm_dp_mst_helper.h:466: warning: No description found for parameter 'destroy_connector_lock' include/drm/drm_dp_mst_helper.h:466: warning: No description found for parameter 'destroy_connector_work' drivers/gpu/drm/drm_dp_mst_topology.c:2356: warning: No description found for parameter 'connector' >> drivers/video/hdmi.c:1250: warning: cannot understand function prototype: 'enum audio_rate ' drivers/gpu/drm/drm_irq.c:176: warning: No description found for parameter 'flags' include/drm/drmP.h:168: warning: No description found for parameter 'fmt' include/drm/drmP.h:184: warning: No description found for parameter 'fmt' include/drm/drmP.h:202: warning: No description found for parameter 'fmt' include/drm/drmP.h:247: warning: No description found for parameter 'dev' include/drm/drmP.h:247: warning: No description found for parameter 'data' include/drm/drmP.h:247: warning: No description found for parameter 'file_priv' include/drm/drmP.h:280: warning: No description found for parameter 'ioctl' include/drm/drmP.h:280: warning: No description found for parameter '_func' include/drm/drmP.h:280: warning: No description found for parameter '_flags' include/drm/drmP.h:362: warning: cannot understand function prototype: 'struct drm_lock_data ' include/drm/drmP.h:415: warning: cannot understand function prototype: 'struct drm_driver ' include/drm/drmP.h:672: warning: cannot understand function prototype: 'struct drm_info_list ' include/drm/drmP.h:682: warning: cannot understand function prototype: 'struct drm_info_node ' include/drm/drmP.h:692: warning: cannot understand function prototype: 'struct drm_minor ' include/drm/drmP.h:740: warning: cannot understand function prototype: 'struct drm_device ' drivers/gpu/drm/i915/intel_runtime_pm.c:2275: warning: No description found for parameter 'resume' drivers/gpu/drm/i915/intel_runtime_pm.c:2275: warning: No description found for parameter 'resume' drivers/gpu/drm/i915/i915_irq.c:2663: warning: No description found for parameter 'fmt' drivers/gpu/drm/i915/i915_irq.c:2663: warning: No description found for parameter 'fmt' drivers/gpu/drm/i915/i915_irq.c:2663: warning: No description found for parameter 'fmt' drivers/gpu/drm/i915/i915_irq.c:2663: warning: No description found for parameter 'fmt' drivers/gpu/drm/i915/i915_gem.c:421: warning: No description found for parameter 'dev' drivers/gpu/drm/i915/i915_gem.c:421: warning: No description found for parameter 'data' drivers/gpu/drm/i915/i915_gem.c:421: warning: No description found for parameter 'file' drivers/gpu/drm/i915/i915_gem.c:686: warning: No description found for parameter 'dev' drivers/gpu/drm/i915/i915_gem.c:686: warning: No description found for parameter 'data' drivers/gpu/drm/i915/i915_gem.c:686: warning: No description found for parameter 'file' drivers/gpu/drm/i915/i915_gem.c:767: warning: No description found for parameter 'dev' drivers/gpu/drm/i915/i915_gem.c:767: warning: No description found for parameter 'obj' drivers/gpu/drm/i915/i915_gem.c:767: warning: No description found for parameter 'args' drivers/gpu/drm/i915/i915_gem.c:767: warning: No description found for parameter 'file' drivers/gpu/drm/i915/i915_gem.c:1029: warning: No description found for parameter 'dev' drivers/gpu/drm/i915/i915_gem.c:1029: warning: No description found for parameter 'data' drivers/gpu/drm/i915/i915_gem.c:1029: warning: No description found for parameter 'file' drivers/gpu/drm/i915/i915_gem.c:1245: warning: No description found for parameter 'rps' drivers/gpu/drm/i915/i915_gem.c:1459: warning: No description found for parameter 'req' drivers/gpu/drm/i915/i915_gem.c:1494: warning: No description found for parameter 'obj' drivers/gpu/drm/i915/i915_gem.c:1494: warning: No description found for parameter 'readonly' drivers/gpu/drm/i915/i915_gem.c:1617: warning: No description found for parameter 'dev' drivers/gpu/drm/i915/i915_gem.c:1617: warning: No description found for parameter 'data' drivers/gpu/drm/i915/i915_gem.c:1617: warning: No description found for parameter 'file' drivers/gpu/drm/i915/i915_gem.c:1680: warning: No description found for parameter 'dev' drivers/gpu/drm/i915/i915_gem.c:1680: warning: No description found for parameter 'data' drivers/gpu/drm/i915/i915_gem.c:1680: warning: No description found for parameter 'file' drivers/gpu/drm/i915/i915_gem.c:1725: warning: No description found for parameter 'dev' drivers/gpu/drm/i915/i915_gem.c:1725: warning: No description found for parameter 'data' drivers/gpu/drm/i915/i915_gem.c:1725: warning: No description found for parameter 'file' drivers/gpu/drm/i915/i915_gem.c:2013: warning: No description found for parameter 'dev' drivers/gpu/drm/i915/i915_gem.c:2013: warning: No description found for parameter 'size' drivers/gpu/drm/i915/i915_gem.c:2013: warning: No description found for parameter 'tiling_mode' drivers/gpu/drm/i915/i915_gem.c:2013: warning: No description found for parameter 'fenced' drivers/gpu/drm/i915/i915_gem.c:2013: warning: Excess function parameter 'obj' description in 'i915_gem_get_gtt_alignment' drivers/gpu/drm/i915/i915_gem.c:2911: warning: No description found for parameter 'engine' drivers/gpu/drm/i915/i915_gem.c:3037: warning: No description found for parameter 'obj' drivers/gpu/drm/i915/i915_gem.c:3087: warning: No description found for parameter 'dev' drivers/gpu/drm/i915/i915_gem.c:3087: warning: No description found for parameter 'data' drivers/gpu/drm/i915/i915_gem.c:3087: warning: No description found for parameter 'file' drivers/gpu/drm/i915/i915_gem.c:3087: warning: Excess function parameter 'DRM_IOCTL_ARGS' description in 'i915_gem_wait_ioctl' drivers/gpu/drm/i915/i915_gem.c:3459: warning: No description found for parameter 'obj' drivers/gpu/drm/i915/i915_gem.c:3459: warning: No description found for parameter 'vm' drivers/gpu/drm/i915/i915_gem.c:3459: warning: No description found for parameter 'ggtt_view' drivers/gpu/drm/i915/i915_gem.c:3459: warning: No description found for parameter 'alignment' drivers/gpu/drm/i915/i915_gem.c:3459: warning: No description found for parameter 'flags' drivers/gpu/drm/i915/i915_gem.c:3714: warning: No description found for parameter 'obj' drivers/gpu/drm/i915/i915_gem.c:3714: warning: No description found for parameter 'write' drivers/gpu/drm/i915/i915_gem.c:3789: warning: No description found for parameter 'obj' drivers/gpu/drm/i915/i915_gem.c:3789: warning: No description found for parameter 'cache_level' drivers/gpu/drm/i915/i915_gem.c:4063: warning: No description found for parameter 'obj' drivers/gpu/drm/i915/i915_gem.c:4063: warning: No description found for parameter 'write' drivers/gpu/drm/i915/i915_cmd_parser.c:748: warning: No description found for parameter 'engine' drivers/gpu/drm/i915/i915_cmd_parser.c:748: warning: Excess function parameter 'ring' description in 'i915_cmd_parser_init_ring' drivers/gpu/drm/i915/i915_cmd_parser.c:838: warning: No description found for parameter 'engine' drivers/gpu/drm/i915/i915_cmd_parser.c:838: warning: Excess function parameter 'ring' description in 'i915_cmd_parser_fini_ring' drivers/gpu/drm/i915/i915_cmd_parser.c:1034: warning: No description found for parameter 'engine' drivers/gpu/drm/i915/i915_cmd_parser.c:1034: warning: Excess function parameter 'ring' description in 'i915_needs_cmd_parser' drivers/gpu/drm/i915/i915_cmd_parser.c:1186: warning: No description found for parameter 'engine' drivers/gpu/drm/i915/i915_cmd_parser.c:1186: warning: Excess function parameter 'ring' description in 'i915_parse_cmds' drivers/gpu/drm/i915/i915_cmd_parser.c:748: warning: No description found for parameter 'engine' drivers/gpu/drm/i915/i915_cmd_parser.c:748: warning: Excess function parameter 'ring' description in 'i915_cmd_parser_init_ring' drivers/gpu/drm/i915/i915_cmd_parser.c:838: warning: No description found for parameter 'engine' drivers/gpu/drm/i915/i915_cmd_parser.c:838: warning: Excess function parameter 'ring' description in 'i915_cmd_parser_fini_ring' drivers/gpu/drm/i915/i915_cmd_parser.c:1034: warning: No description found for parameter 'engine' drivers/gpu/drm/i915/i915_cmd_parser.c:1034: warning: Excess function parameter 'ring' description in 'i915_needs_cmd_parser' drivers/gpu/drm/i915/i915_cmd_parser.c:1186: warning: No description found for parameter 'engine' drivers/gpu/drm/i915/i915_cmd_parser.c:1186: warning: Excess function parameter 'ring' description in 'i915_parse_cmds' drivers/gpu/drm/i915/intel_lrc.c:318: warning: No description found for parameter 'engine' drivers/gpu/drm/i915/intel_lrc.c:318: warning: Excess function parameter 'ring' description in 'intel_lr_context_descriptor_update' drivers/gpu/drm/i915/intel_lrc.c:355: warning: No description found for parameter 'engine' drivers/gpu/drm/i915/intel_lrc.c:355: warning: Excess function parameter 'ring' description in 'intel_execlists_ctx_id' drivers/gpu/drm/i915/intel_lrc.c:547: warning: No description found for parameter 'engine' drivers/gpu/drm/i915/intel_lrc.c:547: warning: Excess function parameter 'ring' description in 'intel_lrc_irq_handler' drivers/gpu/drm/i915/intel_lrc.c:951: warning: No description found for parameter 'params' drivers/gpu/drm/i915/intel_lrc.c:951: warning: Excess function parameter 'dev' description in 'intel_execlists_submission' drivers/gpu/drm/i915/intel_lrc.c:951: warning: Excess function parameter 'file' description in 'intel_execlists_submission' drivers/gpu/drm/i915/intel_lrc.c:951: warning: Excess function parameter 'ring' description in 'intel_execlists_submission' drivers/gpu/drm/i915/intel_lrc.c:951: warning: Excess function parameter 'ctx' description in 'intel_execlists_submission' drivers/gpu/drm/i915/intel_lrc.c:951: warning: Excess function parameter 'batch_obj' description in 'intel_execlists_submission' drivers/gpu/drm/i915/intel_lrc.c:951: warning: Excess function parameter 'exec_start' description in 'intel_execlists_submission' drivers/gpu/drm/i915/intel_lrc.c:951: warning: Excess function parameter 'dispatch_flags' description in 'intel_execlists_submission' vim +1250 drivers/video/hdmi.c 1234 case HDMI_INFOFRAME_TYPE_VENDOR: 1235 ret = hdmi_vendor_any_infoframe_unpack(&frame->vendor, buffer); 1236 break; 1237 default: 1238 ret = -EINVAL; 1239 break; 1240 } 1241 1242 return ret; 1243 } 1244 EXPORT_SYMBOL(hdmi_infoframe_unpack); 1245 1246 /** 1247 * audio clock regeneration (acr) parameters 1248 * N and CTS computation are based on HDMI specification 1.4b 1249 */ > 1250 enum audio_rate { 1251 HDMI_AUDIO_N_CTS_32KHZ, 1252 HDMI_AUDIO_N_CTS_44_1KHZ, 1253 HDMI_AUDIO_N_CTS_48KHZ, 1254 }; 1255 1256 struct hdmi_audio_acr { 1257 unsigned int tmds_clk; 1258 struct hdmi_audio_n_cts n_cts; --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation [-- Attachment #2: .config.gz --] [-- Type: application/octet-stream, Size: 6302 bytes --] [-- Attachment #3: Type: text/plain, Size: 160 bytes --] _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 1/2] video: hdmi: add helper function for N and CTS 2016-04-21 8:07 ` [PATCH v3 1/2] video: hdmi: add helper function for N and CTS Arnaud Pouliquen 2016-04-21 9:24 ` [alsa-devel] " kbuild test robot @ 2016-04-21 12:39 ` Philipp Zabel 2016-04-21 13:52 ` Arnaud Pouliquen 1 sibling, 1 reply; 6+ messages in thread From: Philipp Zabel @ 2016-04-21 12:39 UTC (permalink / raw) To: Arnaud Pouliquen Cc: alsa-devel, Russell King - ARM Linux, Liam Girdwood, dri-devel, Mark Brown, Jyri Sarha, Benjamin Gaignard Hi Arnaud, Am Donnerstag, den 21.04.2016, 10:07 +0200 schrieb Arnaud Pouliquen: > Add helper function to compute HDMI CTS and N parameters > Implementation is based on HDMI 1.4b specification. > > Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com> > Acked-by: Benjamin Gaignard <benjamin.gaignard@linaro.org> > Acked-by: Vincent ABRIOU <vincent.abriou@st.com> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> > --- > drivers/video/hdmi.c | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++ > include/linux/hdmi.h | 22 ++++++ > 2 files changed, 224 insertions(+) > > diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c > index 1626892..6381ce0 100644 > --- a/drivers/video/hdmi.c > +++ b/drivers/video/hdmi.c > @@ -1242,3 +1242,205 @@ int hdmi_infoframe_unpack(union hdmi_infoframe *frame, void *buffer) > return ret; > } > EXPORT_SYMBOL(hdmi_infoframe_unpack); > + > +/** > + * audio clock regeneration (acr) parameters > + * N and CTS computation are based on HDMI specification 1.4b > + */ > +enum audio_rate { > + HDMI_AUDIO_N_CTS_32KHZ, > + HDMI_AUDIO_N_CTS_44_1KHZ, > + HDMI_AUDIO_N_CTS_48KHZ, > +}; > + > +struct hdmi_audio_acr { > + unsigned int tmds_clk; > + struct hdmi_audio_n_cts n_cts; > +}; > + > +static const struct hdmi_audio_acr hdmi_audio_standard_acr[3][12] = { > + { /*32 kHz*/ If you used [HDMI_AUDIO_N_CTS_32KHZ] = { instead, that would mirror how the array is indexed via audio_freq_id in hdmi_audio_get_coherent_n_cts below. > + { 25174825, { 4576, 28125, 0 } }, /* 25,20/1.001 MHz */ ^ s/,/./ > + { 25200000, { 4096, 25200, 0 } }, /* 25.20 MHz */ > + { 27000000, { 4096, 27000, 0 } }, /* 27.00 MHz */ > + { 27027000, { 4096, 27027, 0 } }, /* 27.00*1.001 MHz */ > + { 54000000, { 4096, 54000, 0 } }, /* 54.00 MHz */ > + { 54054000, { 4096, 54054, 0 } }, /* 54.00*1.001 MHz */ > + { 74175824, { 11648, 210937, 50 } }, /* 74.25/1.001 MHz */ > + { 74250000, { 4096, 74250, 0 } }, /* 74.25 MHz */ > + { 148351648, { 11648, 421875, 0 } }, /* 148.50/1.001 MHz */ > + { 148500000, { 4096, 148500, 0 } }, /* 148.50 MHz */ > + { 296703296, { 5824, 421875, 0 } }, /* 297/1.001 MHz */ ^ Maybe add a comment above that tmds_clk is rounded down? > + { 297000000, { 3072, 222750, 0 } }, /* 297 MHz */ > + }, > + { /*44.1 kHz, 88.2 kHz 176.4 kHz*/ > + { 25174825, { 7007, 31250, 0 } }, /* 25,20/1.001 MHz */ > + { 25200000, { 6272, 28000, 0 } }, /* 25.20 MHz */ > + { 27000000, { 6272, 30000, 0 } }, /* 27.00 MHz */ > + { 27027000, { 6272, 30030, 0 } }, /* 27.00*1.001 MHz */ > + { 54000000, { 6272, 60000, 0 } }, /* 54.00 MHz */ > + { 54054000, { 6272, 60060, 0 } }, /* 54.00*1.001 MHz */ > + { 74175824, { 17836, 234375, 0 } }, /* 74.25/1.001 MHz */ > + { 74250000, { 6272, 82500, 0 } }, /* 74.25 MHz */ > + { 148351648, { 8918, 234375, 0 } }, /* 148.50/1.001 MHz */ > + { 148500000, { 6272, 165000, 0 } }, /* 148.50 MHz */ > + { 296703296, { 4459, 234375, 0 } }, /* 297/1.001 MHz */ > + { 297000000, { 4704, 247500, 0 } }, /* 297 MHz */ > + }, > + { /*48 kHz, 96 kHz 192 kHz*/ > + { 25174825, { 6864, 28125, 0 } }, /* 25,20/1.001 MHz */ > + { 25200000, { 6144, 25200, 0 } }, /* 25.20 MHz */ > + { 27000000, { 6144, 27000, 0 } }, /* 27.00 MHz */ > + { 27027000, { 6144, 27027, 0 } }, /* 27.00*1.001 MHz */ > + { 54000000, { 6144, 54000, 0 } }, /* 54.00 MHz */ > + { 54054000, { 6144, 54054, 0 } }, /* 54.00*1.001 MHz */ > + { 74175824, { 11648, 140625, 0 } }, /* 74.25/1.001 MHz */ > + { 74250000, { 6144, 74250, 0 } }, /* 74.25 MHz */ > + { 148351648, { 5824, 140625, 0 } }, /* 148.50/1.001 MHz */ > + { 148500000, { 6144, 148500, 0 } }, /* 148.50 MHz */ > + { 296703296, { 5824, 281250, 0 } }, /* 297/1.001 MHz */ > + { 297000000, { 5120, 247500, 0 } }, /* 297 MHz */ > + } > +}; > + > +/** > + * hdmi_audio_get_coherent_n_cts() - compute N and CTS parameters for coherent > + * clocks. Coherent clock means that audio and TMDS clocks have the same > + * source (no drifts between clocks). > + * > + * @audio_fs: audio frame clock frequency in Hz > + * @tmds_clk: HDMI TMDS clock frequency in Hz > + * @n_cts: N and CTS parameter returned to user > + * > + * Values computed are based on table described in HDMI specification 1.4b > + * > + * Returns 0 on success or a negative error code on failure. > + */ > +int hdmi_audio_get_coherent_n_cts(unsigned int audio_fs, > + unsigned int tmds_clk, > + struct hdmi_audio_n_cts *n_cts) > +{ > + int audio_freq_id, i; > + int rate_coeff = 1; > + u64 val, min; > + const struct hdmi_audio_acr *acr_table; > + const struct hdmi_audio_n_cts *predef_n_cts = NULL; > + > + switch (audio_fs) { > + case 32000: > + audio_freq_id = HDMI_AUDIO_N_CTS_32KHZ; > + n_cts->n = 4096; > + break; > + case 44100: > + audio_freq_id = HDMI_AUDIO_N_CTS_44_1KHZ; > + n_cts->n = 6272; > + break; > + case 48000: > + audio_freq_id = HDMI_AUDIO_N_CTS_48KHZ; > + n_cts->n = 6144; > + break; > + case 88200: > + audio_freq_id = HDMI_AUDIO_N_CTS_44_1KHZ; > + rate_coeff = 2; > + n_cts->n = 6272 * 2; > + break; > + case 96000: > + audio_freq_id = HDMI_AUDIO_N_CTS_48KHZ; > + rate_coeff = 2; > + n_cts->n = 6144 * 2; > + break; > + case 176400: > + audio_freq_id = HDMI_AUDIO_N_CTS_44_1KHZ; > + rate_coeff = 4; > + n_cts->n = 6272 * 4; > + break; > + case 192000: > + audio_freq_id = HDMI_AUDIO_N_CTS_48KHZ; > + rate_coeff = 4; > + n_cts->n = 6144 * 4; > + break; > + default: > + return -EINVAL; > + } > + > + acr_table = hdmi_audio_standard_acr[audio_freq_id]; > + for (i = 0; i < ARRAY_SIZE(hdmi_audio_standard_acr[0]); i++) { > + if (tmds_clk == acr_table[i].tmds_clk) { > + predef_n_cts = &acr_table[i].n_cts; > + n_cts->n = predef_n_cts->n * rate_coeff; > + n_cts->cts = predef_n_cts->cts; > + n_cts->cts_1_ratio = predef_n_cts->cts_1_ratio; > + return 0; > + } > + } > + > + /* > + * predefined frequency not found. Compute CTS using formula: ^ > + * CTS = (Ftdms_clk * N) / (128* audio_fs) ^ ^ > + */ ^ Missing spaces. > + val = (u64)tmds_clk * n_cts->n; > + n_cts->cts = div64_u64(val, 128UL * audio_fs); > + > + n_cts->cts_1_ratio = 0; > + min = (u64)n_cts->cts * 128UL * audio_fs; > + if (min < (val)) { ^ ^ These parentheses are not needed. > + /* > + * non-accurate value for CTS ^ > + * compute ratio, needed by user to alternate in ACR ^ > + * between CTS and CTS + 1 value. ^ > + */ ^ Missing spaces. > + n_cts->cts_1_ratio = 100 - ((u32)(val - min)) * 100 / > + (128 * audio_fs); I don't understand the purpose of the (100-x) above (and how cts_1_ratio is supposed to be used). When for example val == (min + 0.3 * 128 * audio_fs) then cts_1_ratio = 70. To achieve an average CTS of (val), shouldn't (min) be used 70% of the time and (min+1) be used 30% of the time? I would have expected (cts_1_ratio == 30) in that case. > + } > + > + return 0; > +} > +EXPORT_SYMBOL(hdmi_audio_get_coherent_n_cts); > + > +/** > + * hdmi_audio_get_non_coherent_n() - get N parameter for non-coherent > + * clocks. None-coherent clocks means that audio and TMDS clocks have not the > + * same source (drifts between clocks). In this case assumption is that CTS is > + * automatically calculated by hardware. > + * > + * @audio_fs: audio frame clock frequency in Hz > + * > + * Values computed are based on table described in HDMI specification 1.4b > + * > + * Returns n value. > + */ > +int hdmi_audio_get_non_coherent_n(unsigned int audio_fs) > +{ > + unsigned int n; > + > + switch (audio_fs) { > + case 32000: > + n = 4096; > + break; > + case 44100: > + n = 6272; > + break; > + case 48000: > + n = 6144; > + break; > + case 88200: > + n = 6272 * 2; > + break; > + case 96000: > + n = 6144 * 2; > + break; > + case 176400: > + n = 6272 * 4; > + break; > + case 192000: > + n = 6144 * 4; > + break; > + default: > + /* Not pre-defined, recommended value: 128 * fs / 1000 */ > + n = (audio_fs * 128) / 1000; > + } > + > + return n; > +} > +EXPORT_SYMBOL(hdmi_audio_get_non_coherent_n); > + > diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h > index e974420..28b6794 100644 > --- a/include/linux/hdmi.h > +++ b/include/linux/hdmi.h > @@ -333,4 +333,26 @@ int hdmi_infoframe_unpack(union hdmi_infoframe *frame, void *buffer); > void hdmi_infoframe_log(const char *level, struct device *dev, > union hdmi_infoframe *frame); > > +/** > + * struct hdmi_audio_n_cts - n and cts parameter for ACR packets > + * @n: N parameter > + * @cts: CTS parameter > + * @cts_1_ratio: ratio from 0 to 99 to alternate "CTS" and "CTS + 1" values > + * ratio = 0: CTS parameter is accurate, no need to alternate with "CTS + 1" > + * value > + * ratio = x: Need to alternate with ACR "CTS + 1" value x% of the time to > + * generate accurate audio clock Does this mean that at cts_1_ratio == 30, CTS should be used 70% of the time, and CTS+1 should be used 30% of the time, or the other way around? > + */ > +struct hdmi_audio_n_cts { > + unsigned int n; > + unsigned int cts; > + unsigned int cts_1_ratio; > +}; > + > +int hdmi_audio_get_coherent_n_cts(unsigned int audio_fs, > + unsigned int tmds_clk, > + struct hdmi_audio_n_cts *n_cts); > + > +int hdmi_audio_get_non_coherent_n(unsigned int audio_fs); > + > #endif /* _DRM_HDMI_H */ regards Philipp _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 1/2] video: hdmi: add helper function for N and CTS 2016-04-21 12:39 ` Philipp Zabel @ 2016-04-21 13:52 ` Arnaud Pouliquen 0 siblings, 0 replies; 6+ messages in thread From: Arnaud Pouliquen @ 2016-04-21 13:52 UTC (permalink / raw) To: Philipp Zabel Cc: Jean-Francois Moine, alsa-devel@alsa-project.org, Lars-Peter Clausen, Russell King - ARM Linux, David Airlie, Liam Girdwood, dri-devel@lists.freedesktop.org, Takashi Iwai, Mark Brown, Jyri Sarha, Benjamin Gaignard On 04/21/2016 02:39 PM, Philipp Zabel wrote: > Hi Arnaud, > > Am Donnerstag, den 21.04.2016, 10:07 +0200 schrieb Arnaud Pouliquen: >> Add helper function to compute HDMI CTS and N parameters >> Implementation is based on HDMI 1.4b specification. >> >> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com> >> Acked-by: Benjamin Gaignard <benjamin.gaignard@linaro.org> >> Acked-by: Vincent ABRIOU <vincent.abriou@st.com> > > Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> > >> --- >> drivers/video/hdmi.c | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++ >> include/linux/hdmi.h | 22 ++++++ >> 2 files changed, 224 insertions(+) >> >> diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c >> index 1626892..6381ce0 100644 >> --- a/drivers/video/hdmi.c >> +++ b/drivers/video/hdmi.c >> @@ -1242,3 +1242,205 @@ int hdmi_infoframe_unpack(union hdmi_infoframe *frame, void *buffer) >> return ret; >> } >> EXPORT_SYMBOL(hdmi_infoframe_unpack); >> + >> +/** >> + * audio clock regeneration (acr) parameters >> + * N and CTS computation are based on HDMI specification 1.4b >> + */ >> +enum audio_rate { >> + HDMI_AUDIO_N_CTS_32KHZ, >> + HDMI_AUDIO_N_CTS_44_1KHZ, >> + HDMI_AUDIO_N_CTS_48KHZ, >> +}; >> + >> +struct hdmi_audio_acr { >> + unsigned int tmds_clk; >> + struct hdmi_audio_n_cts n_cts; >> +}; >> + >> +static const struct hdmi_audio_acr hdmi_audio_standard_acr[3][12] = { >> + { /*32 kHz*/ > > If you used > > [HDMI_AUDIO_N_CTS_32KHZ] = { > > instead, that would mirror how the array is indexed via audio_freq_id in > hdmi_audio_get_coherent_n_cts below. > >> + { 25174825, { 4576, 28125, 0 } }, /* 25,20/1.001 MHz */ > ^ > s/,/./ > >> + { 25200000, { 4096, 25200, 0 } }, /* 25.20 MHz */ >> + { 27000000, { 4096, 27000, 0 } }, /* 27.00 MHz */ >> + { 27027000, { 4096, 27027, 0 } }, /* 27.00*1.001 MHz */ >> + { 54000000, { 4096, 54000, 0 } }, /* 54.00 MHz */ >> + { 54054000, { 4096, 54054, 0 } }, /* 54.00*1.001 MHz */ >> + { 74175824, { 11648, 210937, 50 } }, /* 74.25/1.001 MHz */ >> + { 74250000, { 4096, 74250, 0 } }, /* 74.25 MHz */ >> + { 148351648, { 11648, 421875, 0 } }, /* 148.50/1.001 MHz */ >> + { 148500000, { 4096, 148500, 0 } }, /* 148.50 MHz */ >> + { 296703296, { 5824, 421875, 0 } }, /* 297/1.001 MHz */ > ^ > Maybe add a comment above that tmds_clk is rounded down? My apologize, I have forgotten to add 296703297 value to take into account truncated and rounded values as discussed in V2: { 296703296, { 5824, 421875, 0 } }, /* 297/1.001 MHz (truncated) */ { 296703297, { 5824, 421875, 0 } }, /* 297/1.001 MHz (rounded) */ > >> + { 297000000, { 3072, 222750, 0 } }, /* 297 MHz */ >> + }, >> + { /*44.1 kHz, 88.2 kHz 176.4 kHz*/ >> + { 25174825, { 7007, 31250, 0 } }, /* 25,20/1.001 MHz */ >> + { 25200000, { 6272, 28000, 0 } }, /* 25.20 MHz */ >> + { 27000000, { 6272, 30000, 0 } }, /* 27.00 MHz */ >> + { 27027000, { 6272, 30030, 0 } }, /* 27.00*1.001 MHz */ >> + { 54000000, { 6272, 60000, 0 } }, /* 54.00 MHz */ >> + { 54054000, { 6272, 60060, 0 } }, /* 54.00*1.001 MHz */ >> + { 74175824, { 17836, 234375, 0 } }, /* 74.25/1.001 MHz */ >> + { 74250000, { 6272, 82500, 0 } }, /* 74.25 MHz */ >> + { 148351648, { 8918, 234375, 0 } }, /* 148.50/1.001 MHz */ >> + { 148500000, { 6272, 165000, 0 } }, /* 148.50 MHz */ >> + { 296703296, { 4459, 234375, 0 } }, /* 297/1.001 MHz */ >> + { 297000000, { 4704, 247500, 0 } }, /* 297 MHz */ >> + }, >> + { /*48 kHz, 96 kHz 192 kHz*/ >> + { 25174825, { 6864, 28125, 0 } }, /* 25,20/1.001 MHz */ >> + { 25200000, { 6144, 25200, 0 } }, /* 25.20 MHz */ >> + { 27000000, { 6144, 27000, 0 } }, /* 27.00 MHz */ >> + { 27027000, { 6144, 27027, 0 } }, /* 27.00*1.001 MHz */ >> + { 54000000, { 6144, 54000, 0 } }, /* 54.00 MHz */ >> + { 54054000, { 6144, 54054, 0 } }, /* 54.00*1.001 MHz */ >> + { 74175824, { 11648, 140625, 0 } }, /* 74.25/1.001 MHz */ >> + { 74250000, { 6144, 74250, 0 } }, /* 74.25 MHz */ >> + { 148351648, { 5824, 140625, 0 } }, /* 148.50/1.001 MHz */ >> + { 148500000, { 6144, 148500, 0 } }, /* 148.50 MHz */ >> + { 296703296, { 5824, 281250, 0 } }, /* 297/1.001 MHz */ >> + { 297000000, { 5120, 247500, 0 } }, /* 297 MHz */ >> + } >> +}; >> + >> +/** >> + * hdmi_audio_get_coherent_n_cts() - compute N and CTS parameters for coherent >> + * clocks. Coherent clock means that audio and TMDS clocks have the same >> + * source (no drifts between clocks). >> + * >> + * @audio_fs: audio frame clock frequency in Hz >> + * @tmds_clk: HDMI TMDS clock frequency in Hz >> + * @n_cts: N and CTS parameter returned to user >> + * >> + * Values computed are based on table described in HDMI specification 1.4b >> + * >> + * Returns 0 on success or a negative error code on failure. >> + */ >> +int hdmi_audio_get_coherent_n_cts(unsigned int audio_fs, >> + unsigned int tmds_clk, >> + struct hdmi_audio_n_cts *n_cts) >> +{ >> + int audio_freq_id, i; >> + int rate_coeff = 1; >> + u64 val, min; >> + const struct hdmi_audio_acr *acr_table; >> + const struct hdmi_audio_n_cts *predef_n_cts = NULL; >> + >> + switch (audio_fs) { >> + case 32000: >> + audio_freq_id = HDMI_AUDIO_N_CTS_32KHZ; >> + n_cts->n = 4096; >> + break; >> + case 44100: >> + audio_freq_id = HDMI_AUDIO_N_CTS_44_1KHZ; >> + n_cts->n = 6272; >> + break; >> + case 48000: >> + audio_freq_id = HDMI_AUDIO_N_CTS_48KHZ; >> + n_cts->n = 6144; >> + break; >> + case 88200: >> + audio_freq_id = HDMI_AUDIO_N_CTS_44_1KHZ; >> + rate_coeff = 2; >> + n_cts->n = 6272 * 2; >> + break; >> + case 96000: >> + audio_freq_id = HDMI_AUDIO_N_CTS_48KHZ; >> + rate_coeff = 2; >> + n_cts->n = 6144 * 2; >> + break; >> + case 176400: >> + audio_freq_id = HDMI_AUDIO_N_CTS_44_1KHZ; >> + rate_coeff = 4; >> + n_cts->n = 6272 * 4; >> + break; >> + case 192000: >> + audio_freq_id = HDMI_AUDIO_N_CTS_48KHZ; >> + rate_coeff = 4; >> + n_cts->n = 6144 * 4; >> + break; >> + default: >> + return -EINVAL; >> + } >> + >> + acr_table = hdmi_audio_standard_acr[audio_freq_id]; >> + for (i = 0; i < ARRAY_SIZE(hdmi_audio_standard_acr[0]); i++) { >> + if (tmds_clk == acr_table[i].tmds_clk) { >> + predef_n_cts = &acr_table[i].n_cts; >> + n_cts->n = predef_n_cts->n * rate_coeff; >> + n_cts->cts = predef_n_cts->cts; >> + n_cts->cts_1_ratio = predef_n_cts->cts_1_ratio; >> + return 0; >> + } >> + } >> + >> + /* >> + * predefined frequency not found. Compute CTS using formula: > ^ >> + * CTS = (Ftdms_clk * N) / (128* audio_fs) > ^ ^ >> + */ > ^ > Missing spaces. > >> + val = (u64)tmds_clk * n_cts->n; >> + n_cts->cts = div64_u64(val, 128UL * audio_fs); >> + >> + n_cts->cts_1_ratio = 0; >> + min = (u64)n_cts->cts * 128UL * audio_fs; >> + if (min < (val)) { > ^ ^ > These parentheses are not needed. > >> + /* >> + * non-accurate value for CTS > ^ >> + * compute ratio, needed by user to alternate in ACR > ^ >> + * between CTS and CTS + 1 value. > ^ >> + */ > ^ > Missing spaces. > >> + n_cts->cts_1_ratio = 100 - ((u32)(val - min)) * 100 / >> + (128 * audio_fs); > > I don't understand the purpose of the (100-x) above (and how cts_1_ratio > is supposed to be used). > > When for example val == (min + 0.3 * 128 * audio_fs) then > cts_1_ratio = 70. > To achieve an average CTS of (val), shouldn't (min) be used 70% of the > time and (min+1) be used 30% of the time? > I would have expected (cts_1_ratio == 30) in that case. you are right! my reasoning is foolish... Thank for pointing this error! >> >> +/** >> + * struct hdmi_audio_n_cts - n and cts parameter for ACR packets >> + * @n: N parameter >> + * @cts: CTS parameter >> + * @cts_1_ratio: ratio from 0 to 99 to alternate "CTS" and "CTS + 1" values >> + * ratio = 0: CTS parameter is accurate, no need to alternate with "CTS + 1" >> + * value >> + * ratio = x: Need to alternate with ACR "CTS + 1" value x% of the time to >> + * generate accurate audio clock > > Does this mean that at cts_1_ratio == 30, CTS should be used 70% of the > time, and CTS+1 should be used 30% of the time, or the other way around? yes CTS should be used 70% of the time, i will add example in comment > >> + */ >> +struct hdmi_audio_n_cts { >> + unsigned int n; >> + unsigned int cts; >> + unsigned int cts_1_ratio; >> +}; >> + >> +int hdmi_audio_get_coherent_n_cts(unsigned int audio_fs, >> + unsigned int tmds_clk, >> + struct hdmi_audio_n_cts *n_cts); >> + >> +int hdmi_audio_get_non_coherent_n(unsigned int audio_fs); >> + >> #endif /* _DRM_HDMI_H */ > > regards > Philipp > thanks and Regards Arnaud ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 2/2] drm: sti: Add ASoC generic hdmi codec support. 2016-04-21 8:07 [PATCH v3 0/2] sti: add audio interface to the hdmi driver Arnaud Pouliquen 2016-04-21 8:07 ` [PATCH v3 1/2] video: hdmi: add helper function for N and CTS Arnaud Pouliquen @ 2016-04-21 8:07 ` Arnaud Pouliquen 1 sibling, 0 replies; 6+ messages in thread From: Arnaud Pouliquen @ 2016-04-21 8:07 UTC (permalink / raw) To: alsa-devel, dri-devel Cc: Jean-Francois Moine, Lars-Peter Clausen, Russell King - ARM Linux, Philipp Zabel, David Airlie, arnaud.pouliquen, Liam Girdwood, Jyri Sarha, Takashi Iwai, Mark Brown, Benjamin Gaignard Add the interface needed by audio hdmi-codec driver. Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com> Acked-by: Benjamin Gaignard <benjamin.gaignard@linaro.org> Acked-by: Vincent ABRIOU <vincent.abriou@st.com> --- drivers/gpu/drm/sti/Kconfig | 1 + drivers/gpu/drm/sti/sti_hdmi.c | 248 ++++++++++++++++++++++++++++++++++++++--- drivers/gpu/drm/sti/sti_hdmi.h | 13 +++ 3 files changed, 245 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/sti/Kconfig b/drivers/gpu/drm/sti/Kconfig index 5ad43a1..494ab25 100644 --- a/drivers/gpu/drm/sti/Kconfig +++ b/drivers/gpu/drm/sti/Kconfig @@ -7,5 +7,6 @@ config DRM_STI select DRM_KMS_CMA_HELPER select DRM_PANEL select FW_LOADER + select SND_SOC_HDMI_CODEC if SND_SOC help Choose this option to enable DRM on STM stiH41x chipset diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c index 6ef0715..3a8bd47 100644 --- a/drivers/gpu/drm/sti/sti_hdmi.c +++ b/drivers/gpu/drm/sti/sti_hdmi.c @@ -18,6 +18,8 @@ #include <drm/drm_crtc_helper.h> #include <drm/drm_edid.h> +#include <sound/hdmi-codec.h> + #include "sti_hdmi.h" #include "sti_hdmi_tx3g4c28phy.h" #include "sti_hdmi_tx3g0c55phy.h" @@ -35,6 +37,8 @@ #define HDMI_DFLT_CHL0_DAT 0x0110 #define HDMI_DFLT_CHL1_DAT 0x0114 #define HDMI_DFLT_CHL2_DAT 0x0118 +#define HDMI_AUDIO_CFG 0x0200 +#define HDMI_SPDIF_FIFO_STATUS 0x0204 #define HDMI_SW_DI_1_HEAD_WORD 0x0210 #define HDMI_SW_DI_1_PKT_WORD0 0x0214 #define HDMI_SW_DI_1_PKT_WORD1 0x0218 @@ -44,6 +48,9 @@ #define HDMI_SW_DI_1_PKT_WORD5 0x0228 #define HDMI_SW_DI_1_PKT_WORD6 0x022C #define HDMI_SW_DI_CFG 0x0230 +#define HDMI_SAMPLE_FLAT_MASK 0x0244 +#define HDMI_AUDN 0x0400 +#define HDMI_AUD_CTS 0x0404 #define HDMI_SW_DI_2_HEAD_WORD 0x0600 #define HDMI_SW_DI_2_PKT_WORD0 0x0604 #define HDMI_SW_DI_2_PKT_WORD1 0x0608 @@ -103,6 +110,7 @@ #define HDMI_INT_DLL_LCK BIT(5) #define HDMI_INT_NEW_FRAME BIT(6) #define HDMI_INT_GENCTRL_PKT BIT(7) +#define HDMI_INT_AUDIO_FIFO_XRUN BIT(8) #define HDMI_INT_SINK_TERM_PRESENT BIT(11) #define HDMI_DEFAULT_INT (HDMI_INT_SINK_TERM_PRESENT \ @@ -111,6 +119,7 @@ | HDMI_INT_GLOBAL) #define HDMI_WORKING_INT (HDMI_INT_SINK_TERM_PRESENT \ + | HDMI_INT_AUDIO_FIFO_XRUN \ | HDMI_INT_GENCTRL_PKT \ | HDMI_INT_NEW_FRAME \ | HDMI_INT_DLL_LCK \ @@ -121,6 +130,27 @@ #define HDMI_STA_SW_RST BIT(1) +#define HDMI_AUD_CFG_8CH BIT(0) +#define HDMI_AUD_CFG_SPDIF_DIV_2 BIT(1) +#define HDMI_AUD_CFG_SPDIF_DIV_3 BIT(2) +#define HDMI_AUD_CFG_SPDIF_CLK_DIV_4 (BIT(1) | BIT(2)) +#define HDMI_AUD_CFG_CTS_CLK_256FS BIT(12) +#define HDMI_AUD_CFG_DTS_INVALID BIT(16) +#define HDMI_AUD_CFG_ONE_BIT_INVALID (BIT(18) | BIT(19) | BIT(20) | BIT(21)) +#define HDMI_AUD_CFG_CH12_VALID BIT(28) +#define HDMI_AUD_CFG_CH34_VALID BIT(29) +#define HDMI_AUD_CFG_CH56_VALID BIT(30) +#define HDMI_AUD_CFG_CH78_VALID BIT(31) + +/* sample flat mask */ +#define HDMI_SAMPLE_FLAT_NO 0 +#define HDMI_SAMPLE_FLAT_SP0 BIT(0) +#define HDMI_SAMPLE_FLAT_SP1 BIT(1) +#define HDMI_SAMPLE_FLAT_SP2 BIT(2) +#define HDMI_SAMPLE_FLAT_SP3 BIT(3) +#define HDMI_SAMPLE_FLAT_ALL (HDMI_SAMPLE_FLAT_SP0 | HDMI_SAMPLE_FLAT_SP1 |\ + HDMI_SAMPLE_FLAT_SP2 | HDMI_SAMPLE_FLAT_SP3) + #define HDMI_INFOFRAME_HEADER_TYPE(x) (((x) & 0xff) << 0) #define HDMI_INFOFRAME_HEADER_VERSION(x) (((x) & 0xff) << 8) #define HDMI_INFOFRAME_HEADER_LEN(x) (((x) & 0x0f) << 16) @@ -171,6 +201,10 @@ static irqreturn_t hdmi_irq_thread(int irq, void *arg) wake_up_interruptible(&hdmi->wait_event); } + /* Audio FIFO underrun IRQ */ + if (hdmi->irq_status & HDMI_INT_AUDIO_FIFO_XRUN) + DRM_INFO("Warning: audio FIFO underrun occurs!"); + return IRQ_HANDLED; } @@ -441,26 +475,29 @@ static int hdmi_avi_infoframe_config(struct sti_hdmi *hdmi) */ static int hdmi_audio_infoframe_config(struct sti_hdmi *hdmi) { - struct hdmi_audio_infoframe infofame; + struct hdmi_audio_params *audio = &hdmi->audio; u8 buffer[HDMI_INFOFRAME_SIZE(AUDIO)]; - int ret; - - ret = hdmi_audio_infoframe_init(&infofame); - if (ret < 0) { - DRM_ERROR("failed to setup audio infoframe: %d\n", ret); - return ret; - } - - infofame.channels = 2; - - ret = hdmi_audio_infoframe_pack(&infofame, buffer, sizeof(buffer)); - if (ret < 0) { - DRM_ERROR("failed to pack audio infoframe: %d\n", ret); - return ret; + int ret, val; + + DRM_DEBUG_DRIVER("enter %s, AIF %s\n", __func__, + audio->enabled ? "enable" : "disable"); + if (audio->enabled) { + /* set audio parameters stored*/ + ret = hdmi_audio_infoframe_pack(&audio->cea, buffer, + sizeof(buffer)); + if (ret < 0) { + DRM_ERROR("failed to pack audio infoframe: %d\n", ret); + return ret; + } + hdmi_infoframe_write_infopack(hdmi, buffer, ret); + } else { + /*disable audio info frame transmission */ + val = hdmi_read(hdmi, HDMI_SW_DI_CFG); + val &= ~HDMI_IFRAME_CFG_DI_N(HDMI_IFRAME_MASK, + HDMI_IFRAME_SLOT_AUDIO); + hdmi_write(hdmi, val, HDMI_SW_DI_CFG); } - hdmi_infoframe_write_infopack(hdmi, buffer, ret); - return 0; } @@ -656,6 +693,10 @@ static int hdmi_dbg_show(struct seq_file *s, void *data) DBGFS_DUMP("", HDMI_SW_DI_CFG); hdmi_dbg_sw_di_cfg(s, hdmi_read(hdmi, HDMI_SW_DI_CFG)); + DBGFS_DUMP("\n", HDMI_AUDIO_CFG); + DBGFS_DUMP("\n", HDMI_SPDIF_FIFO_STATUS); + DBGFS_DUMP("\n", HDMI_AUDN); + seq_printf(s, "\n AVI Infoframe (Data Island slot N=%d):", HDMI_IFRAME_SLOT_AVI); DBGFS_DUMP_DI(HDMI_SW_DI_N_HEAD_WORD, HDMI_IFRAME_SLOT_AVI); @@ -861,6 +902,7 @@ static int sti_hdmi_connector_get_modes(struct drm_connector *connector) count = drm_add_edid_modes(connector, edid); drm_mode_connector_update_edid_property(connector, edid); + drm_edid_to_eld(connector, edid); kfree(edid); return count; @@ -1049,6 +1091,160 @@ static struct drm_encoder *sti_hdmi_find_encoder(struct drm_device *dev) return NULL; } +static int hdmi_audio_configure(struct sti_hdmi *hdmi, + struct hdmi_audio_params *params) +{ + int audio_cfg, n; + struct hdmi_audio_infoframe *info = ¶ms->cea; + + DRM_DEBUG_DRIVER("\n"); + + if (!hdmi->enabled) + return 0; + + /* update N parameter */ + n = hdmi_audio_get_non_coherent_n(params->sample_rate); + + DRM_DEBUG_DRIVER("Audio rate = %d Hz, TMDS clock = %d Hz, n = %d\n", + params->sample_rate, hdmi->mode.clock * 1000, n); + hdmi_write(hdmi, n, HDMI_AUDN); + + /* update HDMI registers according to configuration */ + audio_cfg = HDMI_AUD_CFG_SPDIF_DIV_2 | HDMI_AUD_CFG_DTS_INVALID | + HDMI_AUD_CFG_ONE_BIT_INVALID; + + switch (info->channels) { + case 8: + audio_cfg |= HDMI_AUD_CFG_CH78_VALID; + case 6: + audio_cfg |= HDMI_AUD_CFG_CH56_VALID; + case 4: + audio_cfg |= HDMI_AUD_CFG_CH34_VALID | HDMI_AUD_CFG_8CH; + case 2: + audio_cfg |= HDMI_AUD_CFG_CH12_VALID; + break; + default: + DRM_ERROR("ERROR: Unsupported number of channels (%d)!\n", + info->channels); + return -EINVAL; + } + + hdmi_write(hdmi, audio_cfg, HDMI_AUDIO_CFG); + + hdmi->audio = *params; + + return hdmi_audio_infoframe_config(hdmi); +} + +static void hdmi_audio_shutdown(struct device *dev) +{ + struct sti_hdmi *hdmi = dev_get_drvdata(dev); + int audio_cfg; + + DRM_DEBUG_DRIVER("\n"); + + /* disable audio */ + audio_cfg = HDMI_AUD_CFG_SPDIF_DIV_2 | HDMI_AUD_CFG_DTS_INVALID | + HDMI_AUD_CFG_ONE_BIT_INVALID; + hdmi_write(hdmi, audio_cfg, HDMI_AUDIO_CFG); + + hdmi->audio.enabled = 0; + hdmi_audio_infoframe_config(hdmi); +} + +static int hdmi_audio_hw_params(struct device *dev, + struct hdmi_codec_daifmt *daifmt, + struct hdmi_codec_params *params) +{ + struct sti_hdmi *hdmi = dev_get_drvdata(dev); + int ret; + struct hdmi_audio_params audio = { + .sample_width = params->sample_width, + .sample_rate = params->sample_rate, + .cea = params->cea, + }; + + DRM_DEBUG_DRIVER("\n"); + + if (!hdmi->enabled) + return 0; + + if ((daifmt->fmt != HDMI_I2S) || daifmt->bit_clk_inv || + daifmt->frame_clk_inv || daifmt->bit_clk_master || + daifmt->frame_clk_master) { + dev_err(dev, "%s: Bad flags %d %d %d %d\n", __func__, + daifmt->bit_clk_inv, daifmt->frame_clk_inv, + daifmt->bit_clk_master, + daifmt->frame_clk_master); + return -EINVAL; + } + + audio.enabled = 1; + + ret = hdmi_audio_configure(hdmi, &audio); + if (ret < 0) + return ret; + + return 0; +} + +static int hdmi_audio_digital_mute(struct device *dev, bool enable) +{ + struct sti_hdmi *hdmi = dev_get_drvdata(dev); + + DRM_DEBUG_DRIVER("%s\n", enable ? "enable" : "disable"); + + if (enable) + hdmi_write(hdmi, HDMI_SAMPLE_FLAT_ALL, HDMI_SAMPLE_FLAT_MASK); + else + hdmi_write(hdmi, HDMI_SAMPLE_FLAT_NO, HDMI_SAMPLE_FLAT_MASK); + + return 0; +} + +static int hdmi_audio_get_eld(struct device *dev, uint8_t *buf, size_t len) +{ + struct sti_hdmi *hdmi = dev_get_drvdata(dev); + struct drm_connector *connector = hdmi->drm_connector; + + DRM_DEBUG_DRIVER("\n"); + memcpy(buf, connector->eld, min(sizeof(connector->eld), len)); + + return 0; +} + +static const struct hdmi_codec_ops audio_codec_ops = { + .hw_params = hdmi_audio_hw_params, + .audio_shutdown = hdmi_audio_shutdown, + .digital_mute = hdmi_audio_digital_mute, + .get_eld = hdmi_audio_get_eld, +}; + +static int sti_hdmi_register_audio_driver(struct device *dev, + struct sti_hdmi *hdmi) +{ + struct hdmi_codec_pdata codec_data = { + .ops = &audio_codec_ops, + .max_i2s_channels = 8, + .i2s = 1, + }; + + DRM_DEBUG_DRIVER("\n"); + + hdmi->audio.enabled = 0; + + hdmi->audio_pdev = platform_device_register_data( + dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO, + &codec_data, sizeof(codec_data)); + + if (IS_ERR(hdmi->audio_pdev)) + return PTR_ERR(hdmi->audio_pdev); + + DRM_INFO("%s Driver bound %s\n", HDMI_CODEC_DRV_NAME, dev_name(dev)); + + return 0; +} + static int sti_hdmi_bind(struct device *dev, struct device *master, void *data) { struct sti_hdmi *hdmi = dev_get_drvdata(dev); @@ -1099,12 +1295,27 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data) if (err) goto err_connector; + hdmi->drm_connector = drm_connector; + err = drm_mode_connector_attach_encoder(drm_connector, encoder); if (err) { DRM_ERROR("Failed to attach a connector to a encoder\n"); goto err_sysfs; } + err = sti_hdmi_register_audio_driver(dev, hdmi); + if (err) { + DRM_ERROR("Failed to attach an audio codec\n"); + goto err_sysfs; + } + + /* Initialize audio infoframe */ + err = hdmi_audio_infoframe_init(&hdmi->audio.cea); + if (err) { + DRM_ERROR("Failed to init audio infoframe\n"); + goto err_sysfs; + } + /* Enable default interrupts */ hdmi_write(hdmi, HDMI_DEFAULT_INT, HDMI_INT_EN); @@ -1115,6 +1326,7 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data) err_sysfs: drm_connector_unregister(drm_connector); + hdmi->drm_connector = NULL; err_connector: drm_connector_cleanup(drm_connector); @@ -1267,6 +1479,8 @@ static int sti_hdmi_remove(struct platform_device *pdev) struct sti_hdmi *hdmi = dev_get_drvdata(&pdev->dev); i2c_put_adapter(hdmi->ddc_adapt); + if (hdmi->audio_pdev) + platform_device_unregister(hdmi->audio_pdev); component_del(&pdev->dev, &sti_hdmi_ops); return 0; diff --git a/drivers/gpu/drm/sti/sti_hdmi.h b/drivers/gpu/drm/sti/sti_hdmi.h index ef3a945..119bc35 100644 --- a/drivers/gpu/drm/sti/sti_hdmi.h +++ b/drivers/gpu/drm/sti/sti_hdmi.h @@ -23,6 +23,13 @@ struct hdmi_phy_ops { void (*stop)(struct sti_hdmi *hdmi); }; +struct hdmi_audio_params { + bool enabled; + unsigned int sample_width; + unsigned int sample_rate; + struct hdmi_audio_infoframe cea; +}; + /* values for the framing mode property */ enum sti_hdmi_modes { HDMI_MODE_HDMI, @@ -67,6 +74,9 @@ static const struct drm_prop_enum_list colorspace_mode_names[] = { * @ddc_adapt: i2c ddc adapter * @colorspace: current colorspace selected * @hdmi_mode: select framing for HDMI or DVI + * @audio_pdev: ASoC hdmi-codec platform device + * @audio: hdmi audio parameters. + * @drm_connector: hdmi connector */ struct sti_hdmi { struct device dev; @@ -89,6 +99,9 @@ struct sti_hdmi { struct i2c_adapter *ddc_adapt; enum hdmi_colorspace colorspace; enum sti_hdmi_modes hdmi_mode; + struct platform_device *audio_pdev; + struct hdmi_audio_params audio; + struct drm_connector *drm_connector; }; u32 hdmi_read(struct sti_hdmi *hdmi, int offset); -- 1.9.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2016-04-21 13:52 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-04-21 8:07 [PATCH v3 0/2] sti: add audio interface to the hdmi driver Arnaud Pouliquen 2016-04-21 8:07 ` [PATCH v3 1/2] video: hdmi: add helper function for N and CTS Arnaud Pouliquen 2016-04-21 9:24 ` [alsa-devel] " kbuild test robot 2016-04-21 12:39 ` Philipp Zabel 2016-04-21 13:52 ` Arnaud Pouliquen 2016-04-21 8:07 ` [PATCH v3 2/2] drm: sti: Add ASoC generic hdmi codec support Arnaud Pouliquen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).