[PATCH 00/11] ASoC: hdac_hdmi: Add multichannel support

2016-04-12 Thread Subhransu S. Prusty
On Tue, Apr 12, 2016 at 06:54:35AM +0100, Mark Brown wrote:
> On Tue, Apr 12, 2016 at 07:43:59AM +0200, Takashi Iwai wrote:
> 
> > But the problem is more complicated because you're changing drm stuff,
> > too.  This is usually managed in drm tree.  So this cross over three
> > different trees.
> 
> The DRM folks tend to leave this up to us, or at least review on any of
> these crossover patches has been extremely light.
> 
> > Do we really need this?  Even the direct reference is pretty much
> > obvious.  e.g. I see no big difference between two lines below:
> > spk_alloc = drm_eld_get_spk_alloc(some_eld);
> > spk_alloc = some_eld[DRM_ELD_SPAEKER];
> 
> That'd make things even easier of course.

Takashi/Mark, Thanks for the review. Agree, accomodating in the driver is
easier and the inline function doesn't make much difference. I will
accomodate the change in the driver itself.

Shall I repost the series with these changes, which can be reviewed further
or wait for more review comments before reposting?

Regards,
Subhransu

-- 


[PATCH 02/11] drm/edid: Add API to get speaker allocation

2016-04-12 Thread Subhransu S. Prusty
Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
Cc: Jani Nikula 
Cc: David Airlie 
Cc: dri-devel at lists.freedesktop.org
Cc: Daniel Vetter 
---
 include/drm/drm_edid.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index dec6221..99142d1 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -415,6 +415,15 @@ static inline u8 drm_eld_get_conn_type(const uint8_t *eld)
return eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_CONN_TYPE_MASK;
 }

+/**
+ * drm_eld_get_spk_alloc - Get ELD speaker allocation
+ * @eld: pointer to an eld memory structure
+ */
+static inline const u8 drm_eld_get_spk_alloc(const uint8_t *eld)
+{
+   return eld[DRM_ELD_SPEAKER];
+}
+
 struct edid *drm_do_get_edid(struct drm_connector *connector,
int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
  size_t len),
-- 
1.9.1



[PATCH 00/11] ASoC: hdac_hdmi: Add multichannel support

2016-04-12 Thread Subhransu S. Prusty
This series parses ELD to identify multichannel capability of the
sync, and uses HDA framework to programs codec's channel map
registers.

Channel map controls are registered in patch 8, with which user
can specify a specific channel order. chmap controls are
registered inside jack_init callback. As PCMs need to be
registered before registering chmap controls, jack_init call in
the machine driver is moved to late_probe instead of init
callback.

Skylake driver is modified and buffer size calculation is fixed
for multichannel support.

Please note, patch 2 and 4 adds small macros to read speaker
allocation from ELD and channel counts from cap bits respectively
in DRM and HDA headers.  We have CCed DRM folks here. Please ack
patch 1, so that we can have this series merged through sound
trees. Patch 3 needs Takashi's ack, so that it can be merged
through ASoC.

Patch 9 has dependency on commit#44fde3b ("ALSA: hda - Update
chmap tlv to report sink's capability) which is merged in
Takashi's tree.

So this may be merged in ASoC with Takashi's Ack and pulling in
changes from Takashi's tree or alternatively it can be directly
merged in Takashi's with Mark's Ack

Takashi/Mark, please decide how you guys want this to be merged. 

Cc: Jani Nikula 
Cc: David Airlie 
Cc: dri-devel at lists.freedesktop.org
Cc: Daniel Vetter 

Subhransu S. Prusty (11):
  ASoC: Intel: Skylake: Fix ibs/obs calc for non-integral sampling rates
  drm/edid: Add API to get speaker allocation
  ASoC: hdac_hdmi: parse eld for channel map capability
  ALSA: hda - add helper to get channels from cap bits
  ASoC: hdac_hdmi: Add multichannel support
  ASoC: skl_rt286: Fix to support hdmi channel map support
  ASoC: Intel: boards: Update skl_nau88l25_max98357a driver to support
chmap
  ASoC: Intel: boards: Update skl_nau88l25_ssm4567 driver to support
chmap
  ASoC: hdac_hdmi: Register chmap controls and ops
  ASoC: Intel: Skylake: Add multichannel support for HDMI
  ASoC: Intel: Skylake: Update channel map based on runtime params

 include/drm/drm_edid.h  |   9 ++
 sound/hda/local.h   |  10 ++
 sound/soc/codecs/hdac_hdmi.c| 165 ++--
 sound/soc/intel/boards/skl_nau88l25_max98357a.c |  74 ++-
 sound/soc/intel/boards/skl_nau88l25_ssm4567.c   |  73 ++-
 sound/soc/intel/boards/skl_rt286.c  |  48 ++-
 sound/soc/intel/skylake/skl-pcm.c   |  14 +-
 sound/soc/intel/skylake/skl-topology.c  |  49 +--
 8 files changed, 409 insertions(+), 33 deletions(-)

-- 
1.9.1



[PATCH v6 08/15] drm/edid: Add API to help find connection type

2016-02-12 Thread Subhransu S. Prusty
To fill the audio infoframe it is required to identify the
connection type as DP or HDMI. This patch adds an API which
parses ELD and returns the display type connected.

Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
Reviewed-by: Jani Nikula 
Cc: David Airlie 
Cc: dri-devel at lists.freedesktop.org
Cc: Daniel Vetter 
---
 include/drm/drm_edid.h | 12 
 1 file changed, 12 insertions(+)

diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 2af9769..dec6221 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -403,6 +403,18 @@ static inline int drm_eld_size(const uint8_t *eld)
return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
 }

+/**
+ * drm_eld_get_conn_type - Get device type hdmi/dp connected
+ * @eld: pointer to an ELD memory structure
+ *
+ * The caller need to use %DRM_ELD_CONN_TYPE_HDMI or %DRM_ELD_CONN_TYPE_DP to
+ * identify the display type connected.
+ */
+static inline u8 drm_eld_get_conn_type(const uint8_t *eld)
+{
+   return eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_CONN_TYPE_MASK;
+}
+
 struct edid *drm_do_get_edid(struct drm_connector *connector,
int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
  size_t len),
-- 
1.9.1



[PATCH v6 00/15] ASoC: hdac_hdmi: Add DP & notification support

2016-02-12 Thread Subhransu S. Prusty
This patch series adds DP audio and hotplug notification support.

In skylake platform the DP is on a different port which is not
enabled by default. A vendor widget is programmed to enable
playback on all ports. This also enables all the converters.

Codec Dais, widgets, graph are now created dynamically based on
the nodes enumerated, thus removing the hardcoding. Mux controls
are used to establish routing stream to a specific port.

For DP audio support, infoframe needs to be different. Based on
ELD queried we either pack HDMI or DP infoframe.

Also with this series, Jack notification support is added and
Jack event is reported to userspace as is done in case of legacy
driver.

Few fixes are added to check for possible memory leak,
reconfiguring register during resume from D3 etc.

The 8th patch is adding a small macro for getting connection type
in drm header. It is reviewed by drm folks, CCed them. Please
merge it through sound trees.

changes in v6:
- Fixed some review comments
- Fix afg node D3 state

Cc: Jani Nikula 
Cc: David Airlie 
Cc: dri-devel at lists.freedesktop.org
Cc: Daniel Vetter 

Jeeja KP (2):
  ASoC: hdac_hdmi: Add jack reporting
  ASoC: hdac_hdmi: Add PM support

Ramesh Babu (1):
  ASoC: hdac_hdmi: Fix to keep codec power active during enumeration.

Subhransu S. Prusty (12):
  ASoC: hdac_hdmi: Add hotplug notification and read ELD
  ASoC: hdac_hdmi: Apply constraints based on ELD
  ASoC: hdac_hdmi: Enable DP1.2 and all converters/pins
  ASoC: hdac_hdmi: create dais based on number of cvts
  ASoC: hdac_hdmi: Create widget/route based on nodes enumerated
  ASoC: hdac_hdmi: Enable playback on all enumerated ports
  drm/edid: Add API to help find connection type
  ASoC: hdac_hdmi: Add infoframe support for dp audio
  ASoC: hdac_hdmi: Fix possible memory leak in hw_params
  ASoC: hdac_hdmi: Don't fail in dai startup to make userland happy
  ASoC: hdac_hdmi: Fix to reconfigure registers in runtime resume
  ASoC: hdac_hdmi: Fix to wait for D3 before powering off codec

 include/drm/drm_edid.h   |   12 +
 sound/soc/codecs/Kconfig |1 +
 sound/soc/codecs/hdac_hdmi.c | 1208 +-
 sound/soc/codecs/hdac_hdmi.h |6 +
 4 files changed, 1104 insertions(+), 123 deletions(-)
 create mode 100644 sound/soc/codecs/hdac_hdmi.h

-- 
1.9.1



[PATCH v5 08/14] drm/edid: Add API to help find connection type

2016-01-30 Thread Subhransu S. Prusty
To fill the audio infoframe it is required to identify the
connection type as DP or HDMI. This patch adds an API which
parses ELD and returns the display type of connected.

Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
Reviewed-by: Jani Nikula 
Cc: David Airlie 
Cc: dri-devel at lists.freedesktop.org
Cc: Daniel Vetter 
---
 include/drm/drm_edid.h | 12 
 1 file changed, 12 insertions(+)

diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 2af9769..8c537a0 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -403,6 +403,18 @@ static inline int drm_eld_size(const uint8_t *eld)
return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
 }

+/**
+ * drm_eld_get_conn_type - Get device type hdmi/dp connected
+ * @eld: pointer to an eld memory structure
+ *
+ * The caller need to use %DRM_ELD_CONN_TYPE_HDMI or %DRM_ELD_CONN_TYPE_DP to
+ * identify the display type connected.
+ */
+static inline u8 drm_eld_get_conn_type(const uint8_t *eld)
+{
+   return eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_CONN_TYPE_MASK;
+}
+
 struct edid *drm_do_get_edid(struct drm_connector *connector,
int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
  size_t len),
-- 
1.9.1



[PATCH v5 00/14] ASoC: hdac_hdmi: Add DP & notification support

2016-01-30 Thread Subhransu S. Prusty
This patch series adds DP audio and hotplug notification support.

In skylake platform the DP is on a different port which is not
enabled by default. A vendor widget is programmed to enable
playback on all ports. This also enables all the converters.

Codec Dais, widgets, graph are now created dynamically based on
the nodes enumerated, thus removing the hardcoding. Mux controls
are used to establish routing stream to a specific port.

For DP audio support, infoframe needs to be different. Based on
ELD queried we either pack HDMI or DP infoframe.

Also with this series, Jack notification support is added and
Jack event is reported to userspace as is done in case of legacy
driver.

Few fixes are added to check for possible memory leak,
reconfiguring register during resume from D3 etc.

The 8th patch is adding a small macro for getting connection type
in drm header. It is reviewed by drm folks, CCed them. Please
merge it through sound trees.

Changes in v5:
- Added more comments and reworded some commit messages
- Jack reporting support to user space added
- Fix to check for possible memory leak in hw_params
- Fix not to fail in dai startup to make userland APIs
  happy

Cc: Jani Nikula 
Cc: David Airlie 
Cc: dri-devel at lists.freedesktop.org
Cc: Daniel Vetter 

Jeeja KP (2):
  ASoC: hdac_hdmi: Add jack reporting
  ASoC: hdac_hdmi: Add PM support

Ramesh Babu (1):
  ASoC: hdac_hdmi: Fix to keep codec power active during enumeration.

Subhransu S. Prusty (11):
  ASoC: hdac_hdmi: Add hotplug notification and read eld
  ASoC: hdac_hdmi: Apply constraints based on ELD
  ASoC: hdac_hdmi: Enable DP1.2 and all converters/pins
  ASoC: hdac_hdmi: create dais based on number of cvts
  ASoC: hdac_hdmi: Create widget/route based on nodes enumerated
  ASoC: hdac_hdmi: Enable playback on all enumerated ports
  drm/edid: Add API to help find connection type
  ASoC: hdac_hdmi: Add infoframe support for dp audio
  ASoC: hdac_hdmi: Fix possible memory leak in hw_params
  ASoC: hdac_hdmi: Don't fail in dai startup to make userland happy
  ASoC: hdac_hdmi: Fix to reconfigure registers in runtime resume

 include/drm/drm_edid.h   |   12 +
 sound/soc/codecs/Kconfig |1 +
 sound/soc/codecs/hdac_hdmi.c | 1197 +-
 sound/soc/codecs/hdac_hdmi.h |6 +
 4 files changed, 1094 insertions(+), 122 deletions(-)
 create mode 100644 sound/soc/codecs/hdac_hdmi.h

-- 
1.9.1



[PATCH v4 REPOST 10/14] drm/edid: Add API to help find connection type

2016-01-04 Thread Subhransu S. Prusty
To fill the audio infoframe it is required to identify the
connection type as DP or HDMI. This patch adds an API which
parses ELD and returns the display type of connected.

Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
Reviewed-by: Jani Nikula 
Cc: David Airlie 
Cc: dri-devel at lists.freedesktop.org
Cc: Daniel Vetter 
---
 include/drm/drm_edid.h | 12 
 1 file changed, 12 insertions(+)

diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 2af9769..8c537a0 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -403,6 +403,18 @@ static inline int drm_eld_size(const uint8_t *eld)
return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
 }

+/**
+ * drm_eld_get_conn_type - Get device type hdmi/dp connected
+ * @eld: pointer to an eld memory structure
+ *
+ * The caller need to use %DRM_ELD_CONN_TYPE_HDMI or %DRM_ELD_CONN_TYPE_DP to
+ * identify the display type connected.
+ */
+static inline u8 drm_eld_get_conn_type(const uint8_t *eld)
+{
+   return eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_CONN_TYPE_MASK;
+}
+
 struct edid *drm_do_get_edid(struct drm_connector *connector,
int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
  size_t len),
-- 
1.9.1



[PATCH v4 REPOST 00/14] ASoC: hdac_hdmi: Add DP & notification support

2016-01-04 Thread Subhransu S. Prusty
This patch series adds DP audio and hotplug notification support.

On Skylake two DP ports are available and to enable DP on both
ports all pins need to be enabled.

There is a special vendor widget which need to be programmed to
enable all pins and converters. This series adds hotplug
notification, read/set constraint based on ELD, enable all
pin/cvts, DP1.2, programs the audio infoframe for DP. There is a
one to one mapping between converter and stream, so the dais are
created based on the no of streams supported on hdmi codec.  Even
though cvts can be mapped dynamically to the streams, currently
it is statically mapped as simultaneous playback on both DP and
HDMI is not supported as of now.

Pin muxes and controls are created dynamically to map converter
to pin widget. So at run time specific pin is mapped to the dai
based on the control selected (based on the display type DP/HDMI
connected).

Finally the DP audio infoframe programming is added to support
the DP feature. 

Also with hotplug notification support, ELD is read and
capabilities are set for rate, formats and channels. drm_eld
sound/core framework is updated to limit the formats based on
ELD.

There are few fixes one fixing the static checker warning and
other one not to fail if no connection list is found for a pin
widget.

Pls note, the 10th patch is adding a small macro for getting
connection type in drm header, we have CCed drm folks on that and
this one. Pls ack so that we can have this series merged thru
sound trees

changes in v4:
- Added NULL check
- Dropped the Jack reporting patch for now.

Cc: Jani Nikula 
Cc: David Airlie 
Cc: dri-devel at lists.freedesktop.org
Cc: Daniel Vetter 

Jeeja KP (2):
  ASoC: hdac_hdmi: Add codec suspend/resume handler
  ASoC: hdac_hdmi: Fix to enable device configuration in hw_params

Ramesh Babu (1):
  ASoC: hdac_hdmi: Fix to keep display active while enumerating codec

Subhransu S. Prusty (11):
  ASoC: hdac_hdmi: Fix to check num nodes correctly
  ASoC: hdac_hdmi: Fix to warn instead of err for no connected nids
  ASoC: hdac_hdmi: Use list to add pins and converters
  ASoC: hdac_hdmi: Add hotplug notification and read eld
  ASoC: hdac_hdmi: Apply constraints based on ELD
  ASoC: hdac_hdmi: Enable DP1.2 and all converters/pins
  ASoC: hdac_hdmi: create dais based on number of streams
  ASoC: hdac_hdmi: Create widget/route based on nodes enumerated
  ASoC: hdac_hdmi: Assign pin for stream based on dapm connection
  drm/edid: Add API to help find connection type
  ASoC: hdac_hdmi: Add infoframe support for dp audio

 include/drm/drm_edid.h   |   12 +
 sound/soc/codecs/Kconfig |1 +
 sound/soc/codecs/hdac_hdmi.c | 1116 +++---
 3 files changed, 951 insertions(+), 178 deletions(-)

-- 
1.9.1



[PATCH v4 10/14] drm/edid: Add API to help find connection type

2015-12-09 Thread Subhransu S. Prusty
To fill the audio infoframe it is required to identify the
connection type as DP or HDMI. This patch adds an API which
parses ELD and returns the display type of connected.

Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
Reviewed-by: Jani Nikula 
Cc: David Airlie 
Cc: dri-devel at lists.freedesktop.org
Cc: Daniel Vetter 
---
 include/drm/drm_edid.h | 12 
 1 file changed, 12 insertions(+)

diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 2af9769..8c537a0 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -403,6 +403,18 @@ static inline int drm_eld_size(const uint8_t *eld)
return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
 }

+/**
+ * drm_eld_get_conn_type - Get device type hdmi/dp connected
+ * @eld: pointer to an eld memory structure
+ *
+ * The caller need to use %DRM_ELD_CONN_TYPE_HDMI or %DRM_ELD_CONN_TYPE_DP to
+ * identify the display type connected.
+ */
+static inline u8 drm_eld_get_conn_type(const uint8_t *eld)
+{
+   return eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_CONN_TYPE_MASK;
+}
+
 struct edid *drm_do_get_edid(struct drm_connector *connector,
int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
  size_t len),
-- 
1.9.1



[PATCH v4 00/14] ASoC: hdac_hdmi: Add DP & notification support

2015-12-09 Thread Subhransu S. Prusty
This patch series adds DP audio and hotplug notification support.

On Skylake two DP ports are available and to enable DP on both
ports all pins need to be enabled.

There is a special vendor widget which need to be programmed to
enable all pins and converters. This series adds hotplug
notification, read/set constraint based on ELD, enable all
pin/cvts, DP1.2, programs the audio infoframe for DP. There is a
one to one mapping between converter and stream, so the dais are
created based on the no of streams supported on hdmi codec.  Even
though cvts can be mapped dynamically to the streams, currently
it is statically mapped as simultaneous playback on both DP and
HDMI is not supported as of now.

Pin muxes and controls are created dynamically to map converter
to pin widget. So at run time specific pin is mapped to the dai
based on the control selected (based on the display type DP/HDMI
connected).

Finally the DP audio infoframe programming is added to support
the DP feature. 

Also with hotplug notification support, ELD is read and
capabilities are set for rate, formats and channels. drm_eld
sound/core framework is updated to limit the formats based on
ELD.

There are few fixes one fixing the static checker warning and
other one not to fail if no connection list is found for a pin
widget.

Pls note, the 10th patch is adding a small macro for getting
connection type in drm header, we have CCed drm folks on that and
this one. Pls ack so that we can have this series merged thru
sound trees

changes in v4:
- Added NULL check
- Dropped the Jack reporting patch for now.

Jeeja KP (2):
  ASoC: hdac_hdmi: Add codec suspend/resume handler
  ASoC: hdac_hdmi: Fix to enable device configuration in hw_params

Ramesh Babu (1):
  ASoC: hdac_hdmi: Fix to keep display active while enumerating codec

Subhransu S. Prusty (11):
  ASoC: hdac_hdmi: Fix to check num nodes correctly
  ASoC: hdac_hdmi: Fix to warn instead of err for no connected nids
  ASoC: hdac_hdmi: Use list to add pins and converters
  ASoC: hdac_hdmi: Add hotplug notification and read eld
  ASoC: hdac_hdmi: Apply constraints based on ELD
  ASoC: hdac_hdmi: Enable DP1.2 and all converters/pins
  ASoC: hdac_hdmi: create dais based on number of streams
  ASoC: hdac_hdmi: Create widget/route based on nodes enumerated
  ASoC: hdac_hdmi: Assign pin for stream based on dapm connection
  drm/edid: Add API to help find connection type
  ASoC: hdac_hdmi: Add infoframe support for dp audio

 include/drm/drm_edid.h   |   12 +
 sound/soc/codecs/Kconfig |1 +
 sound/soc/codecs/hdac_hdmi.c | 1113 +++---
 3 files changed, 948 insertions(+), 178 deletions(-)

-- 
1.9.1



[PATCH v3 00/15] ASoC: hdac_hdmi: Add DP & notification support

2015-12-08 Thread Subhransu S. Prusty
On Mon, Dec 07, 2015 at 08:12:00PM +, Mark Brown wrote:
> On Tue, Dec 08, 2015 at 02:47:58AM +0530, Subhransu S. Prusty wrote:
> > This patch series adds DP audio and hotplug notification support.
> 
> Not related to the code but there seems to be something wrong with the
> time configuration on your system which is causing all your patches to
> be submitted quite a few hours in the future which confuses time based
> mailbox sorting - might be worth looking at that.

Sorry about that. Will fix it.



-- 


[PATCH v3 10/15] drm/edid: Add API to help find connection type

2015-12-08 Thread Subhransu S. Prusty
To fill the audio infoframe it is required to identify the
connection type as DP or HDMI. This patch adds an API which
parses ELD and returns the display type of connected.

Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
Cc: David Airlie 
Cc: dri-devel at lists.freedesktop.org
Cc: Daniel Vetter 
---
 include/drm/drm_edid.h | 12 
 1 file changed, 12 insertions(+)

diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 2af9769..8c537a0 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -403,6 +403,18 @@ static inline int drm_eld_size(const uint8_t *eld)
return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
 }

+/**
+ * drm_eld_get_conn_type - Get device type hdmi/dp connected
+ * @eld: pointer to an eld memory structure
+ *
+ * The caller need to use %DRM_ELD_CONN_TYPE_HDMI or %DRM_ELD_CONN_TYPE_DP to
+ * identify the display type connected.
+ */
+static inline u8 drm_eld_get_conn_type(const uint8_t *eld)
+{
+   return eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_CONN_TYPE_MASK;
+}
+
 struct edid *drm_do_get_edid(struct drm_connector *connector,
int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
  size_t len),
-- 
1.9.1



[PATCH v3 00/15] ASoC: hdac_hdmi: Add DP & notification support

2015-12-08 Thread Subhransu S. Prusty
This patch series adds DP audio and hotplug notification support.

On Skylake two DP ports are available and to enable DP on both
ports all pins need to be enabled.

There is a special vendor widget which need to be programmed to
enable all pins and converters. This series adds hotplug
notification, read/set constraint based on ELD, enable all
pin/cvts, DP1.2, programs the audio infoframe for DP. There is a
one to one mapping between converter and stream, so the dais are
created based on the no of streams supported on hdmi codec.  Even
though cvts can be mapped dynamically to the streams, currently
it is statically mapped as simultaneous playback on both DP and
HDMI is not supported as of now.

Pin muxes and controls are created dynamically to map converter
to pin widget. So at run time specific pin is mapped to the dai
based on the control selected (based on the display type DP/HDMI
connected).

Finally the DP audio infoframe programming is added to support
the DP feature. 

Also with hotplug notification support, ELD is read and
capabilities are set for rate, formats and channels. drm_eld
sound/core framework is updated to limit the formats based on
ELD.

There are few fixes one fixing the static checker warning and
other one not to fail if no connection list is found for a pin
widget.

Pls note, the 10th patch is adding a small macro for getting
connection type in drm header, we have CCed drm folks on that and
this one. Pls ack so that we can have this series merged thru
sound trees

changes in v3:
- Addressed review comments
- Use of list_for_each_entry_safe for node deletion.
- Moved the format constraint based on ELD to driver
- Fix constant as per kernel doc for connection type in
  drm helper
- Fix dp infoframe
- Add hotplug event reporting to user space
- Move device configuration from dai startup to hw_params
  as the user space can keep the device open always.

Jeeja KP (2):
  ASoC: hdac_hdmi: Add codec suspend/resume handler
  ASoC: hdac_hdmi: Fix to enable device configuration in hw_params

Ramesh Babu (1):
  ASoC: hdac_hdmi: Fix to keep display active while enumerating codec

Subhransu S. Prusty (12):
  ASoC: hdac_hdmi: Fix to check num nodes correctly
  ASoC: hdac_hdmi: Fix to warn instead of err for no connected nids
  ASoC: hdac_hdmi: Use list to add pins and converters
  ASoC: hdac_hdmi: Add hotplug notification and read eld
  ASoC: hdac_hdmi: Apply constraints based on ELD
  ASoC: hdac_hdmi: Enable DP1.2 and all converters/pins
  ASoC: hdac_hdmi: create dais based on number of streams
  ASoC: hdac_hdmi: Create widget/route based on nodes enumerated
  ASoC: hdac_hdmi: Assign pin for stream based on dapm connection
  drm/edid: Add API to help find connection type
  ASoC: hdac_hdmi: Add infoframe support for dp audio
  ASoC: hdac_hdmi: Add jack reporting for user space

 include/drm/drm_edid.h   |   12 +
 sound/soc/codecs/Kconfig |1 +
 sound/soc/codecs/hdac_hdmi.c | 1101 +++---
 3 files changed, 936 insertions(+), 178 deletions(-)

-- 
1.9.1



[PATCH v2 05/14] ALSA: pcm: Add DRM helper to set constraint for format

2015-12-05 Thread Subhransu S. Prusty
On Sat, Dec 05, 2015 at 09:12:34AM +0100, Takashi Iwai wrote:
> On Sat, 05 Dec 2015 12:27:03 +0100,
> Subhransu S. Prusty wrote:
> > 
> > On Fri, Dec 04, 2015 at 06:59:19AM +0100, Takashi Iwai wrote:
> > > On Fri, 04 Dec 2015 12:08:26 +0100,
> > > Subhransu S. Prusty wrote:
> > > > 
> > > > On Thu, Dec 03, 2015 at 04:57:14PM +0100, Takashi Iwai wrote:
> > > > > On Thu, 03 Dec 2015 22:08:53 +0100,
> > > > > Subhransu S. Prusty wrote:
> > > > > > 
> > > > > > Setting the constraint format based on ELD was missing bit in
> > > > > > the sound/core pcm drm. Added with this patch.
> > > > > 
> > > > > No, you can't define these here.  The format really depends on the
> > > > > hardware, while the rate and the channels are independent.
> > > > 
> > > > Probably then I will move this definition to driver.
> > > > 
> > > > > How do you know it's little-endian?  And why it must be S24_LE for
> > > > > 24bit, not S32_LE?
> > > > 
> > > > Regarding the little-endian, In the driver I think I should set the
> > > > constraint for both LE and BE. And the platform as it only supports LE 
> > > > alone
> > > > it will set the constraint accordingly and edianness will be taken care 
> > > > of.
> > > > 
> > > > Regarding the sample size, from short audio descriptor, the samples can 
> > > > be
> > > > one of 16/20/24 bit. I could use the format bits for 16 and 24 bits but
> > > > don't know which format bits macro is suitable for 20bits. So kept it as
> > > > S32_LE for 20bits. Should I fix the format bits for 20bits to use S24?
> > > 
> > > No you seem misunderstanding the concept...
> > 
> > Sorry about that. 
> > 
> > I re-read the spec, it doesn't mention the container size for the samples.
> > Assuming the container will be 32 bits, then I think we should use S24_LE
> > for both 20 and 24 bits.
> 
> You can't limit easily from the supported bits.  In theory, all
> formats that may fit with the given bit should be set.  For example, 
> for a 20bit sample, S24, U24, S32, U32, S24_3, U24_3, S20_3, etc would
> match, and even for both endianess.
> 
> The format type doesn't specify only the *max* bit it can pack, but
> also only the position of bits to be packed.  For example, S24 packs
> max 24 bits in the lower 24 bits in a 32bit container.  And, S24_3
> packs max 24 bits in a 24bit container.  Most of Intel chips takes the
> upper bits in a container, so usually they need S32 or S16 no matter
> how many bits are used.

Thanks for the quick reply.

I am thinking to set the format as S16 for 16bits and S32 for 20/24bits.

But then we can set S32 for everything as well including 16bits.

What do you recommend?


> 
> 
> Takashi

-- 


[PATCH v2 05/14] ALSA: pcm: Add DRM helper to set constraint for format

2015-12-05 Thread Subhransu S. Prusty
On Fri, Dec 04, 2015 at 06:59:19AM +0100, Takashi Iwai wrote:
> On Fri, 04 Dec 2015 12:08:26 +0100,
> Subhransu S. Prusty wrote:
> > 
> > On Thu, Dec 03, 2015 at 04:57:14PM +0100, Takashi Iwai wrote:
> > > On Thu, 03 Dec 2015 22:08:53 +0100,
> > > Subhransu S. Prusty wrote:
> > > > 
> > > > Setting the constraint format based on ELD was missing bit in
> > > > the sound/core pcm drm. Added with this patch.
> > > 
> > > No, you can't define these here.  The format really depends on the
> > > hardware, while the rate and the channels are independent.
> > 
> > Probably then I will move this definition to driver.
> > 
> > > How do you know it's little-endian?  And why it must be S24_LE for
> > > 24bit, not S32_LE?
> > 
> > Regarding the little-endian, In the driver I think I should set the
> > constraint for both LE and BE. And the platform as it only supports LE alone
> > it will set the constraint accordingly and edianness will be taken care of.
> > 
> > Regarding the sample size, from short audio descriptor, the samples can be
> > one of 16/20/24 bit. I could use the format bits for 16 and 24 bits but
> > don't know which format bits macro is suitable for 20bits. So kept it as
> > S32_LE for 20bits. Should I fix the format bits for 20bits to use S24?
> 
> No you seem misunderstanding the concept...

Sorry about that. 

I re-read the spec, it doesn't mention the container size for the samples.
Assuming the container will be 32 bits, then I think we should use S24_LE
for both 20 and 24 bits.

Can you please help to understand which concept I got wrong here.

Regards,
Subhransu
> 
> 
> Takashi

-- 


[PATCH v2 05/14] ALSA: pcm: Add DRM helper to set constraint for format

2015-12-04 Thread Subhransu S. Prusty
On Thu, Dec 03, 2015 at 04:57:14PM +0100, Takashi Iwai wrote:
> On Thu, 03 Dec 2015 22:08:53 +0100,
> Subhransu S. Prusty wrote:
> > 
> > Setting the constraint format based on ELD was missing bit in
> > the sound/core pcm drm. Added with this patch.
> 
> No, you can't define these here.  The format really depends on the
> hardware, while the rate and the channels are independent.

Probably then I will move this definition to driver.

> How do you know it's little-endian?  And why it must be S24_LE for
> 24bit, not S32_LE?

Regarding the little-endian, In the driver I think I should set the
constraint for both LE and BE. And the platform as it only supports LE alone
it will set the constraint accordingly and edianness will be taken care of.

Regarding the sample size, from short audio descriptor, the samples can be
one of 16/20/24 bit. I could use the format bits for 16 and 24 bits but
don't know which format bits macro is suitable for 20bits. So kept it as
S32_LE for 20bits. Should I fix the format bits for 20bits to use S24?

Regards,
Subhransu

> 
> 
> Takashi

-- 


[PATCH v2 12/14] ASoC: hdac_hdmi: Add infoframe support for dp audio

2015-12-04 Thread Subhransu S. Prusty
On Thu, Dec 03, 2015 at 05:13:16PM +, Daniel Stone wrote:
> Hi Subhransu,
> 
> On 3 December 2015 at 21:09, Subhransu S. Prusty
>  wrote:
> > +   if (conn_type == DRM_ELD_CONN_TYPE_HDMI) {
> > +   hdmi_audio_infoframe_init();
> > +
> > +   /* Default stereo for now */
> > +   frame.channels = channels;
> > +
> > +   ret = hdmi_audio_infoframe_pack(, buffer, 
> > sizeof(buffer));
> > +   if (ret < 0)
> > +   return ret;
> > +
> > +   dip = (u8 *)
> > +
> > +   } else if (conn_type == DRM_ELD_CONN_TYPE_DP) {
> > +   memset(_ai, 0, sizeof(dp_ai));
> > +   dp_ai.type  = 0x84;
> > +   dp_ai.len   = 0x1b;
> > +   dp_ai.ver   = 0x11 << 2;
> > +   dp_ai.CC02_CT47 = channels - 1;
> > +   dp_ai.CA= 0;
> > +
> > +   dip = (u8 *)
> 
> Surely this should be dip = (u8 *) _ai, instead of pointing to itself?

Thanks for pointing. It's a mistake, will fix it.

Regards,
Subhansu
> 
> Cheers,
> Daniel
> 

-- 


[PATCH v2 11/14] drm/edid: Add API to help find connection type

2015-12-04 Thread Subhransu S. Prusty
On Thu, Dec 03, 2015 at 05:16:34PM +0100, Takashi Iwai wrote:
> On Thu, 03 Dec 2015 22:08:59 +0100,
> Subhransu S. Prusty wrote:
> > 
> > To fill the audio infoframe it is required to identify the
> > connection type as DP or HDMI. This patch adds an API which
> > parses ELD and returns the display type of connected.
> > 
> > Signed-off-by: Subhransu S. Prusty 
> > Signed-off-by: Vinod Koul 
> > Cc: David Airlie 
> > Cc: dri-devel at lists.freedesktop.org
> > Cc: Daniel Vetter 
> > ---
> >  include/drm/drm_edid.h | 12 
> >  1 file changed, 12 insertions(+)
> > 
> > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> > index 2af9769..072de90 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -403,6 +403,18 @@ static inline int drm_eld_size(const uint8_t *eld)
> > return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
> >  }
> >  
> > +/**
> > + * drm_eld_get_conn_type - Get device type hdmi/dp connected
> > + * @eld: pointer to an eld memory structure
> > + *
> > + * The caller need to use DRM_ELD_CONN_TYPE_HDMI or DRM_ELD_CONN_TYPE_DP to
> > + * identify the display type connected.
> 
> Constants should be marked with '%'.

Sure will add it. 

Regards,
Subhransu
> 
> 
> Takashi

-- 


[PATCH v2 04/14] ASoC: hdac_hdmi: Add hotplug notification and read eld

2015-12-04 Thread Subhransu S. Prusty
On Thu, Dec 03, 2015 at 04:51:37PM +0100, Takashi Iwai wrote:
> On Thu, 03 Dec 2015 22:08:52 +0100,
> Subhransu S. Prusty wrote:
> > 
> > This patch uses i915 component framework to register for hotplug
> > notification. And once it identifies valid pin sense and valid eld,
> > reads the eld into the corresponding pin map buffer. For now it
> > directly sends the verbs and reads the eld. Later this will use
> > the i915 framework to populate ELD buffer once available.
> > 
> > The eld reading APIs in legacy hda are required for ASoC skylake
> > hdmi driver as well. So keeping a copy here and will remove once
> > component ops for reading ELD are merged in hda core.
> > 
> > Also read the monitor present sense during resume and ignore the
> > ELD notify from graphics during PM as is done in legacy hda.
> > Reference commits:
> > 
> > git: git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
> > 
> > commit 33d58f2bb446 ("ALSA: hda - Skip ELD notification during PM
> > process")
> 
> This one isn't merged yet, so the commit ID may be wrong.
> Maybe I'm going to merge this one at first to for-next branch,
> irrelevant from test/hdmi-jack branch.  So drop it from the
> description for now.

Ok.

> 
> > commit 8ae743e82f0b ("ALSA: hda - Skip ELD notification during
> > system suspend")
> 
> This one is already solid.
> 
> 
> Takashi

-- 


[PATCH v2 03/14] ASoC: hdac_hdmi - Use list to add pins and converters

2015-12-04 Thread Subhransu S. Prusty
On Thu, Dec 03, 2015 at 04:44:55PM +0100, Takashi Iwai wrote:
> On Thu, 03 Dec 2015 22:08:51 +0100,
> Subhransu S. Prusty wrote:
> >  static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev)
> >  {
> > +   struct hdac_hdmi_priv *hdmi = edev->private_data;
> > +   struct hdac_hdmi_pin *pin;
> > +   struct hdac_hdmi_cvt *cvt;
> > +
> > snd_soc_unregister_codec(>hdac.dev);
> >  
> > +   list_for_each_entry(cvt, >cvt_list, head) {
> > +   list_del(>head);
> > +   kfree(cvt);
> > +   }
> > +
> > +   list_for_each_entry(pin, >pin_list, head) {
> > +   list_del(>head);
> > +   kfree(pin);
> > +   }
> 
> These must be list_for_each_entry_safe().

Sure. Will change it.

Regards,
Subhransu
> 
> 
> Takashi

-- 


[PATCH v2 14/14] ASoC: hdac_hdmi: Fix to keep display active while enumerating codec

2015-12-04 Thread Subhransu S. Prusty
From: Ramesh Babu <ramesh.b...@intel.com>

The display power reference count is decremented with the first
explicit call to pm_runtime_suspend. Otherwise the display power
reference count is balanced with runtime resume/suspend. Rest
of the time it is kept off.

Signed-off-by: Ramesh Babu 
Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
---
 sound/soc/codecs/hdac_hdmi.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 73f5612..fb43461 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -1236,6 +1236,18 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device 
*edev)
INIT_LIST_HEAD(_priv->pin_list);
INIT_LIST_HEAD(_priv->cvt_list);

+   /*
+* Turned off in the runtime_suspend during the first explicit
+* pm_runtime_suspend call.
+*/
+   ret = snd_hdac_display_power(edev->hdac.bus, true);
+   if (ret < 0) {
+   dev_err(>hdac.dev,
+   "Cannot turn on display power on i915 err: %d\n",
+   ret);
+   return ret;
+   }
+
ret = hdac_hdmi_parse_and_map_nid(edev, _dais, _dais);
if (ret < 0) {
dev_err(>dev, "Failed in parse and map nid with err: 
%d\n", ret);
-- 
1.9.1



[PATCH v2 13/14] ASoC: hdac_hdmi: Add codec suspend/resume handler

2015-12-04 Thread Subhransu S. Prusty
From: Jeeja KP <jeeja...@intel.com>

Need to add enabling of all pins and DP1.2 feature again after
resume. Also during the device in suspended state ELD notify
callback is not processed. So add ELD check for all pins here.

Signed-off-by: Jeeja KP 
Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
---
 sound/soc/codecs/hdac_hdmi.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index d963d92..73f5612 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -1186,9 +1186,34 @@ static int hdmi_codec_remove(struct snd_soc_codec *codec)
return 0;
 }

+#ifdef CONFIG_PM
+static int hdmi_codec_resume(struct snd_soc_codec *codec)
+{
+   struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
+   struct hdac_hdmi_priv *hdmi = edev->private_data;
+   struct hdac_hdmi_pin *pin;
+
+   hdac_hdmi_skl_enable_all_pins(>hdac);
+   hdac_hdmi_skl_enable_dp12(>hdac);
+
+   /*
+* As the ELD notify callback request is not entertained while the
+* device is in suspend state. Need to manually check detection of
+* all pins here.
+*/
+   list_for_each_entry(pin, >pin_list, head)
+   hdac_hdmi_present_sense(pin, 1);
+
+   return 0;
+}
+#else
+#define hdmi_codec_resume NULL
+#endif
+
 static struct snd_soc_codec_driver hdmi_hda_codec = {
.probe  = hdmi_codec_probe,
.remove = hdmi_codec_remove,
+   .resume = hdmi_codec_resume,
.idle_bias_off  = true,
 };

-- 
1.9.1



[PATCH v2 12/14] ASoC: hdac_hdmi: Add infoframe support for dp audio

2015-12-04 Thread Subhransu S. Prusty
This uses the get_conn_type API added in the previous patch to
identify the type of display connected and fills the infoframe
accordingly.

Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
---
 sound/soc/codecs/hdac_hdmi.c | 68 ++--
 1 file changed, 59 insertions(+), 9 deletions(-)

diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 3ac3498..d963d92 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -201,27 +202,70 @@ hdac_hdmi_set_dip_index(struct hdac_ext_device *hdac, 
hda_nid_t pin_nid,
AC_VERB_SET_HDMI_DIP_INDEX, val);
 }

+struct dp_audio_infoframe {
+   u8 type; /* 0x84 */
+   u8 len;  /* 0x1b */
+   u8 ver;  /* 0x11 << 2 */
+
+   u8 CC02_CT47;   /* match with HDMI infoframe from this on */
+   u8 SS01_SF24;
+   u8 CXT04;
+   u8 CA;
+   u8 LFEPBL01_LSV36_DM_INH7;
+};
+
 static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
hda_nid_t cvt_nid, hda_nid_t pin_nid)
 {
uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];
struct hdmi_audio_infoframe frame;
+   struct dp_audio_infoframe dp_ai;
+   struct hdac_hdmi_priv *hdmi = hdac->private_data;
+   struct hdac_hdmi_pin *pin;
u8 *dip = (u8 *)
int ret;
int i;
+   const u8 *eld_buf;
+   u8 conn_type;
+   int channels = 2;

-   hdmi_audio_infoframe_init();
+   list_for_each_entry(pin, >pin_list, head) {
+   if (pin->nid == pin_nid)
+   break;
+   }

-   /* Default stereo for now */
-   frame.channels = 2;
+   eld_buf = pin->eld.eld_buffer;
+   conn_type = drm_eld_get_conn_type(eld_buf);

/* setup channel count */
snd_hdac_codec_write(>hdac, cvt_nid, 0,
-   AC_VERB_SET_CVT_CHAN_COUNT, frame.channels - 1);
+   AC_VERB_SET_CVT_CHAN_COUNT, channels - 1);

-   ret = hdmi_audio_infoframe_pack(, buffer, sizeof(buffer));
-   if (ret < 0)
-   return ret;
+   if (conn_type == DRM_ELD_CONN_TYPE_HDMI) {
+   hdmi_audio_infoframe_init();
+
+   /* Default stereo for now */
+   frame.channels = channels;
+
+   ret = hdmi_audio_infoframe_pack(, buffer, sizeof(buffer));
+   if (ret < 0)
+   return ret;
+
+   dip = (u8 *)
+
+   } else if (conn_type == DRM_ELD_CONN_TYPE_DP) {
+   memset(_ai, 0, sizeof(dp_ai));
+   dp_ai.type  = 0x84;
+   dp_ai.len   = 0x1b;
+   dp_ai.ver   = 0x11 << 2;
+   dp_ai.CC02_CT47 = channels - 1;
+   dp_ai.CA= 0;
+
+   dip = (u8 *)
+   } else {
+   dev_err(>hdac.dev, "Invalid connection type: %d\n", 
conn_type);
+   return -EIO;
+   }

/* stop infoframe transmission */
hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
@@ -231,9 +275,15 @@ static int hdac_hdmi_setup_audio_infoframe(struct 
hdac_ext_device *hdac,

/*  Fill infoframe. Index auto-incremented */
hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
-   for (i = 0; i < sizeof(frame); i++)
-   snd_hdac_codec_write(>hdac, pin_nid, 0,
+   if (conn_type == 0) {
+   for (i = 0; i < sizeof(frame); i++)
+   snd_hdac_codec_write(>hdac, pin_nid, 0,
AC_VERB_SET_HDMI_DIP_DATA, dip[i]);
+   } else {
+   for (i = 0; i < sizeof(dp_ai); i++)
+   snd_hdac_codec_write(>hdac, pin_nid, 0,
+   AC_VERB_SET_HDMI_DIP_DATA, dip[i]);
+   }

/* Start infoframe */
hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
-- 
1.9.1



[PATCH v2 11/14] drm/edid: Add API to help find connection type

2015-12-04 Thread Subhransu S. Prusty
To fill the audio infoframe it is required to identify the
connection type as DP or HDMI. This patch adds an API which
parses ELD and returns the display type of connected.

Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
Cc: David Airlie 
Cc: dri-devel at lists.freedesktop.org
Cc: Daniel Vetter 
---
 include/drm/drm_edid.h | 12 
 1 file changed, 12 insertions(+)

diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 2af9769..072de90 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -403,6 +403,18 @@ static inline int drm_eld_size(const uint8_t *eld)
return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
 }

+/**
+ * drm_eld_get_conn_type - Get device type hdmi/dp connected
+ * @eld: pointer to an eld memory structure
+ *
+ * The caller need to use DRM_ELD_CONN_TYPE_HDMI or DRM_ELD_CONN_TYPE_DP to
+ * identify the display type connected.
+ */
+static inline u8 drm_eld_get_conn_type(const uint8_t *eld)
+{
+   return eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_CONN_TYPE_MASK;
+}
+
 struct edid *drm_do_get_edid(struct drm_connector *connector,
int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
  size_t len),
-- 
1.9.1



[PATCH v2 10/14] ASoC: hdac_hdmi: Assign pin for stream based on dapm connection

2015-12-04 Thread Subhransu S. Prusty
Now that we have all the widgets enumerated we can route the stream
to any pin widget based on Mux connection. So map the pin to stream
accordingly.

Also seems the connection list to the pin widgets are not static
and is updated runtime based on type of display attached to the port.
This looks to be a hardware behavior.

So querying of the connection list is removed from pin initialization
and used in selecting the pin for a dai map.

Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
---
 sound/soc/codecs/hdac_hdmi.c | 208 +++
 1 file changed, 151 insertions(+), 57 deletions(-)

diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index cded3d7..3ac3498 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -37,6 +37,8 @@

 #define HDA_MAX_CONNECTIONS 32

+#define HDA_MAX_CVTS   3
+
 #define ELD_MAX_SIZE256
 #define ELD_FIXED_BYTES20

@@ -79,7 +81,7 @@ struct hdac_hdmi_dai_pin_map {
 };

 struct hdac_hdmi_priv {
-   struct hdac_hdmi_dai_pin_map dai_map[3];
+   struct hdac_hdmi_dai_pin_map dai_map[HDA_MAX_CVTS];
struct list_head pin_list;
struct list_head cvt_list;
int num_pin;
@@ -332,12 +334,126 @@ static int hdac_hdmi_playback_cleanup(struct 
snd_pcm_substream *substream,
return 0;
 }

+static int hdac_hdmi_enable_pin(struct hdac_ext_device *hdac,
+   struct hdac_hdmi_dai_pin_map *dai_map)
+{
+   int mux_idx;
+   struct hdac_hdmi_pin *pin = dai_map->pin;
+
+   for (mux_idx = 0; mux_idx < pin->num_mux_nids; mux_idx++) {
+   if (pin->mux_nids[mux_idx] == dai_map->cvt->nid) {
+   snd_hdac_codec_write(>hdac, pin->nid, 0,
+   AC_VERB_SET_CONNECT_SEL, mux_idx);
+   break;
+   }
+   }
+
+   if (mux_idx == pin->num_mux_nids)
+   return -EIO;
+
+   /* Enable out path for this pin widget */
+   snd_hdac_codec_write(>hdac, pin->nid, 0,
+   AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+
+   hdac_hdmi_set_power_state(hdac, dai_map, AC_PWRST_D0);
+
+   snd_hdac_codec_write(>hdac, pin->nid, 0,
+   AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+
+   return 0;
+}
+
+static int hdac_hdmi_query_pin_connlist(struct hdac_ext_device *hdac,
+   struct hdac_hdmi_pin *pin)
+{
+   if (!(get_wcaps(>hdac, pin->nid) & AC_WCAP_CONN_LIST)) {
+   dev_warn(>hdac.dev,
+   "HDMI: pin %d wcaps %#x does not support connection 
list\n",
+   pin->nid, get_wcaps(>hdac, pin->nid));
+   return -EINVAL;
+   }
+
+   pin->num_mux_nids = snd_hdac_get_connections(>hdac, pin->nid,
+   pin->mux_nids, HDA_MAX_CONNECTIONS);
+   if (pin->num_mux_nids == 0)
+   dev_warn(>hdac.dev, "No connections found for pin: %d\n", 
pin->nid);
+
+   dev_dbg(>hdac.dev, "num_mux_nids %d for pin: %d\n",
+   pin->num_mux_nids, pin->nid);
+
+   return pin->num_mux_nids;
+}
+
+static inline struct hdac_hdmi_pin *hdac_hdmi_get_pin(
+   struct hdac_ext_device *edev,
+   struct snd_soc_dapm_path *p,
+   struct hdac_hdmi_cvt *cvt)
+{
+   struct hdac_hdmi_priv *hdmi = edev->private_data;
+   struct hdac_hdmi_pin *pin;
+   hda_nid_t *nid;
+   int ret, i;
+
+   nid = (hda_nid_t *)p->sink->priv;
+   list_for_each_entry(pin, >pin_list, head) {
+   if (pin->nid == *nid) {
+   ret = hdac_hdmi_query_pin_connlist(edev, pin);
+   if (ret < 0)
+   continue;
+
+   for (i = 0; i < pin->num_mux_nids; i++) {
+   if (pin->mux_nids[i] == cvt->nid)
+   return pin;
+   }
+   }
+   }
+
+   return NULL;
+}
+
+/*
+ * This queries mux widgets in each sink path of the dai widget and returns
+ * a matching pin widget to which the stream may be routed.
+ *
+ * The converter may be input to multiple pin muxes. So each
+ * pin mux (basically each pin widget) is queried to identify if
+ * the converter as one of the input, then the first pin match
+ * is selected for rendering.
+ *
+ * Same stream rendering to multiple pins simultaneously can be done
+ * possibly, but not supported for now.
+ *
+ * So return the first pin connected
+ */
+static struct hdac_hdmi_pin *hdac_hdmi_get_pin_from_daistream(
+   struct hdac_ext_device *edev,
+   struct snd_soc_dapm_widget *strm_w,
+   struct

[PATCH v2 09/14] ASoC: hdac_hdmi: Create widget/route based on nodes enumerated

2015-12-04 Thread Subhransu S. Prusty
Instead of direct mapping between converter and pin, Muxes are
added between them to support any converter connection to any pin.

As the possible mux inputs can only be identified during runtime,
all possible routes are created to connect all converters to all
pin muxes. The user should enable appropriate mux inputs to enable
correct port.

In the process to support the above changes widget/route fill APIs
are updated to take all required parameters.

Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
---
 sound/soc/codecs/hdac_hdmi.c | 224 ++-
 1 file changed, 202 insertions(+), 22 deletions(-)

diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 83248ad..cded3d7 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -420,46 +420,224 @@ static int hdac_hdmi_query_pin_connlist(struct 
hdac_ext_device *hdac,
return pin->num_mux_nids;
 }

-static void hdac_hdmi_fill_widget_info(struct snd_soc_dapm_widget *w,
-   enum snd_soc_dapm_type id,
-   const char *wname, const char *stream)
+static void hdac_hdmi_fill_widget_info(struct device *dev,
+   struct snd_soc_dapm_widget *w,
+   enum snd_soc_dapm_type id, void *priv,
+   const char *wname, const char *stream,
+   struct snd_kcontrol_new *wc, int numkc)
 {
w->id = id;
-   w->name = wname;
+   w->name = devm_kstrdup(dev, wname, GFP_KERNEL);
w->sname = stream;
w->reg = SND_SOC_NOPM;
w->shift = 0;
-   w->kcontrol_news = NULL;
-   w->num_kcontrols = 0;
-   w->priv = NULL;
+   w->kcontrol_news = wc;
+   w->num_kcontrols = numkc;
+   w->priv = priv;
 }

 static void hdac_hdmi_fill_route(struct snd_soc_dapm_route *route,
-   const char *sink, const char *control, const char *src)
+   const char *sink, const char *control, const char *src,
+   int (*handler)(struct snd_soc_dapm_widget *sr,
+   struct snd_soc_dapm_widget *snk))
 {
route->sink = sink;
route->source = src;
route->control = control;
-   route->connected = NULL;
+   route->connected = handler;
 }

-static void create_fill_widget_route_map(struct snd_soc_dapm_context *dapm,
-   struct hdac_hdmi_dai_pin_map *dai_map)
+/*
+ * Ideally the Mux inputs should be based on the num_muxs enumerated, but
+ * the display driver seem to be programming the connection list for the pin
+ * widget runtime.
+ *
+ * So programming all the possible inputs for the mux, the user has to take
+ * care of selecting the right one and leaving all other inputs selected to
+ * "NONE"
+ */
+static int hdac_hdmi_create_pin_muxs(struct hdac_ext_device *edev,
+   struct hdac_hdmi_pin *pin,
+   struct snd_soc_dapm_widget *widget,
+   const char *widget_name)
 {
-   struct snd_soc_dapm_route route[1];
-   struct snd_soc_dapm_widget widgets[2] = { {0} };
+   struct hdac_hdmi_priv *hdmi = edev->private_data;
+   struct snd_kcontrol_new *kc;
+   struct hdac_hdmi_cvt *cvt;
+   struct soc_enum *se;
+   char kc_name[NAME_SIZE];
+   char mux_items[NAME_SIZE];
+   /* To hold inputs to the Pin mux */
+   char *items[HDA_MAX_CONNECTIONS];
+   int i = 0;
+   int num_items = hdmi->num_cvt + 1;
+
+   kc = devm_kzalloc(>hdac.dev, sizeof(*kc), GFP_KERNEL);
+   if (!kc)
+   return -ENOMEM;
+
+   se = devm_kzalloc(>hdac.dev, sizeof(*se), GFP_KERNEL);
+   if (!se)
+   return -ENOMEM;
+
+   sprintf(kc_name, "Pin %d Input", pin->nid);
+   kc->name = devm_kstrdup(>hdac.dev, kc_name, GFP_KERNEL);
+   kc->private_value = (long)se;
+   kc->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+   kc->access = 0;
+   kc->info = snd_soc_info_enum_double;
+   kc->put = snd_soc_dapm_put_enum_double;
+   kc->get = snd_soc_dapm_get_enum_double;

-   memset(, 0, sizeof(route));
+   se->reg = SND_SOC_NOPM;

-   hdac_hdmi_fill_widget_info([0], snd_soc_dapm_output,
-   "hif1 Output", NULL);
-   hdac_hdmi_fill_widget_info([1], snd_soc_dapm_aif_in,
-   "Coverter 1", "hif1");
+   /* enum texts: ["NONE", "cvt #", "cvt #", ...] */
+   se->items = num_items;
+   se->mask = roundup_pow_of_two(se->items) - 1;
+
+   sprintf(mux_items, "NONE");
+   items[i] = devm_kstrdup(>hdac.dev, mux_items, GFP_KERNEL);
+
+   list_for_each_entry(cvt, >cvt_list, head) {
+

[PATCH v2 08/14] ASoC: hdac_hdmi - create dais based on number of streams

2015-12-04 Thread Subhransu S. Prusty
A stream is mapped to a converter. So based on the converters
queried, dais are created.

The streams can be dynamically routed to any converter. For
now it is mapped statically. The dynamic mapping of stream
to converter will be added when required.

Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
---
 sound/soc/codecs/hdac_hdmi.c | 124 ---
 1 file changed, 92 insertions(+), 32 deletions(-)

diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 325d22b..83248ad 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -29,6 +29,8 @@
 #include 
 #include "../../hda/local.h"

+#define NAME_SIZE  32
+
 #define AMP_OUT_MUTE   0xb080
 #define AMP_OUT_UNMUTE 0xb000
 #define PIN_OUT(AC_PINCTL_OUT_EN)
@@ -640,11 +642,84 @@ static void hdac_hdmi_skl_enable_dp12(struct hdac_device 
*hdac)

 }

+static struct snd_soc_dai_ops hdmi_dai_ops = {
+   .startup = hdac_hdmi_pcm_open,
+   .shutdown = hdac_hdmi_pcm_close,
+   .hw_params = hdac_hdmi_set_hw_params,
+   .prepare = hdac_hdmi_playback_prepare,
+   .hw_free = hdac_hdmi_playback_cleanup,
+};
+
+static int hdac_hdmi_create_dais(struct hdac_device *hdac,
+   struct snd_soc_dai_driver **dais,
+   struct hdac_hdmi_priv *hdmi, int num_dais)
+{
+   struct snd_soc_dai_driver *hdmi_dais;
+   struct hdac_hdmi_cvt *cvt;
+   char name[NAME_SIZE], dai_name[NAME_SIZE];
+   int i = 0, j;
+   u32 rates, bps;
+   unsigned int rate_max = 384000, rate_min = 8000;
+   u64 formats;
+   int ret;
+   static unsigned int rate_pcm[] = {
+   8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
+   96000, 176400, 192000, 384000
+   };
+
+   hdmi_dais = devm_kzalloc(>dev, (sizeof(*hdmi_dais) * num_dais),
+   GFP_KERNEL);
+   if (!hdmi_dais)
+   return -ENOMEM;
+
+   list_for_each_entry(cvt, >cvt_list, head) {
+   ret = snd_hdac_query_supported_pcm(hdac, cvt->nid, ,
+   , );
+   if (ret)
+   return ret;
+   for (j = 0; j < ARRAY_SIZE(rate_pcm); j++) {
+   if (rates & (1 << j)) {
+   rate_min = rate_pcm[j];
+   break;
+   }
+   }
+
+   for (j = ARRAY_SIZE(rate_pcm) - 1; j >= 0; j--) {
+   if (rates & (1 << j)) {
+   rate_max = rate_pcm[j];
+   break;
+   }
+   }
+
+   sprintf(dai_name, "intel-hdmi-hifi%d", i+1);
+   hdmi_dais[i].name = devm_kstrdup(>dev, dai_name,
+   GFP_KERNEL);
+
+   snprintf(name, sizeof(name), "hifi%d", i+1);
+   hdmi_dais[i].playback.stream_name =
+   devm_kstrdup(>dev, name, GFP_KERNEL);
+   hdmi_dais[i].playback.formats = formats;
+   hdmi_dais[i].playback.rates = rates;
+   hdmi_dais[i].playback.rate_max = rate_max;
+   hdmi_dais[i].playback.rate_min = rate_min;
+   hdmi_dais[i].playback.channels_min = 2;
+   hdmi_dais[i].playback.channels_max = 2;
+   hdmi_dais[i].ops = _dai_ops;
+
+   i++;
+   }
+
+   *dais = hdmi_dais;
+
+   return 0;
+}
+
 /*
  * Parse all nodes and store the cvt/pin nids in array
  * Add one time initialization for pin and cvt widgets
  */
-static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev)
+static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev,
+   struct snd_soc_dai_driver **dais, int *num_dais)
 {
hda_nid_t nid;
int i, num_nodes;
@@ -695,6 +770,15 @@ static int hdac_hdmi_parse_and_map_nid(struct 
hdac_ext_device *edev)
if (!hdmi->num_pin || !hdmi->num_cvt)
return -EIO;

+   ret = hdac_hdmi_create_dais(hdac, dais, hdmi, hdmi->num_cvt);
+   if (ret) {
+   dev_err(>dev, "Failed to create dais with err: %d\n",
+   ret);
+   return ret;
+   }
+
+   *num_dais = hdmi->num_cvt;
+
return hdac_hdmi_init_dai_map(edev);
 }

@@ -784,38 +868,12 @@ static struct snd_soc_codec_driver hdmi_hda_codec = {
.idle_bias_off  = true,
 };

-static struct snd_soc_dai_ops hdmi_dai_ops = {
-   .startup = hdac_hdmi_pcm_open,
-   .shutdown = hdac_hdmi_pcm_close,
-   .hw_params = hdac_hdmi_set_hw_params,
-   .prepare = hdac_hdmi_playback_prepare,
-   .hw_free = hdac_hdmi_playback_cleanup,
-};
-
-static struct snd_soc

[PATCH v2 07/14] ASoC: hdac_hdmi: Enable DP1.2 and all converters/pins

2015-12-04 Thread Subhransu S. Prusty
By default only one converter and pin widget are enabled. A vendor
widget required to be configured to enable all the widgets of the
codec.

As we are enabling the DP support enable the DP1.2 feature as well.

The changes below are copied from patch_hdmi.c

Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
---
 sound/soc/codecs/hdac_hdmi.c | 43 +++
 1 file changed, 43 insertions(+)

diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index d891ad7..325d22b 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -600,6 +600,46 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, 
hda_nid_t nid)
return 0;
 }

+#define INTEL_VENDOR_NID 0x08
+#define INTEL_GET_VENDOR_VERB 0xf81
+#define INTEL_SET_VENDOR_VERB 0x781
+#define INTEL_EN_DP12  0x02 /* enable DP 1.2 features */
+#define INTEL_EN_ALL_PIN_CVTS  0x01 /* enable 2nd & 3rd pins and convertors */
+
+static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac)
+{
+   unsigned int vendor_param;
+
+   vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
+   INTEL_GET_VENDOR_VERB, 0);
+   if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS)
+   return;
+
+   vendor_param |= INTEL_EN_ALL_PIN_CVTS;
+   vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
+   INTEL_SET_VENDOR_VERB, vendor_param);
+   if (vendor_param == -1)
+   return;
+}
+
+static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdac)
+{
+   unsigned int vendor_param;
+
+   vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
+   INTEL_GET_VENDOR_VERB, 0);
+   if (vendor_param == -1 || vendor_param & INTEL_EN_DP12)
+   return;
+
+   /* enable DP1.2 mode */
+   vendor_param |= INTEL_EN_DP12;
+   vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
+   INTEL_SET_VENDOR_VERB, vendor_param);
+   if (vendor_param == -1)
+   return;
+
+}
+
 /*
  * Parse all nodes and store the cvt/pin nids in array
  * Add one time initialization for pin and cvt widgets
@@ -612,6 +652,9 @@ static int hdac_hdmi_parse_and_map_nid(struct 
hdac_ext_device *edev)
struct hdac_hdmi_priv *hdmi = edev->private_data;
int ret;

+   hdac_hdmi_skl_enable_all_pins(hdac);
+   hdac_hdmi_skl_enable_dp12(hdac);
+
num_nodes = snd_hdac_get_sub_nodes(hdac, hdac->afg, );
if (!nid || num_nodes <= 0) {
dev_warn(>dev, "HDMI: failed to get afg sub nodes\n");
-- 
1.9.1



[PATCH v2 06/14] ASoC: hdac_hdmi: Apply constraints based on ELD

2015-12-04 Thread Subhransu S. Prusty
Uses the drm eld core framework to apply rate, channel and
format constraint.

Even though the channel constraint is based on ELD, infoframe
is set with stereo only. Multichannel support will be added
later.

Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
---
 sound/soc/codecs/Kconfig | 1 +
 sound/soc/codecs/hdac_hdmi.c | 7 +++
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index c0c5c8e..f805cb6 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -486,6 +486,7 @@ config SND_SOC_GTM601
 config SND_SOC_HDAC_HDMI
tristate
select SND_HDA_EXT_CORE
+   select SND_PCM_ELD
select HDMI

 config SND_SOC_ICS43432
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 65796ce..d891ad7 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "../../hda/local.h"

 #define AMP_OUT_MUTE   0xb080
@@ -356,10 +357,8 @@ static int hdac_hdmi_pcm_open(struct snd_pcm_substream 
*substream,
snd_hdac_codec_write(>hdac, dai_map->pin->nid, 0,
AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);

-   snd_pcm_hw_constraint_step(substream->runtime, 0,
-  SNDRV_PCM_HW_PARAM_CHANNELS, 2);
-
-   return 0;
+   return snd_pcm_hw_constraint_eld(substream->runtime,
+   dai_map->pin->eld.eld_buffer);
 }

 static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream,
-- 
1.9.1



[PATCH v2 05/14] ALSA: pcm: Add DRM helper to set constraint for format

2015-12-04 Thread Subhransu S. Prusty
Setting the constraint format based on ELD was missing bit in
the sound/core pcm drm. Added with this patch.

Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
---
 sound/core/pcm_drm_eld.c | 42 +-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/sound/core/pcm_drm_eld.c b/sound/core/pcm_drm_eld.c
index e70379f..0c5653e 100644
--- a/sound/core/pcm_drm_eld.c
+++ b/sound/core/pcm_drm_eld.c
@@ -20,11 +20,49 @@ static const unsigned int eld_rates[] = {
192000,
 };

+static unsigned int sad_format(const u8 *sad)
+{
+   return ((sad[0] >> 0x3) & 0x1f);
+}
+
+static unsigned int sad_sample_bits_lpcm(const u8 *sad)
+{
+   return (sad[2] & 7);
+}
+
 static unsigned int sad_max_channels(const u8 *sad)
 {
return 1 + (sad[0] & 7);
 }

+static int eld_limit_formats(struct snd_pcm_runtime *runtime, void *eld)
+{
+   u64 formats = SNDRV_PCM_FMTBIT_S16_LE;
+   int i;
+   const u8 *sad, *eld_buf = eld;
+
+   sad = drm_eld_sad(eld_buf);
+   if (!sad)
+   goto format_constraint;
+
+   for (i = drm_eld_sad_count(eld_buf); i > 0; i--, sad += 3) {
+   if (sad_format(sad) == 1) { /* AUDIO_CODING_TYPE_LPCM */
+
+   /* 20 bit */
+   if (sad_sample_bits_lpcm(sad) & 0x2)
+   formats |= SNDRV_PCM_FMTBIT_S32_LE;
+
+   /* 24 bit */
+   if (sad_sample_bits_lpcm(sad) & 0x4)
+   formats |= SNDRV_PCM_FMTBIT_S24_LE;
+   }
+   }
+
+format_constraint:
+   return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT,
+   formats);
+}
+
 static int eld_limit_rates(struct snd_pcm_hw_params *params,
   struct snd_pcm_hw_rule *rule)
 {
@@ -93,7 +131,9 @@ int snd_pcm_hw_constraint_eld(struct snd_pcm_runtime 
*runtime, void *eld)
ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
  eld_limit_channels, eld,
  SNDRV_PCM_HW_PARAM_RATE, -1);
+   if (ret < 0)
+   return ret;

-   return ret;
+   return eld_limit_formats(runtime, eld);
 }
 EXPORT_SYMBOL_GPL(snd_pcm_hw_constraint_eld);
-- 
1.9.1



[PATCH v2 04/14] ASoC: hdac_hdmi: Add hotplug notification and read eld

2015-12-04 Thread Subhransu S. Prusty
This patch uses i915 component framework to register for hotplug
notification. And once it identifies valid pin sense and valid eld,
reads the eld into the corresponding pin map buffer. For now it
directly sends the verbs and reads the eld. Later this will use
the i915 framework to populate ELD buffer once available.

The eld reading APIs in legacy hda are required for ASoC skylake
hdmi driver as well. So keeping a copy here and will remove once
component ops for reading ELD are merged in hda core.

Also read the monitor present sense during resume and ignore the
ELD notify from graphics during PM as is done in legacy hda.
Reference commits:

git: git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git

commit 33d58f2bb446 ("ALSA: hda - Skip ELD notification during PM
process")
commit 8ae743e82f0b ("ALSA: hda - Skip ELD notification during
system suspend")

Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
---
 sound/soc/codecs/hdac_hdmi.c | 214 +--
 1 file changed, 207 insertions(+), 7 deletions(-)

diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 31ab37b..65796ce 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -34,6 +34,9 @@

 #define HDA_MAX_CONNECTIONS 32

+#define ELD_MAX_SIZE256
+#define ELD_FIXED_BYTES20
+
 struct hdac_hdmi_cvt_params {
unsigned int channels_min;
unsigned int channels_max;
@@ -48,11 +51,22 @@ struct hdac_hdmi_cvt {
struct hdac_hdmi_cvt_params params;
 };

+struct hdmi_eld {
+   boolmonitor_present;
+   booleld_valid;
+   int eld_size;
+   chareld_buffer[ELD_MAX_SIZE];
+};
+
 struct hdac_hdmi_pin {
struct list_head head;
hda_nid_t nid;
int num_mux_nids;
hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
+   struct hdmi_eld eld;
+   struct hdac_ext_device *edev;
+   int repoll_count;
+   struct delayed_work work;
 };

 struct hdac_hdmi_dai_pin_map {
@@ -76,6 +90,81 @@ static inline struct hdac_ext_device 
*to_hda_ext_device(struct device *dev)
return container_of(hdac, struct hdac_ext_device, hdac);
 }

+ /* HDMI Eld routines */
+static unsigned int hdac_hdmi_get_eld_data(struct hdac_device *codec,
+   hda_nid_t nid, int byte_index)
+{
+   unsigned int val;
+
+   val = snd_hdac_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_ELDD,
+   byte_index);
+
+   dev_dbg(>dev, "HDMI: ELD data byte %d: 0x%x\n",
+   byte_index, val);
+
+   return val;
+}
+
+static int hdac_hdmi_get_eld_size(struct hdac_device *codec, hda_nid_t nid)
+{
+   return snd_hdac_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
+AC_DIPSIZE_ELD_BUF);
+}
+
+/*
+ * This function queries the eld size and eld data and fills in the buffer
+ * passed by user
+ */
+int hdac_hdmi_get_eld(struct hdac_device *codec, hda_nid_t nid,
+unsigned char *buf, int *eld_size)
+{
+   int i;
+   int ret = 0;
+   int size;
+
+   /*
+* ELD size is initialized to zero in caller function. If no errors and
+* ELD is valid, actual eld_size is assigned.
+*/
+
+   size = hdac_hdmi_get_eld_size(codec, nid);
+   if (size < ELD_FIXED_BYTES || size > ELD_MAX_SIZE) {
+   dev_info(>dev, "HDMI: invalid ELD buf size %d\n", size);
+   return -ERANGE;
+   }
+
+   /* set ELD buffer */
+   for (i = 0; i < size; i++) {
+   unsigned int val = hdac_hdmi_get_eld_data(codec, nid, i);
+   /*
+* Graphics driver might be writing to ELD buffer right now.
+* Just abort. The caller will repoll after a while.
+*/
+   if (!(val & AC_ELDD_ELD_VALID)) {
+   dev_info(>dev, "HDMI: invalid ELD data byte 
%d\n", i);
+   ret = -EINVAL;
+   goto error;
+   }
+   val &= AC_ELDD_ELD_DATA;
+   /*
+* The first byte cannot be zero. This can happen on some DVI
+* connections. Some Intel chips may also need some 250ms delay
+* to return non-zero ELD data, even when the graphics driver
+* correctly writes ELD content before setting ELD_valid bit.
+*/
+   if (!val && !i) {
+   dev_dbg(>dev, "HDMI: 0 ELD data\n");
+   ret = -EINVAL;
+   goto error;
+   }
+   buf[i] = val;
+   }
+
+   *eld_size = size;
+error:
+   return ret;
+}
+
 static int hdac_hdmi_setup_stream(struct hdac_ext_device *hdac,
hda_nid_t 

[PATCH v2 03/14] ASoC: hdac_hdmi - Use list to add pins and converters

2015-12-04 Thread Subhransu S. Prusty
Future platforms may have a different set of pins/converters.
So use lists to add pins and converters based on enumeration.

Also it may be required to connect any converter to any pin
dynamically as per different use cases (for example DP is
connected to pin 6 on skylake board). So this will help in
dynamically select and route.

Fix the dai map as well to use the pin/cvt from list. Not
enabling all dai maps for now.

Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
---
 sound/soc/codecs/hdac_hdmi.c | 154 +--
 1 file changed, 106 insertions(+), 48 deletions(-)

diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 429fa14..31ab37b 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -43,11 +43,13 @@ struct hdac_hdmi_cvt_params {
 };

 struct hdac_hdmi_cvt {
+   struct list_head head;
hda_nid_t nid;
struct hdac_hdmi_cvt_params params;
 };

 struct hdac_hdmi_pin {
+   struct list_head head;
hda_nid_t nid;
int num_mux_nids;
hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
@@ -55,14 +57,16 @@ struct hdac_hdmi_pin {

 struct hdac_hdmi_dai_pin_map {
int dai_id;
-   struct hdac_hdmi_pin pin;
-   struct hdac_hdmi_cvt cvt;
+   struct hdac_hdmi_pin *pin;
+   struct hdac_hdmi_cvt *cvt;
 };

 struct hdac_hdmi_priv {
-   hda_nid_t pin_nid[3];
-   hda_nid_t cvt_nid[3];
struct hdac_hdmi_dai_pin_map dai_map[3];
+   struct list_head pin_list;
+   struct list_head cvt_list;
+   int num_pin;
+   int num_cvt;
 };

 static inline struct hdac_ext_device *to_hda_ext_device(struct device *dev)
@@ -149,13 +153,15 @@ static void hdac_hdmi_set_power_state(struct 
hdac_ext_device *edev,
struct hdac_hdmi_dai_pin_map *dai_map, unsigned int pwr_state)
 {
/* Power up pin widget */
-   if (!snd_hdac_check_power_state(>hdac, dai_map->pin.nid, 
pwr_state))
-   snd_hdac_codec_write(>hdac, dai_map->pin.nid, 0,
+   if (!snd_hdac_check_power_state(>hdac, dai_map->pin->nid,
+   pwr_state))
+   snd_hdac_codec_write(>hdac, dai_map->pin->nid, 0,
AC_VERB_SET_POWER_STATE, pwr_state);

/* Power up converter */
-   if (!snd_hdac_check_power_state(>hdac, dai_map->cvt.nid, 
pwr_state))
-   snd_hdac_codec_write(>hdac, dai_map->cvt.nid, 0,
+   if (!snd_hdac_check_power_state(>hdac, dai_map->cvt->nid,
+   pwr_state))
+   snd_hdac_codec_write(>hdac, dai_map->cvt->nid, 0,
AC_VERB_SET_POWER_STATE, pwr_state);
 }

@@ -179,13 +185,13 @@ static int hdac_hdmi_playback_prepare(struct 
snd_pcm_substream *substream,
dev_dbg(>hdac.dev, "stream tag from cpu dai %d format in cvt 
0x%x\n",
dd->stream_tag, dd->format);

-   ret = hdac_hdmi_setup_audio_infoframe(hdac, dai_map->cvt.nid,
-   dai_map->pin.nid);
+   ret = hdac_hdmi_setup_audio_infoframe(hdac, dai_map->cvt->nid,
+   dai_map->pin->nid);
if (ret < 0)
return ret;

-   return hdac_hdmi_setup_stream(hdac, dai_map->cvt.nid, dai_map->pin.nid,
-   dd->stream_tag, dd->format);
+   return hdac_hdmi_setup_stream(hdac, dai_map->cvt->nid,
+   dai_map->pin->nid, dd->stream_tag, dd->format);
 }

 static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream,
@@ -221,9 +227,9 @@ static int hdac_hdmi_playback_cleanup(struct 
snd_pcm_substream *substream,

dai_map = >dai_map[dai->id];

-   snd_hdac_codec_write(>hdac, dai_map->cvt.nid, 0,
+   snd_hdac_codec_write(>hdac, dai_map->cvt->nid, 0,
AC_VERB_SET_CHANNEL_STREAMID, 0);
-   snd_hdac_codec_write(>hdac, dai_map->cvt.nid, 0,
+   snd_hdac_codec_write(>hdac, dai_map->cvt->nid, 0,
AC_VERB_SET_STREAM_FORMAT, 0);

dd = (struct hdac_ext_dma_params *)snd_soc_dai_get_dma_data(dai, 
substream);
@@ -249,7 +255,7 @@ static int hdac_hdmi_pcm_open(struct snd_pcm_substream 
*substream,

dai_map = >dai_map[dai->id];

-   val = snd_hdac_codec_read(>hdac, dai_map->pin.nid, 0,
+   val = snd_hdac_codec_read(>hdac, dai_map->pin->nid, 0,
AC_VERB_GET_PIN_SENSE, 0);
dev_info(>hdac.dev, "Val for AC_VERB_GET_PIN_SENSE: %x\n", val);

@@ -260,7 +266,7 @@ static int hdac_hdmi_pcm_open(struct snd_pcm_substream 
*substream,

hdac_hdmi_set_power_state(hdac, dai_map, AC_PWRST_D0);

-   snd_hdac_c

[PATCH v2 02/14] ASoC: hdac_hdmi: Fix to warn instead of err for no connected nids

2015-12-04 Thread Subhransu S. Prusty
It is possible that some pin widget may return with no converter
connected. So don't throw error if none are found to be connected.
Instead print a warning and continue.

Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
---
 sound/soc/codecs/hdac_hdmi.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 929f27b..429fa14 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -316,10 +316,12 @@ static int hdac_hdmi_query_pin_connlist(struct 
hdac_ext_device *hdac,

pin->num_mux_nids = snd_hdac_get_connections(>hdac, pin->nid,
pin->mux_nids, HDA_MAX_CONNECTIONS);
-   if (pin->num_mux_nids == 0) {
-   dev_err(>hdac.dev, "No connections found\n");
-   return -ENODEV;
-   }
+   if (pin->num_mux_nids == 0)
+   dev_warn(>hdac.dev, "No connections found for pin: %d\n",
+   pin->nid);
+
+   dev_dbg(>hdac.dev, "num_mux_nids %d for pin: %d\n",
+   pin->num_mux_nids, pin->nid);

return pin->num_mux_nids;
 }
-- 
1.9.1



[PATCH v2 01/14] ASoC: hdac_hdmi: Fix to check num nodes correctly

2015-12-04 Thread Subhransu S. Prusty
commit 3c83ac23253c ("ASoC: hdac_hdmi: check error return") fixes
the static checker warning reported by Dan Carpenter:

sound/soc/codecs/hdac_hdmi.c:416 hdac_hdmi_parse_and_map_nid()
warn: unsigned 'hdac->num_nodes' is never less than zero.

But it doesn't fix the issue completely.

It's also a failure if no sub nodes found for an afg node. So modify
the return condition appropriately.

Cc: Dan Carpenter 
Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
---
 sound/soc/codecs/hdac_hdmi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 1a2f33b..929f27b 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -415,7 +415,7 @@ static int hdac_hdmi_parse_and_map_nid(struct 
hdac_ext_device *edev)
int cvt_nid = 0, pin_nid = 0;

num_nodes = snd_hdac_get_sub_nodes(hdac, hdac->afg, );
-   if (!nid || num_nodes < 0) {
+   if (!nid || num_nodes <= 0) {
dev_warn(>dev, "HDMI: failed to get afg sub nodes\n");
return -EINVAL;
}
-- 
1.9.1



[PATCH v2 00/14] ASoC: hdac_hdmi: Add DP & notification support

2015-12-04 Thread Subhransu S. Prusty
This patch series adds DP audio and hotplug notification
support.

On Skylake two DP ports are available and to enable DP on both
ports all pins need to be enabled.

There is a special vendor widget which need to be programmed to
enable all pins and converters. This series adds hotplug
notification, read/set constraint based on ELD, enable all
pin/cvts, DP1.2, programs the audio infoframe for DP. There is
a one to one mapping between converter and stream, so the dais
are created based on the no of streams supported on hdmi codec.
Even though cvts can be mapped dynamically to the streams,
currently it is statically mapped as simultaneous playback on
both DP and HDMI is not supported as of now.

Pin muxes and controls are created dynamically to map converter
to pin widget. So at run time specific pin is mapped to the dai
based on the control selected (based on the display type DP/HDMI
connected).

Finally the DP audio infoframe programming is added to support
the DP feature. 

Also with hotplug notification support, ELD is read and
capabilities are set for rate, formats and channels. drm_eld
sound/core framework is updated to limit the formats based on
ELD.

There are few fixes one fixing the static checker warning and
other one not to fail if no connection list is found for a pin
widget.

Pls note, the 11th patch is adding a small macro for getting
connection type in drm header, we have CCed drm folks on that and
this one. Pls ack so that we can have this series merged thru
sound trees

changes in v2:
- Address review comments
- Dropped devm_xxx for cvt and pin memory allocation.
- Dropped the ELD helper APIs from core and copied to driver.
- Updated notification patch to add PM fixes from legacy hda.
- commit message and change log updated for display power fix.
- Updated DRM helper APIs and the caller

Jeeja KP (1):
  ASoC: hdac_hdmi: Add codec suspend/resume handler

Ramesh Babu (1):
  ASoC: hdac_hdmi: Fix to keep display active while enumerating codec

Subhransu S. Prusty (12):
  ASoC: hdac_hdmi: Fix to check num nodes correctly
  ASoC: hdac_hdmi: Fix to warn instead of err for no connected nids
  ASoC: hdac_hdmi - Use list to add pins and converters
  ASoC: hdac_hdmi: Add hotplug notification and read eld
  ALSA: pcm: Add DRM helper to set constraint for format
  ASoC: hdac_hdmi: Apply constraints based on ELD
  ASoC: hdac_hdmi: Enable DP1.2 and all converters/pins
  ASoC: hdac_hdmi - create dais based on number of streams
  ASoC: hdac_hdmi: Create widget/route based on nodes enumerated
  ASoC: hdac_hdmi: Assign pin for stream based on dapm connection
  drm/edid: Add API to help find connection type
  ASoC: hdac_hdmi: Add infoframe support for dp audio

 include/drm/drm_edid.h   |   12 +
 sound/core/pcm_drm_eld.c |   42 +-
 sound/soc/codecs/Kconfig |1 +
 sound/soc/codecs/hdac_hdmi.c | 1019 --
 4 files changed, 925 insertions(+), 149 deletions(-)

-- 
1.9.1



[alsa-devel] [PATCH 12/15] drm/edid: Add API to help find connection type

2015-12-03 Thread Subhransu S. Prusty
On Thu, Dec 03, 2015 at 12:21:42PM +0100, Thierry Reding wrote:
> On Thu, Dec 03, 2015 at 01:09:16PM +0200, Jani Nikula wrote:
> > On Thu, 03 Dec 2015, "Subhransu S. Prusty"  > intel.com> wrote:
> > > On Wed, Dec 02, 2015 at 06:07:01PM +0100, Thierry Reding wrote:
> > >> On Wed, Dec 02, 2015 at 11:53:02AM +0200, Jani Nikula wrote:
> > >> > On Tue, 01 Dec 2015, "Subhransu S. Prusty"  > >> > intel.com> wrote:
> > >> > > To fill the audio infoframe it is required to identify the 
> > >> > > connection type
> > >> > > as DP or HDMI. So parse the required bits in ELD to find the 
> > >> > > connection
> > >> > > type.
> > >> > >
> > >> > > Signed-off-by: Subhransu S. Prusty 
> > >> > > Signed-off-by: Vinod Koul 
> > >> > > Cc: David Airlie 
> > >> > > Cc: dri-devel at lists.freedesktop.org
> > >> > > Cc: Daniel Vetter 
> > >> > > ---
> > >> > >  include/drm/drm_edid.h | 10 ++
> > >> > >  1 file changed, 10 insertions(+)
> > >> > >
> > >> > > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> > >> > > index 2af9769..c7595a5 100644
> > >> > > --- a/include/drm/drm_edid.h
> > >> > > +++ b/include/drm/drm_edid.h
> > >> > > @@ -403,6 +403,16 @@ static inline int drm_eld_size(const uint8_t 
> > >> > > *eld)
> > >> > >  return DRM_ELD_HEADER_BLOCK_SIZE + 
> > >> > > eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
> > >> > >  }
> > >> > >  
> > >> > > +/**
> > >> > > + * drm_eld_get_conn_type - Get device type hdmi/dp connected
> > >> > > + * @eld: pointer to an eld memory structure
> > >> > > + */
> > >> > > +static inline int drm_eld_get_conn_type(const uint8_t *eld)
> > >> > > +{
> > >> > > +return (eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & 
> > >> > > DRM_ELD_CONN_TYPE_MASK) >>
> > >> > > +DRM_ELD_CONN_TYPE_SHIFT;
> > >> > > +}
> > >> > 
> > >> > I'm not sure how much this helps when the caller still needs to
> > >> > magically know what the return value means...  Indeed the next patch
> > >> > with /* 0 is hdmi and 1 is DP */ and "conn_type == 0" is a bit ugly.
> > >> > 
> > >> > How about just not shifting the return value, and using
> > >> > DRM_ELD_CONN_TYPE_HDMI and DRM_ELD_CONN_TYPE_DP in the caller? Bonus
> > >> > points for referencing those in the kernel-doc above.
> > >> 
> > >> We already have a similar function for detecting HDMI vs. DVI (see the
> > >> drm_detect_hdmi_monitor()), so perhaps adhering to that convention might
> > >> be preferable. This could be:
> > >> 
> > >>  static inline bool drm_eld_detect_dp(const u8 *eld)
> > >>  {
> > >>  u8 type = eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & 
> > >> DRM_ELD_CONN_TYPE_MASK;
> > >> 
> > >>  return type == DRM_ELD_CONN_TYPE_DP;
> > >>  }
> > >
> > > With this approach it needs two APIs to be added for HDMI or DP
> > > detection. So I prefer what Jani suggested and caller compares
> > > whether it is HDMI/DP connection type. Will updae the kernel doc
> > > for the same as well.
> > 
> > I presume Thierry means you'd assume HDMI if drm_eld_detect_dp() returns
> > false.
> 
> Yes, that's what I was implying. This is probably highly subjective, but
> I personally find boolean return values much easier to deal with because
> of the limited set of values. With drm_eld_get_conn_type() you'd need to
> explicitly check == DRM_ELD_CONN_TYPE_HDMI and == DRM_ELD_CONN_TYPE_DP
> and then still have special code to reject all other values. Unless of

I don't know what does the second bit mean in the connection type. So was
just planning to reject anything other that DP/HDMI. If that bit doesn't
carry any information, then yes I would also prefer returning a boolean.

> course if you consider != DRM_ELD_CONN_TYPE_DP as being HDMI, in which
> case a boolean is much more concise.
> 
> But like I said, this is just my opinion, and I don't feel strongly
> enough to object to the current patch.
> 
> Thierry



-- 


[alsa-devel] [PATCH 12/15] drm/edid: Add API to help find connection type

2015-12-03 Thread Subhransu S. Prusty
On Wed, Dec 02, 2015 at 06:07:01PM +0100, Thierry Reding wrote:
> On Wed, Dec 02, 2015 at 11:53:02AM +0200, Jani Nikula wrote:
> > On Tue, 01 Dec 2015, "Subhransu S. Prusty"  > intel.com> wrote:
> > > To fill the audio infoframe it is required to identify the connection type
> > > as DP or HDMI. So parse the required bits in ELD to find the connection
> > > type.
> > >
> > > Signed-off-by: Subhransu S. Prusty 
> > > Signed-off-by: Vinod Koul 
> > > Cc: David Airlie 
> > > Cc: dri-devel at lists.freedesktop.org
> > > Cc: Daniel Vetter 
> > > ---
> > >  include/drm/drm_edid.h | 10 ++
> > >  1 file changed, 10 insertions(+)
> > >
> > > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> > > index 2af9769..c7595a5 100644
> > > --- a/include/drm/drm_edid.h
> > > +++ b/include/drm/drm_edid.h
> > > @@ -403,6 +403,16 @@ static inline int drm_eld_size(const uint8_t *eld)
> > >   return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
> > >  }
> > >  
> > > +/**
> > > + * drm_eld_get_conn_type - Get device type hdmi/dp connected
> > > + * @eld: pointer to an eld memory structure
> > > + */
> > > +static inline int drm_eld_get_conn_type(const uint8_t *eld)
> > > +{
> > > + return (eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_CONN_TYPE_MASK) >>
> > > + DRM_ELD_CONN_TYPE_SHIFT;
> > > +}
> > 
> > I'm not sure how much this helps when the caller still needs to
> > magically know what the return value means...  Indeed the next patch
> > with /* 0 is hdmi and 1 is DP */ and "conn_type == 0" is a bit ugly.
> > 
> > How about just not shifting the return value, and using
> > DRM_ELD_CONN_TYPE_HDMI and DRM_ELD_CONN_TYPE_DP in the caller? Bonus
> > points for referencing those in the kernel-doc above.
> 
> We already have a similar function for detecting HDMI vs. DVI (see the
> drm_detect_hdmi_monitor()), so perhaps adhering to that convention might
> be preferable. This could be:
> 
>   static inline bool drm_eld_detect_dp(const u8 *eld)
>   {
>   u8 type = eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & 
> DRM_ELD_CONN_TYPE_MASK;
> 
>   return type == DRM_ELD_CONN_TYPE_DP;
>   }

With this approach it needs two APIs to be added for HDMI or DP
detection. So I prefer what Jani suggested and caller compares
whether it is HDMI/DP connection type. Will updae the kernel doc
for the same as well.

> 
> Thierry



> ___
> Alsa-devel mailing list
> Alsa-devel at alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel


-- 


[PATCH 12/15] drm/edid: Add API to help find connection type

2015-12-02 Thread Subhransu S. Prusty
On Wed, Dec 02, 2015 at 11:53:02AM +0200, Jani Nikula wrote:
> On Tue, 01 Dec 2015, "Subhransu S. Prusty"  
> wrote:
> > To fill the audio infoframe it is required to identify the connection type
> > as DP or HDMI. So parse the required bits in ELD to find the connection
> > type.
> >
> > Signed-off-by: Subhransu S. Prusty 
> > Signed-off-by: Vinod Koul 
> > Cc: David Airlie 
> > Cc: dri-devel at lists.freedesktop.org
> > Cc: Daniel Vetter 
> > ---
> >  include/drm/drm_edid.h | 10 ++
> >  1 file changed, 10 insertions(+)
> >
> > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> > index 2af9769..c7595a5 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -403,6 +403,16 @@ static inline int drm_eld_size(const uint8_t *eld)
> > return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
> >  }
> >  
> > +/**
> > + * drm_eld_get_conn_type - Get device type hdmi/dp connected
> > + * @eld: pointer to an eld memory structure
> > + */
> > +static inline int drm_eld_get_conn_type(const uint8_t *eld)
> > +{
> > +   return (eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_CONN_TYPE_MASK) >>
> > +   DRM_ELD_CONN_TYPE_SHIFT;
> > +}
> 
> I'm not sure how much this helps when the caller still needs to
> magically know what the return value means...  Indeed the next patch
> with /* 0 is hdmi and 1 is DP */ and "conn_type == 0" is a bit ugly.
> 
> How about just not shifting the return value, and using
> DRM_ELD_CONN_TYPE_HDMI and DRM_ELD_CONN_TYPE_DP in the caller? Bonus
> points for referencing those in the kernel-doc above.

Sure, will update and submit again.

Regards,
Subhransu
> 
> BR,
> Jani.
> 
> 
> > +
> >  struct edid *drm_do_get_edid(struct drm_connector *connector,
> > int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
> >   size_t len),
> 
> -- 
> Jani Nikula, Intel Open Source Technology Center

-- 


[PATCH 12/15] drm/edid: Add API to help find connection type

2015-12-01 Thread Subhransu S. Prusty
To fill the audio infoframe it is required to identify the connection type
as DP or HDMI. So parse the required bits in ELD to find the connection
type.

Signed-off-by: Subhransu S. Prusty 
Signed-off-by: Vinod Koul 
Cc: David Airlie 
Cc: dri-devel at lists.freedesktop.org
Cc: Daniel Vetter 
---
 include/drm/drm_edid.h | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 2af9769..c7595a5 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -403,6 +403,16 @@ static inline int drm_eld_size(const uint8_t *eld)
return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
 }

+/**
+ * drm_eld_get_conn_type - Get device type hdmi/dp connected
+ * @eld: pointer to an eld memory structure
+ */
+static inline int drm_eld_get_conn_type(const uint8_t *eld)
+{
+   return (eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_CONN_TYPE_MASK) >>
+   DRM_ELD_CONN_TYPE_SHIFT;
+}
+
 struct edid *drm_do_get_edid(struct drm_connector *connector,
int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
  size_t len),
-- 
1.9.1



[PATCH 00/15] ASoC: hdac_hdmi: Add DP & notification support

2015-12-01 Thread Subhransu S. Prusty
This patch series adds DP audio and hotplug notification
support.

On Skylake two DP ports are available and to enable DP on both
ports all pins need to be enabled.

There is a special vendor widget which need to be programmed to
enable all pins and converters. This series adds hotplug
notification, read/set constraint based on ELD, enable all
pin/cvts, DP1.2, programs the audio infoframe for DP. There is
a one to one mapping between converter and stream, so the dais
are created based on the no of streams supported on hdmi codec.
Even though cvts can be mapped dynamically to the streams,
currently it is statically mapped as simultaneous playback on
both DP and HDMI is not supported as of now.

Pin muxes and controls are created dynamically to map converter
to pin widget. So at run time specific pin is mapped to the dai
based on the control selected (based on the display type DP/HDMI
connected).

Finally the DP audio infoframe programming is added to support
the DP feature. 

Also with hotplug notification support, ELD is read and
capabilities are set for rate, formats and channels. drm_eld
sound/core framework is updated to limit the formats based on
ELD.

There are few fixes one fixing the static checker warning and
other one not to fail if no connection list is found for a pin
widget.


Pls note, the 12th patch is adding a small macro for getting
connection type in drm header, we have CCed drm folks on that and
this one. Pls ack so that we can have this series merged thru
sound trees

Jeeja KP (1):
  ASoC: hdac_hdmi: Add codec suspend/resume handler

Ramesh Babu (1):
  ASoC: hdac_hdmi: Keep display active while enumerating codec

Subhransu S. Prusty (13):
  ASoC: hdac_hdmi: Fix to check num nodes correctly
  ASoC: hdac_hdmi: Fix to warn instead of err for no connected nids
  ASoC: hdac_hdmi - Use list to add pins and converters
  ALSA: hda - Add helper to read eld data
  ASoC: hdac_hdmi: Add hotplug notification and read eld
  ALSA: pcm: Add DRM helper to set constraint for format
  ASoC: hdac_hdmi: Apply constraints based on ELD
  ASoC: hdac_hdmi: Enable DP1.2 and all converters/pins
  ASoC: hdac_hdmi - create dais based on number of streams
  ASoC: hdac_hdmi: Create widget/route based on nodes enumerated
  ASoC: hdac_hdmi: Assign pin for stream based on dapm connection
  drm/edid: Add API to help find connection type
  ASoC: hdac_hdmi: Add infoframe support for dp audio

 include/drm/drm_edid.h   |  10 +
 include/sound/hdaudio.h  |   3 +
 sound/core/pcm_drm_eld.c |  42 +-
 sound/hda/Makefile   |   2 +-
 sound/hda/hdac_eld.c |  95 +
 sound/soc/codecs/Kconfig |   1 +
 sound/soc/codecs/hdac_hdmi.c | 908 ---
 7 files changed, 908 insertions(+), 153 deletions(-)
 create mode 100644 sound/hda/hdac_eld.c

-- 
1.9.1