Re: [PATCH RFC v2 0/2] Disable planes on blanked CRTC and enable on unblank

2015-11-17 Thread Jyri Sarha

On 11/17/15 12:28, Daniel Vetter wrote:

On Fri, Nov 13, 2015 at 05:53:13PM +0200, Jyri Sarha wrote:

Since first RFC version:
- Added "drm/atomic: Track drm_plane's active state"-patch

We would need something like this to get rid off OMAPDSS somewhat
messy runtime_resume code. How does this look, could this generic
solution be refined to be acceptable for mainline, or should we start
looking a local solution to omapdrm?


One more comment besides what I've written in the older thread: You're not
on latest drm-next, which has gained an active_only paramter to the plane
commit helper.

It might be best to discuss this topic on #dri-devel on freenode irc a
bit.



Thanks a lot for you comments!

I just rebased my stuff on top the the latest drm-next. I think I need 
digest your earlier comments about drm_atomic_add_affected_planes etc. a 
bit before I can take advantage of any interactive communication. I'll 
try to follow those instruction first and see where it leads me.


Thanks,
Jyri


Cheers, Daniel



Jyri Sarha (2):
   drm/atomic: Track drm_plane's active state
   drm/atomic: Disable planes on blanked CRTC and enable on unblank

  drivers/gpu/drm/drm_atomic_helper.c | 82 +
  drivers/gpu/drm/drm_plane_helper.c  | 10 +
  include/drm/drm_atomic_helper.h | 39 +-
  include/drm/drm_crtc.h  |  2 +
  4 files changed, 70 insertions(+), 63 deletions(-)

--
1.9.1





--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] clk: gpio: Get parent clk names already in of_gpio_clk_setup()

2015-11-17 Thread Jyri Sarha
Get parent clk names already in of_gpio_clk_setup() and store the
names in struct clk_gpio_delayed_register_data. of_clk_get_parent_name()
can not be called in struct of_clk_provider's get() callback since it
may make a recursive call to of_clk_get_from_provider() and this in turn
tries to recursively lock of_clk_mutex.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
Cc: Sergej Sawazki <c...@gmx.de>
---
Something has changed in Linux mainline so that getting the clk
parent names in struct of_clk_provider's get() callback does not work
anymore. This patch should fix the problem.

 drivers/clk/clk-gpio.c | 33 +
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c
index 10819e2..335322d 100644
--- a/drivers/clk/clk-gpio.c
+++ b/drivers/clk/clk-gpio.c
@@ -209,6 +209,8 @@ EXPORT_SYMBOL_GPL(clk_register_gpio_mux);
 
 struct clk_gpio_delayed_register_data {
const char *gpio_name;
+   int num_parents;
+   const char **parent_names;
struct device_node *node;
struct mutex lock;
struct clk *clk;
@@ -222,8 +224,6 @@ static struct clk *of_clk_gpio_delayed_register_get(
 {
struct clk_gpio_delayed_register_data *data = _data;
struct clk *clk;
-   const char **parent_names;
-   int i, num_parents;
int gpio;
enum of_gpio_flags of_flags;
 
@@ -248,26 +248,14 @@ static struct clk *of_clk_gpio_delayed_register_get(
return ERR_PTR(gpio);
}
 
-   num_parents = of_clk_get_parent_count(data->node);
-
-   parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL);
-   if (!parent_names) {
-   clk = ERR_PTR(-ENOMEM);
-   goto out;
-   }
-
-   for (i = 0; i < num_parents; i++)
-   parent_names[i] = of_clk_get_parent_name(data->node, i);
-
-   clk = data->clk_register_get(data->node->name, parent_names,
-   num_parents, gpio, of_flags & OF_GPIO_ACTIVE_LOW);
+   clk = data->clk_register_get(data->node->name, data->parent_names,
+   data->num_parents, gpio, of_flags & OF_GPIO_ACTIVE_LOW);
if (IS_ERR(clk))
goto out;
 
data->clk = clk;
 out:
mutex_unlock(>lock);
-   kfree(parent_names);
 
return clk;
 }
@@ -296,11 +284,24 @@ static void __init of_gpio_clk_setup(struct device_node 
*node,
unsigned gpio, bool active_low))
 {
struct clk_gpio_delayed_register_data *data;
+   const char **parent_names;
+   int i, num_parents;
 
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data)
return;
 
+   num_parents = of_clk_get_parent_count(node);
+
+   parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL);
+   if (!parent_names)
+   return;
+
+   for (i = 0; i < num_parents; i++)
+   parent_names[i] = of_clk_get_parent_name(node, i);
+
+   data->num_parents = num_parents;
+   data->parent_names = parent_names;
data->node = node;
data->gpio_name = gpio_name;
data->clk_register_get = clk_register_get;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] clk: gpio: Get parent clk names already in of_gpio_clk_setup()

2015-11-17 Thread Jyri Sarha
Get parent clk names already in of_gpio_clk_setup() and store the
names in struct clk_gpio_delayed_register_data. of_clk_get_parent_name()
can not be called in struct of_clk_provider's get() callback since it
may make a recursive call to of_clk_get_from_provider() and this in turn
tries to recursively lock of_clk_mutex.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
Cc: Sergej Sawazki <c...@gmx.de>
---
Something has changed in Linux mainline so that getting the clk
parent names in struct of_clk_provider's get() callback does not work
anymore. This patch should fix the problem.

 drivers/clk/clk-gpio.c | 33 +
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c
index 10819e2..335322d 100644
--- a/drivers/clk/clk-gpio.c
+++ b/drivers/clk/clk-gpio.c
@@ -209,6 +209,8 @@ EXPORT_SYMBOL_GPL(clk_register_gpio_mux);
 
 struct clk_gpio_delayed_register_data {
const char *gpio_name;
+   int num_parents;
+   const char **parent_names;
struct device_node *node;
struct mutex lock;
struct clk *clk;
@@ -222,8 +224,6 @@ static struct clk *of_clk_gpio_delayed_register_get(
 {
struct clk_gpio_delayed_register_data *data = _data;
struct clk *clk;
-   const char **parent_names;
-   int i, num_parents;
int gpio;
enum of_gpio_flags of_flags;
 
@@ -248,26 +248,14 @@ static struct clk *of_clk_gpio_delayed_register_get(
return ERR_PTR(gpio);
}
 
-   num_parents = of_clk_get_parent_count(data->node);
-
-   parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL);
-   if (!parent_names) {
-   clk = ERR_PTR(-ENOMEM);
-   goto out;
-   }
-
-   for (i = 0; i < num_parents; i++)
-   parent_names[i] = of_clk_get_parent_name(data->node, i);
-
-   clk = data->clk_register_get(data->node->name, parent_names,
-   num_parents, gpio, of_flags & OF_GPIO_ACTIVE_LOW);
+   clk = data->clk_register_get(data->node->name, data->parent_names,
+   data->num_parents, gpio, of_flags & OF_GPIO_ACTIVE_LOW);
if (IS_ERR(clk))
goto out;
 
data->clk = clk;
 out:
mutex_unlock(>lock);
-   kfree(parent_names);
 
return clk;
 }
@@ -296,11 +284,24 @@ static void __init of_gpio_clk_setup(struct device_node 
*node,
unsigned gpio, bool active_low))
 {
struct clk_gpio_delayed_register_data *data;
+   const char **parent_names;
+   int i, num_parents;
 
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data)
return;
 
+   num_parents = of_clk_get_parent_count(node);
+
+   parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL);
+   if (!parent_names)
+   return;
+
+   for (i = 0; i < num_parents; i++)
+   parent_names[i] = of_clk_get_parent_name(node, i);
+
+   data->num_parents = num_parents;
+   data->parent_names = parent_names;
data->node = node;
data->gpio_name = gpio_name;
data->clk_register_get = clk_register_get;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC v2 0/2] Disable planes on blanked CRTC and enable on unblank

2015-11-13 Thread Jyri Sarha
Since first RFC version:
- Added "drm/atomic: Track drm_plane's active state"-patch

We would need something like this to get rid off OMAPDSS somewhat
messy runtime_resume code. How does this look, could this generic
solution be refined to be acceptable for mainline, or should we start
looking a local solution to omapdrm?

Jyri Sarha (2):
  drm/atomic: Track drm_plane's active state
  drm/atomic: Disable planes on blanked CRTC and enable on unblank

 drivers/gpu/drm/drm_atomic_helper.c | 82 +
 drivers/gpu/drm/drm_plane_helper.c  | 10 +
 include/drm/drm_atomic_helper.h | 39 +-
 include/drm/drm_crtc.h  |  2 +
 4 files changed, 70 insertions(+), 63 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC v2 1/2] drm/atomic: Track drm_plane's active state

2015-11-13 Thread Jyri Sarha
Track drm_plane's active state with a new boolean in struct
drm_plane_state. The patch replaces drm_atomic_plane_disabling() with
drm_atomic_helper_update_plane_state(). In addition to all the same
things the drm_atomic_plane_disabling() used to do the new function
updates the active-flag and calls atomic_update() or atomic_disable()
from the plane's helper funcs as needed.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
 drivers/gpu/drm/drm_atomic_helper.c | 63 -
 drivers/gpu/drm/drm_plane_helper.c  | 10 +-
 include/drm/drm_atomic_helper.h | 39 ++-
 include/drm/drm_crtc.h  |  2 ++
 4 files changed, 53 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index aecb5d6..d03e2ac 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1197,15 +1197,7 @@ void drm_atomic_helper_commit_planes(struct drm_device 
*dev,
if (!funcs)
continue;
 
-   /*
-* Special-case disabling the plane if drivers support it.
-*/
-   if (drm_atomic_plane_disabling(plane, old_plane_state) &&
-   funcs->atomic_disable)
-   funcs->atomic_disable(plane, old_plane_state);
-   else if (plane->state->crtc ||
-drm_atomic_plane_disabling(plane, old_plane_state))
-   funcs->atomic_update(plane, old_plane_state);
+   drm_atomic_helper_update_plane_state(plane, old_plane_state);
}
 
for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
@@ -1266,12 +1258,7 @@ drm_atomic_helper_commit_planes_on_crtc(struct 
drm_crtc_state *old_crtc_state)
 
WARN_ON(plane->state->crtc && plane->state->crtc != crtc);
 
-   if (drm_atomic_plane_disabling(plane, old_plane_state) &&
-   plane_funcs->atomic_disable)
-   plane_funcs->atomic_disable(plane, old_plane_state);
-   else if (plane->state->crtc ||
-drm_atomic_plane_disabling(plane, old_plane_state))
-   plane_funcs->atomic_update(plane, old_plane_state);
+   drm_atomic_helper_update_plane_state(plane, old_plane_state);
}
 
if (crtc_funcs && crtc_funcs->atomic_flush)
@@ -1279,6 +1266,52 @@ drm_atomic_helper_commit_planes_on_crtc(struct 
drm_crtc_state *old_crtc_state)
 }
 EXPORT_SYMBOL(drm_atomic_helper_commit_planes_on_crtc);
 
+/*
+ * drm_atomic_helper_update_plane_state - update plane's atomic state
+ * @plane: plane object
+ * @old_state: previous atomic state
+ *
+ * Update plane's atomic state, disables it if that is required, and
+ * updates drm_palnes_state's active-flag. This also WARNs if it
+ * detects an invalid state (both CRTC and FB need to either both be
+ * NULL or both be non-NULL).
+ */
+void drm_atomic_helper_update_plane_state(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
+{
+   const struct drm_plane_helper_funcs *funcs = plane->helper_private;
+
+   /*
+* When disabling a plane, CRTC and FB should always be NULL together.
+* Anything else should be considered a bug in the atomic core, so we
+* gently warn about it.
+*/
+   WARN_ON((plane->state->crtc == NULL && plane->state->fb != NULL) ||
+   (plane->state->crtc != NULL && plane->state->fb == NULL));
+
+   if (!funcs)
+   return;
+
+   /*
+* The plane needs to be active only if it has an associated CRTC
+* and the CRTC is active. Use atomic_disable() if available.
+*/
+   if (plane->state->active) {
+   if (!plane->state->crtc || !plane->state->crtc->state->active) {
+   plane->state->active = false;
+   if (funcs->atomic_disable) {
+   funcs->atomic_disable(plane, old_state);
+   return;
+   }
+   }
+   funcs->atomic_update(plane, old_state);
+   } else if (plane->state->crtc && plane->state->crtc->state->active) {
+   plane->state->active = true;
+   funcs->atomic_update(plane, old_state);
+   }
+}
+EXPORT_SYMBOL(drm_atomic_helper_update_plane_state);
+
 /**
  * drm_atomic_helper_cleanup_planes - cleanup plane resources after commit
  * @dev: DRM device
diff --git a/drivers/gpu/drm/drm_plane_helper.c 
b/drivers/gpu/drm/drm_plane_helper.c
index 5e5a07a..93052de 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -440,

[PATCH RFC v2 2/2] drm/atomic: Disable planes on blanked CRTC and enable on unblank

2015-11-13 Thread Jyri Sarha
Disable planes if they are on to be blanked CRTC and enable them when
the CRTC is turned back on by DMPS.

This is desirable on HW that loses its context on blanking. When
planes are enabled and disabled with the associated CRTCs, there is no
need to restore the plane context in runtime_resume callback.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
 drivers/gpu/drm/drm_atomic_helper.c | 19 +--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index d03e2ac..5cd8016 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2027,8 +2027,8 @@ EXPORT_SYMBOL(drm_atomic_helper_page_flip);
  *
  * This is the main helper function provided by the atomic helper framework for
  * implementing the legacy DPMS connector interface. It computes the new 
desired
- * ->active state for the corresponding CRTC (if the connector is enabled) and
- *  updates it.
+ * ->active state for the corresponding CRTC and planes on it (if the connector
+ * is enabled) and updates it.
  *
  * Returns:
  * Returns 0 on success, negative errno numbers on failure.
@@ -2041,6 +2041,7 @@ int drm_atomic_helper_connector_dpms(struct drm_connector 
*connector,
struct drm_crtc_state *crtc_state;
struct drm_crtc *crtc;
struct drm_connector *tmp_connector;
+   struct drm_plane *tmp_plane;
int ret;
bool active = false;
int old_mode = connector->dpms;
@@ -2079,6 +2080,20 @@ retry:
}
crtc_state->active = active;
 
+   /* Collect associated plane states to global state object. */
+   list_for_each_entry(tmp_plane, >plane_list, head) {
+   struct drm_plane_state *plane_state;
+
+   if (tmp_plane->state->crtc != crtc)
+   continue;
+
+   plane_state = drm_atomic_get_plane_state(state, tmp_plane);
+   if (IS_ERR(plane_state)) {
+   ret = PTR_ERR(plane_state);
+   goto fail;
+   }
+   }
+
ret = drm_atomic_commit(state);
if (ret != 0)
goto fail;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] ASoC: davinci-mcasp: Fix TDM slot rx/tx mask associations

2015-11-09 Thread Jyri Sarha

Reviewed-by: Jyri Sarha <jsa...@ti.com>

For what little there is to review.

I only had HW that worked with symmetric masks, so I did not hit this 
myself. Should have hacked something to codec end to be able to test 
asymetric masks at McASP end.


Thanks,
Jyri

On 11/09/15 20:19, Andreas Dannenberg wrote:

Fixes the associations between the tx_mask and rx_mask and the associated
playback / capture streams during setting of the TDM slot. With this
patch in place it is now possible for example to only populate tx_mask
(leaving rx_mask as 0) for output-only codecs to control the TDM slot(s)
the McASP serial port uses for transmit. Before that, this scenario
would incorrectly rely on the rx_mask for this.

Signed-off-by: Andreas Dannenberg <dannenb...@ti.com>
---
  sound/soc/davinci/davinci-mcasp.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/soc/davinci/davinci-mcasp.c 
b/sound/soc/davinci/davinci-mcasp.c
index 4495a40..caa0beb 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -681,8 +681,8 @@ static int davinci_mcasp_set_tdm_slot(struct snd_soc_dai 
*dai,
}

mcasp->tdm_slots = slots;
-   mcasp->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = rx_mask;
-   mcasp->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = tx_mask;
+   mcasp->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = tx_mask;
+   mcasp->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = rx_mask;
mcasp->slot_width = slot_width;

return davinci_mcasp_set_ch_constraints(mcasp);



--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC] ASoC: simple-card: Update clocks binding for simple-card DAI subnodes

2015-09-28 Thread Jyri Sarha

On 09/19/15 21:42, Mark Brown wrote:

On Fri, Sep 11, 2015 at 04:18:02PM +0300, Jyri Sarha wrote:


The updated binding provides a way to set clock-ID and direction
parameters for DAI drivers set_sysclk() call back.



I proposed something similar about a year ago, but Mark rejected that
at the time. This RFC is to start that discussion again. This time
before I do any code changes.


What's the use case again?  Can we address this by converting the
relevant drivers to the clock API (or improving their clock API
support)?



Sorry, I forgot to reply this earlier. The reason why we need this is 
the way McASP driver uses and provides clocks for different purposes. 
The most pressing need is to be able to select if we want to use some 
external clock pin as an input for McASP clock divider that produces the 
i2s bit-clock or if we want to use McASP's internal clock source.


There are several other things this binding would allow us, and others 
with flexible i2s HW, to do. Some TI codecs would also benefit from a 
flexible way of describing the used clock configuration, but Peter know 
that part better.


I tried to make the binding as flexible and generic as possible. But I 
do not currently see any immediate need for more than one set_sysclk() 
call per dai. I just did not see any reason to not allow it either.


Best regards,
Jyri
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC v4 3/8] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders

2015-09-28 Thread Jyri Sarha

On 09/28/15 12:01, Arnaud Pouliquen wrote:

few questions/remarks
BR,
Arnaud


+static void hdmi_codec_abort(struct device *dev)
+{
+struct hdmi_codec_priv *hcp = dev_get_drvdata(dev);
+
+dev_dbg(dev, "%s()\n", __func__);
+
+mutex_lock(>current_stream_lock);
+if (hcp->current_stream && hcp->current_stream->runtime &&
+snd_pcm_running(hcp->current_stream)) {
+dev_info(dev, "HDMI audio playback aborted\n");
+snd_pcm_stream_lock_irq(hcp->current_stream);
+snd_pcm_stop(hcp->current_stream, SNDRV_PCM_STATE_DISCONNECTED);
+snd_pcm_stream_unlock_irq(hcp->current_stream);
+}
+mutex_unlock(>current_stream_lock);
+}

Does driver should stop the stream in case of unplug?
This could generate unexpected behavior at application level.
Perhaps should be better if this part is managed in DRM driver. if HDMI
master, I2S bus should be maintained ON to consume the audio stream
until application action.



The whole point of this abort callback is to provide the means for the 
video side to stop the audio playback in a clean way.


The abort callback is given to the video side in startup() callback 
(ASoC side calls video side). If the video side sees that the playback 
can not go on it can call the abort callback and the audio playback will 
abort in standard ALSA way and a properly written applications should 
not get confused.


Nothing is forcing the video side to call the callback ever, if so 
decided. But if for instance power management stops the i2s clocks when 
connector is unplugged, then the audio can not go on any more and it 
should be aborted (actually it would abort in a moment when ALSA 
realizes that the DMA is not running).



+
+static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
+struct snd_pcm_hw_params *params,
+struct snd_soc_dai *dai)
+{
+struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
+struct hdmi_codec_params hp = {
+.iec = {
+.status = { 0 },
+.subcode = { 0 },
+.pad = 0,
+.dig_subframe = { 0 },
+}
+};
+int ret;
+
+dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__,
+params_width(params), params_rate(params),
+params_channels(params));
+
+ret = snd_pcm_create_iec958_consumer_hw_params(params,
hp.iec.status,
+   sizeof(hp.iec.status));

Tell me if i am wrong, but in case of SPDIF format, IEC status is
managed by cpu_dai not by the codec.
To manage IEC61937 a control should be needed to update IEC status bits...



AFAIK yes. However, the video side implementation is free to ignore 
status bits in the struct hdmi_codec_params and it should normally do so 
if the format is SPDIF. Of course I could save couple CPU cycles in the 
codec code if would not even produce the bits when the format is SPDIF.


Best regards,
Jyri


+if (ret < 0) {
+dev_err(dai->dev, "Creating IEC958 channel status failed %d\n",
+ret);
+return ret;
+}
+
+ret = hdmi_codec_new_stream(substream, dai);
+if (ret)
+return ret;
+
+hdmi_audio_infoframe_init();
+hp.cea.channels = params_channels(params);
+hp.cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
+hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
+hp.cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
+
+hp.sample_width = params_width(params);
+hp.sample_rate = params_rate(params);
+hp.channels = params_channels(params);
+
+return hcp->hcd.ops->hw_params(dai->dev->parent,
>daifmt[dai->id],
+   );
+}
+


--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC v4 3/8] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders

2015-09-21 Thread Jyri Sarha

On 09/21/15 12:31, Russell King - ARM Linux wrote:

On Sat, Sep 19, 2015 at 10:54:51AM -0700, Mark Brown wrote:

On Fri, Sep 18, 2015 at 02:06:40PM +0300, Jyri Sarha wrote:

+#define SPDIF_FORMATS  (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\
+SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
+SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\
+SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
+
+#define I2S_FORMATS(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\
+SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE |\
+SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
+SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\
+SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\
+SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)


I'm not sure how abstracted this I2S and S/PDIF DAI business is - it
doesn't feel like something that's going to be a property of all HDMI
devices, and the specific sets of formats above cause me to raise a bit
of an eyebrow.  Should this be an interface where the HDMI chip
registers multiple interfaces if it has them instead of automatically
getting this split as is?


The inclusion of the 32-bit formats does raise an eyebrow here too.
Audio transmission across the HDMI link is S/PDIF, supporting up to
24-bit uncompressed audio (aka L-PCM).

The device may accept 32 bit I2S, but it would have to be truncated to
24 bit before transmitting it to the sink.  This should be mentioned
somewhere.



There is ".sig_bits = 24" in hdmi_i2s_dai, but I can add an explicit 
comment about it.


We needed 32bit format in practice until Peter got 24_LE properly 
working with McASP. I just thought the may still be some platforms out 
there that can not produce 24bit i2s samples for some reason, but work 
just fine with 32bit samples. Those platforms would be limited to less 
than 24bit precision without 32bit formats. But as said, it is not 
critical to us any more and I can drop the 32bit formats as well.


BR,
Jyri



--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [alsa-devel] [PATCH RFC v4 2/8] ALSA: pcm: add IEC958 channel status helper for hw_params

2015-09-21 Thread Jyri Sarha

On 09/21/15 18:08, Clemens Ladisch wrote:

>But there is no downside in using prepare callback.

The prepare callback also can be called multiple times.  This certainly
happens when the stream is stopped/restarted multiple times.

If something does not need to be done again when a stream is restarted,
then it should be done in the hw_params callback.


Oh, forgot about that. This would suggest to keep the stream header 
configuration in the hw_params().


Thanks,
Jyri
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC v4 2/8] ALSA: pcm: add IEC958 channel status helper for hw_params

2015-09-21 Thread Jyri Sarha

On 09/21/15 12:37, Russell King - ARM Linux wrote:

On Fri, Sep 18, 2015 at 02:06:39PM +0300, Jyri Sarha wrote:

Add IEC958 channel status helper that gets the audio properties from
snd_pcm_hw_params instead of snd_pcm_runtime. This is needed to
produce the channel status bits already in audio stream configuration
phase.


What is the reason for doing this early?



After some thinking, there is no good reason. It makes the codec bit 
more complicated, but that is not a good reason. I'll change that and 
use the prepare callback.


This patch can be dropped.


ALSA documentation (which may be out of date) says that the hw_params
callback can be called multiple times during stream setup.  Do we want
to be repeatedly programming the HDMI infoframe with different settings,
potentially confusing the attached device, or would it be better to do
it slightly later (in the prepare callback) after the parameters have
been fully negotiated?



If it is possible that hw_params() can be called multiple times, at 
least it does not happen very often. I wonder if it would ever happen 
again after a successful hw_params() call. But there is no downside in 
using prepare callback. I was just too much following the way ASoC 
codecs usually do the thing by writing everything to iron as the 
callbacks come in.


Best regards,
Jyri




--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC v4 7/8] drm/i2c: tda998x: Register ASoC HDMI codec for audio functionality

2015-09-18 Thread Jyri Sarha
Register ASoC HDMI codec for audio functionality. This is an initial
ASoC audio implementation for tda998x driver and it does not use all
the features provided by hdmi-codec.

HDMI audio info-frame and audio stream header is generated by the ASoC
HDMI codec. The codec also applies constraints for available
sample-rates.

Implementation of audio_startup for hdmi_codec_ops would enable
tda998x driver to abort ongoing playback if the HDMI cable is
unplugged or re-plugged to a device without audio capability.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
 drivers/gpu/drm/i2c/Kconfig   |   1 +
 drivers/gpu/drm/i2c/tda998x_drv.c | 181 +++---
 include/drm/i2c/tda998x.h |   1 +
 3 files changed, 150 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i2c/Kconfig b/drivers/gpu/drm/i2c/Kconfig
index 22c7ed6..088f278 100644
--- a/drivers/gpu/drm/i2c/Kconfig
+++ b/drivers/gpu/drm/i2c/Kconfig
@@ -28,6 +28,7 @@ config DRM_I2C_SIL164
 config DRM_I2C_NXP_TDA998X
tristate "NXP Semiconductors TDA998X HDMI encoder"
default m if DRM_TILCDC
+   select SND_SOC_HDMI_CODEC if SND_SOC
help
  Support for NXP Semiconductors TDA998X HDMI encoders.
 
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 2fc6399..1a9bbf2 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -30,9 +31,9 @@
 
 #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
 
-struct tda998x_audio {
-   u8 ports[2];/* AP value */
-   u8 port_types[2];   /* AFMT_xxx */
+struct tda998x_audio_port {
+   u8 format;  /* AFMT_xxx */
+   u8 config;  /* AP value */
 };
 
 struct tda998x_priv {
@@ -49,11 +50,13 @@ struct tda998x_priv {
u8 vip_cntrl_2;
struct tda998x_audio_params audio_params;
 
+   struct platform_device *audio_pdev;
+
wait_queue_head_t wq_edid;
volatile int wq_edid_wait;
struct drm_encoder *encoder;
 
-   struct tda998x_audio audio;
+   struct tda998x_audio_port audio_port[2];
 };
 
 #define to_tda998x_priv(x)  ((struct tda998x_priv 
*)to_encoder_slave(x)->slave_priv)
@@ -701,7 +704,7 @@ tda998x_configure_audio(struct tda998x_priv *priv,
break;
 
default:
-   BUG();
+   dev_err(>hdmi->dev, "Unsupported I2S format\n");
return -EINVAL;
}
 
@@ -1028,7 +1031,7 @@ tda998x_encoder_mode_set(struct tda998x_priv *priv,
 
tda998x_write_avi(priv, adjusted_mode);
 
-   if (priv->audio_params.config) {
+   if (priv->audio_params.format != AFMT_UNUSED) {
tda998x_configure_audio(priv,
>audio_params,
adjusted_mode->clock);
@@ -1124,6 +1127,8 @@ tda998x_encoder_get_modes(struct tda998x_priv *priv,
drm_mode_connector_update_edid_property(connector, edid);
n = drm_add_edid_modes(connector, edid);
priv->is_hdmi_sink = drm_detect_hdmi_monitor(edid);
+   drm_edid_to_eld(connector, edid);
+
kfree(edid);
 
return n;
@@ -1160,6 +1165,9 @@ static void tda998x_destroy(struct tda998x_priv *priv)
}
 
i2c_unregister_device(priv->cec);
+
+   if (priv->audio_pdev)
+   platform_device_unregister(priv->audio_pdev);
 }
 
 /* Slave encoder support */
@@ -1234,6 +1242,133 @@ static struct drm_encoder_slave_funcs 
tda998x_encoder_slave_funcs = {
.set_property = tda998x_encoder_set_property,
 };
 
+static int tda998x_audio_hw_params(struct device *dev,
+  struct hdmi_codec_daifmt *daifmt,
+  struct hdmi_codec_params *params)
+{
+   struct tda998x_priv *priv = dev_get_drvdata(dev);
+   int i, ret;
+   struct tda998x_audio_params audio = {
+   .sample_width = params->sample_width,
+   .sample_rate = params->sample_rate,
+   .cea = params->cea,
+   };
+
+   if (!priv->encoder->crtc)
+   return -ENODEV;
+
+   memcpy(audio.status, params->iec.status,
+  min(sizeof(audio.status), sizeof(params->iec.status)));
+
+   switch (daifmt->fmt) {
+   case HDMI_I2S:
+   if (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-&

[PATCH RFC v4 3/8] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders

2015-09-18 Thread Jyri Sarha
The hdmi-codec is a platform device driver to be registered from
drivers of external HDMI encoders with I2S and/or spdif interface. The
driver in turn registers an ASoC codec for the HDMI encoder's audio
functionality.

The structures and definitions in the API header are mostly redundant
copies of similar structures in ASoC headers. This is on purpose to
avoid direct dependencies to ASoC structures in video side driver.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
 include/sound/hdmi-codec.h| 104 +++
 sound/soc/codecs/Kconfig  |   6 +
 sound/soc/codecs/Makefile |   2 +
 sound/soc/codecs/hdmi-codec.c | 404 ++
 4 files changed, 516 insertions(+)
 create mode 100644 include/sound/hdmi-codec.h
 create mode 100644 sound/soc/codecs/hdmi-codec.c

diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h
new file mode 100644
index 000..15fe70f
--- /dev/null
+++ b/include/sound/hdmi-codec.h
@@ -0,0 +1,104 @@
+/*
+ * hdmi-codec.h - HDMI Codec driver API
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Author: Jyri Sarha <jsa...@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef __HDMI_CODEC_H__
+#define __HDMI_CODEC_H__
+
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Protocol between ASoC cpu-dai and HDMI-encoder
+ */
+struct hdmi_codec_daifmt {
+   enum {
+   HDMI_I2S,
+   HDMI_RIGHT_J,
+   HDMI_LEFT_J,
+   HDMI_DSP_A,
+   HDMI_DSP_B,
+   HDMI_AC97,
+   HDMI_SPDIF,
+   } fmt;
+   int bit_clk_inv:1;
+   int frame_clk_inv:1;
+   int bit_clk_master:1;
+   int frame_clk_master:1;
+};
+
+/*
+ * HDMI audio parameters
+ */
+struct hdmi_codec_params {
+   struct hdmi_audio_infoframe cea;
+   struct snd_aes_iec958 iec;
+   int sample_rate;
+   int sample_width;
+   int channels;
+};
+
+struct hdmi_codec_ops {
+   /*
+* Called when ASoC starts an audio stream setup. The call
+* provides an audio abort callback for stoping an ongoing
+* stream from video side driver if the HDMI audio becomes
+* unavailable.
+* Optional
+*/
+   int (*audio_startup)(struct device *dev,
+void (*abort_cb)(struct device *dev));
+
+   /*
+* Configures HDMI-encoder for audio stream.
+* Mandatory
+*/
+   int (*hw_params)(struct device *dev,
+struct hdmi_codec_daifmt *fmt,
+struct hdmi_codec_params *hparms);
+
+   /*
+* Shuts down the audio stream.
+* Mandatory
+*/
+   void (*audio_shutdown)(struct device *dev);
+
+   /*
+* Mute/unmute HDMI audio stream.
+* Optional
+*/
+   int (*digital_mute)(struct device *dev, bool enable);
+
+   /*
+* Provides EDID-Like-Data from connected HDMI device.
+* Optional
+*/
+   int (*get_eld)(struct device *dev, uint8_t *buf, size_t len);
+};
+
+/* HDMI codec initalization data */
+struct hdmi_codec_pdata {
+   const struct hdmi_codec_ops *ops;
+   uint i2s:1;
+   uint spdif:1;
+   int max_i2s_channels;
+};
+
+#define HDMI_CODEC_DRV_NAME "hdmi-audio-codec"
+
+#endif /* __HDMI_CODEC_H__ */
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 0142396..1e6c7e7 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -79,6 +79,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_MAX9877 if I2C
select SND_SOC_MC13783 if MFD_MC13XXX
select SND_SOC_ML26124 if I2C
+   select SND_SOC_HDMI_CODEC
select SND_SOC_PCM1681 if I2C
select SND_SOC_PCM1792A if SPI_MASTER
select SND_SOC_PCM3008
@@ -441,6 +442,11 @@ config SND_SOC_BT_SCO
 config SND_SOC_DMIC
tristate
 
+config SND_SOC_HDMI_CODEC
+   tristate
+   select SND_PCM_ELD
+   select SND_PCM_IEC958
+
 config SND_SOC_ES8328
tristate "Everest Semi ES8328 CODEC"
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 7d7cc1b..068d483 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -72,6 +72,7 @@ snd-soc-max98925-objs := max98925.o
 snd-soc-max9850-objs := max9850.o
 snd-soc-mc13783-objs := mc13783.o
 snd-soc-ml26124-objs := ml26124.o
+snd-soc-hdmi-codec-objs := hdmi-codec.o
 snd-soc-pcm1681-objs := pcm1681.o
 snd-soc-pcm1792a-codec-objs := pcm1792a.o
 snd-soc-pcm3008-ob

[PATCH RFC v4 0/8] Implement generic ASoC HDMI codec and use it in tda998x

2015-09-18 Thread Jyri Sarha
Changes since RFC v3,
ASoC side:
- Add "ALSA: pcm: add IEC958 channel status helper for hw_params"
- Add "tda998x: Improve tda998x_configure_audio() audio related pdata"
- use snd_pcm_create_iec958_consumer_hw_params() to construct the stream header
- Remove set_clk() callback from hdmi-codec. It is not needed for now.
- Refer to stream header in AIF as specified in HDMI standard
- Set current_stream to NULL only after video side audio_shutdown() has
  been called. Avoid potential race if video side attempts to abort audio
  at the same time.
- No need to have video side device pointer in the hdmi codec's pdata as
  it is found from dev->parent.
- Fix hdmi-codec enum: DAI_ID_I2C > DAI_ID_I2S
- Improve audio_startup API comment
- Make improved checkpatch happy 
  - BUG_ON > WARN_ON
  - put */ ending the block comment to a separate line

DRM side:
- Fix tda998x get_eld() locking
- Change tda998x audio parameters in pdata to more generic, that can
  be readily used in tda998x_audio_config()
- Rename and restructure audio port related private data members to
  be more descriptive
- Require audio configuration trough ASoC hdmi-codec if HDMI audio is
  configured trough DT binding. 

DTS:
- Increase McASP fifo usage form 1 to 32

The binding for tda998x is taken from Jean Francois' patch series[1] on
the same subject. The implementation of the of-node parsing has some
minor changes from my self.

Here is what I think at least could or should still be done, but non of
that stuff does not sounds critical right now.
 
Missing from tda998x driver side
- hdmi_codec_ops audio_startup() implementation for audio abort support
- multi channel audio support (I would need specs and preferably some
  HW to test for this).

Missing from ASoC side generic implementation:
- channel_allocation handling is completely left for the video side driver,
  see if ASoC side could help in any way
- snd_soc_jack functionality to handle hdmi cable plug/unplug events

[1] http://mailman.alsa-project.org/pipermail/alsa-devel/2015-July/095596.html

Best regards,
Jyri

Jean-Francois Moine (1):
  drm/i2c: tda998x: Add support of a DT graph of ports

Jyri Sarha (7):
  ASoC: hdmi: Remove obsolete dummy HDMI codec
  ALSA: pcm: add IEC958 channel status helper for hw_params
  ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders
  drm/i2c: tda998x: Remove include/sound/tda998x.h and fix graph parsing
  drm/i2c: tda998x: Improve tda998x_configure_audio() audio related
pdata
  drm/i2c: tda998x: Register ASoC HDMI codec for audio functionality
  ARM: dts: am335x-boneblack: Add HDMI audio support

 .../devicetree/bindings/drm/i2c/tda998x.txt|  51 +++
 arch/arm/boot/dts/am335x-boneblack.dts |  90 -
 drivers/gpu/drm/armada/armada_drv.c|  25 +-
 drivers/gpu/drm/i2c/Kconfig|   1 +
 drivers/gpu/drm/i2c/tda998x_drv.c  | 319 +---
 include/drm/i2c/tda998x.h  |  24 +-
 include/sound/hdmi-codec.h | 104 ++
 include/sound/pcm_iec958.h |   2 +
 sound/core/pcm_iec958.c|  52 ++-
 sound/soc/codecs/Kconfig   |   4 +-
 sound/soc/codecs/Makefile  |   4 +-
 sound/soc/codecs/hdmi-codec.c  | 404 +
 sound/soc/codecs/hdmi.c| 109 --
 13 files changed, 985 insertions(+), 204 deletions(-)
 create mode 100644 include/sound/hdmi-codec.h
 create mode 100644 sound/soc/codecs/hdmi-codec.c
 delete mode 100644 sound/soc/codecs/hdmi.c

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC v4 1/8] ASoC: hdmi: Remove obsolete dummy HDMI codec

2015-09-18 Thread Jyri Sarha
The hdmi stub codec has not been used since refactoring of OMAP HDMI
audio support.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
 sound/soc/codecs/Kconfig  |   4 --
 sound/soc/codecs/Makefile |   2 -
 sound/soc/codecs/hdmi.c   | 109 --
 3 files changed, 115 deletions(-)
 delete mode 100644 sound/soc/codecs/hdmi.c

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 0c9733e..0142396 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -79,7 +79,6 @@ config SND_SOC_ALL_CODECS
select SND_SOC_MAX9877 if I2C
select SND_SOC_MC13783 if MFD_MC13XXX
select SND_SOC_ML26124 if I2C
-   select SND_SOC_HDMI_CODEC
select SND_SOC_PCM1681 if I2C
select SND_SOC_PCM1792A if SPI_MASTER
select SND_SOC_PCM3008
@@ -442,9 +441,6 @@ config SND_SOC_BT_SCO
 config SND_SOC_DMIC
tristate
 
-config SND_SOC_HDMI_CODEC
-   tristate "HDMI stub CODEC"
-
 config SND_SOC_ES8328
tristate "Everest Semi ES8328 CODEC"
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 4a32077..7d7cc1b 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -72,7 +72,6 @@ snd-soc-max98925-objs := max98925.o
 snd-soc-max9850-objs := max9850.o
 snd-soc-mc13783-objs := mc13783.o
 snd-soc-ml26124-objs := ml26124.o
-snd-soc-hdmi-codec-objs := hdmi.o
 snd-soc-pcm1681-objs := pcm1681.o
 snd-soc-pcm1792a-codec-objs := pcm1792a.o
 snd-soc-pcm3008-objs := pcm3008.o
@@ -264,7 +263,6 @@ obj-$(CONFIG_SND_SOC_MAX98925)  += snd-soc-max98925.o
 obj-$(CONFIG_SND_SOC_MAX9850)  += snd-soc-max9850.o
 obj-$(CONFIG_SND_SOC_MC13783)  += snd-soc-mc13783.o
 obj-$(CONFIG_SND_SOC_ML26124)  += snd-soc-ml26124.o
-obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o
 obj-$(CONFIG_SND_SOC_PCM1681)  += snd-soc-pcm1681.o
 obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o
 obj-$(CONFIG_SND_SOC_PCM3008)  += snd-soc-pcm3008.o
diff --git a/sound/soc/codecs/hdmi.c b/sound/soc/codecs/hdmi.c
deleted file mode 100644
index bd42ad3..000
--- a/sound/soc/codecs/hdmi.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * ALSA SoC codec driver for HDMI audio codecs.
- * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
- * Author: Ricardo Neri <ricardo.n...@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#include 
-#include 
-#include 
-#include 
-
-#define DRV_NAME "hdmi-audio-codec"
-
-static const struct snd_soc_dapm_widget hdmi_widgets[] = {
-   SND_SOC_DAPM_INPUT("RX"),
-   SND_SOC_DAPM_OUTPUT("TX"),
-};
-
-static const struct snd_soc_dapm_route hdmi_routes[] = {
-   { "Capture", NULL, "RX" },
-   { "TX", NULL, "Playback" },
-};
-
-static struct snd_soc_dai_driver hdmi_codec_dai = {
-   .name = "hdmi-hifi",
-   .playback = {
-   .stream_name = "Playback",
-   .channels_min = 2,
-   .channels_max = 8,
-   .rates = SNDRV_PCM_RATE_32000 |
-   SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
-   SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
-   SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
-   .formats = SNDRV_PCM_FMTBIT_S16_LE |
-   SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
-   .sig_bits = 24,
-   },
-   .capture = {
-   .stream_name = "Capture",
-   .channels_min = 2,
-   .channels_max = 2,
-   .rates = SNDRV_PCM_RATE_32000 |
-   SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
-   SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
-   SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
-   .formats = SNDRV_PCM_FMTBIT_S16_LE |
-   SNDRV_PCM_FMTBIT_S24_LE,
-   },
-
-};
-
-#ifdef CONFIG_OF
-static const struct of_device_id hdmi_audio_codec_ids[] = {
-   { .compatible = "linux,hdmi-audio", },
-   { }
-};
-MODULE_DEVICE_TABLE(of, hdmi_audio_codec_ids);
-#endif
-
-static struct snd_soc_codec_driver hdmi_codec = {
-   .dapm_widgets = hdmi_widgets,
-   .num_dapm_widgets = ARRAY_SIZE(hdmi_widge

[PATCH RFC v4 4/8] drm/i2c: tda998x: Add support of a DT graph of ports

2015-09-18 Thread Jyri Sarha
From: Jean-Francois Moine <moin...@free.fr>

Two kinds of ports may be declared in a DT graph of ports: video and audio.
This patch accepts the port value from a video port as an alternative
to the video-ports property.
It also accepts audio ports in the case the transmitter is not used as
a slave encoder.
The new file include/sound/tda998x.h prepares to the definition of
a tda998x CODEC.

Signed-off-by: Jean-Francois Moine <moin...@free.fr>
Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
 .../devicetree/bindings/drm/i2c/tda998x.txt| 51 
 drivers/gpu/drm/i2c/tda998x_drv.c  | 90 +++---
 include/sound/tda998x.h|  8 ++
 3 files changed, 140 insertions(+), 9 deletions(-)
 create mode 100644 include/sound/tda998x.h

diff --git a/Documentation/devicetree/bindings/drm/i2c/tda998x.txt 
b/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
index e9e4bce..35f6a80 100644
--- a/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
+++ b/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
@@ -16,6 +16,35 @@ Optional properties:
 
   - video-ports: 24 bits value which defines how the video controller
output is wired to the TDA998x input - default: <0x230145>
+   This property is not used when ports are defined.
+
+Optional nodes:
+
+  - port: up to three ports.
+   The ports are defined according to [1].
+
+Video port.
+   There may be only one video port.
+   This one must contain the following property:
+
+   - port-type: must be "rgb"
+
+   and may contain the optional property:
+
+   - reg: 24 bits value which defines how the video controller
+   output is wired to the TDA998x input (video pins)
+   When absent, the default value is <0x230145>.
+
+Audio ports.
+   There may be one or two audio ports.
+   These ones must contain the following properties:
+
+   - port-type: must be "i2s" or "spdif"
+
+   - reg: 8 bits value which defines how the audio controller
+   output is wired to the TDA998x input (audio pins)
+
+[1] Documentation/devicetree/bindings/graph.txt
 
 Example:
 
@@ -26,4 +55,26 @@ Example:
interrupts = <27 2>;/* falling edge */
pinctrl-0 = <_camera>;
pinctrl-names = "default";
+
+   port@230145 {
+   port-type = "rgb";
+   reg = <0x230145>;
+   hdmi_0: endpoint {
+   remote-endpoint = <_0>;
+   };
+   };
+   port@3 {/* AP1 = I2S */
+   port-type = "i2s";
+   reg = <0x03>;
+   tda998x_i2s: endpoint {
+   remote-endpoint = <_i2s>;
+   };
+   };
+   port@4 { /* AP2 = S/PDIF */
+   port-type = "spdif";
+   reg = <0x04>;
+   tda998x_spdif: endpoint {
+   remote-endpoint = <_spdif1>;
+   };
+   };
};
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 424228b..0952eac 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
 
@@ -47,6 +48,8 @@ struct tda998x_priv {
wait_queue_head_t wq_edid;
volatile int wq_edid_wait;
struct drm_encoder *encoder;
+
+   struct tda998x_audio audio;
 };
 
 #define to_tda998x_priv(x)  ((struct tda998x_priv 
*)to_encoder_slave(x)->slave_priv)
@@ -774,6 +777,8 @@ static void tda998x_encoder_set_config(struct tda998x_priv 
*priv,
(p->mirr_f ? VIP_CNTRL_2_MIRR_F : 0);
 
priv->params = *p;
+   priv->audio.port_types[0] = p->audio_format;
+   priv->audio.ports[0] = p->audio_cfg;
 }
 
 static void tda998x_encoder_dpms(struct tda998x_priv *priv, int mode)
@@ -1230,9 +1235,57 @@ static struct drm_encoder_slave_funcs 
tda998x_encoder_slave_funcs = {
 
 /* I2C driver functions */
 
+static int tda998x_parse_ports(struct tda998x_priv *priv,
+   struct device_node *np)
+{
+   struct device_node *of_port;
+   const char *port_type;
+   int ret, audio_index, reg, afmt;
+
+   audio_index = 0;
+   for_each_child_of_node(np, of_port) {
+   if (!of_port->name
+|| of_node_cmp(of_port->name, "port") != 0)
+   continue;
+   ret = of_property_read_s

[PATCH RFC v4 2/8] ALSA: pcm: add IEC958 channel status helper for hw_params

2015-09-18 Thread Jyri Sarha
Add IEC958 channel status helper that gets the audio properties from
snd_pcm_hw_params instead of snd_pcm_runtime. This is needed to
produce the channel status bits already in audio stream configuration
phase.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
 include/sound/pcm_iec958.h |  2 ++
 sound/core/pcm_iec958.c| 52 +++---
 2 files changed, 37 insertions(+), 17 deletions(-)

diff --git a/include/sound/pcm_iec958.h b/include/sound/pcm_iec958.h
index 0eed397..36f023a 100644
--- a/include/sound/pcm_iec958.h
+++ b/include/sound/pcm_iec958.h
@@ -6,4 +6,6 @@
 int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
size_t len);
 
+int snd_pcm_create_iec958_consumer_hw_params(struct snd_pcm_hw_params *params,
+u8 *cs, size_t len);
 #endif
diff --git a/sound/core/pcm_iec958.c b/sound/core/pcm_iec958.c
index 36b2d7a..c9f8b66 100644
--- a/sound/core/pcm_iec958.c
+++ b/sound/core/pcm_iec958.c
@@ -9,30 +9,18 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
-/**
- * snd_pcm_create_iec958_consumer - create consumer format IEC958 channel 
status
- * @runtime: pcm runtime structure with ->rate filled in
- * @cs: channel status buffer, at least four bytes
- * @len: length of channel status buffer
- *
- * Create the consumer format channel status data in @cs of maximum size
- * @len corresponding to the parameters of the PCM runtime @runtime.
- *
- * Drivers may wish to tweak the contents of the buffer after creation.
- *
- * Returns: length of buffer, or negative error code if something failed.
- */
-int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
-   size_t len)
+static int create_iec958_consumer(uint rate, uint sample_width,
+ u8 *cs, size_t len)
 {
unsigned int fs, ws;
 
if (len < 4)
return -EINVAL;
 
-   switch (runtime->rate) {
+   switch (rate) {
case 32000:
fs = IEC958_AES3_CON_FS_32000;
break;
@@ -59,7 +47,7 @@ int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime 
*runtime, u8 *cs,
}
 
if (len > 4) {
-   switch (snd_pcm_format_width(runtime->format)) {
+   switch (sample_width) {
case 16:
ws = IEC958_AES4_CON_WORDLEN_20_16;
break;
@@ -92,4 +80,34 @@ int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime 
*runtime, u8 *cs,
 
return len;
 }
+
+/**
+ * snd_pcm_create_iec958_consumer - create consumer format IEC958 channel 
status
+ * @runtime: pcm runtime structure with ->rate filled in
+ * @cs: channel status buffer, at least four bytes
+ * @len: length of channel status buffer
+ *
+ * Create the consumer format channel status data in @cs of maximum size
+ * @len corresponding to the parameters of the PCM runtime @runtime.
+ *
+ * Drivers may wish to tweak the contents of the buffer after creation.
+ *
+ * Returns: length of buffer, or negative error code if something failed.
+ */
+int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
+   size_t len)
+{
+   return create_iec958_consumer(runtime->rate,
+ snd_pcm_format_width(runtime->format),
+ cs, len);
+}
 EXPORT_SYMBOL(snd_pcm_create_iec958_consumer);
+
+
+int snd_pcm_create_iec958_consumer_hw_params(struct snd_pcm_hw_params *params,
+u8 *cs, size_t len)
+{
+   return create_iec958_consumer(params_rate(params), params_width(params),
+ cs, len);
+}
+EXPORT_SYMBOL(snd_pcm_create_iec958_consumer_hw_params);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC v4 5/8] drm/i2c: tda998x: Remove include/sound/tda998x.h and fix graph parsing

2015-09-18 Thread Jyri Sarha
Move struct tda998x_audio definition to tda998x_drv.c and remove
include/sound/tda998x.h. There is no external use for struct
tda998x_audio.

Fix graph parsing to allow ports to be inside a separate "ports"-node as
specified in Documentation/devicetree/bindings/graph.txt.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 59 +--
 include/sound/tda998x.h   |  8 --
 2 files changed, 32 insertions(+), 35 deletions(-)
 delete mode 100644 include/sound/tda998x.h

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 0952eac..4dc2dc0 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -27,10 +27,14 @@
 #include 
 #include 
 #include 
-#include 
 
 #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
 
+struct tda998x_audio {
+   u8 ports[2];/* AP value */
+   u8 port_types[2];   /* AFMT_xxx */
+};
+
 struct tda998x_priv {
struct i2c_client *cec;
struct i2c_client *hdmi;
@@ -1240,9 +1244,10 @@ static int tda998x_parse_ports(struct tda998x_priv *priv,
 {
struct device_node *of_port;
const char *port_type;
-   int ret, audio_index, reg, afmt;
+   int ret, audio_index, reg, afmt, rgb_initialized;
 
audio_index = 0;
+   rgb_initialized = 0;
for_each_child_of_node(np, of_port) {
if (!of_port->name
 || of_node_cmp(of_port->name, "port") != 0)
@@ -1252,11 +1257,17 @@ static int tda998x_parse_ports(struct tda998x_priv 
*priv,
if (ret < 0)
continue;
ret = of_property_read_u32(of_port, "reg", );
+   if (ret < 0) {
+   dev_err(>hdmi->dev, "missing reg for %s\n",
+   port_type);
+   return ret;
+   }
if (strcmp(port_type, "rgb") == 0) {
if (!ret) { /* video reg is optional */
priv->vip_cntrl_0 = reg >> 16;
priv->vip_cntrl_1 = reg >> 8;
priv->vip_cntrl_2 = reg;
+   rgb_initialized = 1;
}
continue;
}
@@ -1266,11 +1277,6 @@ static int tda998x_parse_ports(struct tda998x_priv *priv,
afmt = AFMT_SPDIF;
else
continue;
-   if (ret < 0) {
-   dev_err(>hdmi->dev, "missing reg for %s\n",
-   port_type);
-   return ret;
-   }
if (audio_index >= ARRAY_SIZE(priv->audio.ports)) {
dev_err(>hdmi->dev, "too many audio ports\n");
break;
@@ -1279,13 +1285,13 @@ static int tda998x_parse_ports(struct tda998x_priv 
*priv,
priv->audio.port_types[audio_index] = afmt;
audio_index++;
}
-   return 0;
+   return rgb_initialized;
 }
 
 static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
 {
struct device_node *np = client->dev.of_node;
-   struct device_node *of_port;
+   struct device_node *ports;
u32 video;
int rev_lo, rev_hi, ret;
unsigned short cec_addr;
@@ -1392,24 +1398,15 @@ static int tda998x_create(struct i2c_client *client, 
struct tda998x_priv *priv)
 
/* get the device tree parameters */
if (np) {
-   of_port = of_get_child_by_name(np, "port");
-   if (of_port) {  /* graph of ports */
-   of_node_put(of_port);
-   ret = tda998x_parse_ports(priv, np);
-   if (ret < 0)
-   goto fail;
-
-   /* initialize the default audio configuration */
-   if (priv->audio.ports[0]) {
-   priv->params.audio_cfg = priv->audio.ports[0];
-   priv->params.audio_format =
-   priv->audio.port_types[0];
-   priv->params.audio_clk_cfg =
-   priv->params.audio_format ==
-   AFMT_SPDIF ? 0 : 1;
-   }
-   } else {
-
+   ports = of_get_child_by_name(np, "ports");
+   if (!ports)
+   ports = of_node_get(np);
+   /* graph of ports */
+   ret = tda998x_parse_ports(pr

[PATCH RFC v4 6/8] drm/i2c: tda998x: Improve tda998x_configure_audio() audio related pdata

2015-09-18 Thread Jyri Sarha
Declare struct tda998x_audio_params in include/drm/i2c/tda998x.h and
use it in pdata and for tda998x_configure_audio() parameters. Also updates
tda998x_write_aif() to use hdmi_audio_infoframe_pack() and friends.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
 drivers/gpu/drm/armada/armada_drv.c |  25 ++--
 drivers/gpu/drm/i2c/tda998x_drv.c   | 123 
 include/drm/i2c/tda998x.h   |  23 ---
 3 files changed, 102 insertions(+), 69 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_drv.c 
b/drivers/gpu/drm/armada/armada_drv.c
index 225034b..d500840 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -20,6 +20,7 @@
 
 #ifdef CONFIG_DRM_ARMADA_TDA1998X
 #include 
+#include 
 #include "armada_slave.h"
 
 static struct tda998x_encoder_params params = {
@@ -35,10 +36,26 @@ static struct tda998x_encoder_params params = {
.swap_d = 5,
.swap_e = 0,
.swap_f = 1,
-   .audio_cfg = BIT(2),
-   .audio_frame[1] = 1,
-   .audio_format = AFMT_SPDIF,
-   .audio_sample_rate = 44100,
+   .audio = {
+   .config = BIT(2),
+   .format = AFMT_SPDIF,
+   .sample_width = 24,
+   .sample_rate = 44100,
+   .cea = {
+   .channels = 2,
+   .coding_type = HDMI_AUDIO_CODING_TYPE_STREAM,
+   .sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM,
+   .sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM,
+   },
+   .status = {
+   IEC958_AES0_CON_NOT_COPYRIGHT,
+   IEC958_AES1_CON_GENERAL,
+   IEC958_AES2_CON_SOURCE_UNSPEC |
+   IEC958_AES2_CON_CHANNEL_UNSPEC,
+   IEC958_AES3_CON_CLOCK_1000PPM |
+   IEC958_AES3_CON_FS_NOTID,
+   },
+   }
 };
 
 static const struct armada_drm_slave_config tda19988_config = {
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 4dc2dc0..2fc6399 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -47,7 +47,7 @@ struct tda998x_priv {
u8 vip_cntrl_0;
u8 vip_cntrl_1;
u8 vip_cntrl_2;
-   struct tda998x_encoder_params params;
+   struct tda998x_audio_params audio_params;
 
wait_queue_head_t wq_edid;
volatile int wq_edid_wait;
@@ -597,15 +597,6 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data)
return IRQ_HANDLED;
 }
 
-static uint8_t tda998x_cksum(uint8_t *buf, size_t bytes)
-{
-   int sum = 0;
-
-   while (bytes--)
-   sum -= *buf++;
-   return sum;
-}
-
 #define HB(x) (x)
 #define PB(x) (HB(2) + 1 + (x))
 
@@ -618,24 +609,22 @@ tda998x_write_if(struct tda998x_priv *priv, uint8_t bit, 
uint16_t addr,
reg_set(priv, REG_DIP_IF_FLAGS, bit);
 }
 
-static void
-tda998x_write_aif(struct tda998x_priv *priv, struct tda998x_encoder_params *p)
+static int tda998x_write_aif(struct tda998x_priv *priv,
+struct hdmi_audio_infoframe *cea)
 {
-   u8 buf[PB(HDMI_AUDIO_INFOFRAME_SIZE) + 1];
-
-   memset(buf, 0, sizeof(buf));
-   buf[HB(0)] = HDMI_INFOFRAME_TYPE_AUDIO;
-   buf[HB(1)] = 0x01;
-   buf[HB(2)] = HDMI_AUDIO_INFOFRAME_SIZE;
-   buf[PB(1)] = p->audio_frame[1] & 0x07; /* CC */
-   buf[PB(2)] = p->audio_frame[2] & 0x1c; /* SF */
-   buf[PB(4)] = p->audio_frame[4];
-   buf[PB(5)] = p->audio_frame[5] & 0xf8; /* DM_INH + LSV */
+   uint8_t buf[HDMI_INFOFRAME_SIZE(AUDIO)];
+   int len;
 
-   buf[PB(0)] = tda998x_cksum(buf, sizeof(buf));
+   len = hdmi_audio_infoframe_pack(cea, buf, sizeof(buf));
+   if (len < 0) {
+   dev_err(>hdmi->dev,
+   "Failed to pack audio infoframe: %d\n", len);
+   return len;
+   }
 
-   tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf,
-sizeof(buf));
+   /* Write the audio information packet */
+   tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf, len);
+   return 0;
 }
 
 static void
@@ -670,19 +659,20 @@ static void tda998x_audio_mute(struct tda998x_priv *priv, 
bool on)
}
 }
 
-static void
+static int
 tda998x_configure_audio(struct tda998x_priv *priv,
-   struct drm_display_mode *mode, struct tda998x_encoder_params *p)
+   struct tda998x_audio_params *params,
+   unsigned mode_clock)
 {
uint8_t buf[6], clksel_aip, clksel_fs, cts_n, adiv;
uint32_t n;
 
/* Enable audio ports */
-   reg_write(priv, REG_ENA_AP, p->audio_cfg);
-   reg_write(priv, REG_ENA_ACLK, p->audio_clk_cfg);
+   reg_write(priv, REG_ENA_AP, params->config);
+   reg_write(priv, REG_ENA

[PATCH RFC v4 8/8] ARM: dts: am335x-boneblack: Add HDMI audio support

2015-09-18 Thread Jyri Sarha
Add HDMI audio support. Adds mcasp0_pins, clk_mcasp0_fixed,
clk_mcasp0, mcasp0, sound node, and updates the tda19988 node to
follow the new binding.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
 arch/arm/boot/dts/am335x-boneblack.dts | 90 --
 1 file changed, 86 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/am335x-boneblack.dts 
b/arch/arm/boot/dts/am335x-boneblack.dts
index eadbba3..05347dc 100644
--- a/arch/arm/boot/dts/am335x-boneblack.dts
+++ b/arch/arm/boot/dts/am335x-boneblack.dts
@@ -64,6 +64,16 @@
0x1b0 0x03  /* xdma_event_intr0, OMAP_MUX_MODE3 | 
AM33XX_PIN_OUTPUT */
>;
};
+
+   mcasp0_pins: mcasp0_pins {
+   pinctrl-single,pins = <
+   0x1ac (PIN_INPUT_PULLUP | MUX_MODE0)/* 
mcasp0_ahclkx.mcasp0_ahclkx */
+   0x19c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* 
mcasp0_ahclkr.mcasp0_axr2 */
+   0x194 (PIN_OUTPUT_PULLUP | MUX_MODE0)   /* 
mcasp0_fsx.mcasp0_fsx */
+   0x190 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* 
mcasp0_aclkx.mcasp0_aclkx */
+   0x06c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* 
gpmc_a11.GPIO1_27 */
+   >;
+   };
 };
 
  {
@@ -76,17 +86,89 @@
 };
 
  {
-   tda19988 {
+   tda19988: tda19988 {
compatible = "nxp,tda998x";
reg = <0x70>;
+
+   #sound-dai-cells = <0>;
+
pinctrl-names = "default", "off";
pinctrl-0 = <_hdmi_bonelt_pins>;
pinctrl-1 = <_hdmi_bonelt_off_pins>;
 
-   port {
-   hdmi_0: endpoint@0 {
-   remote-endpoint = <_0>;
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   port@0 {
+   port-type = "rgb";
+   reg = <0x230145>;
+   hdmi_0: endpoint@0 {
+   remote-endpoint = <_0>;
+   };
};
+   port@1 {
+   port-type = "i2s";
+   reg = <0x03>;
+   tda19988_i2s: endpoint {
+   remote-endpoint = <_i2s>;
+   };
+   };
+   };
+   };
+};
+
+ {
+   system-power-controller;
+};
+
+{
+   #sound-dai-cells = <0>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "okay";
+   op-mode = <0>;  /* MCASP_IIS_MODE */
+   tdm-slots = <2>;
+   serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
+   0 0 1 0
+   >;
+   tx-num-evt = <32>;
+   rx-num-evt = <32>;
+
+   port {
+   mcasp0_i2s: endpoint {
+   remote-endpoint = <_i2s>;
+   };
+   };
+};
+
+/ {
+   clk_mcasp0_fixed: clk_mcasp0_fixed {
+   #clock-cells = <0>;
+   compatible = "fixed-clock";
+   clock-frequency = <24576000>;
+   };
+
+   clk_mcasp0: clk_mcasp0 {
+   #clock-cells = <0>;
+   compatible = "gpio-gate-clock";
+   clocks = <_mcasp0_fixed>;
+   enable-gpios = < 27 0>; /* BeagleBone Black Clk enable on 
GPIO1_27 */
+   };
+
+   sound {
+   compatible = "simple-audio-card";
+   simple-audio-card,name = "TI BeagleBone Black";
+   simple-audio-card,format = "i2s";
+   simple-audio-card,bitclock-master = <_master>;
+   simple-audio-card,frame-master = <_master>;
+
+   dailink0_master: simple-audio-card,cpu {
+   sound-dai = <>;
+   clocks = <_mcasp0>;
+   };
+
+   simple-audio-card,codec {
+   sound-dai = <>;
};
};
 };
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] ASoC: davinci-mcasp: Get rid of bclk_lrclk_ratio in private data

2015-09-17 Thread Jyri Sarha
The slot_width is for essentially same thing. Instead of storing
bclk_lrclk_ratio, just store the slot_width. Comments has been updated
accordingly and some variable names changed to more descriptive.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
Added the missing __func__ to dev_warn() warn call in
__davinci_mcasp_set_clkdiv().

 sound/soc/davinci/davinci-mcasp.c | 56 ++-
 1 file changed, 31 insertions(+), 25 deletions(-)

diff --git a/sound/soc/davinci/davinci-mcasp.c 
b/sound/soc/davinci/davinci-mcasp.c
index de1e3a8..9a9d633 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -87,7 +87,6 @@ struct davinci_mcasp {
u8  *serial_dir;
u8  version;
u8  bclk_div;
-   u16 bclk_lrclk_ratio;
int streams;
u32 irq_request[2];
int dma_request[2];
@@ -558,8 +557,21 @@ static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai 
*dai, int div_id,
mcasp->bclk_div = div;
break;
 
-   case 2: /* BCLK/LRCLK ratio */
-   mcasp->bclk_lrclk_ratio = div;
+   case 2: /*
+* BCLK/LRCLK ratio descries how many bit-clock cycles
+* fit into one frame. The clock ratio is given for a
+* full period of data (for I2S format both left and
+* right channels), so it has to be divided by number
+* of tdm-slots (for I2S - divided by 2).
+* Instead of storing this ratio, we calculate a new
+* tdm_slot width by dividing the the ratio by the
+* number of configured tdm slots.
+*/
+   mcasp->slot_width = div / mcasp->tdm_slots;
+   if (div % mcasp->tdm_slots)
+   dev_warn(mcasp->dev,
+"%s(): BCLK/LRCLK %d is not divisible by %d 
tdm slots",
+__func__, div, mcasp->tdm_slots);
break;
 
default:
@@ -682,11 +694,13 @@ static int davinci_mcasp_set_tdm_slot(struct snd_soc_dai 
*dai,
 }
 
 static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
-  int word_length)
+  int sample_width)
 {
u32 fmt;
-   u32 tx_rotate = (word_length / 4) & 0x7;
-   u32 mask = (1ULL << word_length) - 1;
+   u32 tx_rotate = (sample_width / 4) & 0x7;
+   u32 mask = (1ULL << sample_width) - 1;
+   u32 slot_width = sample_width;
+
/*
 * For captured data we should not rotate, inversion and masking is
 * enoguh to get the data to the right position:
@@ -699,31 +713,23 @@ static int davinci_config_channel_size(struct 
davinci_mcasp *mcasp,
u32 rx_rotate = 0;
 
/*
-* if s BCLK-to-LRCLK ratio has been configured via the set_clkdiv()
-* callback, take it into account here. That allows us to for example
-* send 32 bits per channel to the codec, while only 16 of them carry
-* audio payload.
-* The clock ratio is given for a full period of data (for I2S format
-* both left and right channels), so it has to be divided by number of
-* tdm-slots (for I2S - divided by 2).
+* Setting the tdm slot width either with set_clkdiv() or
+* set_tdm_slot() allows us to for example send 32 bits per
+* channel to the codec, while only 16 of them carry audio
+* payload.
 */
-   if (mcasp->bclk_lrclk_ratio) {
-   u32 slot_length = mcasp->bclk_lrclk_ratio / mcasp->tdm_slots;
-
+   if (mcasp->slot_width) {
/*
-* When we have more bclk then it is needed for the data, we
-* need to use the rotation to move the received samples to have
-* correct alignment.
+* When we have more bclk then it is needed for the
+* data, we need to use the rotation to move the
+* received samples to have correct alignment.
 */
-   rx_rotate = (slot_length - word_length) / 4;
-   word_length = slot_length;
-   } else if (mcasp->slot_width) {
-   rx_rotate = (mcasp->slot_width - word_length) / 4;
-   word_length = mcasp->slot_width;
+   slot_width = mcasp->slot_width;
+   rx_rotate = (slot_width - sample_width) / 4;
}
 
/* mapping of the XSSZ bit-field as described in the datasheet */
-   fmt = (word_length >> 1) - 1;
+   fmt = (slot_width >> 1) - 1;
 
if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) {
mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXSSZ(fmt),
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsub

[PATCH] ASoC: soc-core: Fix sparse warning in be32_to_cpup() call

2015-09-17 Thread Jyri Sarha
Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
 sound/soc/soc-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 1929f0e..614b831 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3301,7 +3301,7 @@ static int snd_soc_of_get_slot_mask(struct device_node 
*np,
return 0;
val /= sizeof(u32);
for (i = 0; i < val; i++)
-   if (be32_to_cpup(_slot_mask[i]))
+   if (be32_to_cpup((__be32 *)_slot_mask[i]))
*mask |= (1 << i);
 
return val;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3] ASoC: soc-core: Fix sparse warning in be32_to_cpup() call

2015-09-17 Thread Jyri Sarha
Store return value of of_get_property() to a pointer of __be32 type as
device tree has big endian type. This fixes a sparse warning couple of
lines later when be32_to_cpup() is used to convert from big endian to
cpu endian.

The whole conversion is not really necessary, as we are only checking
if the value is zero or not, but I wanted to add it to remind in the
future that the data has to be converted before use. Compiler should
optimize the unnecessary operations away.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
Damn, I wrote description ready but forgot to produce the patch again.
So here is a v3 of the same one liner patch.

 sound/soc/soc-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 1929f0e..af4999c 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3294,7 +3294,7 @@ static int snd_soc_of_get_slot_mask(struct device_node 
*np,
unsigned int *mask)
 {
u32 val;
-   const u32 *of_slot_mask = of_get_property(np, prop_name, );
+   const __be32 *of_slot_mask = of_get_property(np, prop_name, );
int i;
 
if (!of_slot_mask)
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] ASoC: soc-core: Fix sparse warning in be32_to_cpup() call

2015-09-17 Thread Jyri Sarha

On 09/17/15 12:22, Mark Brown wrote:

On Thu, Sep 17, 2015 at 11:02:57AM +0300, Jyri Sarha wrote:


val /= sizeof(u32);
for (i = 0; i < val; i++)
-   if (be32_to_cpup(_slot_mask[i]))
+   if (be32_to_cpup((__be32 *)_slot_mask[i]))
*mask |= (1 << i);



There was no changelog and this is setting off alarm bells since the
cast just smashes warnings - are you sure we're not missing some other
annotations and that a cast is the best thing here?



You are right, I was a bit hasty. It is better to declare of_slot_mask 
to const __be32 * in the first place, instead of just const u32 * and 
then casting it to something else.


I'll send a new patch shortly.

BR,
Jyri
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] ASoC: soc-core: Fix sparse warning in be32_to_cpup() call

2015-09-17 Thread Jyri Sarha
Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
 sound/soc/soc-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 1929f0e..af4999c 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3294,7 +3294,7 @@ static int snd_soc_of_get_slot_mask(struct device_node 
*np,
unsigned int *mask)
 {
u32 val;
-   const u32 *of_slot_mask = of_get_property(np, prop_name, );
+   const __be32 *of_slot_mask = of_get_property(np, prop_name, );
int i;
 
if (!of_slot_mask)
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC] ASoC: simple-card: Update clocks binding for simple-card DAI subnodes

2015-09-11 Thread Jyri Sarha
The updated binding provides a way to set clock-ID and direction
parameters for DAI drivers set_sysclk() call back.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
I proposed something similar about a year ago, but Mark rejected that
at the time. This RFC is to start that discussion again. This time
before I do any code changes.

Best regards,
Jyri

 Documentation/devicetree/bindings/sound/simple-card.txt | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt 
b/Documentation/devicetree/bindings/sound/simple-card.txt
index cf3979e..d10bf2d 100644
--- a/Documentation/devicetree/bindings/sound/simple-card.txt
+++ b/Documentation/devicetree/bindings/sound/simple-card.txt
@@ -76,6 +76,7 @@ Optional CPU/CODEC subnodes properties:
 - dai-tdm-slot-num : Please refer to tdm-slot.txt.
 - dai-tdm-slot-width   : Please refer to tdm-slot.txt.
 - clocks / system-clock-frequency  : specify subnode's clock if needed.
+
  it can be specified via "clocks" if 
system has
  clock node (= common clock), or 
"system-clock-frequency"
  (if system doens't support common 
clock)
@@ -83,7 +84,21 @@ Optional CPU/CODEC subnodes properties:
  enabled with clk_prepare_enable()
  in dai startup() and disabled with
  clk_disable_unprepare() in dai
- shutdown().
+ shutdown(). "system-clock-frequency" 
+ can also be an array if more than one
+ clock is described.
+- clock-ids: An array of clock ID integers,
+ preferrably defined in DT header.
+ Each entry corresponds to the same
+ index postion first in "clocks" and
+ after the end of clocks array to
+ "system-clock-frequency" array.
+- clock-dirs   : An array of integers describing
+ clock directions: CLK_IN (= 0) or
+ OUT (= 1). Entries in the array
+ refer to clocks in the same way as
+ in clock-ids property.
+
 
 Example 1 - single DAI link:
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC 4/5] ASoC: davinci-mcasp: Get rid of bclk_lrclk_ratio in private data

2015-09-10 Thread Jyri Sarha

On 09/09/15 21:27, Jyri Sarha wrote:

The slot_width is for essentially same thing. Instead of storing
bclk_lrclk_ratio, just store the slot_width. Comments has been updated
accordingly and some variable names changed to more descriptive.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
  sound/soc/davinci/davinci-mcasp.c | 56 ++-
  1 file changed, 31 insertions(+), 25 deletions(-)

diff --git a/sound/soc/davinci/davinci-mcasp.c 
b/sound/soc/davinci/davinci-mcasp.c
index de1e3a8..25ff1fc 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -87,7 +87,6 @@ struct davinci_mcasp {
u8  *serial_dir;
u8  version;
u8  bclk_div;
-   u16 bclk_lrclk_ratio;
int streams;
u32 irq_request[2];
int dma_request[2];
@@ -558,8 +557,21 @@ static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai 
*dai, int div_id,
mcasp->bclk_div = div;
break;

-   case 2: /* BCLK/LRCLK ratio */
-   mcasp->bclk_lrclk_ratio = div;
+   case 2: /*
+* BCLK/LRCLK ratio descries how many bit-clock cycles
+* fit into one frame. The clock ratio is given for a
+* full period of data (for I2S format both left and
+* right channels), so it has to be divided by number
+* of tdm-slots (for I2S - divided by 2).
+* Instead of storing this ratio, we calculate a new
+* tdm_slot width by dividing the the ratio by the
+* number of configured tdm slots.
+*/
+   mcasp->slot_width = div / mcasp->tdm_slots;
+   if (div % mcasp->tdm_slots)
+   dev_warn(mcasp->dev,
+"%s(): BCLK/LRCLK %d is not divisible by %d tdm 
slots",
+div, mcasp->tdm_slots);


Oops, there is a __func__ missing here.


break;

default:
@@ -682,11 +694,13 @@ static int davinci_mcasp_set_tdm_slot(struct snd_soc_dai 
*dai,
  }

  static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
-  int word_length)
+  int sample_width)
  {
u32 fmt;
-   u32 tx_rotate = (word_length / 4) & 0x7;
-   u32 mask = (1ULL << word_length) - 1;
+   u32 tx_rotate = (sample_width / 4) & 0x7;
+   u32 mask = (1ULL << sample_width) - 1;
+   u32 slot_width = sample_width;
+
/*
 * For captured data we should not rotate, inversion and masking is
 * enoguh to get the data to the right position:
@@ -699,31 +713,23 @@ static int davinci_config_channel_size(struct 
davinci_mcasp *mcasp,
u32 rx_rotate = 0;

/*
-* if s BCLK-to-LRCLK ratio has been configured via the set_clkdiv()
-* callback, take it into account here. That allows us to for example
-* send 32 bits per channel to the codec, while only 16 of them carry
-* audio payload.
-* The clock ratio is given for a full period of data (for I2S format
-* both left and right channels), so it has to be divided by number of
-* tdm-slots (for I2S - divided by 2).
+* Setting the tdm slot width either with set_clkdiv() or
+* set_tdm_slot() allows us to for example send 32 bits per
+* channel to the codec, while only 16 of them carry audio
+* payload.
 */
-   if (mcasp->bclk_lrclk_ratio) {
-   u32 slot_length = mcasp->bclk_lrclk_ratio / mcasp->tdm_slots;
-
+   if (mcasp->slot_width) {
/*
-* When we have more bclk then it is needed for the data, we
-* need to use the rotation to move the received samples to have
-* correct alignment.
+* When we have more bclk then it is needed for the
+* data, we need to use the rotation to move the
+* received samples to have correct alignment.
 */
-   rx_rotate = (slot_length - word_length) / 4;
-   word_length = slot_length;
-   } else if (mcasp->slot_width) {
-   rx_rotate = (mcasp->slot_width - word_length) / 4;
-   word_length = mcasp->slot_width;
+   slot_width = mcasp->slot_width;
+   rx_rotate = (slot_width - sample_width) / 4;
}

/* mapping of the XSSZ bit-field as described in the datasheet */
-   fmt = (word_length >> 1) - 1;
+   fmt = (slot_width >> 1) - 1;

if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) {
mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXSSZ(fmt),



--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
t

[PATCH RFC 3/5] ASoC: davinci-mcasp: Add set_tdm_slots() support

2015-09-09 Thread Jyri Sarha
Implements set_tdm_slot() callback for mcasp. Channel constraints are
updated according to the configured tdm mask and slots each time
set_tdm_slot() is called. The special case when slot width is set to
zero is allowed and it means that slot width is the same as the sample
width.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
 sound/soc/davinci/davinci-mcasp.c | 255 ++
 1 file changed, 174 insertions(+), 81 deletions(-)

diff --git a/sound/soc/davinci/davinci-mcasp.c 
b/sound/soc/davinci/davinci-mcasp.c
index bbd1987..de1e3a8 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -80,6 +80,8 @@ struct davinci_mcasp {
 
/* McASP specific data */
int tdm_slots;
+   u32 tdm_mask[2];
+   int slot_width;
u8  op_mode;
u8  num_serializer;
u8  *serial_dir;
@@ -601,6 +603,84 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai 
*dai, int clk_id,
return 0;
 }
 
+/* All serializers must have equal number of channels */
+static int davinci_mcasp_ch_constraint(struct davinci_mcasp *mcasp, int stream,
+  int serializers)
+{
+   struct snd_pcm_hw_constraint_list *cl = >chconstr[stream];
+   unsigned int *list = (unsigned int *) cl->list;
+   int slots = mcasp->tdm_slots;
+   int i, count = 0;
+
+   if (mcasp->tdm_mask[stream])
+   slots = hweight32(mcasp->tdm_mask[stream]);
+
+   for (i = 2; i <= slots; i++)
+   list[count++] = i;
+
+   for (i = 2; i <= serializers; i++)
+   list[count++] = i*slots;
+
+   cl->count = count;
+
+   return 0;
+}
+
+static int davinci_mcasp_set_ch_constraints(struct davinci_mcasp *mcasp)
+{
+   int rx_serializers = 0, tx_serializers = 0, ret, i;
+
+   for (i = 0; i < mcasp->num_serializer; i++)
+   if (mcasp->serial_dir[i] == TX_MODE)
+   tx_serializers++;
+   else if (mcasp->serial_dir[i] == RX_MODE)
+   rx_serializers++;
+
+   ret = davinci_mcasp_ch_constraint(mcasp, SNDRV_PCM_STREAM_PLAYBACK,
+ tx_serializers);
+   if (ret)
+   return ret;
+
+   ret = davinci_mcasp_ch_constraint(mcasp, SNDRV_PCM_STREAM_CAPTURE,
+ rx_serializers);
+
+   return ret;
+}
+
+
+static int davinci_mcasp_set_tdm_slot(struct snd_soc_dai *dai,
+ unsigned int tx_mask,
+ unsigned int rx_mask,
+ int slots, int slot_width)
+{
+   struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
+
+   dev_dbg(mcasp->dev,
+"%s() tx_mask 0x%08x rx_mask 0x%08x slots %d width %d\n",
+__func__, tx_mask, rx_mask, slots, slot_width);
+
+   if (tx_mask >= (1<<slots) || rx_mask >= (1<<slots)) {
+   dev_err(mcasp->dev,
+   "Bad tdm mask tx: 0x%08x rx: 0x%08x slots %d\n",
+   tx_mask, rx_mask, slots);
+   return -EINVAL;
+   }
+
+   if (slot_width &&
+   (slot_width < 8 || slot_width > 32 || slot_width % 4 != 0)) {
+   dev_err(mcasp->dev, "%s: Unsupported slot_width %d\n",
+   __func__, slot_width);
+   return -EINVAL;
+   }
+
+   mcasp->tdm_slots = slots;
+   mcasp->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = rx_mask;
+   mcasp->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = tx_mask;
+   mcasp->slot_width = slot_width;
+
+   return davinci_mcasp_set_ch_constraints(mcasp);
+}
+
 static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
   int word_length)
 {
@@ -637,6 +717,9 @@ static int davinci_config_channel_size(struct davinci_mcasp 
*mcasp,
 */
rx_rotate = (slot_length - word_length) / 4;
word_length = slot_length;
+   } else if (mcasp->slot_width) {
+   rx_rotate = (mcasp->slot_width - word_length) / 4;
+   word_length = mcasp->slot_width;
}
 
/* mapping of the XSSZ bit-field as described in the datasheet */
@@ -782,33 +865,50 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp 
*mcasp, int stream,
 
/*
 * If more than one serializer is needed, then use them with
-* their specified tdm_slots count. Otherwise, one serializer
-* can cope with the transaction using as many slots as channels
-* in the stream, requires channels symmetry
+* all the specified tdm_slots. Otherwise, one serializer can
+* cope with the transaction using just as many slots as there
+* are channels i

[PATCH RFC 2/5] ASoC: simple-card: Add tdm slot mask support to simple-card

2015-09-09 Thread Jyri Sarha
Adds DT binding for explicitly choosing a tdm mask for DAI and uses it
in simple-card. The API for snd_soc_of_parse_tdm_slot() has also been
changed.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
 .../devicetree/bindings/sound/tdm-slot.txt | 11 +-
 include/sound/simple_card.h|  2 ++
 include/sound/soc.h|  2 ++
 sound/soc/generic/simple-card.c|  8 +--
 sound/soc/soc-core.c   | 25 ++
 5 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/tdm-slot.txt 
b/Documentation/devicetree/bindings/sound/tdm-slot.txt
index 6a2c842..34cf70e 100644
--- a/Documentation/devicetree/bindings/sound/tdm-slot.txt
+++ b/Documentation/devicetree/bindings/sound/tdm-slot.txt
@@ -4,11 +4,15 @@ This specifies audio DAI's TDM slot.
 
 TDM slot properties:
 dai-tdm-slot-num : Number of slots in use.
-dai-tdm-slot-width :  Width in bits for each slot.
+dai-tdm-slot-width : Width in bits for each slot.
+dai-tdm-slot-tx-mask : Transmit direction slot mask, optional
+dai-tdm-slot-rx-mask : Receive direction slot mask, optional
 
 For instance:
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <8>;
+   dai-tdm-slot-tx-mask = <0 1>;
+   dai-tdm-slot-rx-mask = <1 0>;
 
 And for each spcified driver, there could be one .of_xlate_tdm_slot_mask()
 to specify a explicit mapping of the channels and the slots. If it's absent
@@ -18,3 +22,8 @@ tx and rx masks.
 For snd_soc_of_xlate_tdm_slot_mask(), the tx and rx masks will use a 1 bit
 for an active slot as default, and the default active bits are at the LSB of
 the masks.
+
+The explicit masks are given as array of integers, where the first
+number presents bit-0 (LSB), second presents bit-1, etc. Any non zero
+number is considered 1 and 0 is 0. snd_soc_of_xlate_tdm_slot_mask()
+does not do anything, if either mask is set non zero value.
diff --git a/include/sound/simple_card.h b/include/sound/simple_card.h
index b9b4f28..0399352 100644
--- a/include/sound/simple_card.h
+++ b/include/sound/simple_card.h
@@ -19,6 +19,8 @@ struct asoc_simple_dai {
unsigned int sysclk;
int slots;
int slot_width;
+   unsigned int tx_slot_mask;
+   unsigned int rx_slot_mask;
struct clk *clk;
 };
 
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 4cef20e..ca009bf 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1598,6 +1598,8 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card,
 int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
  const char *propname);
 int snd_soc_of_parse_tdm_slot(struct device_node *np,
+ unsigned int *tx_mask,
+ unsigned int *rx_mask,
  unsigned int *slots,
  unsigned int *slot_width);
 void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 3ff76d4..54c3320 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -151,7 +151,9 @@ static int __asoc_simple_card_dai_init(struct snd_soc_dai 
*dai,
}
 
if (set->slots) {
-   ret = snd_soc_dai_set_tdm_slot(dai, 0, 0,
+   ret = snd_soc_dai_set_tdm_slot(dai,
+  set->tx_slot_mask,
+  set->rx_slot_mask,
set->slots,
set->slot_width);
if (ret && ret != -ENOTSUPP) {
@@ -243,7 +245,9 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
return ret;
 
/* Parse TDM slot */
-   ret = snd_soc_of_parse_tdm_slot(np, >slots, >slot_width);
+   ret = snd_soc_of_parse_tdm_slot(np, >tx_slot_mask,
+   >rx_slot_mask,
+   >slots, >slot_width);
if (ret)
return ret;
 
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index c81aec9..1929f0e 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3289,13 +3289,38 @@ int snd_soc_of_parse_audio_simple_widgets(struct 
snd_soc_card *card,
 }
 EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets);
 
+static int snd_soc_of_get_slot_mask(struct device_node *np,
+   const char *prop_name,
+   unsigned int *mask)
+{
+   u32 val;
+   const u32 *of_slot_mask = of_get_property(np, prop_name, );
+   int i;
+
+   if (!of_slot_mask)
+   return 0;
+   val /= sizeof(u32);
+   for (i = 0; i < val; i++)
+  

[PATCH RFC 1/5] ASoC: davinci-mcasp: Set .symmetric_rates = 1 in snd_soc_dai_driver

2015-09-09 Thread Jyri Sarha
The TX and RX direction share the same bit clock and frame sync, so
the samplerate must be the same to both directions.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
 sound/soc/davinci/davinci-mcasp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sound/soc/davinci/davinci-mcasp.c 
b/sound/soc/davinci/davinci-mcasp.c
index fa0511b..bbd1987 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -1304,6 +1304,7 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
.ops= _mcasp_dai_ops,
 
.symmetric_samplebits   = 1,
+   .symmetric_rates= 1,
},
{
.name   = "davinci-mcasp.1",
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 4/5] ASoC: davinci-mcasp: Get rid of bclk_lrclk_ratio in private data

2015-09-09 Thread Jyri Sarha
The slot_width is for essentially same thing. Instead of storing
bclk_lrclk_ratio, just store the slot_width. Comments has been updated
accordingly and some variable names changed to more descriptive.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
 sound/soc/davinci/davinci-mcasp.c | 56 ++-
 1 file changed, 31 insertions(+), 25 deletions(-)

diff --git a/sound/soc/davinci/davinci-mcasp.c 
b/sound/soc/davinci/davinci-mcasp.c
index de1e3a8..25ff1fc 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -87,7 +87,6 @@ struct davinci_mcasp {
u8  *serial_dir;
u8  version;
u8  bclk_div;
-   u16 bclk_lrclk_ratio;
int streams;
u32 irq_request[2];
int dma_request[2];
@@ -558,8 +557,21 @@ static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai 
*dai, int div_id,
mcasp->bclk_div = div;
break;
 
-   case 2: /* BCLK/LRCLK ratio */
-   mcasp->bclk_lrclk_ratio = div;
+   case 2: /*
+* BCLK/LRCLK ratio descries how many bit-clock cycles
+* fit into one frame. The clock ratio is given for a
+* full period of data (for I2S format both left and
+* right channels), so it has to be divided by number
+* of tdm-slots (for I2S - divided by 2).
+* Instead of storing this ratio, we calculate a new
+* tdm_slot width by dividing the the ratio by the
+* number of configured tdm slots.
+*/
+   mcasp->slot_width = div / mcasp->tdm_slots;
+   if (div % mcasp->tdm_slots)
+   dev_warn(mcasp->dev,
+"%s(): BCLK/LRCLK %d is not divisible by %d 
tdm slots",
+div, mcasp->tdm_slots);
break;
 
default:
@@ -682,11 +694,13 @@ static int davinci_mcasp_set_tdm_slot(struct snd_soc_dai 
*dai,
 }
 
 static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
-  int word_length)
+  int sample_width)
 {
u32 fmt;
-   u32 tx_rotate = (word_length / 4) & 0x7;
-   u32 mask = (1ULL << word_length) - 1;
+   u32 tx_rotate = (sample_width / 4) & 0x7;
+   u32 mask = (1ULL << sample_width) - 1;
+   u32 slot_width = sample_width;
+
/*
 * For captured data we should not rotate, inversion and masking is
 * enoguh to get the data to the right position:
@@ -699,31 +713,23 @@ static int davinci_config_channel_size(struct 
davinci_mcasp *mcasp,
u32 rx_rotate = 0;
 
/*
-* if s BCLK-to-LRCLK ratio has been configured via the set_clkdiv()
-* callback, take it into account here. That allows us to for example
-* send 32 bits per channel to the codec, while only 16 of them carry
-* audio payload.
-* The clock ratio is given for a full period of data (for I2S format
-* both left and right channels), so it has to be divided by number of
-* tdm-slots (for I2S - divided by 2).
+* Setting the tdm slot width either with set_clkdiv() or
+* set_tdm_slot() allows us to for example send 32 bits per
+* channel to the codec, while only 16 of them carry audio
+* payload.
 */
-   if (mcasp->bclk_lrclk_ratio) {
-   u32 slot_length = mcasp->bclk_lrclk_ratio / mcasp->tdm_slots;
-
+   if (mcasp->slot_width) {
/*
-* When we have more bclk then it is needed for the data, we
-* need to use the rotation to move the received samples to have
-* correct alignment.
+* When we have more bclk then it is needed for the
+* data, we need to use the rotation to move the
+* received samples to have correct alignment.
 */
-   rx_rotate = (slot_length - word_length) / 4;
-   word_length = slot_length;
-   } else if (mcasp->slot_width) {
-   rx_rotate = (mcasp->slot_width - word_length) / 4;
-   word_length = mcasp->slot_width;
+   slot_width = mcasp->slot_width;
+   rx_rotate = (slot_width - sample_width) / 4;
}
 
/* mapping of the XSSZ bit-field as described in the datasheet */
-   fmt = (word_length >> 1) - 1;
+   fmt = (slot_width >> 1) - 1;
 
if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) {
mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXSSZ(fmt),
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 5/5] ASoC: tlv320aic3x: Improve tdm support

2015-09-09 Thread Jyri Sarha
Before this patch the set_tdm_slots() callback did not store the value
of slot width anywhere. The tdm support only worked if selected slot
width was equal to the sample width. With this patch all sample widths
that fit into the slot width are supported. There unused bits are
filled unnecessarily in the capture direction, but the other end of
the i2s bus should be able to ignore them.

Signed-off-by: Jyri Sarha <jsa...@ti.com>
---
 sound/soc/codecs/tlv320aic3x.c | 30 ++
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 1a82b19..f1c9fff 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -80,6 +80,7 @@ struct aic3x_priv {
unsigned int sysclk;
unsigned int dai_fmt;
unsigned int tdm_delay;
+   unsigned int slot_width;
struct list_head list;
int master;
int gpio_reset;
@@ -1025,10 +1026,14 @@ static int aic3x_hw_params(struct snd_pcm_substream 
*substream,
u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
u16 d, pll_d = 1;
int clk;
+   int width = aic3x->slot_width;
+
+   if (!width)
+   width = params_width(params);
 
/* select data word length */
data = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
-   switch (params_width(params)) {
+   switch (width) {
case 16:
break;
case 20:
@@ -1170,12 +1175,16 @@ static int aic3x_prepare(struct snd_pcm_substream 
*substream,
struct snd_soc_codec *codec = dai->codec;
struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
int delay = 0;
+   int width = aic3x->slot_width;
+
+   if (!width)
+   width = substream->runtime->sample_bits;
 
/* TDM slot selection only valid in DSP_A/_B mode */
if (aic3x->dai_fmt == SND_SOC_DAIFMT_DSP_A)
-   delay += (aic3x->tdm_delay + 1);
+   delay += (aic3x->tdm_delay*width + 1);
else if (aic3x->dai_fmt == SND_SOC_DAIFMT_DSP_B)
-   delay += aic3x->tdm_delay;
+   delay += aic3x->tdm_delay*width;
 
/* Configure data delay */
snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, delay);
@@ -1296,7 +1305,20 @@ static int aic3x_set_dai_tdm_slot(struct snd_soc_dai 
*codec_dai,
return -EINVAL;
}
 
-   aic3x->tdm_delay = lsb * slot_width;
+   switch (slot_width) {
+   case 16:
+   case 20:
+   case 24:
+   case 32:
+   break;
+   default:
+   dev_err(codec->dev, "Unsupported slot width %d\n", slot_width);
+   return -EINVAL;
+   }
+
+
+   aic3x->tdm_delay = lsb;
+   aic3x->slot_width = slot_width;
 
/* DOUT in high-impedance on inactive bit clocks */
snd_soc_update_bits(codec, AIC3X_ASD_INTF_CTRLA,
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 0/5] ASoC: TDM stuff for simple-card, mcasp, and tlv320aic3x

2015-09-09 Thread Jyri Sarha
The first patch is an independent fix.

The symmetric_samplebits constraint could probably be removed too
(with some changes to mcasp code too), but as tlv320aic3x family
codecs won't support it, I could not test it.

Jyri Sarha (5):
  ASoC: davinci-mcasp: Set .symmetric_rates = 1 in snd_soc_dai_driver
  ASoC: simple-card: Add tdm slot mask support to simple-card
  ASoC: davinci-mcasp: Add set_tdm_slots() support
  ASoC: davinci-mcasp: Get rid of bclk_lrclk_ratio in private data
  ASoC: tlv320aic3x: Improve tdm support

 .../devicetree/bindings/sound/tdm-slot.txt |  11 +-
 include/sound/simple_card.h|   2 +
 include/sound/soc.h|   2 +
 sound/soc/codecs/tlv320aic3x.c |  30 +-
 sound/soc/davinci/davinci-mcasp.c  | 306 ++---
 sound/soc/generic/simple-card.c|   8 +-
 sound/soc/soc-core.c   |  25 ++
 7 files changed, 274 insertions(+), 110 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] OMAPDSS: hdmi: Reconfigure and restart audio when display is enabled

2015-08-28 Thread Jyri Sarha

On 08/28/15 13:37, Tomi Valkeinen wrote:


On 26/08/15 16:11, Jyri Sarha wrote:


diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c 
b/drivers/video/fbdev/omap2/dss/hdmi5.c
index 7f87578..f352c4b 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5.c
@@ -352,6 +352,7 @@ static int read_edid(u8 *buf, int len)
  static int hdmi_display_enable(struct omap_dss_device *dssdev)
  {
struct omap_dss_device *out = hdmi.output;
+   unsigned long flags;
int r = 0;

DSSDBG(ENTER hdmi_display_enable\n);
@@ -370,7 +371,37 @@ static int hdmi_display_enable(struct omap_dss_device 
*dssdev)
goto err0;
}

+   if (hdmi.audio_configured) {
+   spin_lock_irqsave(hdmi.audio_playing_lock, flags);
+   hdmi_wp_audio_core_req_enable(hdmi.wp, false);
+   hdmi_wp_audio_enable(hdmi.wp, false);
+   if (hdmi.wp_idlemode  0)
+   REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG,
+   hdmi.wp_idlemode, 3, 2);
+   hdmi.wp_idlemode = -1;
+   spin_unlock_irqrestore(hdmi.audio_playing_lock, flags);


Here I think the audio HW is always disabled already. It has to be,
because the whole HDMI IP has been off. So the above should not be needed.


+
+   r = hdmi5_audio_config(hdmi.core, hdmi.wp, hdmi.audio_config,
+  hdmi.cfg.timings.pixelclock);
+   if (r) {
+   DSSERR(Error restoring audio configuration: %d, r);
+   hdmi.audio_abort_cb(hdmi.pdev-dev);
+   hdmi.audio_configured = false;
+   }
+   }
+
+   spin_lock_irqsave(hdmi.audio_playing_lock, flags);
+   if (hdmi.audio_configured  hdmi.audio_playing) {
+   /* No-idle while playing audio, store the old value */
+   hdmi.wp_idlemode =
+   REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2);
+   REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
+
+   hdmi_wp_audio_enable(hdmi.wp, true);
+   hdmi_wp_audio_core_req_enable(hdmi.wp, true);
+   }
hdmi.display_enabled = true;
+   spin_unlock_irqrestore(hdmi.audio_playing_lock, flags);


Maybe you've looked at the locking carefully, but it's not obvious to
me. So is hdmi_audio_start and hdmi_audio_stop the only functions that
are called from atomic context? Every other function is protected with
the mutex?



The idea is for the spinlock to make audio start, audio stop, and 
updates to hdmi.display_enabled and hdmi.audio_playing variable atomic.


This is needed for the transitions from display enabled state (when 
audio start/stop commands can be written to HW) to display disabled 
state (when audio start/stop commands update only the hdmi.audio_playing 
variable) to always serialize correctly.


IOW, the idea is to make sure the hdmi.audio_playing variable is always 
in sync with what is in the HW when hdmi.display_enabled == true.


For example: when display is turned back on we take the spinlock and we 
can be sure that the audio start/stop status won't change while we 
update the HW according to current state and set hdmi.display_enabled to 
true. After releasing the lock hdmi.display_enabled is true and all 
audio_start and audio_stop commands write their stuff directly to HW.


In theory, just making hdmi.display_enabled and hdmi.audio_playing 
atomic-variables and touching them always in correct oreder should be 
enough, but explaining the mechanism would then be even trickier.


Cheers,
Jyri
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] OMAPDSS: hdmi: Reconfigure and restart audio when display is enabled

2015-08-28 Thread Jyri Sarha

On 08/28/15 16:04, Tomi Valkeinen wrote:
...

The question is (which was my point in the earlier mail), we already
have mutex, so why a new spinlock?

I think the answer is that audio start/stop (anything else?) are called
in atomic context, so mutex cannot be used.



Yes, that is correct.


Also (not exactly related to this patch), if the audio callbacks must be
atomic, could we use a workqueue to run the audio start/stop work in
non-atomic context? Protecting the whole hdmi state with a single mutex
would be much nicer.


The reason why the audio start and stop are done in atomic context is 
for audio synchronization to other audio devices or video stream to be 
more accurate.


I guess in theory a work queue could be used to serialize the audio 
commands, but that would ruin the whole point of why the start and stop 
commands are atomic in the first place.


Cheers,
Jyri

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3] OMAPDSS: hdmi: Reconfigure and restart audio when display is enabled

2015-08-28 Thread Jyri Sarha
Reconfigure and restart audio when display is enabled, if audio
playback was active before. This is needed in a situation when an
audio+video stream application opens the audio stream before the
video. When video stream is opened the display mode may change and
that would aborted audio playback, because the display is momentarily
turned off.

The audio configuration is stored when it is successfully applied and
a boolean is set when the audio playback is started and unset when
stopped. This data is used to reconfigure the audio when display is
re-enabled. The audio playback is aborted if the reconfiguration fails.

A new spin lock is introduced in order to protect state variables
related to audio playback status. This is needed for the transition
from display enabled state (when audio start/stop commands can be
written to HW) to display disabled state (when audio start/stop
commands update only the hdmi.audio_playing variable) to always
serialize correctly with the start/stop audio commands. The already
existing mutex can not be used, because the audio start and stop
commands are executed in atomic context.

For example: when display is turned back on we take the spinlock and
we can be sure that the audio start/stop status will not change while
we update the HW according to hdmi.audio_playing state and set
hdmi.display_enabled to true. After releasing the lock
hdmi.display_enabled is true and all audio_start and audio_stop
commands write their stuff directly to HW.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/video/fbdev/omap2/dss/hdmi.h  |  9 -
 drivers/video/fbdev/omap2/dss/hdmi4.c | 66 +-
 drivers/video/fbdev/omap2/dss/hdmi5.c | 76 ---
 3 files changed, 124 insertions(+), 27 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h 
b/drivers/video/fbdev/omap2/dss/hdmi.h
index e4a32fe..53616b0 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi.h
@@ -351,13 +351,20 @@ struct omap_hdmi {
struct regulator *vdda_reg;
 
bool core_enabled;
-   bool display_enabled;
 
struct omap_dss_device output;
 
struct platform_device *audio_pdev;
void (*audio_abort_cb)(struct device *dev);
int wp_idlemode;
+
+   bool audio_configured;
+   struct omap_dss_audio audio_config;
+
+   /* This lock should be taken when booleans bellow are touched. */
+   spinlock_t audio_playing_lock;
+   bool audio_playing;
+   bool display_enabled;
 };
 
 #endif
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c 
b/drivers/video/fbdev/omap2/dss/hdmi4.c
index 6d3aa3f..94c8d55 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4.c
@@ -321,9 +321,22 @@ static int read_edid(u8 *buf, int len)
return r;
 }
 
+static void hdmi_start_audio_stream(struct omap_hdmi *hd)
+{
+   hdmi_wp_audio_enable(hd-wp, true);
+   hdmi4_audio_start(hd-core, hd-wp);
+}
+
+static void hdmi_stop_audio_stream(struct omap_hdmi *hd)
+{
+   hdmi4_audio_stop(hd-core, hd-wp);
+   hdmi_wp_audio_enable(hd-wp, false);
+}
+
 static int hdmi_display_enable(struct omap_dss_device *dssdev)
 {
struct omap_dss_device *out = hdmi.output;
+   unsigned long flags;
int r = 0;
 
DSSDBG(ENTER hdmi_display_enable\n);
@@ -342,7 +355,21 @@ static int hdmi_display_enable(struct omap_dss_device 
*dssdev)
goto err0;
}
 
+   if (hdmi.audio_configured) {
+   r = hdmi4_audio_config(hdmi.core, hdmi.wp, hdmi.audio_config,
+  hdmi.cfg.timings.pixelclock);
+   if (r) {
+   DSSERR(Error restoring audio configuration: %d, r);
+   hdmi.audio_abort_cb(hdmi.pdev-dev);
+   hdmi.audio_configured = false;
+   }
+   }
+
+   spin_lock_irqsave(hdmi.audio_playing_lock, flags);
+   if (hdmi.audio_configured  hdmi.audio_playing)
+   hdmi_start_audio_stream(hdmi);
hdmi.display_enabled = true;
+   spin_unlock_irqrestore(hdmi.audio_playing_lock, flags);
 
mutex_unlock(hdmi.lock);
return 0;
@@ -354,17 +381,19 @@ err0:
 
 static void hdmi_display_disable(struct omap_dss_device *dssdev)
 {
+   unsigned long flags;
+
DSSDBG(Enter hdmi_display_disable\n);
 
mutex_lock(hdmi.lock);
 
-   if (hdmi.audio_pdev  hdmi.audio_abort_cb)
-   hdmi.audio_abort_cb(hdmi.audio_pdev-dev);
+   spin_lock_irqsave(hdmi.audio_playing_lock, flags);
+   hdmi_stop_audio_stream(hdmi);
+   hdmi.display_enabled = false;
+   spin_unlock_irqrestore(hdmi.audio_playing_lock, flags);
 
hdmi_power_off_full(dssdev);
 
-   hdmi.display_enabled = false;
-
mutex_unlock(hdmi.lock);
 }
 
@@ -568,6 +597,8 @@ static int hdmi_audio_shutdown(struct device *dev)
 
mutex_lock(hd-lock);
hd

[PATCH v2] OMAPDSS: hdmi: Reconfigure and restart audio when display is enabled

2015-08-28 Thread Jyri Sarha
Reconfigure and restart audio when display is enabled, if audio
playback was active before. The audio configuration is stored when is
is successfully applied and a boolean is set when playback has started
and unset when stopped. This data is used to reconfigure the audio
when display is re-enabled. Abort audio playback if reconfiguration
fails.

A new spin lock is introduced in order to protect state variables
related to audio playback status. This is needed for the transitions
from display enabled state (when audio start/stop commands can be
written to HW) to display disabled state (when audio start/stop
commands update only the hdmi.audio_playing variable) to always
serialize correctly with the start/stop audio commands.

For example: when display is turned back on we take the spinlock and
we can be sure that the audio start/stop status won't change while we
update the HW according to hdmi.audio_playing state and set
hdmi.display_enabled to true. After releasing the lock
hdmi.display_enabled is true and all audio_start and audio_stop
commands write their stuff directly to HW.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
I dropped the ASoC maintainers from the recipient list as this patch
hardly concerns them.

 drivers/video/fbdev/omap2/dss/hdmi.h  |  9 +++-
 drivers/video/fbdev/omap2/dss/hdmi4.c | 69 +-
 drivers/video/fbdev/omap2/dss/hdmi5.c | 79 ---
 3 files changed, 130 insertions(+), 27 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h 
b/drivers/video/fbdev/omap2/dss/hdmi.h
index e4a32fe..e48aefd 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi.h
@@ -351,13 +351,20 @@ struct omap_hdmi {
struct regulator *vdda_reg;
 
bool core_enabled;
-   bool display_enabled;
 
struct omap_dss_device output;
 
struct platform_device *audio_pdev;
void (*audio_abort_cb)(struct device *dev);
int wp_idlemode;
+
+   bool audio_configured;
+   struct omap_dss_audio audio_config;
+
+   /* This lock should be taken when booleas bellow is touched. */
+   spinlock_t audio_playing_lock;
+   bool audio_playing;
+   bool display_enabled;
 };
 
 #endif
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c 
b/drivers/video/fbdev/omap2/dss/hdmi4.c
index 6d3aa3f..6b9817a 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4.c
@@ -321,9 +321,22 @@ static int read_edid(u8 *buf, int len)
return r;
 }
 
+static void hdmi_start_audio_stream(struct omap_hdmi *hd)
+{
+   hdmi_wp_audio_enable(hd-wp, true);
+   hdmi4_audio_start(hd-core, hd-wp);
+}
+
+static void hdmi_stop_audio_stream(struct omap_hdmi *hd)
+{
+   hdmi4_audio_stop(hd-core, hd-wp);
+   hdmi_wp_audio_enable(hd-wp, false);
+}
+
 static int hdmi_display_enable(struct omap_dss_device *dssdev)
 {
struct omap_dss_device *out = hdmi.output;
+   unsigned long flags;
int r = 0;
 
DSSDBG(ENTER hdmi_display_enable\n);
@@ -342,7 +355,21 @@ static int hdmi_display_enable(struct omap_dss_device 
*dssdev)
goto err0;
}
 
+   if (hdmi.audio_configured) {
+   r = hdmi4_audio_config(hdmi.core, hdmi.wp, hdmi.audio_config,
+  hdmi.cfg.timings.pixelclock);
+   if (r) {
+   DSSERR(Error restoring audio configuration: %d, r);
+   hdmi.audio_abort_cb(hdmi.pdev-dev);
+   hdmi.audio_configured = false;
+   }
+   }
+
+   spin_lock_irqsave(hdmi.audio_playing_lock, flags);
+   if (hdmi.audio_configured  hdmi.audio_playing)
+   hdmi_start_audio_stream(hdmi);
hdmi.display_enabled = true;
+   spin_unlock_irqrestore(hdmi.audio_playing_lock, flags);
 
mutex_unlock(hdmi.lock);
return 0;
@@ -354,17 +381,19 @@ err0:
 
 static void hdmi_display_disable(struct omap_dss_device *dssdev)
 {
+   unsigned long flags;
+
DSSDBG(Enter hdmi_display_disable\n);
 
mutex_lock(hdmi.lock);
 
-   if (hdmi.audio_pdev  hdmi.audio_abort_cb)
-   hdmi.audio_abort_cb(hdmi.audio_pdev-dev);
+   spin_lock_irqsave(hdmi.audio_playing_lock, flags);
+   hdmi_stop_audio_stream(hdmi);
+   hdmi.display_enabled = false;
+   spin_unlock_irqrestore(hdmi.audio_playing_lock, flags);
 
hdmi_power_off_full(dssdev);
 
-   hdmi.display_enabled = false;
-
mutex_unlock(hdmi.lock);
 }
 
@@ -565,9 +594,14 @@ out:
 static int hdmi_audio_shutdown(struct device *dev)
 {
struct omap_hdmi *hd = dev_get_drvdata(dev);
+   unsigned long flags;
 
mutex_lock(hd-lock);
hd-audio_abort_cb = NULL;
+   hd-audio_configured = false;
+   spin_lock_irqsave(hd-audio_playing_lock, flags);
+   hd-audio_playing = false;
+   spin_unlock_irqrestore(hd-audio_playing_lock, flags

Re: [PATCH v2] OMAPDSS: hdmi: Reconfigure and restart audio when display is enabled

2015-08-28 Thread Jyri Sarha

On 08/28/15 15:24, Jyri Sarha wrote:

@@ -565,9 +594,14 @@ out:
  static int hdmi_audio_shutdown(struct device *dev)
  {
struct omap_hdmi *hd = dev_get_drvdata(dev);
+   unsigned long flags;

mutex_lock(hd-lock);
hd-audio_abort_cb = NULL;
+   hd-audio_configured = false;
+   spin_lock_irqsave(hd-audio_playing_lock, flags);
+   hd-audio_playing = false;
+   spin_unlock_irqrestore(hd-audio_playing_lock, flags);



BTW, This extra locking (and the corresponding change in hdmi5.c) should 
not be needed. But it does not harm either. I'll fix that, but I'll wait 
first if there is anything else fix.


Best regards,
Jyri
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4] OMAPDSS: hdmi: Reconfigure and restart audio when display is enabled

2015-08-28 Thread Jyri Sarha
Reconfigure and restart audio when display is enabled, if audio
playback was active before. This is needed in a situation when an
audio+video stream application opens the audio stream before the
video. When video stream is opened the display mode may change and
that aborts audio playback, because the display is momentarily
turned off.

The audio configuration is stored when it is successfully applied and
a boolean is set when the audio playback is started and unset when
stopped. This data is used to reconfigure the audio when display is
re-enabled. The audio playback is aborted if the reconfiguration fails.

A new spin lock is introduced in order to protect state variables
related to audio playback status. This is needed for the transition
from display enabled state (when audio start/stop commands can be
written to HW) to display disabled state (when audio start/stop
commands update only the hdmi.audio_playing variable) to always
serialize correctly with the start/stop audio commands. The already
existing mutex can not be used, because the audio start and stop
commands are executed in atomic context.

For example: when display is turned back on we take the spinlock and
we can be sure that the audio start/stop status will not change while
we update the HW according to hdmi.audio_playing state and set
hdmi.display_enabled to true. After releasing the lock
hdmi.display_enabled is true and all audio_start and audio_stop
commands write their stuff directly to HW.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
Fixed one bad sentece in the description.

 drivers/video/fbdev/omap2/dss/hdmi.h  |  9 -
 drivers/video/fbdev/omap2/dss/hdmi4.c | 66 +-
 drivers/video/fbdev/omap2/dss/hdmi5.c | 76 ---
 3 files changed, 124 insertions(+), 27 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h 
b/drivers/video/fbdev/omap2/dss/hdmi.h
index e4a32fe..53616b0 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi.h
@@ -351,13 +351,20 @@ struct omap_hdmi {
struct regulator *vdda_reg;
 
bool core_enabled;
-   bool display_enabled;
 
struct omap_dss_device output;
 
struct platform_device *audio_pdev;
void (*audio_abort_cb)(struct device *dev);
int wp_idlemode;
+
+   bool audio_configured;
+   struct omap_dss_audio audio_config;
+
+   /* This lock should be taken when booleans bellow are touched. */
+   spinlock_t audio_playing_lock;
+   bool audio_playing;
+   bool display_enabled;
 };
 
 #endif
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c 
b/drivers/video/fbdev/omap2/dss/hdmi4.c
index 6d3aa3f..94c8d55 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4.c
@@ -321,9 +321,22 @@ static int read_edid(u8 *buf, int len)
return r;
 }
 
+static void hdmi_start_audio_stream(struct omap_hdmi *hd)
+{
+   hdmi_wp_audio_enable(hd-wp, true);
+   hdmi4_audio_start(hd-core, hd-wp);
+}
+
+static void hdmi_stop_audio_stream(struct omap_hdmi *hd)
+{
+   hdmi4_audio_stop(hd-core, hd-wp);
+   hdmi_wp_audio_enable(hd-wp, false);
+}
+
 static int hdmi_display_enable(struct omap_dss_device *dssdev)
 {
struct omap_dss_device *out = hdmi.output;
+   unsigned long flags;
int r = 0;
 
DSSDBG(ENTER hdmi_display_enable\n);
@@ -342,7 +355,21 @@ static int hdmi_display_enable(struct omap_dss_device 
*dssdev)
goto err0;
}
 
+   if (hdmi.audio_configured) {
+   r = hdmi4_audio_config(hdmi.core, hdmi.wp, hdmi.audio_config,
+  hdmi.cfg.timings.pixelclock);
+   if (r) {
+   DSSERR(Error restoring audio configuration: %d, r);
+   hdmi.audio_abort_cb(hdmi.pdev-dev);
+   hdmi.audio_configured = false;
+   }
+   }
+
+   spin_lock_irqsave(hdmi.audio_playing_lock, flags);
+   if (hdmi.audio_configured  hdmi.audio_playing)
+   hdmi_start_audio_stream(hdmi);
hdmi.display_enabled = true;
+   spin_unlock_irqrestore(hdmi.audio_playing_lock, flags);
 
mutex_unlock(hdmi.lock);
return 0;
@@ -354,17 +381,19 @@ err0:
 
 static void hdmi_display_disable(struct omap_dss_device *dssdev)
 {
+   unsigned long flags;
+
DSSDBG(Enter hdmi_display_disable\n);
 
mutex_lock(hdmi.lock);
 
-   if (hdmi.audio_pdev  hdmi.audio_abort_cb)
-   hdmi.audio_abort_cb(hdmi.audio_pdev-dev);
+   spin_lock_irqsave(hdmi.audio_playing_lock, flags);
+   hdmi_stop_audio_stream(hdmi);
+   hdmi.display_enabled = false;
+   spin_unlock_irqrestore(hdmi.audio_playing_lock, flags);
 
hdmi_power_off_full(dssdev);
 
-   hdmi.display_enabled = false;
-
mutex_unlock(hdmi.lock);
 }
 
@@ -568,6 +597,8 @@ static int hdmi_audio_shutdown(struct device *dev

[PATCH 1/2] OMAPDSS: hdmi: Reconfigure and restart audio when display is enabled

2015-08-26 Thread Jyri Sarha
Reconfigure and restart audio when display is enabled, if audio
playback was active before. The audio configuration is stored when is
is successfully applied and a boolean is set when playback has started
and unset when stopped. This data is used to reconfigure the audio
when display is re-enabled. Abort audio playback if reconfiguration
fails.

A new spin lock is introduced to in order protect state variables
related to audio playback status. The wp_idlemode protection relies on
PM not touching it after the original initialization. A power
management API for controlling the idlemode would be needed for proper
synchronization.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/video/fbdev/omap2/dss/hdmi.h  | 10 +++-
 drivers/video/fbdev/omap2/dss/hdmi4.c | 65 -
 drivers/video/fbdev/omap2/dss/hdmi5.c | 89 +--
 3 files changed, 137 insertions(+), 27 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h 
b/drivers/video/fbdev/omap2/dss/hdmi.h
index e4a32fe..1e45b84 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi.h
@@ -351,12 +351,20 @@ struct omap_hdmi {
struct regulator *vdda_reg;
 
bool core_enabled;
-   bool display_enabled;
 
struct omap_dss_device output;
 
struct platform_device *audio_pdev;
void (*audio_abort_cb)(struct device *dev);
+
+   bool audio_configured;
+   struct omap_dss_audio audio_config;
+
+   /* This lock should be taken when any one of the three
+  state variables bellow are touched. */
+   spinlock_t audio_playing_lock;
+   bool audio_playing;
+   bool display_enabled;
int wp_idlemode;
 };
 
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c 
b/drivers/video/fbdev/omap2/dss/hdmi4.c
index 6d3aa3f..ea1fa64 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4.c
@@ -324,6 +324,7 @@ static int read_edid(u8 *buf, int len)
 static int hdmi_display_enable(struct omap_dss_device *dssdev)
 {
struct omap_dss_device *out = hdmi.output;
+   unsigned long flags;
int r = 0;
 
DSSDBG(ENTER hdmi_display_enable\n);
@@ -342,7 +343,26 @@ static int hdmi_display_enable(struct omap_dss_device 
*dssdev)
goto err0;
}
 
+   if (hdmi.audio_configured) {
+   hdmi4_audio_stop(hdmi.core, hdmi.wp);
+   hdmi_wp_audio_enable(hdmi.wp, false);
+
+   r = hdmi4_audio_config(hdmi.core, hdmi.wp, hdmi.audio_config,
+  hdmi.cfg.timings.pixelclock);
+   if (r) {
+   DSSERR(Error restoring audio configuration: %d, r);
+   hdmi.audio_abort_cb(hdmi.pdev-dev);
+   hdmi.audio_configured = false;
+   }
+   }
+
+   spin_lock_irqsave(hdmi.audio_playing_lock, flags);
+   if (hdmi.audio_configured  hdmi.audio_playing) {
+   hdmi_wp_audio_enable(hdmi.wp, true);
+   hdmi4_audio_start(hdmi.core, hdmi.wp);
+   }
hdmi.display_enabled = true;
+   spin_unlock_irqrestore(hdmi.audio_playing_lock, flags);
 
mutex_unlock(hdmi.lock);
return 0;
@@ -354,17 +374,18 @@ err0:
 
 static void hdmi_display_disable(struct omap_dss_device *dssdev)
 {
+   unsigned long flags;
+
DSSDBG(Enter hdmi_display_disable\n);
 
mutex_lock(hdmi.lock);
 
-   if (hdmi.audio_pdev  hdmi.audio_abort_cb)
-   hdmi.audio_abort_cb(hdmi.audio_pdev-dev);
+   spin_lock_irqsave(hdmi.audio_playing_lock, flags);
+   hdmi.display_enabled = false;
+   spin_unlock_irqrestore(hdmi.audio_playing_lock, flags);
 
hdmi_power_off_full(dssdev);
 
-   hdmi.display_enabled = false;
-
mutex_unlock(hdmi.lock);
 }
 
@@ -565,9 +586,14 @@ out:
 static int hdmi_audio_shutdown(struct device *dev)
 {
struct omap_hdmi *hd = dev_get_drvdata(dev);
+   unsigned long flags;
 
mutex_lock(hd-lock);
hd-audio_abort_cb = NULL;
+   hd-audio_configured = false;
+   spin_lock_irqsave(hd-audio_playing_lock, flags);
+   hd-audio_playing = false;
+   spin_unlock_irqrestore(hd-audio_playing_lock, flags);
mutex_unlock(hd-lock);
 
return 0;
@@ -576,25 +602,38 @@ static int hdmi_audio_shutdown(struct device *dev)
 static int hdmi_audio_start(struct device *dev)
 {
struct omap_hdmi *hd = dev_get_drvdata(dev);
+   unsigned long flags;
 
WARN_ON(!hdmi_mode_has_audio(hd-cfg));
-   WARN_ON(!hd-display_enabled);
 
-   hdmi_wp_audio_enable(hd-wp, true);
-   hdmi4_audio_start(hd-core, hd-wp);
+   spin_lock_irqsave(hd-audio_playing_lock, flags);
+
+   if (hd-display_enabled) {
+   hdmi_wp_audio_enable(hd-wp, true);
+   hdmi4_audio_start(hd-core, hd-wp);
+   }
+   hd-audio_playing = true;
 
+   spin_unlock_irqrestore(hd

[PATCH 0/2] OMAPDSS: Couple of HDMI audio fixes

2015-08-26 Thread Jyri Sarha
The first fix is a hairy one, but I think the locking is fool proof
now. It is needed because there is no telling in which order user
space starts an audio and video stream playback. If the audio is
started first and the video mode is changed when video playback starts
the audio setup needs to survive display turning off and back on
again. After this patch the audio streams should survive a
suspend-resume cycle too.
 
The second one is a trivial work-around to a problem in ALSA constraint
resolver code.

The two fixes are totally independent and the video and audio side
patches applied separately trough their own trees.

Jyri Sarha (2):
  OMAPDSS: hdmi: Reconfigure and restart audio when display is enabled
  ASoC: omap-hdmi-audio: Set buffer bytes step constraint to 128

 drivers/video/fbdev/omap2/dss/hdmi.h  | 10 +++-
 drivers/video/fbdev/omap2/dss/hdmi4.c | 65 -
 drivers/video/fbdev/omap2/dss/hdmi5.c | 89 +--
 sound/soc/omap/omap-hdmi-audio.c  | 10 +++-
 4 files changed, 146 insertions(+), 28 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] ASoC: omap-hdmi-audio: Set buffer bytes step constraint to 128

2015-08-26 Thread Jyri Sarha
Set buffer bytes step constraint to 128. A matching constraint has
already been set to period size. This helps PCM setup to tolerate ALSA
clients that set the PCM hw params in unusual order.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 sound/soc/omap/omap-hdmi-audio.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/omap/omap-hdmi-audio.c
index aeef25c..584b237 100644
--- a/sound/soc/omap/omap-hdmi-audio.c
+++ b/sound/soc/omap/omap-hdmi-audio.c
@@ -81,7 +81,15 @@ static int hdmi_dai_startup(struct snd_pcm_substream 
*substream,
ret = snd_pcm_hw_constraint_step(substream-runtime, 0,
 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 128);
if (ret  0) {
-   dev_err(dai-dev, could not apply constraint\n);
+   dev_err(dai-dev, Could not apply period constraint: %d\n,
+   ret);
+   return ret;
+   }
+   ret = snd_pcm_hw_constraint_step(substream-runtime, 0,
+SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 128);
+   if (ret  0) {
+   dev_err(dai-dev, Could not apply buffer constraint: %d\n,
+   ret);
return ret;
}
 
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC v3 3/7] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders

2015-08-17 Thread Jyri Sarha

On 08/17/15 10:57, Jyri Sarha wrote:

Missed one commet first time around...

On 08/14/15 19:18, Mark Brown wrote:

On Fri, Aug 14, 2015 at 12:30:41PM +0300, Jyri Sarha wrote:

...

+/* HDMI codec initalization data */
+struct hdmi_codec_pdata {
+struct device *dev; /* The HDMI encoder registering the codec */


Shouldn't this just be dev-parent?



No. The HDMI encoder device is the parent for HDMI-codec.

The patch you took in in the last round uses the ASoC component drivers
parent's of-node if the component driver does not have one itself. In
this case the phandle in the binding points to the HDMI encoder's node,
which is the parent of the HDMI codec.



After reading the comment again I see now what you meant.

Yes, I can extract the encoder device from the dev-parent pointer. No 
need to have it in pdata.


Thanks,
Jyri


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC v3 6/7] drm/i2c: tda998x: Register ASoC HDMI codec for audio functionality

2015-08-17 Thread Jyri Sarha

On 08/14/15 13:06, Russell King - ARM Linux wrote:

On Fri, Aug 14, 2015 at 12:30:44PM +0300, Jyri Sarha wrote:

+static int tda998x_write_aif(struct tda998x_priv *priv,
+struct hdmi_audio_infoframe *cea)
+{
+   uint8_t buf[HDMI_INFOFRAME_SIZE(AUDIO)];
+   int len;
+
+   len = hdmi_audio_infoframe_pack(cea, buf, sizeof(buf));
+   if (len  0) {
+   dev_err(priv-hdmi-dev,
+   Failed to pack audio infoframe: %d\n, len);
+   return len;
+   }
+
+   /* Write the audio information packet */
+   tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf, len);
+   return 0;
+}
+


I have such a function already queued up, but I can't push it out at the
moment because of too many conflicts across all my DRM work.  I'm waiting
for after 4.3-rc1 before publishing anything from or accepting anything
else into DRM branches.



Ok, is the code available some where? Could take a look so I can align 
my code to that.



  static void
  tda998x_write_avi(struct tda998x_priv *priv, struct drm_display_mode *mode)
  {
@@ -670,19 +691,24 @@ static void tda998x_audio_mute(struct tda998x_priv *priv, 
bool on)
}
  }

-static void
+static int
  tda998x_configure_audio(struct tda998x_priv *priv,
-   struct drm_display_mode *mode, struct tda998x_encoder_params *p)
+   int mode_clock,
+   int ena_ap,
+   int dai_format,
+   int sample_width,
+   int sample_rate,
+   const u8 *status)


I don't think this is an improvement.



Still it makes the function more generic and enables its usage in 
HDMI-codec API implementation. I'll try to make it look tidier.



+static int tda998x_audio_get_eld(struct device *dev, uint8_t *buf, size_t len)
+{
+   struct tda998x_priv *priv = dev_get_drvdata(dev);
+   struct drm_mode_config *config = priv-encoder-dev-mode_config;
+   struct drm_connector *connector;
+   int ret = -ENODEV;
+
+   mutex_lock(config.mutex);
+   list_for_each_entry(connector, config-connector_list, head) {
+   if (priv-encoder == connector-encoder) {
+   memcpy(buf, connector-eld,
+  min(sizeof(connector-eld), len));
+   ret = 0;
+   }
+   }
+   mutex_unlock(config.mutex);


Obviously untested.  Should be config-mutex.



Sorry. Should never do these last minute changes. I must have been 
compiling and testing different code version. I first had this function 
using config-connection_mutex, but then - after reading the eld related 
code - found that mode_config mutex should be used instead.



But in any case, when I kill the DRM slave encoder code in here, this
becomes unnecessary.



Ok, The information from ELD needs be passed to audio side constraints 
somehow. I'd love to see the code you have in queue.


Best regards,
Jyri

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC v3 3/7] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders

2015-08-17 Thread Jyri Sarha

Missed one commet first time around...

On 08/14/15 19:18, Mark Brown wrote:

On Fri, Aug 14, 2015 at 12:30:41PM +0300, Jyri Sarha wrote:

...

+/* HDMI codec initalization data */
+struct hdmi_codec_pdata {
+   struct device *dev; /* The HDMI encoder registering the codec */


Shouldn't this just be dev-parent?



No. The HDMI encoder device is the parent for HDMI-codec.

The patch you took in in the last round uses the ASoC component drivers 
parent's of-node if the component driver does not have one itself. In 
this case the phandle in the binding points to the HDMI encoder's node, 
which is the parent of the HDMI codec.


Best regards,
Jyri
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC v3 3/7] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders

2015-08-17 Thread Jyri Sarha

On 08/17/15 21:41, Mark Brown wrote:

On Mon, Aug 17, 2015 at 10:07:55AM +0300, Jyri Sarha wrote:

On 08/14/15 19:18, Mark Brown wrote:

On Fri, Aug 14, 2015 at 12:30:41PM +0300, Jyri Sarha wrote:



+   /* Called when ASoC starts an audio stream setup. The call
+* provides an audio abort callback for stoping an ongoing
+* stream if the HDMI audio becomes unavailable.
+* Optional */
+   int (*audio_startup)(struct device *dev,
+void (*abort_cb)(struct device *dev));



I'm a bit confused about what is going to use abort_cb() and why they
wouldn't just call shutdown instead?



audio_shutdown() is for ASoC side to tell video side that audio playback has
stopped.



The abort_cb() is for video side to inform ASoC that current audio stream
can not continue anymore and it should be aborted. The similar mechanism is
currently in use in sound/soc/omap/omap-hdmi-audio.c.


Someone reading the code needs to be able to understand this.



Ok, I'll improve the comment above.

Thanks,
Jyri
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC v3 3/7] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders

2015-08-17 Thread Jyri Sarha

On 08/14/15 12:57, Russell King - ARM Linux wrote:

On Fri, Aug 14, 2015 at 12:30:41PM +0300, Jyri Sarha wrote:

+static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
+   struct snd_pcm_hw_params *params,
+   struct snd_soc_dai *dai)
+{
+   struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
+   struct hdmi_codec_params hp = {
+   .cea = { 0 },


Unnecessary initialisation - because you are initialising this structure,
all unnamed fields will be zeroed.



True, I just tried to be explicit.


+   .iec = {
+   .status = {
+   IEC958_AES0_CON_NOT_COPYRIGHT,
+   IEC958_AES1_CON_GENERAL,
+   IEC958_AES2_CON_SOURCE_UNSPEC,
+   IEC958_AES3_CON_CLOCK_VARIABLE,
+   },


...


+   hdmi_audio_infoframe_init(hp.cea);
+   hp.cea.coding_type = HDMI_AUDIO_CODING_TYPE_PCM;


Something tells me here that you haven't read the HDMI specification.
HDMI says that the coding type will be zero (refer to stream header).
The same goes for much of the CEA audio infoframe.  Please see the
Audio InfoFrame details in the HDMI specification.



Must admit, that I have not read it end to end. Obviously I have missed 
a relevant piece of information here. I'll fix that and check the 
related items too.



+   hp.cea.channels = params_channels(params);
+
+   switch (params_width(params)) {
+   case 16:
+   hp.iec.status[4] |= IEC958_AES4_CON_WORDLEN_20_16;
+   hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+   break;
+   case 18:
+   hp.iec.status[4] |= IEC958_AES4_CON_WORDLEN_22_18;
+   hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_20;
+   break;
+   case 20:
+   hp.iec.status[4] |= IEC958_AES4_CON_WORDLEN_24_20;
+   hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_20;
+   break;
+   case 24:
+   case 32:
+   hp.iec.status[4] |= IEC958_AES4_CON_MAX_WORDLEN_24 |
+   IEC958_AES4_CON_WORDLEN_24_20;


Why not use the generic code to generate the AES channel status bits?
See sound/core/pcm_iec958.c.



Thanks, I did not know that exist. I'll make use of that.

Best regards,
Jyri

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC v3 2/7] ASoC: hdmi: Remove obsolete dummy HDMI codec

2015-08-17 Thread Jyri Sarha

On 08/14/15 19:10, Mark Brown wrote:

On Fri, Aug 14, 2015 at 12:30:40PM +0300, Jyri Sarha wrote:

The hdmi stub codec has not been used since refactoring of OMAP HDMI
audio support.


grep tells me that the OMAP HDMI4 and HDMI5 drivers are still
registering this device in -next...



Really? My source trees for mainline and linux-next look like this:

$ git grep hdmi-audio-codec
sound/soc/codecs/hdmi.c:#define DRV_NAME hdmi-audio-codec

Don't you mean omap-hdmi-audio, that is implemented in 
sound/soc/omap/omap-hdmi-audio.c ?


That driver is bit different. It implements ASoC card and uses generic 
dummy codec. The hdmi-audio-codec has not been used for OMAP HDMI 
audio for several releases already.


Best regards,
Jyri
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC v3 3/7] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders

2015-08-17 Thread Jyri Sarha

On 08/14/15 19:18, Mark Brown wrote:

On Fri, Aug 14, 2015 at 12:30:41PM +0300, Jyri Sarha wrote:


+struct hdmi_codec_ops {
+   /* For runtime clock configuration from ASoC machine driver.
+* A direct forward from set_sysclk in struct snd_soc_dai_ops.
+* Optional */
+   int (*set_clk)(struct device *dev, int clk_id, int freq);


I'd be much happier if we were using the clock API as the external
interface here, it's where we want to be internally too and it's going
to be easier to not introduce any external dependencies on the ASoC
internal stuff.



Sounds better. I'll change that.


+   /* Called when ASoC starts an audio stream setup. The call
+* provides an audio abort callback for stoping an ongoing
+* stream if the HDMI audio becomes unavailable.
+* Optional */
+   int (*audio_startup)(struct device *dev,
+void (*abort_cb)(struct device *dev));


I'm a bit confused about what is going to use abort_cb() and why they
wouldn't just call shutdown instead?



audio_shutdown() is for ASoC side to tell video side that audio playback 
has stopped.


The abort_cb() is for video side to inform ASoC that current audio 
stream can not continue anymore and it should be aborted. The similar 
mechanism is currently in use in sound/soc/omap/omap-hdmi-audio.c.



+/* HDMI codec initalization data */
+struct hdmi_codec_pdata {
+   struct device *dev; /* The HDMI encoder registering the codec */


Shouldn't this just be dev-parent?


+enum {
+   DAI_ID_I2C = 0,
+   DAI_ID_SPDIF,
+};


I2C?  :P



Right, should be I2S. Thanks!

Best regards,
Jyri

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC v2 3/7] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders

2015-08-17 Thread Jyri Sarha

On 08/14/15 22:25, Mark Brown wrote:

On Tue, May 26, 2015 at 09:59:07PM +0300, Jyri Sarha wrote:


+
+   mutex_lock(hcp-current_stream_lock);
+   if (hcp-current_stream  hcp-current_stream-runtime 
+   snd_pcm_running(hcp-current_stream)) {
+   dev_info(dev, HDMI audio playback aborted\n);


Does this really need to be dev_info()?



No, I'll change that to debug level.


+   if (hcp-hcd.ops-get_eld) {
+   hcp-eld = hcp-hcd.ops-get_eld(hcp-hcd.dev);
+
+   /* Call snd_pcm_hw_constraint_eld here */
+   }


...


+   dev_dbg(dai-dev, %s()\n, __func__);
+
+   mutex_lock(hcp-current_stream_lock);
+   BUG_ON(hcp-current_stream != substream);
+   hcp-current_stream = NULL;
+   mutex_unlock(hcp-current_stream_lock);
+
+   hcp-hcd.ops-audio_shutdown(hcp-hcd.dev);


Shouldn't the callback be in or before the lock?  Otherwise we could
potentially race with starting a new stream.



Yes, it should be before it. I'll fix that.

If it is inside, there is a possible deadlock warning (atleast in the 
similar place in omap-hdmi-audio there was) if those warnings are turned 
on and there is another lock that is taken in the video side callbacks.


Thanks,
Jyri
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC v3 7/7] ARM: dts: am335x-boneblack: Add HDMI audio support

2015-08-14 Thread Jyri Sarha
Add HDMI audio support. Adds mcasp0_pins, clk_mcasp0_fixed,
clk_mcasp0, mcasp0, sound node, and updates the tda19988 node to
follow the new binding.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 arch/arm/boot/dts/am335x-boneblack.dts | 90 --
 1 file changed, 86 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/am335x-boneblack.dts 
b/arch/arm/boot/dts/am335x-boneblack.dts
index eadbba3..7d3e899 100644
--- a/arch/arm/boot/dts/am335x-boneblack.dts
+++ b/arch/arm/boot/dts/am335x-boneblack.dts
@@ -64,6 +64,16 @@
0x1b0 0x03  /* xdma_event_intr0, OMAP_MUX_MODE3 | 
AM33XX_PIN_OUTPUT */
;
};
+
+   mcasp0_pins: mcasp0_pins {
+   pinctrl-single,pins = 
+   0x1ac (PIN_INPUT_PULLUP | MUX_MODE0)/* 
mcasp0_ahclkx.mcasp0_ahclkx */
+   0x19c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* 
mcasp0_ahclkr.mcasp0_axr2 */
+   0x194 (PIN_OUTPUT_PULLUP | MUX_MODE0)   /* 
mcasp0_fsx.mcasp0_fsx */
+   0x190 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* 
mcasp0_aclkx.mcasp0_aclkx */
+   0x06c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* 
gpmc_a11.GPIO1_27 */
+   ;
+   };
 };
 
 lcdc {
@@ -76,17 +86,89 @@
 };
 
 i2c0 {
-   tda19988 {
+   tda19988: tda19988 {
compatible = nxp,tda998x;
reg = 0x70;
+
+   #sound-dai-cells = 0;
+
pinctrl-names = default, off;
pinctrl-0 = nxp_hdmi_bonelt_pins;
pinctrl-1 = nxp_hdmi_bonelt_off_pins;
 
-   port {
-   hdmi_0: endpoint@0 {
-   remote-endpoint = lcdc_0;
+   ports {
+   #address-cells = 1; 
+   #size-cells = 0;
+   port@0 {
+   port-type = rgb;
+   reg = 0x230145;
+   hdmi_0: endpoint@0 {
+   remote-endpoint = lcdc_0;
+   };
};
+   port@1 {
+   port-type = i2s;
+   reg = 0x03;
+   tda19988_i2s: endpoint {
+   remote-endpoint = mcasp0_i2s;
+   };
+   };
+   };
+   };
+};
+
+rtc {
+   system-power-controller;
+};
+
+mcasp0{
+   #sound-dai-cells = 0;
+   pinctrl-names = default;
+   pinctrl-0 = mcasp0_pins;
+   status = okay;
+   op-mode = 0;  /* MCASP_IIS_MODE */
+   tdm-slots = 2;
+   serial-dir =   /* 0: INACTIVE, 1: TX, 2: RX */
+   0 0 1 0
+   ;
+   tx-num-evt = 1;
+   rx-num-evt = 1;
+
+   port {
+   mcasp0_i2s: endpoint {
+   remote-endpoint = tda19988_i2s;
+   };
+   };
+};
+
+/ {
+   clk_mcasp0_fixed: clk_mcasp0_fixed {
+   #clock-cells = 0;
+   compatible = fixed-clock;
+   clock-frequency = 24576000;
+   };
+
+   clk_mcasp0: clk_mcasp0 {
+   #clock-cells = 0;
+   compatible = gpio-gate-clock;
+   clocks = clk_mcasp0_fixed;
+   enable-gpios = gpio1 27 0; /* BeagleBone Black Clk enable on 
GPIO1_27 */
+   };
+
+   sound {
+   compatible = simple-audio-card;
+   simple-audio-card,name = TI BeagleBone Black;
+   simple-audio-card,format = i2s;
+   simple-audio-card,bitclock-master = dailink0_master;
+   simple-audio-card,frame-master = dailink0_master;
+
+   dailink0_master: simple-audio-card,cpu {
+   sound-dai = mcasp0;
+   clocks = clk_mcasp0;
+   };
+
+   simple-audio-card,codec {
+   sound-dai = tda19988;
};
};
 };
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC v3 4/7] drm/i2c: tda998x: Add support of a DT graph of ports

2015-08-14 Thread Jyri Sarha
From: Jean-Francois Moine moin...@free.fr

Two kinds of ports may be declared in a DT graph of ports: video and audio.
This patch accepts the port value from a video port as an alternative
to the video-ports property.
It also accepts audio ports in the case the transmitter is not used as
a slave encoder.
The new file include/sound/tda998x.h prepares to the definition of
a tda998x CODEC.

Signed-off-by: Jean-Francois Moine moin...@free.fr
Signed-off-by: Jyri Sarha jsa...@ti.com
---
 .../devicetree/bindings/drm/i2c/tda998x.txt| 51 
 drivers/gpu/drm/i2c/tda998x_drv.c  | 90 +++---
 include/sound/tda998x.h|  8 ++
 3 files changed, 140 insertions(+), 9 deletions(-)
 create mode 100644 include/sound/tda998x.h

diff --git a/Documentation/devicetree/bindings/drm/i2c/tda998x.txt 
b/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
index e9e4bce..35f6a80 100644
--- a/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
+++ b/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
@@ -16,6 +16,35 @@ Optional properties:
 
   - video-ports: 24 bits value which defines how the video controller
output is wired to the TDA998x input - default: 0x230145
+   This property is not used when ports are defined.
+
+Optional nodes:
+
+  - port: up to three ports.
+   The ports are defined according to [1].
+
+Video port.
+   There may be only one video port.
+   This one must contain the following property:
+
+   - port-type: must be rgb
+
+   and may contain the optional property:
+
+   - reg: 24 bits value which defines how the video controller
+   output is wired to the TDA998x input (video pins)
+   When absent, the default value is 0x230145.
+
+Audio ports.
+   There may be one or two audio ports.
+   These ones must contain the following properties:
+
+   - port-type: must be i2s or spdif
+
+   - reg: 8 bits value which defines how the audio controller
+   output is wired to the TDA998x input (audio pins)
+
+[1] Documentation/devicetree/bindings/graph.txt
 
 Example:
 
@@ -26,4 +55,26 @@ Example:
interrupts = 27 2;/* falling edge */
pinctrl-0 = pmx_camera;
pinctrl-names = default;
+
+   port@230145 {
+   port-type = rgb;
+   reg = 0x230145;
+   hdmi_0: endpoint {
+   remote-endpoint = lcd0_0;
+   };
+   };
+   port@3 {/* AP1 = I2S */
+   port-type = i2s;
+   reg = 0x03;
+   tda998x_i2s: endpoint {
+   remote-endpoint = audio1_i2s;
+   };
+   };
+   port@4 { /* AP2 = S/PDIF */
+   port-type = spdif;
+   reg = 0x04;
+   tda998x_spdif: endpoint {
+   remote-endpoint = audio1_spdif1;
+   };
+   };
};
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 424228b..0952eac 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -27,6 +27,7 @@
 #include drm/drm_edid.h
 #include drm/drm_of.h
 #include drm/i2c/tda998x.h
+#include sound/tda998x.h
 
 #define DBG(fmt, ...) DRM_DEBUG(fmt\n, ##__VA_ARGS__)
 
@@ -47,6 +48,8 @@ struct tda998x_priv {
wait_queue_head_t wq_edid;
volatile int wq_edid_wait;
struct drm_encoder *encoder;
+
+   struct tda998x_audio audio;
 };
 
 #define to_tda998x_priv(x)  ((struct tda998x_priv 
*)to_encoder_slave(x)-slave_priv)
@@ -774,6 +777,8 @@ static void tda998x_encoder_set_config(struct tda998x_priv 
*priv,
(p-mirr_f ? VIP_CNTRL_2_MIRR_F : 0);
 
priv-params = *p;
+   priv-audio.port_types[0] = p-audio_format;
+   priv-audio.ports[0] = p-audio_cfg;
 }
 
 static void tda998x_encoder_dpms(struct tda998x_priv *priv, int mode)
@@ -1230,9 +1235,57 @@ static struct drm_encoder_slave_funcs 
tda998x_encoder_slave_funcs = {
 
 /* I2C driver functions */
 
+static int tda998x_parse_ports(struct tda998x_priv *priv,
+   struct device_node *np)
+{
+   struct device_node *of_port;
+   const char *port_type;
+   int ret, audio_index, reg, afmt;
+
+   audio_index = 0;
+   for_each_child_of_node(np, of_port) {
+   if (!of_port-name
+|| of_node_cmp(of_port-name, port) != 0)
+   continue;
+   ret = of_property_read_string(of_port, port-type,
+   port_type);
+   if (ret  0)
+   continue;
+   ret = of_property_read_u32(of_port

[PATCH RFC v3 0/7] Implement generic ASoC HDMI codec and use it in tda998x

2015-08-14 Thread Jyri Sarha
This is my third RFC patch series on the subject. This time also the
tda998x driver patches are a serious attempt to come up with an
initial implementation for HDMI audio ASoC support.

Russell's drm/edid: add function to help find SADs is here just to
produce a working patch-set on top of mainline. It should be getting in
trough drm-next at some point.

The binding for tda998x is taken from Jean Francois' patch series[1] on
the same subject. The implementation of the of-node parsing has some
minor changes from my self.

Here is what I think at least could or should still be done, but non of
that stuff does not sounds critical right now.
 
Missing from tda998x driver side
- hdmi_codec_ops audio_startup() implementation for audio abort support
- multi channel audio support (I would need specs and preferably some
  HW to test for this).

Missing from ASoC side generic implementation:
- channel_allocation handling is completely left for the video side driver,
  see if ASoC side could help in any way
- snd_soc_jack functionality to handle hdmi cable plug/unplug events

[1] http://mailman.alsa-project.org/pipermail/alsa-devel/2015-July/095596.html

Best regards,
Jyri

Jean-Francois Moine (1):
  drm/i2c: tda998x: Add support of a DT graph of ports

Jyri Sarha (5):
  ASoC: hdmi: Remove obsolete dummy HDMI codec
  ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders
  drm/i2c: tda998x: Remove include/sound/tda998x.h and fix graph parsing
  drm/i2c: tda998x: Register ASoC HDMI codec for audio functionality
  ARM: dts: am335x-boneblack: Add HDMI audio support

Russell King - ARM Linux (1):
  drm/edid: add function to help find SADs, DO NOT MERGE

 .../devicetree/bindings/drm/i2c/tda998x.txt|  51 +++
 arch/arm/boot/dts/am335x-boneblack.dts |  90 +++-
 drivers/gpu/drm/i2c/Kconfig|   1 +
 drivers/gpu/drm/i2c/tda998x_drv.c  | 336 +--
 include/drm/drm_edid.h |  19 +
 include/sound/hdmi-codec.h |  99 +
 sound/soc/codecs/Kconfig   |   3 +-
 sound/soc/codecs/Makefile  |   4 +-
 sound/soc/codecs/hdmi-codec.c  | 467 +
 sound/soc/codecs/hdmi.c| 109 -
 10 files changed, 1026 insertions(+), 153 deletions(-)
 create mode 100644 include/sound/hdmi-codec.h
 create mode 100644 sound/soc/codecs/hdmi-codec.c
 delete mode 100644 sound/soc/codecs/hdmi.c

-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC v3 6/7] drm/i2c: tda998x: Register ASoC HDMI codec for audio functionality

2015-08-14 Thread Jyri Sarha
Register ASoC HDMI codec for audio functionality. This is an initial
ASoC audio implementation for tda998x driver and it does not use all
the features provided by hdmi-codec.

HDMI audio info-frame and audio stream header is generated by the ASoC
HDMI codec. The codec also applies constraints for available
sample-rates.

Implementation of audio_startup for hdmi_codec_ops would enable
tda998x driver to abort ongoing playback if the HDMI cable is
unplugged or re-plugged to a device without audio capability.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/gpu/drm/i2c/Kconfig   |   1 +
 drivers/gpu/drm/i2c/tda998x_drv.c | 241 +-
 2 files changed, 214 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i2c/Kconfig b/drivers/gpu/drm/i2c/Kconfig
index 22c7ed6..088f278 100644
--- a/drivers/gpu/drm/i2c/Kconfig
+++ b/drivers/gpu/drm/i2c/Kconfig
@@ -28,6 +28,7 @@ config DRM_I2C_SIL164
 config DRM_I2C_NXP_TDA998X
tristate NXP Semiconductors TDA998X HDMI encoder
default m if DRM_TILCDC
+   select SND_SOC_HDMI_CODEC if SND_SOC
help
  Support for NXP Semiconductors TDA998X HDMI encoders.
 
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 4dc2dc0..8444e18 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -20,6 +20,7 @@
 #include linux/module.h
 #include linux/irq.h
 #include sound/asoundef.h
+#include sound/hdmi-codec.h
 
 #include drm/drmP.h
 #include drm/drm_crtc_helper.h
@@ -49,6 +50,8 @@ struct tda998x_priv {
u8 vip_cntrl_2;
struct tda998x_encoder_params params;
 
+   struct platform_device *audio_pdev;
+
wait_queue_head_t wq_edid;
volatile int wq_edid_wait;
struct drm_encoder *encoder;
@@ -435,7 +438,7 @@ out:
 }
 
 static void
-reg_write_range(struct tda998x_priv *priv, uint16_t reg, uint8_t *p, int cnt)
+reg_write_range(struct tda998x_priv *priv, uint16_t reg, const u8 *p, int cnt)
 {
struct i2c_client *client = priv-hdmi;
uint8_t buf[cnt+1];
@@ -619,7 +622,7 @@ tda998x_write_if(struct tda998x_priv *priv, uint8_t bit, 
uint16_t addr,
 }
 
 static void
-tda998x_write_aif(struct tda998x_priv *priv, struct tda998x_encoder_params *p)
+tda998x_write_raw_aif(struct tda998x_priv *priv, u8 *audio_frame)
 {
u8 buf[PB(HDMI_AUDIO_INFOFRAME_SIZE) + 1];
 
@@ -627,10 +630,10 @@ tda998x_write_aif(struct tda998x_priv *priv, struct 
tda998x_encoder_params *p)
buf[HB(0)] = HDMI_INFOFRAME_TYPE_AUDIO;
buf[HB(1)] = 0x01;
buf[HB(2)] = HDMI_AUDIO_INFOFRAME_SIZE;
-   buf[PB(1)] = p-audio_frame[1]  0x07; /* CC */
-   buf[PB(2)] = p-audio_frame[2]  0x1c; /* SF */
-   buf[PB(4)] = p-audio_frame[4];
-   buf[PB(5)] = p-audio_frame[5]  0xf8; /* DM_INH + LSV */
+   buf[PB(1)] = audio_frame[1]  0x07; /* CC */
+   buf[PB(2)] = audio_frame[2]  0x1c; /* SF */
+   buf[PB(4)] = audio_frame[4];
+   buf[PB(5)] = audio_frame[5]  0xf8; /* DM_INH + LSV */
 
buf[PB(0)] = tda998x_cksum(buf, sizeof(buf));
 
@@ -638,6 +641,24 @@ tda998x_write_aif(struct tda998x_priv *priv, struct 
tda998x_encoder_params *p)
 sizeof(buf));
 }
 
+static int tda998x_write_aif(struct tda998x_priv *priv,
+struct hdmi_audio_infoframe *cea)
+{
+   uint8_t buf[HDMI_INFOFRAME_SIZE(AUDIO)];
+   int len;
+
+   len = hdmi_audio_infoframe_pack(cea, buf, sizeof(buf));
+   if (len  0) {
+   dev_err(priv-hdmi-dev,
+   Failed to pack audio infoframe: %d\n, len);
+   return len;
+   }
+
+   /* Write the audio information packet */
+   tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf, len);
+   return 0;
+}
+
 static void
 tda998x_write_avi(struct tda998x_priv *priv, struct drm_display_mode *mode)
 {
@@ -670,19 +691,24 @@ static void tda998x_audio_mute(struct tda998x_priv *priv, 
bool on)
}
 }
 
-static void
+static int
 tda998x_configure_audio(struct tda998x_priv *priv,
-   struct drm_display_mode *mode, struct tda998x_encoder_params *p)
+   int mode_clock,
+   int ena_ap,
+   int dai_format,
+   int sample_width,
+   int sample_rate,
+   const u8 *status)
 {
uint8_t buf[6], clksel_aip, clksel_fs, cts_n, adiv;
uint32_t n;
 
/* Enable audio ports */
-   reg_write(priv, REG_ENA_AP, p-audio_cfg);
-   reg_write(priv, REG_ENA_ACLK, p-audio_clk_cfg);
+   reg_write(priv, REG_ENA_AP, ena_ap);
+   reg_write(priv, REG_ENA_ACLK, dai_format == AFMT_SPDIF ? 0 : 1);
 
/* Set audio input source */
-   switch (p-audio_format) {
+   switch (dai_format) {
case AFMT_SPDIF:
reg_write(priv, REG_MUX_AP, MUX_AP_SELECT_SPDIF);
clksel_aip

[PATCH RFC v3 5/7] drm/i2c: tda998x: Remove include/sound/tda998x.h and fix graph parsing

2015-08-14 Thread Jyri Sarha
Move struct tda998x_audio definition to tda998x_drv.c and remove
include/sound/tda998x.h. There is no external use for struct
tda998x_audio.

Fix graph parsing to allow ports to be inside a separate ports-node as
specified in Documentation/devicetree/bindings/graph.txt.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 59 +--
 include/sound/tda998x.h   |  8 --
 2 files changed, 32 insertions(+), 35 deletions(-)
 delete mode 100644 include/sound/tda998x.h

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 0952eac..4dc2dc0 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -27,10 +27,14 @@
 #include drm/drm_edid.h
 #include drm/drm_of.h
 #include drm/i2c/tda998x.h
-#include sound/tda998x.h
 
 #define DBG(fmt, ...) DRM_DEBUG(fmt\n, ##__VA_ARGS__)
 
+struct tda998x_audio {
+   u8 ports[2];/* AP value */
+   u8 port_types[2];   /* AFMT_xxx */
+};
+
 struct tda998x_priv {
struct i2c_client *cec;
struct i2c_client *hdmi;
@@ -1240,9 +1244,10 @@ static int tda998x_parse_ports(struct tda998x_priv *priv,
 {
struct device_node *of_port;
const char *port_type;
-   int ret, audio_index, reg, afmt;
+   int ret, audio_index, reg, afmt, rgb_initialized;
 
audio_index = 0;
+   rgb_initialized = 0;
for_each_child_of_node(np, of_port) {
if (!of_port-name
 || of_node_cmp(of_port-name, port) != 0)
@@ -1252,11 +1257,17 @@ static int tda998x_parse_ports(struct tda998x_priv 
*priv,
if (ret  0)
continue;
ret = of_property_read_u32(of_port, reg, reg);
+   if (ret  0) {
+   dev_err(priv-hdmi-dev, missing reg for %s\n,
+   port_type);
+   return ret;
+   }
if (strcmp(port_type, rgb) == 0) {
if (!ret) { /* video reg is optional */
priv-vip_cntrl_0 = reg  16;
priv-vip_cntrl_1 = reg  8;
priv-vip_cntrl_2 = reg;
+   rgb_initialized = 1;
}
continue;
}
@@ -1266,11 +1277,6 @@ static int tda998x_parse_ports(struct tda998x_priv *priv,
afmt = AFMT_SPDIF;
else
continue;
-   if (ret  0) {
-   dev_err(priv-hdmi-dev, missing reg for %s\n,
-   port_type);
-   return ret;
-   }
if (audio_index = ARRAY_SIZE(priv-audio.ports)) {
dev_err(priv-hdmi-dev, too many audio ports\n);
break;
@@ -1279,13 +1285,13 @@ static int tda998x_parse_ports(struct tda998x_priv 
*priv,
priv-audio.port_types[audio_index] = afmt;
audio_index++;
}
-   return 0;
+   return rgb_initialized;
 }
 
 static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
 {
struct device_node *np = client-dev.of_node;
-   struct device_node *of_port;
+   struct device_node *ports;
u32 video;
int rev_lo, rev_hi, ret;
unsigned short cec_addr;
@@ -1392,24 +1398,15 @@ static int tda998x_create(struct i2c_client *client, 
struct tda998x_priv *priv)
 
/* get the device tree parameters */
if (np) {
-   of_port = of_get_child_by_name(np, port);
-   if (of_port) {  /* graph of ports */
-   of_node_put(of_port);
-   ret = tda998x_parse_ports(priv, np);
-   if (ret  0)
-   goto fail;
-
-   /* initialize the default audio configuration */
-   if (priv-audio.ports[0]) {
-   priv-params.audio_cfg = priv-audio.ports[0];
-   priv-params.audio_format =
-   priv-audio.port_types[0];
-   priv-params.audio_clk_cfg =
-   priv-params.audio_format ==
-   AFMT_SPDIF ? 0 : 1;
-   }
-   } else {
-
+   ports = of_get_child_by_name(np, ports);
+   if (!ports)
+   ports = of_node_get(np);
+   /* graph of ports */
+   ret = tda998x_parse_ports(priv, ports);
+   of_node_put(ports);
+   if (ret  0)
+   goto fail;
+   if (ret == 0) {
/* optional video properties

[PATCH RFC v3 2/7] ASoC: hdmi: Remove obsolete dummy HDMI codec

2015-08-14 Thread Jyri Sarha
The hdmi stub codec has not been used since refactoring of OMAP HDMI
audio support.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 sound/soc/codecs/Kconfig  |   4 --
 sound/soc/codecs/Makefile |   2 -
 sound/soc/codecs/hdmi.c   | 109 --
 3 files changed, 115 deletions(-)
 delete mode 100644 sound/soc/codecs/hdmi.c

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index efaafce..fc8e729 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -76,7 +76,6 @@ config SND_SOC_ALL_CODECS
select SND_SOC_MAX9877 if I2C
select SND_SOC_MC13783 if MFD_MC13XXX
select SND_SOC_ML26124 if I2C
-   select SND_SOC_HDMI_CODEC
select SND_SOC_PCM1681 if I2C
select SND_SOC_PCM1792A if SPI_MASTER
select SND_SOC_PCM3008
@@ -432,9 +431,6 @@ config SND_SOC_BT_SCO
 config SND_SOC_DMIC
tristate
 
-config SND_SOC_HDMI_CODEC
-   tristate HDMI stub CODEC
-
 config SND_SOC_ES8328
tristate Everest Semi ES8328 CODEC
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index cf160d9..01b4601 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -69,7 +69,6 @@ snd-soc-max98925-objs := max98925.o
 snd-soc-max9850-objs := max9850.o
 snd-soc-mc13783-objs := mc13783.o
 snd-soc-ml26124-objs := ml26124.o
-snd-soc-hdmi-codec-objs := hdmi.o
 snd-soc-pcm1681-objs := pcm1681.o
 snd-soc-pcm1792a-codec-objs := pcm1792a.o
 snd-soc-pcm3008-objs := pcm3008.o
@@ -256,7 +255,6 @@ obj-$(CONFIG_SND_SOC_MAX98925)  += snd-soc-max98925.o
 obj-$(CONFIG_SND_SOC_MAX9850)  += snd-soc-max9850.o
 obj-$(CONFIG_SND_SOC_MC13783)  += snd-soc-mc13783.o
 obj-$(CONFIG_SND_SOC_ML26124)  += snd-soc-ml26124.o
-obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o
 obj-$(CONFIG_SND_SOC_PCM1681)  += snd-soc-pcm1681.o
 obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o
 obj-$(CONFIG_SND_SOC_PCM3008)  += snd-soc-pcm3008.o
diff --git a/sound/soc/codecs/hdmi.c b/sound/soc/codecs/hdmi.c
deleted file mode 100644
index bd42ad3..000
--- a/sound/soc/codecs/hdmi.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * ALSA SoC codec driver for HDMI audio codecs.
- * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
- * Author: Ricardo Neri ricardo.n...@ti.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#include linux/module.h
-#include sound/soc.h
-#include linux/of.h
-#include linux/of_device.h
-
-#define DRV_NAME hdmi-audio-codec
-
-static const struct snd_soc_dapm_widget hdmi_widgets[] = {
-   SND_SOC_DAPM_INPUT(RX),
-   SND_SOC_DAPM_OUTPUT(TX),
-};
-
-static const struct snd_soc_dapm_route hdmi_routes[] = {
-   { Capture, NULL, RX },
-   { TX, NULL, Playback },
-};
-
-static struct snd_soc_dai_driver hdmi_codec_dai = {
-   .name = hdmi-hifi,
-   .playback = {
-   .stream_name = Playback,
-   .channels_min = 2,
-   .channels_max = 8,
-   .rates = SNDRV_PCM_RATE_32000 |
-   SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
-   SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
-   SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
-   .formats = SNDRV_PCM_FMTBIT_S16_LE |
-   SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
-   .sig_bits = 24,
-   },
-   .capture = {
-   .stream_name = Capture,
-   .channels_min = 2,
-   .channels_max = 2,
-   .rates = SNDRV_PCM_RATE_32000 |
-   SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
-   SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
-   SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
-   .formats = SNDRV_PCM_FMTBIT_S16_LE |
-   SNDRV_PCM_FMTBIT_S24_LE,
-   },
-
-};
-
-#ifdef CONFIG_OF
-static const struct of_device_id hdmi_audio_codec_ids[] = {
-   { .compatible = linux,hdmi-audio, },
-   { }
-};
-MODULE_DEVICE_TABLE(of, hdmi_audio_codec_ids);
-#endif
-
-static struct snd_soc_codec_driver hdmi_codec = {
-   .dapm_widgets = hdmi_widgets,
-   .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),
-   .dapm_routes = hdmi_routes,
-   .num_dapm_routes = ARRAY_SIZE(hdmi_routes),
-   .ignore_pmdown_time

[PATCH RFC v3 3/7] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders

2015-08-14 Thread Jyri Sarha
The hdmi-codec is a platform device driver to be registered from
drivers of external HDMI encoders with I2S and/or spdif interface. The
driver in turn registers an ASoC codec for the HDMI encoder's audio
functionality.

The structures and definitions in the API header are mostly redundant
copies of similar structures in ASoC headers. This is on purpose to
avoid direct dependencies to ASoC structures in video side driver.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 include/sound/hdmi-codec.h|  99 +
 sound/soc/codecs/Kconfig  |   5 +
 sound/soc/codecs/Makefile |   2 +
 sound/soc/codecs/hdmi-codec.c | 467 ++
 4 files changed, 573 insertions(+)
 create mode 100644 include/sound/hdmi-codec.h
 create mode 100644 sound/soc/codecs/hdmi-codec.c

diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h
new file mode 100644
index 000..b8a90f7
--- /dev/null
+++ b/include/sound/hdmi-codec.h
@@ -0,0 +1,99 @@
+/*
+ * hdmi-codec.h - HDMI Codec driver API
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Author: Jyri Sarha jsa...@ti.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef __HDMI_CODEC_H__
+#define __HDMI_CODEC_H__
+
+#include linux/hdmi.h
+#include drm/drm_edid.h
+#include sound/asoundef.h
+#include uapi/sound/asound.h
+
+/*
+ * Protocol between ASoC cpu-dai and HDMI-encoder
+ */
+struct hdmi_codec_daifmt {
+   enum {
+   HDMI_I2S,
+   HDMI_RIGHT_J,
+   HDMI_LEFT_J,
+   HDMI_DSP_A,
+   HDMI_DSP_B,
+   HDMI_AC97,
+   HDMI_SPDIF,
+   } fmt;
+   int bit_clk_inv:1;
+   int frame_clk_inv:1;
+   int bit_clk_master:1;
+   int frame_clk_master:1;
+};
+
+/*
+ * HDMI audio parameters
+ */
+struct hdmi_codec_params {
+   struct hdmi_audio_infoframe cea;
+   struct snd_aes_iec958 iec;
+   int sample_rate;
+   int sample_width;
+   int channels;
+};
+
+struct hdmi_codec_ops {
+   /* For runtime clock configuration from ASoC machine driver.
+* A direct forward from set_sysclk in struct snd_soc_dai_ops.
+* Optional */
+   int (*set_clk)(struct device *dev, int clk_id, int freq);
+
+   /* Called when ASoC starts an audio stream setup. The call
+* provides an audio abort callback for stoping an ongoing
+* stream if the HDMI audio becomes unavailable.
+* Optional */
+   int (*audio_startup)(struct device *dev,
+void (*abort_cb)(struct device *dev));
+
+   /* Configures HDMI-encoder for audio stream.
+* Mandatory */
+   int (*hw_params)(struct device *dev,
+struct hdmi_codec_daifmt *fmt,
+struct hdmi_codec_params *hparms);
+
+   /* Shuts down the audio stream.
+* Mandatory */
+   void (*audio_shutdown)(struct device *dev);
+
+   /* Mute/unmute HDMI audio stream.
+* Optional */
+   int (*digital_mute)(struct device *dev, bool enable);
+
+   /* Provides EDID-Like-Data from connected HDMI device.
+* Optional */
+   int (*get_eld)(struct device *dev, uint8_t *buf, size_t len);
+};
+
+/* HDMI codec initalization data */
+struct hdmi_codec_pdata {
+   struct device *dev; /* The HDMI encoder registering the codec */
+   const struct hdmi_codec_ops *ops;
+   uint i2s:1;
+   uint spdif:1;
+   int max_i2s_channels;
+};
+
+#define HDMI_CODEC_DRV_NAME hdmi-audio-codec
+
+#endif /* __HDMI_CODEC_H__ */
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index fc8e729..a5cc574 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -76,6 +76,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_MAX9877 if I2C
select SND_SOC_MC13783 if MFD_MC13XXX
select SND_SOC_ML26124 if I2C
+   select SND_SOC_HDMI_CODEC
select SND_SOC_PCM1681 if I2C
select SND_SOC_PCM1792A if SPI_MASTER
select SND_SOC_PCM3008
@@ -431,6 +432,10 @@ config SND_SOC_BT_SCO
 config SND_SOC_DMIC
tristate
 
+config SND_SOC_HDMI_CODEC
+   tristate
+   select SND_PCM_ELD
+
 config SND_SOC_ES8328
tristate Everest Semi ES8328 CODEC
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 01b4601..0245e67 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -69,6 +69,7 @@ snd-soc-max98925-objs := max98925.o
 snd-soc-max9850-objs := max9850.o
 snd-soc-mc13783-objs := mc13783.o
 snd-soc-ml26124-objs

[PATCH RFC v3 1/7] drm/edid: add function to help find SADs, DO NOT MERGE

2015-08-14 Thread Jyri Sarha
From: Russell King - ARM Linux li...@arm.linux.org.uk

Add a function to find the start of the SADs in the ELD.  This
complements the helper to retrieve the SAD count.

Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk

This should already be coming in from drm-next.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 include/drm/drm_edid.h | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 7990501..53c53c4 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -348,6 +348,25 @@ static inline int drm_eld_mnl(const uint8_t *eld)
 }
 
 /**
+ * drm_eld_sad - Get ELD SAD structures.
+ * @eld: pointer to an eld memory structure with sad_count set
+ */
+static inline const uint8_t *drm_eld_sad(const uint8_t *eld)
+{
+   unsigned int ver, mnl;
+
+   ver = (eld[DRM_ELD_VER]  DRM_ELD_VER_MASK)  DRM_ELD_VER_SHIFT;
+   if (ver != 2  ver != 31)
+   return NULL;
+
+   mnl = drm_eld_mnl(eld);
+   if (mnl  16)
+   return NULL;
+
+   return eld + DRM_ELD_CEA_SAD(mnl, 0);
+}
+
+/**
  * drm_eld_sad_count - Get ELD SAD count.
  * @eld: pointer to an eld memory structure with sad_count set
  */
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/2] OMAPDSS: Fix omap_dss_find_output_by_port_node() port refcount decrement

2015-08-07 Thread Jyri Sarha
Fix omap_dss_find_output_by_port_node() port parameter refcount
decrementation. The only user of dss_of_port_get_parent_device()
function is omap_dss_find_output_by_port_node() and it assumes the
refcount of the port parameter is not decremented by the call.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/video/fbdev/omap2/dss/dss-of.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/omap2/dss/dss-of.c 
b/drivers/video/fbdev/omap2/dss/dss-of.c
index ab6ef16..43f999d 100644
--- a/drivers/video/fbdev/omap2/dss/dss-of.c
+++ b/drivers/video/fbdev/omap2/dss/dss-of.c
@@ -95,7 +95,7 @@ struct device_node *dss_of_port_get_parent_device(struct 
device_node *port)
if (!port)
return NULL;
 
-   np = of_get_next_parent(port);
+   np = of_get_parent(port);
 
for (i = 0; i  2  np; ++i) {
struct property *prop;
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/2] OMAPDSS: Fix node refcount leak in omapdss_of_get_next_port()

2015-08-07 Thread Jyri Sarha
Fix node refcount leak in omapdss_of_get_next_port().

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/video/fbdev/omap2/dss/dss-of.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/video/fbdev/omap2/dss/dss-of.c 
b/drivers/video/fbdev/omap2/dss/dss-of.c
index 928ee63..ab6ef16 100644
--- a/drivers/video/fbdev/omap2/dss/dss-of.c
+++ b/drivers/video/fbdev/omap2/dss/dss-of.c
@@ -60,6 +60,7 @@ omapdss_of_get_next_port(const struct device_node *parent,
}
prev = port;
} while (of_node_cmp(port-name, port) != 0);
+   of_node_put(ports);
}
 
return port;
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/2] OMAPDSS: Fix of-node refcount issues

2015-08-07 Thread Jyri Sarha
Changes since the first version:
- Fix commit descriptions and subject according to Tomi's comments

I found couple of refcounting issues related to OMAP DSS of-node
handling. Second patch should fix the ERROR: Bad of_node_put() on
/encoder@0/ports/port@1 -problem.

In the long run it would make sense start using of_graph_*() functions
in OMAP DSS too. However the semantics of of_graph_*() functions are
quite different from omapdss_of_*() counterparts. So it better to just
fix these bugs first.

Jyri Sarha (2):
  OMAPDSS: Fix node refcount leak in omapdss_of_get_next_port()
  OMAPDSS: Fix omap_dss_find_output_by_port_node() port refcount
decrement

 drivers/video/fbdev/omap2/dss/dss-of.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] OMAPDSS: dss-of: Fix node refcount leak in omapdss_of_get_next_port()

2015-08-06 Thread Jyri Sarha
Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/video/fbdev/omap2/dss/dss-of.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/video/fbdev/omap2/dss/dss-of.c 
b/drivers/video/fbdev/omap2/dss/dss-of.c
index 928ee63..ab6ef16 100644
--- a/drivers/video/fbdev/omap2/dss/dss-of.c
+++ b/drivers/video/fbdev/omap2/dss/dss-of.c
@@ -60,6 +60,7 @@ omapdss_of_get_next_port(const struct device_node *parent,
}
prev = port;
} while (of_node_cmp(port-name, port) != 0);
+   of_node_put(ports);
}
 
return port;
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/2] OMAPDSS: Fix of-node refcount issues

2015-08-06 Thread Jyri Sarha
I found couple of refcounting issues related to OMAP DSS of-node
handling. Second patch should fix the ERROR: Bad of_node_put() on
/encoder@0/ports/port@1 -problem.

In the long run it would make sense start using of_graph_*() functions
in OMAP DSS too. However the semantics of of_graph_*() functions are
quite different from omapdss_of_*() counterparts. So it better to just
fix these bugs first.

Jyri Sarha (2):
  OMAPDSS: dss-of: Fix node refcount leak in omapdss_of_get_next_port()
  OMAPDSS: of-dss: omap_dss_find_output_by_port_node() keep port
refcount

 drivers/video/fbdev/omap2/dss/dss-of.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] OMAPDSS: of-dss: omap_dss_find_output_by_port_node() keep port refcount

2015-08-06 Thread Jyri Sarha
The only user of dss_of_port_get_parent_device() function is
omap_dss_find_output_by_port_node() and it assumes the refcount of the
port parameter is not decremented by the call.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/video/fbdev/omap2/dss/dss-of.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/omap2/dss/dss-of.c 
b/drivers/video/fbdev/omap2/dss/dss-of.c
index ab6ef16..43f999d 100644
--- a/drivers/video/fbdev/omap2/dss/dss-of.c
+++ b/drivers/video/fbdev/omap2/dss/dss-of.c
@@ -95,7 +95,7 @@ struct device_node *dss_of_port_get_parent_device(struct 
device_node *port)
if (!port)
return NULL;
 
-   np = of_get_next_parent(port);
+   np = of_get_parent(port);
 
for (i = 0; i  2  np; ++i) {
struct property *prop;
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] drm/tilcdc: Allocate register storage based on the actual number registers

2015-07-03 Thread Jyri Sarha
Allocate suspend/resume register storage based on the actual number
registers the driver is aware of. The static allocation for register
storage had falen behind badly.

Reported-by: Michael Bode mich...@bumbleb.de
Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/gpu/drm/tilcdc/tilcdc_drv.c | 20 +++-
 drivers/gpu/drm/tilcdc/tilcdc_drv.h |  2 +-
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c 
b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 4908c1f..2f87263 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -139,11 +139,14 @@ static int tilcdc_unload(struct drm_device *dev)
 
pm_runtime_disable(dev-dev);
 
+   kfree(priv-saved_register);
kfree(priv);
 
return 0;
 }
 
+static size_t tilcdc_num_regs(void);
+
 static int tilcdc_load(struct drm_device *dev, unsigned long flags)
 {
struct platform_device *pdev = dev-platformdev;
@@ -155,7 +158,11 @@ static int tilcdc_load(struct drm_device *dev, unsigned 
long flags)
int ret;
 
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-   if (!priv) {
+   if (priv)
+   priv-saved_register = kcalloc(sizeof(*priv-saved_register),
+  tilcdc_num_regs(), GFP_KERNEL);
+   if (!priv || !priv-saved_register) {
+   kfree(priv);
dev_err(dev-dev, failed to allocate private data\n);
return -ENOMEM;
}
@@ -345,6 +352,7 @@ fail_free_wq:
 
 fail_free_priv:
dev-dev_private = NULL;
+   kfree(priv-saved_register);
kfree(priv);
return ret;
 }
@@ -467,6 +475,16 @@ static const struct {
REG(2, true,  LCDC_INT_ENABLE_SET_REG),
 #undef REG
 };
+
+static size_t tilcdc_num_regs(void)
+{
+   return ARRAY_SIZE(registers);
+}
+#else
+static size_t tilcdc_num_regs(void)
+{
+   return 0;
+}
 #endif
 
 #ifdef CONFIG_DEBUG_FS
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h 
b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
index e863ad0..bc94835 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
@@ -67,7 +67,7 @@ struct tilcdc_drm_private {
uint32_t max_width;
 
/* register contents saved across suspend/resume: */
-   u32 saved_register[12];
+   u32 *saved_register;
 
 #ifdef CONFIG_CPU_FREQ
struct notifier_block freq_transition;
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] drm/tilcdc: Implement dma-buf support for tilcdc

2015-06-30 Thread Jyri Sarha
There is nothing special about tilcdc HW when the video memory is
concerned. Just using the standard drm helpers for implementation is
enough.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/gpu/drm/tilcdc/tilcdc_drv.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c 
b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 0f283a3..4908c1f 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -553,7 +553,8 @@ static const struct file_operations fops = {
 };
 
 static struct drm_driver tilcdc_driver = {
-   .driver_features= DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET,
+   .driver_features= (DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET |
+  DRIVER_PRIME),
.load   = tilcdc_load,
.unload = tilcdc_unload,
.preclose   = tilcdc_preclose,
@@ -571,6 +572,16 @@ static struct drm_driver tilcdc_driver = {
.dumb_create= drm_gem_cma_dumb_create,
.dumb_map_offset= drm_gem_cma_dumb_map_offset,
.dumb_destroy   = drm_gem_dumb_destroy,
+
+   .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+   .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+   .gem_prime_import   = drm_gem_prime_import,
+   .gem_prime_export   = drm_gem_prime_export,
+   .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
+   .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
+   .gem_prime_vmap = drm_gem_cma_prime_vmap,
+   .gem_prime_vunmap   = drm_gem_cma_prime_vunmap,
+   .gem_prime_mmap = drm_gem_cma_prime_mmap,
 #ifdef CONFIG_DEBUG_FS
.debugfs_init   = tilcdc_debugfs_init,
.debugfs_cleanup= tilcdc_debugfs_cleanup,
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] drm/tilcdc: Fix bad if statement in tilcdc_get_external_components()

2015-06-12 Thread Jyri Sarha
The if statement condition should have been !node ||
!of_device_is_available(node) ( changed to ||), but let's rewrite
the whole inside of the loop for better readability.

Reported-by: Dan Carpenter dan.carpen...@oracle.com
Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/gpu/drm/tilcdc/tilcdc_external.c | 19 ---
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_external.c 
b/drivers/gpu/drm/tilcdc/tilcdc_external.c
index 03acb4f..a641808 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_external.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_external.c
@@ -142,19 +142,16 @@ int tilcdc_get_external_components(struct device *dev,
int count = 0;
 
while ((ep = of_graph_get_next_endpoint(dev-of_node, ep))) {
-   struct device_node *node;
-
-   node = of_graph_get_remote_port_parent(ep);
-   if (!node  !of_device_is_available(node)) {
-   of_node_put(node);
-   continue;
+   struct device_node *node = of_graph_get_remote_port_parent(ep);
+
+   if (node  of_device_is_available(node)) {
+   dev_dbg(dev, Subdevice node '%s' found\n, node-name);
+   if (match)
+   component_match_add(dev, match, dev_match_of,
+   node);
+   count++;
}
-
-   dev_dbg(dev, Subdevice node '%s' found\n, node-name);
-   if (match)
-   component_match_add(dev, match, dev_match_of, node);
of_node_put(node);
-   count++;
}
 
if (count  1) {
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] ASoC: davinci-mcasp: Choose PCM driver based on configured DMA controller

2015-06-02 Thread Jyri Sarha
Find the configured DMA controller by asking for a DMA channel in the
probe phase and releasing it right after. The controller device can be
found via the dma_chan struct and the controller is recognized from
the compatible property of its device node. The patch assumes EDMA if
there is no device node.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 sound/soc/davinci/davinci-mcasp.c | 61 ---
 1 file changed, 51 insertions(+), 10 deletions(-)

diff --git a/sound/soc/davinci/davinci-mcasp.c 
b/sound/soc/davinci/davinci-mcasp.c
index d793494..5bc2712 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -1565,6 +1565,46 @@ static int davinci_mcasp_init_ch_constraints(struct 
davinci_mcasp *mcasp)
return ret;
 }
 
+enum {
+   MCASP_EDMA = 1,
+   MCASP_SDMA,
+};
+static const char *sdma_prefix = ti,omap;
+
+static int davinci_mcasp_get_dma_type(struct davinci_mcasp *mcasp)
+{
+   struct dma_chan *chan;
+   const char *tmp;
+   int ret = MCASP_EDMA;
+
+   tmp = mcasp-dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data;
+   chan = dma_request_slave_channel_reason(mcasp-dev, tmp);
+   if (IS_ERR(chan)) {
+   if (PTR_ERR(chan) != -EPROBE_DEFER)
+   dev_err(mcasp-dev,
+   Can't verify DMA configuration (%ld)\n,
+   PTR_ERR(chan));
+   return PTR_ERR(chan);
+   }
+   BUG_ON(!chan-device || !chan-device-dev);
+
+   if (chan-device-dev-of_node)
+   ret = of_property_read_string(chan-device-dev-of_node,
+ compatible, tmp);
+   else
+   dev_dbg(mcasp-dev, DMA controller has no of-node\n);
+
+   dma_release_channel(chan);
+   if (ret)
+   return ret;
+
+   dev_dbg(mcasp-dev, DMA controller compatible = \%s\\n, tmp);
+   if (!strncmp(tmp, sdma_prefix, strlen(sdma_prefix)))
+   return MCASP_SDMA;
+
+   return MCASP_EDMA;
+}
+
 static int davinci_mcasp_probe(struct platform_device *pdev)
 {
struct snd_dmaengine_dai_dma_data *dma_data;
@@ -1763,27 +1803,28 @@ static int davinci_mcasp_probe(struct platform_device 
*pdev)
if (ret != 0)
goto err;
 
-   switch (mcasp-version) {
+   ret = -EINVAL;
+   switch (davinci_mcasp_get_dma_type(mcasp)) {
+   case MCASP_EDMA:
 #if IS_BUILTIN(CONFIG_SND_EDMA_SOC) || \
(IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP)  \
 IS_MODULE(CONFIG_SND_EDMA_SOC))
-   case MCASP_VERSION_1:
-   case MCASP_VERSION_2:
-   case MCASP_VERSION_3:
ret = edma_pcm_platform_register(pdev-dev);
-   break;
+#else
+   dev_err(pdev-dev, Missing SND_EDMA_SOC\n);
 #endif
+   break;
+   case MCASP_SDMA:
 #if IS_BUILTIN(CONFIG_SND_OMAP_SOC) || \
(IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP)  \
 IS_MODULE(CONFIG_SND_OMAP_SOC))
-   case MCASP_VERSION_4:
ret = omap_pcm_platform_register(pdev-dev);
-   break;
+#else
+   dev_err(pdev-dev, Missing SND_SDMA_SOC\n);
 #endif
+   break;
default:
-   dev_err(pdev-dev, Invalid McASP version: %d\n,
-   mcasp-version);
-   ret = -EINVAL;
+   dev_err(pdev-dev, No DMA controller found\n);
break;
}
 
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] ASoC: davinci-mcasp: Choose PCM driver based on configured DMA controller

2015-06-02 Thread Jyri Sarha

On 06/02/15 19:16, Misael Lopez Cruz wrote:

Jyri,

On 06/02/2015 08:49 AM, Jyri Sarha wrote:

Find the configured DMA controller by asking for a DMA channel in the
probe phase and releasing it right after. The controller device can be
found via the dma_chan struct and the controller is recognized from
the compatible property of its device node. The patch assumes EDMA if
there is no device node.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
Changes since first patch version:
- Change enum names from MCASP_?DMA to PCM_?DMA
- Return PCM_EDMA if !mcasp-dev-of_node
- Do not ignore possible error code returned by
   davinci_mcasp_get_dma_type()

  sound/soc/davinci/davinci-mcasp.c | 68
+--
  1 file changed, 58 insertions(+), 10 deletions(-)

diff --git a/sound/soc/davinci/davinci-mcasp.c
b/sound/soc/davinci/davinci-mcasp.c
index d793494..3b78c3e 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -1565,6 +1565,49 @@ static int
davinci_mcasp_init_ch_constraints(struct davinci_mcasp *mcasp)
  return ret;
  }

+enum {
+PCM_EDMA,
+PCM_SDMA,
+};
+static const char *sdma_prefix = ti,omap;
+
+static int davinci_mcasp_get_dma_type(struct davinci_mcasp *mcasp)
+{
+struct dma_chan *chan;
+const char *tmp;
+int ret = PCM_EDMA;
+
+if (!mcasp-dev-of_node)
+return PCM_EDMA;
+
+tmp = mcasp-dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data;
+chan = dma_request_slave_channel_reason(mcasp-dev, tmp);
+if (IS_ERR(chan)) {
+if (PTR_ERR(chan) != -EPROBE_DEFER)
+dev_err(mcasp-dev,
+Can't verify DMA configuration (%ld)\n,
+PTR_ERR(chan));
+return PTR_ERR(chan);
+}
+BUG_ON(!chan-device || !chan-device-dev);
+
+if (chan-device-dev-of_node)
+ret = of_property_read_string(chan-device-dev-of_node,
+  compatible, tmp);


I wonder how this is going to play out when the DMA crossbar is present
(i.e. dra7 family).

In that case, isn't the 'compatible' string here that of the DMA
crossbar (not the one from the DMA controller)?


That is exactly why I am requesting a channel and going from there. The 
DMA router will do its thing in the middle and the device pointer found 
via the returned dma_chan is pointing at the actual DMA controller.


I have tested the code on am57xx-beagle-x15, which is also using the DMA 
crossbar.





+else
+dev_dbg(mcasp-dev, DMA controller has no of-node\n);
+
+dma_release_channel(chan);
+if (ret)
+return ret;
+
+dev_dbg(mcasp-dev, DMA controller compatible = \%s\\n, tmp);
+if (!strncmp(tmp, sdma_prefix, strlen(sdma_prefix)))
+return PCM_SDMA;
+
+return PCM_EDMA;
+}
+
  static int davinci_mcasp_probe(struct platform_device *pdev)
  {
  struct snd_dmaengine_dai_dma_data *dma_data;
@@ -1763,27 +1806,32 @@ static int davinci_mcasp_probe(struct
platform_device *pdev)
  if (ret != 0)
  goto err;

-switch (mcasp-version) {
+ret = davinci_mcasp_get_dma_type(mcasp);
+switch (ret) {
+case PCM_EDMA:
  #if IS_BUILTIN(CONFIG_SND_EDMA_SOC) || \
  (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP)  \
   IS_MODULE(CONFIG_SND_EDMA_SOC))
-case MCASP_VERSION_1:
-case MCASP_VERSION_2:
-case MCASP_VERSION_3:
  ret = edma_pcm_platform_register(pdev-dev);
-break;
+#else
+dev_err(pdev-dev, Missing SND_EDMA_SOC\n);
+ret = -EINVAL;
  #endif
+break;
+case PCM_SDMA:
  #if IS_BUILTIN(CONFIG_SND_OMAP_SOC) || \
  (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP)  \
   IS_MODULE(CONFIG_SND_OMAP_SOC))
-case MCASP_VERSION_4:
  ret = omap_pcm_platform_register(pdev-dev);
-break;
+#else
+dev_err(pdev-dev, Missing SND_SDMA_SOC\n);
+ret = -EINVAL;
  #endif
+break;
+case -EPROBE_DEFER:
+break;
  default:
-dev_err(pdev-dev, Invalid McASP version: %d\n,
-mcasp-version);
-ret = -EINVAL;
+dev_err(pdev-dev, No DMA controller found (%d)\n, ret);
  break;
  }




--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3] ASoC: davinci-mcasp: Choose PCM driver based on configured DMA controller

2015-06-02 Thread Jyri Sarha
Find the configured DMA controller by asking for a DMA channel in the
probe phase and releasing it right after. The controller device can be
found via the dma_chan struct and the controller is recognized from
the compatible property of its device node. The patch assumes EDMA if
there is no device node.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
Changes since v2:
- Print only one error message if DMA probing fails
  and none in case of -EPROBE_DEFER

Changes since first patch version:
- Change enum names from MCASP_?DMA to PCM_?DMA
- Return PCM_EDMA if !mcasp-dev-of_node
- Do not ignore possible error code returned by
  davinci_mcasp_get_dma_type()

 sound/soc/davinci/davinci-mcasp.c | 70 +--
 1 file changed, 60 insertions(+), 10 deletions(-)

diff --git a/sound/soc/davinci/davinci-mcasp.c 
b/sound/soc/davinci/davinci-mcasp.c
index d793494..a73cd57 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -1565,6 +1565,49 @@ static int davinci_mcasp_init_ch_constraints(struct 
davinci_mcasp *mcasp)
return ret;
 }
 
+enum {
+   PCM_EDMA,
+   PCM_SDMA,
+};
+static const char *sdma_prefix = ti,omap;
+
+static int davinci_mcasp_get_dma_type(struct davinci_mcasp *mcasp)
+{
+   struct dma_chan *chan;
+   const char *tmp;
+   int ret = PCM_EDMA;
+
+   if (!mcasp-dev-of_node)
+   return PCM_EDMA;
+
+   tmp = mcasp-dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data;
+   chan = dma_request_slave_channel_reason(mcasp-dev, tmp);
+   if (IS_ERR(chan)) {
+   if (PTR_ERR(chan) != -EPROBE_DEFER)
+   dev_err(mcasp-dev,
+   Can't verify DMA configuration (%ld)\n,
+   PTR_ERR(chan));
+   return PTR_ERR(chan);
+   }
+   BUG_ON(!chan-device || !chan-device-dev);
+
+   if (chan-device-dev-of_node)
+   ret = of_property_read_string(chan-device-dev-of_node,
+ compatible, tmp);
+   else
+   dev_dbg(mcasp-dev, DMA controller has no of-node\n);
+
+   dma_release_channel(chan);
+   if (ret)
+   return ret;
+
+   dev_dbg(mcasp-dev, DMA controller compatible = \%s\\n, tmp);
+   if (!strncmp(tmp, sdma_prefix, strlen(sdma_prefix)))
+   return PCM_SDMA;
+
+   return PCM_EDMA;
+}
+
 static int davinci_mcasp_probe(struct platform_device *pdev)
 {
struct snd_dmaengine_dai_dma_data *dma_data;
@@ -1763,27 +1806,34 @@ static int davinci_mcasp_probe(struct platform_device 
*pdev)
if (ret != 0)
goto err;
 
-   switch (mcasp-version) {
+   ret = davinci_mcasp_get_dma_type(mcasp);
+   switch (ret) {
+   case PCM_EDMA:
 #if IS_BUILTIN(CONFIG_SND_EDMA_SOC) || \
(IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP)  \
 IS_MODULE(CONFIG_SND_EDMA_SOC))
-   case MCASP_VERSION_1:
-   case MCASP_VERSION_2:
-   case MCASP_VERSION_3:
ret = edma_pcm_platform_register(pdev-dev);
-   break;
+#else
+   dev_err(pdev-dev, Missing SND_EDMA_SOC\n);
+   ret = -EINVAL;
+   goto err;
 #endif
+   break;
+   case PCM_SDMA:
 #if IS_BUILTIN(CONFIG_SND_OMAP_SOC) || \
(IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP)  \
 IS_MODULE(CONFIG_SND_OMAP_SOC))
-   case MCASP_VERSION_4:
ret = omap_pcm_platform_register(pdev-dev);
-   break;
+#else
+   dev_err(pdev-dev, Missing SND_SDMA_SOC\n);
+   ret = -EINVAL;
+   goto err;
 #endif
+   break;
default:
-   dev_err(pdev-dev, Invalid McASP version: %d\n,
-   mcasp-version);
-   ret = -EINVAL;
+   dev_err(pdev-dev, No DMA controller found (%d)\n, ret);
+   case -EPROBE_DEFER:
+   goto err;
break;
}
 
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] ASoC: davinci-mcasp: Choose PCM driver based on configured DMA controller

2015-06-02 Thread Jyri Sarha

On 06/02/15 13:31, Peter Ujfalusi wrote:

On 06/02/2015 11:58 AM, Jyri Sarha wrote:

Find the configured DMA controller by asking for a DMA channel in the
probe phase and releasing it right after. The controller device can be
found via the dma_chan struct and the controller is recognized from
the compatible property of its device node. The patch assumes EDMA if
there is no device node.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
  sound/soc/davinci/davinci-mcasp.c | 61 ---
  1 file changed, 51 insertions(+), 10 deletions(-)

diff --git a/sound/soc/davinci/davinci-mcasp.c 
b/sound/soc/davinci/davinci-mcasp.c
index d793494..5bc2712 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -1565,6 +1565,46 @@ static int davinci_mcasp_init_ch_constraints(struct 
davinci_mcasp *mcasp)
return ret;
  }

+enum {
+   MCASP_EDMA = 1,


Why start from 1?


This is just an implementation detail, for if statement below. Maybe I 
should restucture for better readability.



I'm not sure about the name. It somehow implies that McASP has something to do
with the dma engine.
MCASP_SERVICED_BY_E/SDMA
PLATFORM_USES_E/SDMA

I can not come up with a decent name :(



What about PCM_EDMA/PCM_SDMA? This is a local definition after all.




+   MCASP_SDMA,
+};
+static const char *sdma_prefix = ti,omap;
+
+static int davinci_mcasp_get_dma_type(struct davinci_mcasp *mcasp)
+{
+   struct dma_chan *chan;
+   const char *tmp;
+   int ret = MCASP_EDMA;
+
+   tmp = mcasp-dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data;
+   chan = dma_request_slave_channel_reason(mcasp-dev, tmp);


this will return with error in case of !dev-of_node.
The first check should be:
if (!mcasp-dev-of_node)
return MCASP_EDMA;

since we can only boot in legacy mode with daVinci devices and they are using
eDMA.


+   if (IS_ERR(chan)) {
+   if (PTR_ERR(chan) != -EPROBE_DEFER)
+   dev_err(mcasp-dev,
+   Can't verify DMA configuration (%ld)\n,
+   PTR_ERR(chan));
+   return PTR_ERR(chan);
+   }
+   BUG_ON(!chan-device || !chan-device-dev);
+
+   if (chan-device-dev-of_node)
+   ret = of_property_read_string(chan-device-dev-of_node,
+ compatible, tmp);
+   else
+   dev_dbg(mcasp-dev, DMA controller has no of-node\n);


Now this is not likely to happen...



Not having of_node happens on am335x, but not having compatible property 
is unlikely...



+
+   dma_release_channel(chan);
+   if (ret)
+   return ret;
+
+   dev_dbg(mcasp-dev, DMA controller compatible = \%s\\n, tmp);
+   if (!strncmp(tmp, sdma_prefix, strlen(sdma_prefix)))
+   return MCASP_SDMA;
+
+   return MCASP_EDMA;
+}
+
  static int davinci_mcasp_probe(struct platform_device *pdev)
  {
struct snd_dmaengine_dai_dma_data *dma_data;
@@ -1763,27 +1803,28 @@ static int davinci_mcasp_probe(struct platform_device 
*pdev)
if (ret != 0)
goto err;

-   switch (mcasp-version) {
+   ret = -EINVAL;


Why? What was the problem with setting the ret in the default case?


+   switch (davinci_mcasp_get_dma_type(mcasp)) {
+   case MCASP_EDMA:
  #if IS_BUILTIN(CONFIG_SND_EDMA_SOC) || \
(IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP)  \
 IS_MODULE(CONFIG_SND_EDMA_SOC))
-   case MCASP_VERSION_1:
-   case MCASP_VERSION_2:
-   case MCASP_VERSION_3:
ret = edma_pcm_platform_register(pdev-dev);
-   break;
+#else
+   dev_err(pdev-dev, Missing SND_EDMA_SOC\n);
  #endif
+   break;
+   case MCASP_SDMA:
  #if IS_BUILTIN(CONFIG_SND_OMAP_SOC) || \
(IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP)  \
 IS_MODULE(CONFIG_SND_OMAP_SOC))
-   case MCASP_VERSION_4:
ret = omap_pcm_platform_register(pdev-dev);
-   break;
+#else
+   dev_err(pdev-dev, Missing SND_SDMA_SOC\n);
  #endif
+   break;
default:
-   dev_err(pdev-dev, Invalid McASP version: %d\n,
-   mcasp-version);
-   ret = -EINVAL;
+   dev_err(pdev-dev, No DMA controller found\n);
break;
}







--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] ASoC: davinci-mcasp: Choose PCM driver based on configured DMA controller

2015-06-02 Thread Jyri Sarha

I missed two comments first time around...

On 06/02/15 13:31, Peter Ujfalusi wrote:

On 06/02/2015 11:58 AM, Jyri Sarha wrote:

Find the configured DMA controller by asking for a DMA channel in the
probe phase and releasing it right after. The controller device can be
found via the dma_chan struct and the controller is recognized from
the compatible property of its device node. The patch assumes EDMA if
there is no device node.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
  sound/soc/davinci/davinci-mcasp.c | 61 ---
  1 file changed, 51 insertions(+), 10 deletions(-)

diff --git a/sound/soc/davinci/davinci-mcasp.c 
b/sound/soc/davinci/davinci-mcasp.c
index d793494..5bc2712 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -1565,6 +1565,46 @@ static int davinci_mcasp_init_ch_constraints(struct 
davinci_mcasp *mcasp)
return ret;
  }

+enum {
+   MCASP_EDMA = 1,


Why start from 1?
I'm not sure about the name. It somehow implies that McASP has something to do
with the dma engine.
MCASP_SERVICED_BY_E/SDMA
PLATFORM_USES_E/SDMA

I can not come up with a decent name :(



+   MCASP_SDMA,
+};
+static const char *sdma_prefix = ti,omap;
+
+static int davinci_mcasp_get_dma_type(struct davinci_mcasp *mcasp)
+{
+   struct dma_chan *chan;
+   const char *tmp;
+   int ret = MCASP_EDMA;
+
+   tmp = mcasp-dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data;
+   chan = dma_request_slave_channel_reason(mcasp-dev, tmp);


this will return with error in case of !dev-of_node.
The first check should be:
if (!mcasp-dev-of_node)
return MCASP_EDMA;

since we can only boot in legacy mode with daVinci devices and they are using
eDMA.



Yep, I'll add that back. I tought that I would not need it, but am not 
so familiar with the generic dmaengine pcm...



+   if (IS_ERR(chan)) {
+   if (PTR_ERR(chan) != -EPROBE_DEFER)
+   dev_err(mcasp-dev,
+   Can't verify DMA configuration (%ld)\n,
+   PTR_ERR(chan));
+   return PTR_ERR(chan);
+   }
+   BUG_ON(!chan-device || !chan-device-dev);
+
+   if (chan-device-dev-of_node)
+   ret = of_property_read_string(chan-device-dev-of_node,
+ compatible, tmp);
+   else
+   dev_dbg(mcasp-dev, DMA controller has no of-node\n);


Now this is not likely to happen...


+
+   dma_release_channel(chan);
+   if (ret)
+   return ret;
+
+   dev_dbg(mcasp-dev, DMA controller compatible = \%s\\n, tmp);
+   if (!strncmp(tmp, sdma_prefix, strlen(sdma_prefix)))
+   return MCASP_SDMA;
+
+   return MCASP_EDMA;
+}
+
  static int davinci_mcasp_probe(struct platform_device *pdev)
  {
struct snd_dmaengine_dai_dma_data *dma_data;
@@ -1763,27 +1803,28 @@ static int davinci_mcasp_probe(struct platform_device 
*pdev)
if (ret != 0)
goto err;

-   switch (mcasp-version) {
+   ret = -EINVAL;


Why? What was the problem with setting the ret in the default case?



I would need to have that I three places now for the #else cases, when 
devicetree tries to configure pcm driver that has not been compiled.



+   switch (davinci_mcasp_get_dma_type(mcasp)) {
+   case MCASP_EDMA:
  #if IS_BUILTIN(CONFIG_SND_EDMA_SOC) || \
(IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP)  \
 IS_MODULE(CONFIG_SND_EDMA_SOC))
-   case MCASP_VERSION_1:
-   case MCASP_VERSION_2:
-   case MCASP_VERSION_3:
ret = edma_pcm_platform_register(pdev-dev);
-   break;
+#else
+   dev_err(pdev-dev, Missing SND_EDMA_SOC\n);
  #endif
+   break;
+   case MCASP_SDMA:
  #if IS_BUILTIN(CONFIG_SND_OMAP_SOC) || \
(IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP)  \
 IS_MODULE(CONFIG_SND_OMAP_SOC))
-   case MCASP_VERSION_4:
ret = omap_pcm_platform_register(pdev-dev);
-   break;
+#else
+   dev_err(pdev-dev, Missing SND_SDMA_SOC\n);
  #endif
+   break;
default:
-   dev_err(pdev-dev, Invalid McASP version: %d\n,
-   mcasp-version);
-   ret = -EINVAL;
+   dev_err(pdev-dev, No DMA controller found\n);
break;
}







--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] ASoC: davinci-mcasp: Choose PCM driver based on configured DMA controller

2015-06-02 Thread Jyri Sarha
Find the configured DMA controller by asking for a DMA channel in the
probe phase and releasing it right after. The controller device can be
found via the dma_chan struct and the controller is recognized from
the compatible property of its device node. The patch assumes EDMA if
there is no device node.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
Changes since first patch version:
- Change enum names from MCASP_?DMA to PCM_?DMA
- Return PCM_EDMA if !mcasp-dev-of_node
- Do not ignore possible error code returned by
  davinci_mcasp_get_dma_type()

 sound/soc/davinci/davinci-mcasp.c | 68 +--
 1 file changed, 58 insertions(+), 10 deletions(-)

diff --git a/sound/soc/davinci/davinci-mcasp.c 
b/sound/soc/davinci/davinci-mcasp.c
index d793494..3b78c3e 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -1565,6 +1565,49 @@ static int davinci_mcasp_init_ch_constraints(struct 
davinci_mcasp *mcasp)
return ret;
 }
 
+enum {
+   PCM_EDMA,
+   PCM_SDMA,
+};
+static const char *sdma_prefix = ti,omap;
+
+static int davinci_mcasp_get_dma_type(struct davinci_mcasp *mcasp)
+{
+   struct dma_chan *chan;
+   const char *tmp;
+   int ret = PCM_EDMA;
+
+   if (!mcasp-dev-of_node)
+   return PCM_EDMA;
+
+   tmp = mcasp-dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data;
+   chan = dma_request_slave_channel_reason(mcasp-dev, tmp);
+   if (IS_ERR(chan)) {
+   if (PTR_ERR(chan) != -EPROBE_DEFER)
+   dev_err(mcasp-dev,
+   Can't verify DMA configuration (%ld)\n,
+   PTR_ERR(chan));
+   return PTR_ERR(chan);
+   }
+   BUG_ON(!chan-device || !chan-device-dev);
+
+   if (chan-device-dev-of_node)
+   ret = of_property_read_string(chan-device-dev-of_node,
+ compatible, tmp);
+   else
+   dev_dbg(mcasp-dev, DMA controller has no of-node\n);
+
+   dma_release_channel(chan);
+   if (ret)
+   return ret;
+
+   dev_dbg(mcasp-dev, DMA controller compatible = \%s\\n, tmp);
+   if (!strncmp(tmp, sdma_prefix, strlen(sdma_prefix)))
+   return PCM_SDMA;
+
+   return PCM_EDMA;
+}
+
 static int davinci_mcasp_probe(struct platform_device *pdev)
 {
struct snd_dmaengine_dai_dma_data *dma_data;
@@ -1763,27 +1806,32 @@ static int davinci_mcasp_probe(struct platform_device 
*pdev)
if (ret != 0)
goto err;
 
-   switch (mcasp-version) {
+   ret = davinci_mcasp_get_dma_type(mcasp);
+   switch (ret) {
+   case PCM_EDMA:
 #if IS_BUILTIN(CONFIG_SND_EDMA_SOC) || \
(IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP)  \
 IS_MODULE(CONFIG_SND_EDMA_SOC))
-   case MCASP_VERSION_1:
-   case MCASP_VERSION_2:
-   case MCASP_VERSION_3:
ret = edma_pcm_platform_register(pdev-dev);
-   break;
+#else
+   dev_err(pdev-dev, Missing SND_EDMA_SOC\n);
+   ret = -EINVAL;
 #endif
+   break;
+   case PCM_SDMA:
 #if IS_BUILTIN(CONFIG_SND_OMAP_SOC) || \
(IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP)  \
 IS_MODULE(CONFIG_SND_OMAP_SOC))
-   case MCASP_VERSION_4:
ret = omap_pcm_platform_register(pdev-dev);
-   break;
+#else
+   dev_err(pdev-dev, Missing SND_SDMA_SOC\n);
+   ret = -EINVAL;
 #endif
+   break;
+   case -EPROBE_DEFER:
+   break;
default:
-   dev_err(pdev-dev, Invalid McASP version: %d\n,
-   mcasp-version);
-   ret = -EINVAL;
+   dev_err(pdev-dev, No DMA controller found (%d)\n, ret);
break;
}
 
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 3/7] drm/tilcdc: Add support for external tda998x encoder

2015-05-27 Thread Jyri Sarha
Add support for an external compontised DRM encoder. The external
encoder can be connected to tilcdc trough device tree graph binding.
The binding document for tilcdc has been updated. The current
implementation supports only tda998x encoder.

To be able to filter out the unsupported video modes the tilcdc driver
needs to hijack the external connectors helper functions. The tilcdc
installes new helper functions that are otherwise identical to
orignals, but the mode_valid() call-back check the mode first localy,
before calling the original call-back. The tilcdc dirver restores the
original helper functions before it is unbound from the external
device.

I got the idea and some lines of code from Jean-Francois Moine's
drm/tilcdc: Change the interface with the tda998x driver-patch.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 .../devicetree/bindings/drm/tilcdc/tilcdc.txt  |  27 
 drivers/gpu/drm/tilcdc/Makefile|   1 +
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c   |  33 
 drivers/gpu/drm/tilcdc/tilcdc_drv.c|  85 +--
 drivers/gpu/drm/tilcdc/tilcdc_drv.h|   5 +
 drivers/gpu/drm/tilcdc/tilcdc_external.c   | 166 +
 drivers/gpu/drm/tilcdc/tilcdc_external.h   |  25 
 7 files changed, 329 insertions(+), 13 deletions(-)
 create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_external.c
 create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_external.h

diff --git a/Documentation/devicetree/bindings/drm/tilcdc/tilcdc.txt 
b/Documentation/devicetree/bindings/drm/tilcdc/tilcdc.txt
index fff10da..2136ee8 100644
--- a/Documentation/devicetree/bindings/drm/tilcdc/tilcdc.txt
+++ b/Documentation/devicetree/bindings/drm/tilcdc/tilcdc.txt
@@ -18,6 +18,12 @@ Optional properties:
  - max-pixelclock: The maximum pixel clock that can be supported
by the lcd controller in KHz.
 
+Optional nodes:
+
+ - port/ports: to describe a connection to an external encoder. The
+   binding follows Documentation/devicetree/bindings/graph.txt and
+   suppors a single port with a single endpoint.
+
 Example:
 
fb: fb@4830e000 {
@@ -26,4 +32,25 @@ Example:
interrupt-parent = intc;
interrupts = 36;
ti,hwmods = lcdc;
+
+   port {
+   lcdc_0: endpoint@0 {
+   remote-endpoint = hdmi_0;
+   };
+   };
+   };
+
+   tda19988: tda19988 {
+   compatible = nxp,tda998x;
+   reg = 0x70;
+
+   pinctrl-names = default, off;
+   pinctrl-0 = nxp_hdmi_bonelt_pins;
+   pinctrl-1 = nxp_hdmi_bonelt_off_pins;
+
+   port {
+   hdmi_0: endpoint@0 {
+   remote-endpoint = lcdc_0;
+   };
+   };
};
diff --git a/drivers/gpu/drm/tilcdc/Makefile b/drivers/gpu/drm/tilcdc/Makefile
index 44485f9..e1f738b 100644
--- a/drivers/gpu/drm/tilcdc/Makefile
+++ b/drivers/gpu/drm/tilcdc/Makefile
@@ -7,6 +7,7 @@ tilcdc-y := \
tilcdc_crtc.o \
tilcdc_tfp410.o \
tilcdc_panel.o \
+   tilcdc_external.o \
tilcdc_drv.o
 
 obj-$(CONFIG_DRM_TILCDC)   += tilcdc.o
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c 
b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index c2d5980..7d07733 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -37,6 +37,9 @@ struct tilcdc_crtc {
 
/* for deferred fb unref's: */
struct drm_flip_work unref_work;
+
+   /* Only set if an external encoder is connected */
+   bool simulate_vesa_sync;
 };
 #define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base)
 
@@ -214,6 +217,28 @@ static bool tilcdc_crtc_mode_fixup(struct drm_crtc *crtc,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
 {
+   struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
+
+   if (!tilcdc_crtc-simulate_vesa_sync)
+   return true;
+
+   /*
+* tilcdc does not generate VESA-compliant sync but aligns
+* VS on the second edge of HS instead of first edge.
+* We use adjusted_mode, to fixup sync by aligning both rising
+* edges and add HSKEW offset to fix the sync.
+*/
+   adjusted_mode-hskew = mode-hsync_end - mode-hsync_start;
+   adjusted_mode-flags |= DRM_MODE_FLAG_HSKEW;
+
+   if (mode-flags  DRM_MODE_FLAG_NHSYNC) {
+   adjusted_mode-flags |= DRM_MODE_FLAG_PHSYNC;
+   adjusted_mode-flags = ~DRM_MODE_FLAG_NHSYNC;
+   } else {
+   adjusted_mode-flags |= DRM_MODE_FLAG_NHSYNC;
+   adjusted_mode-flags = ~DRM_MODE_FLAG_PHSYNC;
+   }
+
return true;
 }
 
@@ -534,6 +559,14 @@ void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc,
tilcdc_crtc-info = info;
 }
 
+void

[PATCH v6 7/7] ARM: dts: am335x-boneblack: Use new binding for HDMI

2015-05-27 Thread Jyri Sarha
Use new binding for the external tda19988 HDMI encoder.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 arch/arm/boot/dts/am335x-boneblack.dts | 20 +++-
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/am335x-boneblack.dts 
b/arch/arm/boot/dts/am335x-boneblack.dts
index 5c42d25..eadbba3 100644
--- a/arch/arm/boot/dts/am335x-boneblack.dts
+++ b/arch/arm/boot/dts/am335x-boneblack.dts
@@ -68,16 +68,26 @@
 
 lcdc {
status = okay;
+   port {
+   lcdc_0: endpoint@0 {
+   remote-endpoint = hdmi_0;
+   };
+   };
 };
 
-/ {
-   hdmi {
-   compatible = ti,tilcdc,slave;
-   i2c = i2c0;
+i2c0 {
+   tda19988 {
+   compatible = nxp,tda998x;
+   reg = 0x70;
pinctrl-names = default, off;
pinctrl-0 = nxp_hdmi_bonelt_pins;
pinctrl-1 = nxp_hdmi_bonelt_off_pins;
-   status = okay;
+
+   port {
+   hdmi_0: endpoint@0 {
+   remote-endpoint = lcdc_0;
+   };
+   };
};
 };
 
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 4/7] drm/tilcdc: use pm_runtime_irq_safe()

2015-05-27 Thread Jyri Sarha
From: Tomi Valkeinen tomi.valkei...@ti.com

tilcdc calls runtime PM get/put functions everywhere. Some of those
places will be called in irq context, crashing the driver.

As a quick fix, use pm_runtime_irq_safe() for tilcdc.

Signed-off-by: Tomi Valkeinen tomi.valkei...@ti.com
Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/gpu/drm/tilcdc/tilcdc_drv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c 
b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index fcc0508..0f283a3 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -227,6 +227,7 @@ static int tilcdc_load(struct drm_device *dev, unsigned 
long flags)
DBG(Maximum Pixel Clock Value %dKHz, priv-max_pixelclock);
 
pm_runtime_enable(dev-dev);
+   pm_runtime_irq_safe(dev-dev);
 
/* Determine LCD IP Version */
pm_runtime_get_sync(dev-dev);
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 5/7] drm/tilcdc: Add DRM_TILCDC_SLAVE_COMPAT for ti,tilcdc,slave binding support

2015-05-27 Thread Jyri Sarha
Adds a CONFIG_DRM_TILCDC_SLAVE_COMPAT module for ti,tilcdc,slave
node conversion. The implementation is in tilcdc_slave_compat.c and it
uses tilcdc_slave_compat.dts as a basis for creating a DTS
overlay. The DTS overlay adds an external tda998x encoder to tilcdc
that corresponds to the old tda998x based slave encoder.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/gpu/drm/tilcdc/Kconfig |  12 ++
 drivers/gpu/drm/tilcdc/Makefile|   3 +
 drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c   | 270 +
 drivers/gpu/drm/tilcdc/tilcdc_slave_compat.dts |  72 +++
 drivers/gpu/drm/tilcdc/tilcdc_slave_compat.h   |  25 +++
 5 files changed, 382 insertions(+)
 create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c
 create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_slave_compat.dts
 create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_slave_compat.h

diff --git a/drivers/gpu/drm/tilcdc/Kconfig b/drivers/gpu/drm/tilcdc/Kconfig
index 8394a0b..78beafb 100644
--- a/drivers/gpu/drm/tilcdc/Kconfig
+++ b/drivers/gpu/drm/tilcdc/Kconfig
@@ -12,3 +12,15 @@ config DRM_TILCDC
  Choose this option if you have an TI SoC with LCDC display
  controller, for example AM33xx in beagle-bone, DA8xx, or
  OMAP-L1xx.  This driver replaces the FB_DA8XX fbdev driver.
+
+config DRM_TILCDC_SLAVE_COMPAT
+   bool Support device tree blobs using TI LCDC Slave binding
+   depends on DRM_TILCDC
+   default y
+   select OF_RESOLVE
+   select OF_OVERLAY
+   help
+ Choose this option if you need a kernel that is compatible
+ with device tree blobs using the obsolete ti,tilcdc,slave
+ binding. If you find ti,tilcdc,slave-string from your DTB,
+ you probably need this. Otherwise you do not.
diff --git a/drivers/gpu/drm/tilcdc/Makefile b/drivers/gpu/drm/tilcdc/Makefile
index e1f738b..deeca48 100644
--- a/drivers/gpu/drm/tilcdc/Makefile
+++ b/drivers/gpu/drm/tilcdc/Makefile
@@ -3,6 +3,9 @@ ifeq (, $(findstring -W,$(EXTRA_CFLAGS)))
ccflags-y += -Werror
 endif
 
+obj-$(CONFIG_DRM_TILCDC_SLAVE_COMPAT) += tilcdc_slave_compat.o \
+tilcdc_slave_compat.dtb.o
+
 tilcdc-y := \
tilcdc_crtc.o \
tilcdc_tfp410.o \
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c 
b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c
new file mode 100644
index 000..106679b
--- /dev/null
+++ b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2015 Texas Instruments
+ * Author: Jyri Sarha jsa...@ti.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ */
+
+/*
+ * To support the old ti,tilcdc,slave binding the binding has to be
+ * transformed to the new external encoder binding.
+ */
+
+#include linux/kernel.h
+#include linux/of.h
+#include linux/of_graph.h
+#include linux/of_fdt.h
+#include linux/slab.h
+#include linux/list.h
+
+#include tilcdc_slave_compat.h
+
+struct kfree_table {
+   int total;
+   int num;
+   void **table;
+};
+
+static int __init kfree_table_init(struct kfree_table *kft)
+{
+   kft-total = 32;
+   kft-num = 0;
+   kft-table = kmalloc(kft-total * sizeof(*kft-table),
+GFP_KERNEL);
+   if (!kft-table)
+   return -ENOMEM;
+
+   return 0;
+}
+
+static int __init kfree_table_add(struct kfree_table *kft, void *p)
+{
+   if (kft-num == kft-total) {
+   void **old = kft-table;
+
+   kft-total *= 2;
+   kft-table = krealloc(old, kft-total * sizeof(*kft-table),
+ GFP_KERNEL);
+   if (!kft-table) {
+   kft-table = old;
+   kfree(p);
+   return -ENOMEM;
+   }
+   }
+   kft-table[kft-num++] = p;
+   return 0;
+}
+
+static void __init kfree_table_free(struct kfree_table *kft)
+{
+   int i;
+
+   for (i = 0; i  kft-num; i++)
+   kfree(kft-table[i]);
+
+   kfree(kft-table);
+}
+
+static
+struct property * __init tilcdc_prop_dup(const struct property *prop,
+struct kfree_table *kft)
+{
+   struct property *nprop;
+
+   nprop = kzalloc(sizeof(*nprop), GFP_KERNEL);
+   if (!nprop || kfree_table_add(kft, nprop))
+   return NULL;
+
+   nprop-name = kstrdup(prop-name, GFP_KERNEL);
+   if (!nprop-name || kfree_table_add(kft, nprop-name))
+   return NULL;
+
+   nprop-value = kmemdup(prop-value, prop-length, GFP_KERNEL);
+   if (!nprop-value || kfree_table_add(kft, nprop-value))
+   return NULL;
+
+   nprop-length = prop-length;
+
+   return nprop;
+}
+
+static void __init tilcdc_copy_props(struct device_node *from

[PATCH v6 2/7] drm/tilcdc: Remove tilcdc slave support for tda998x driver

2015-05-27 Thread Jyri Sarha
Remove tilcdc slave support for tda998x driver. The tilcdc slave
support would conflicts with componentized use of tda998x.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 .../devicetree/bindings/drm/tilcdc/slave.txt   |  18 -
 drivers/gpu/drm/tilcdc/Makefile|   1 -
 drivers/gpu/drm/tilcdc/tilcdc_drv.c|  13 -
 drivers/gpu/drm/tilcdc/tilcdc_drv.h|   1 -
 drivers/gpu/drm/tilcdc/tilcdc_slave.c  | 411 -
 drivers/gpu/drm/tilcdc/tilcdc_slave.h  |  26 --
 6 files changed, 470 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/drm/tilcdc/slave.txt
 delete mode 100644 drivers/gpu/drm/tilcdc/tilcdc_slave.c
 delete mode 100644 drivers/gpu/drm/tilcdc/tilcdc_slave.h

diff --git a/Documentation/devicetree/bindings/drm/tilcdc/slave.txt 
b/Documentation/devicetree/bindings/drm/tilcdc/slave.txt
deleted file mode 100644
index 3d2c524..000
--- a/Documentation/devicetree/bindings/drm/tilcdc/slave.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-Device-Tree bindings for tilcdc DRM encoder slave output driver
-
-Required properties:
- - compatible: value should be ti,tilcdc,slave.
- - i2c: the phandle for the i2c device the encoder slave is connected to
-
-Recommended properties:
- - pinctrl-names, pinctrl-0: the pincontrol settings to configure
-   muxing properly for pins that connect to TFP410 device
-
-Example:
-
-   hdmi {
-   compatible = ti,tilcdc,slave;
-   i2c = i2c0;
-   pinctrl-names = default;
-   pinctrl-0 = nxp_hdmi_bonelt_pins;
-   };
diff --git a/drivers/gpu/drm/tilcdc/Makefile b/drivers/gpu/drm/tilcdc/Makefile
index 7d2eefe..44485f9 100644
--- a/drivers/gpu/drm/tilcdc/Makefile
+++ b/drivers/gpu/drm/tilcdc/Makefile
@@ -6,7 +6,6 @@ endif
 tilcdc-y := \
tilcdc_crtc.o \
tilcdc_tfp410.o \
-   tilcdc_slave.o \
tilcdc_panel.o \
tilcdc_drv.o
 
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c 
b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 095fca9..0f1e099 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -20,13 +20,11 @@
 #include tilcdc_drv.h
 #include tilcdc_regs.h
 #include tilcdc_tfp410.h
-#include tilcdc_slave.h
 #include tilcdc_panel.h
 
 #include drm_fb_helper.h
 
 static LIST_HEAD(module_list);
-static bool slave_probing;
 
 void tilcdc_module_init(struct tilcdc_module *mod, const char *name,
const struct tilcdc_module_ops *funcs)
@@ -42,11 +40,6 @@ void tilcdc_module_cleanup(struct tilcdc_module *mod)
list_del(mod-list);
 }
 
-void tilcdc_slave_probedefer(bool defered)
-{
-   slave_probing = defered;
-}
-
 static struct of_device_id tilcdc_of_match[];
 
 static struct drm_framebuffer *tilcdc_fb_create(struct drm_device *dev,
@@ -620,10 +613,6 @@ static int tilcdc_pdev_probe(struct platform_device *pdev)
return -ENXIO;
}
 
-   /* defer probing if slave is in deferred probing */
-   if (slave_probing == true)
-   return -EPROBE_DEFER;
-
return drm_platform_init(tilcdc_driver, pdev);
 }
 
@@ -654,7 +643,6 @@ static int __init tilcdc_drm_init(void)
 {
DBG(init);
tilcdc_tfp410_init();
-   tilcdc_slave_init();
tilcdc_panel_init();
return platform_driver_register(tilcdc_platform_driver);
 }
@@ -664,7 +652,6 @@ static void __exit tilcdc_drm_fini(void)
DBG(fini);
platform_driver_unregister(tilcdc_platform_driver);
tilcdc_panel_fini();
-   tilcdc_slave_fini();
tilcdc_tfp410_fini();
 }
 
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h 
b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
index 7596c14..6336512 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
@@ -116,7 +116,6 @@ struct tilcdc_module {
 void tilcdc_module_init(struct tilcdc_module *mod, const char *name,
const struct tilcdc_module_ops *funcs);
 void tilcdc_module_cleanup(struct tilcdc_module *mod);
-void tilcdc_slave_probedefer(bool defered);
 
 /* Panel config that needs to be set in the crtc, but is not coming from
  * the mode timings.  The display module is expected to call
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave.c 
b/drivers/gpu/drm/tilcdc/tilcdc_slave.c
deleted file mode 100644
index 3775fd4..000
--- a/drivers/gpu/drm/tilcdc/tilcdc_slave.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- * Copyright (C) 2012 Texas Instruments
- * Author: Rob Clark robdcl...@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You

[PATCH v6 6/7] drm/tilcdc: Force building of DRM_TILCDC_SLAVE_COMPAT

2015-05-27 Thread Jyri Sarha
If I read Documentation/kbuild/makefiles.txt section 3.6 right, this
patch should not be needed. However, without this patch the objects
needed for DRM_TILCDC_SLAVE_COMPAT are not linked, if DRM_TILCDC is
built as module.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/gpu/drm/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 7d4944e..6081fa6 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -60,7 +60,7 @@ obj-$(CONFIG_DRM_ATMEL_HLCDC) += atmel-hlcdc/
 obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/
 obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
 obj-$(CONFIG_DRM_OMAP) += omapdrm/
-obj-$(CONFIG_DRM_TILCDC)   += tilcdc/
+obj-y  += tilcdc/
 obj-$(CONFIG_DRM_QXL) += qxl/
 obj-$(CONFIG_DRM_BOCHS) += bochs/
 obj-$(CONFIG_DRM_MSM) += msm/
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 0/7] Use DRM component API in tilcdc to connect to tda998x

2015-05-27 Thread Jyri Sarha
Like the last time, for all that I know this should be good for taking :).

Changes since v5
* Move DRM_TILCDC_SLAVE_COMPAT after DRM_TILCDC in .../drm/tilcdc/Kconfig
* Add drm/tilcdc: use pm_runtime_irq_safe()-patch

Changes since v4
* Rebased on top linux-4.1-rc2
* Drop drm/tilcdc: Decrement refcount of ep-node from of_graph_get_next_...
* Make connector_funcs const in struct tilcdc_drm_private because
  struct drm_connector's helper_private has been qualified as const in
  linux-4.1
* Check if a subcomponent has already triggered the unloading.
  - Fixes an oops if the external encoder is unloaded first and tilcdc after
* Add comment to explain hijacking of external drm connectors helper hijacking

Changes since v3 version of the patch-set:
* drm/tilcdc: Add support for external tda998x encoder
 - Hijack external connectors helper functions
 - Remove select of nonexistent DRM_TILCDC_INIT in tilcdc Kconfig
 - Correct author mail address to tilcdc_exteral.h
* drm/tilcdc: Add DRM_TILCDC_SLAVE_COMPAT for ti,tilcdc,slave binding
 - Add a header file for tilcdc_slave_compat.dtb symbol declarations

Changes since v2 version of the patch-set:
- use obj-y in Makefle for tilcdc subdir in:
  drm/tilcdc: Force building of DRM_TILCDC_SLAVE_COMPAT
- move to last:
  drm/tilcdc: Decrement refcount of ep-node from of_graph_get_next_endpoint

Changes since first version of the patch-set:
- Rename DRM_TILCDC_INIT to DRM_TILCDC_SLAVE_COMPAT and make it visible
- Add separate: 
  drm/tilcdc: Decrement refcount of ep-node from of_graph_get_next_endpoint
- Reduce info-level spam
- Use component_master_add_with_match()
- Be more explicit about tda998x being the only supported external encoder

Remove tilcdc slave support and connect to tda998x trough its
component DRM API. For dtb backward compatibility the code creates at
boot time a DT overlay based on the earlier binding. The overlay
conforms to the new graph based binding.

The drm/tilcdc: Decrement refcount of ep-node from
of_graph_get_next_endpoint should probably not be merged. The of:
Decrement refcount of previous endpoint in of_graph_get_next_endpoint
is eventually going to be merged and before that leaking of two
of-node refcount increments each time the module is loaded is not that
serious. The of-nodes live forever anyway.

The merge of the dts patch can be delayed until the next merger
window, when the other patches are already in. The
DRM_TILCDC_SLAVE_COMPAT should keep the bbb HDMI operational until
then.

The first patch is just a bugfix and can be applied or dropped
independently.

Jyri Sarha (6):
  drm/tilcdc: Fix module unloading
  drm/tilcdc: Remove tilcdc slave support for tda998x driver
  drm/tilcdc: Add support for external tda998x encoder
  drm/tilcdc: Add DRM_TILCDC_SLAVE_COMPAT for ti,tilcdc,slave binding
support
  drm/tilcdc: Force building of DRM_TILCDC_SLAVE_COMPAT
  ARM: dts: am335x-boneblack: Use new binding for HDMI

Tomi Valkeinen (1):
  drm/tilcdc: use pm_runtime_irq_safe()

 .../devicetree/bindings/drm/tilcdc/slave.txt   |  18 -
 .../devicetree/bindings/drm/tilcdc/tilcdc.txt  |  27 ++
 arch/arm/boot/dts/am335x-boneblack.dts |  20 +-
 drivers/gpu/drm/Makefile   |   2 +-
 drivers/gpu/drm/tilcdc/Kconfig |  12 +
 drivers/gpu/drm/tilcdc/Makefile|   5 +-
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c   |  36 +-
 drivers/gpu/drm/tilcdc/tilcdc_drv.c|  99 +++--
 drivers/gpu/drm/tilcdc/tilcdc_drv.h|   6 +-
 drivers/gpu/drm/tilcdc/tilcdc_external.c   | 166 +
 drivers/gpu/drm/tilcdc/tilcdc_external.h   |  25 ++
 drivers/gpu/drm/tilcdc/tilcdc_slave.c  | 411 -
 drivers/gpu/drm/tilcdc/tilcdc_slave.h  |  26 --
 drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c   | 270 ++
 drivers/gpu/drm/tilcdc/tilcdc_slave_compat.dts |  72 
 drivers/gpu/drm/tilcdc/tilcdc_slave_compat.h   |  25 ++
 16 files changed, 730 insertions(+), 490 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/drm/tilcdc/slave.txt
 create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_external.c
 create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_external.h
 delete mode 100644 drivers/gpu/drm/tilcdc/tilcdc_slave.c
 delete mode 100644 drivers/gpu/drm/tilcdc/tilcdc_slave.h
 create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c
 create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_slave_compat.dts
 create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_slave_compat.h

-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 1/7] drm/tilcdc: Fix module unloading

2015-05-27 Thread Jyri Sarha
Force crtc dpms off before destroying the crtc instead of just
checking the dpms state. This fixes warning message and frozen picture
after tilcdc module unloading.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c 
b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index c735884..c2d5980 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -135,11 +135,12 @@ static void stop(struct drm_crtc *crtc)
tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
 }
 
+static void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode);
 static void tilcdc_crtc_destroy(struct drm_crtc *crtc)
 {
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
 
-   WARN_ON(tilcdc_crtc-dpms == DRM_MODE_DPMS_ON);
+   tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
 
drm_crtc_cleanup(crtc);
drm_flip_work_cleanup(tilcdc_crtc-unref_work);
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC v2 4/7] ASoC: hdmi-codec: Add ELD based audio pcm rules DO NOT MERGE

2015-05-26 Thread Jyri Sarha
This patch is mostly just a copy paste from Russel King's generic
patchs[1] for the same thing. The patche is included only for testing
purposes. Do not merge!

[1] http://lists.freedesktop.org/archives/dri-devel/2015-April/080525.html

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 sound/soc/codecs/hdmi-codec.c | 104 +-
 1 file changed, 103 insertions(+), 1 deletion(-)

diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index c208cef..2d26ce8 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -78,6 +78,103 @@ static int hdmi_codec_new_stream(struct snd_pcm_substream 
*substream,
return ret;
 }
 
+static const uint8_t *eld_sad(const uint8_t *eld)
+{
+   unsigned int ver, mnl;
+
+   ver = (eld[DRM_ELD_VER]  DRM_ELD_VER_MASK)  DRM_ELD_VER_SHIFT;
+   if (ver != 2  ver != 31)
+   return NULL;
+
+   mnl = drm_eld_mnl(eld);
+   if (mnl  16)
+   return NULL;
+
+   return eld + DRM_ELD_CEA_SAD(mnl, 0);
+}
+
+static const unsigned int eld_rates[] = {
+   32000,
+   44100,
+   48000,
+   88200,
+   96000,
+   176400,
+   192000,
+};
+
+static int eld_limit_rates(struct snd_pcm_hw_params *params,
+  struct snd_pcm_hw_rule *rule)
+{
+   struct snd_interval *r = hw_param_interval(params, rule-var);
+   unsigned int rate_mask = 7, i;
+   const u8 *sad, *eld = rule-private;
+
+   sad = eld_sad(eld);
+   if (sad) {
+   for (i = drm_eld_sad_count(eld); i  0; i--, sad += 3) {
+   unsigned channels = 1 + (sad[0]  7);
+
+   /*
+* Exclude SADs which do not include the
+* requested number of channels.
+*/
+   if (params_channels(params) == channels)
+   rate_mask |= sad[1];
+   }
+   }
+
+   return snd_interval_list(r, ARRAY_SIZE(eld_rates), eld_rates,
+rate_mask);
+}
+
+static int eld_limit_channels(struct snd_pcm_hw_params *params,
+ struct snd_pcm_hw_rule *rule)
+{
+   struct snd_interval *var = hw_param_interval(params, rule-var);
+   struct snd_interval t = { .min = 1, .max = 2, .integer = 1, };
+   unsigned int i, j;
+   const u8 *sad, *eld = rule-private;
+   int rate = params_rate(params);
+
+   sad = eld_sad(eld);
+   if (!sad)
+   return 0;
+
+   for (i = drm_eld_sad_count(eld); i  0; i--, sad += 3) {
+   for (j = 0; j  ARRAY_SIZE(eld_rates); j++) {
+   if ((sad[1]  (1j))  rate == eld_rates[j]) {
+   switch (sad[0]  0x78) {
+   case 0x08:
+   t.max = max(t.max, (sad[0]  7) + 1u);
+   break;
+   }
+   }
+   }
+   }
+
+   return snd_interval_refine(var, t);
+}
+
+static int hdmi_codec_constraint_eld(struct snd_pcm_runtime *runtime, void 
*eld)
+{
+   int ret;
+
+   ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ eld_limit_rates, eld,
+ SNDRV_PCM_HW_PARAM_RATE,
+ SNDRV_PCM_HW_PARAM_CHANNELS, -1);
+   if (ret  0)
+   return ret;
+
+   ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ eld_limit_channels, eld,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ SNDRV_PCM_HW_PARAM_RATE, -1);
+
+   return ret;
+}
+
 static int hdmi_codec_startup(struct snd_pcm_substream *substream,
  struct snd_soc_dai *dai)
 {
@@ -104,7 +201,12 @@ static int hdmi_codec_startup(struct snd_pcm_substream 
*substream,
if (hcp-hcd.ops-get_eld) {
hcp-eld = hcp-hcd.ops-get_eld(hcp-hcd.dev);
 
-   /* Call snd_pcm_hw_constraint_eld here */
+   if (hcp-eld) {
+   ret = hdmi_codec_constraint_eld(substream-runtime,
+   hcp-eld);
+   if (ret)
+   return ret;
+   }
}
return 0;
 }
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC v2 3/7] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders

2015-05-26 Thread Jyri Sarha
The hdmi-codec is a platform device driver to be registered from
drivers of external HDMI encoders with I2S and/or spdif interface. The
driver in turn registers an ASoC codec for the encoder's audio
functionality.

The structures and definitions in the API header are mostly redundant
copies of similar structures in ASoC headers. This is on purpose to
avoid direct dependencies to ASoC structures in video side driver.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 include/sound/hdmi-codec.h|  99 +
 sound/soc/codecs/Kconfig  |   4 +
 sound/soc/codecs/Makefile |   2 +
 sound/soc/codecs/hdmi-codec.c | 458 ++
 4 files changed, 563 insertions(+)
 create mode 100644 include/sound/hdmi-codec.h
 create mode 100644 sound/soc/codecs/hdmi-codec.c

diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h
new file mode 100644
index 000..0632bcb
--- /dev/null
+++ b/include/sound/hdmi-codec.h
@@ -0,0 +1,99 @@
+/*
+ * hdmi-codec.h - HDMI Codec driver API
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Author: Jyri Sarha jsa...@ti.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef __HDMI_CODEC_H__
+#define __HDMI_CODEC_H__
+
+#include linux/hdmi.h
+#include drm/drm_edid.h
+#include sound/asoundef.h
+#include uapi/sound/asound.h
+
+/*
+ * Protocol between ASoC cpu-dai and HDMI-encoder
+ */
+struct hdmi_codec_daifmt {
+   enum {
+   HDMI_I2S,
+   HDMI_RIGHT_J,
+   HDMI_LEFT_J,
+   HDMI_DSP_A,
+   HDMI_DSP_B,
+   HDMI_AC97,
+   HDMI_SPDIF,
+   } fmt;
+   int bit_clk_inv:1;
+   int frame_clk_inv:1;
+   int bit_clk_master:1;
+   int frame_clk_master:1;
+};
+
+/*
+ * HDMI audio parameters
+ */
+struct hdmi_codec_params {
+   struct hdmi_audio_infoframe cea;
+   struct snd_aes_iec958 iec;
+   int sample_rate;
+   int sample_width;
+   int channels;
+};
+
+struct hdmi_codec_ops {
+   /* For runtime clock configuration from ASoC machine driver.
+* A direct forward from set_sysclk in struct snd_soc_dai_ops.
+* Optional */
+   int (*set_clk)(struct device *dev, int clk_id, int freq);
+
+   /* Called when ASoC starts an audio stream setup. The call
+* provides an audio abort callback for stoping an ongoing
+* stream if the HDMI audio becomes unavailable.
+* Optional */
+   int (*audio_startup)(struct device *dev,
+void (*abort_cb)(struct device *dev));
+
+   /* Configures HDMI-encoder for audio stream.
+* Mandatory */
+   int (*hw_params)(struct device *dev,
+struct hdmi_codec_daifmt *fmt,
+struct hdmi_codec_params *hparms);
+
+   /* Shuts down the audio stream.
+* Mandatory */
+   void (*audio_shutdown)(struct device *dev);
+
+   /* Mute/unmute HDMI audio stream.
+* Optional */
+   int (*digital_mute)(struct device *dev, bool enable);
+
+   /* Provides EDID-Like-Data from connected HDMI device.
+* Optional */
+   uint8_t *(*get_eld)(struct device *dev);
+};
+
+/* HDMI codec initalization data */
+struct hdmi_codec_pdata {
+   struct device *dev; /* The HDMI encoder registering the codec */
+   const struct hdmi_codec_ops *ops;
+   uint i2s:1;
+   uint spdif:1;
+   int max_i2s_channels;
+};
+
+#define HDMI_CODEC_DRV_NAME hdmi-audio-codec
+
+#endif /* __HDMI_CODEC_H__ */
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index fb7f978..ef9646f 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -76,6 +76,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_MAX9877 if I2C
select SND_SOC_MC13783 if MFD_MC13XXX
select SND_SOC_ML26124 if I2C
+   select SND_SOC_HDMI_CODEC
select SND_SOC_PCM1681 if I2C
select SND_SOC_PCM1792A if SPI_MASTER
select SND_SOC_PCM3008
@@ -429,6 +430,9 @@ config SND_SOC_BT_SCO
 config SND_SOC_DMIC
tristate
 
+config SND_SOC_HDMI_CODEC
+   tristate
+
 config SND_SOC_ES8328
tristate Everest Semi ES8328 CODEC
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 4e5d17c..a128c2b 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -69,6 +69,7 @@ snd-soc-max98925-objs := max98925.o
 snd-soc-max9850-objs := max9850.o
 snd-soc-mc13783-objs := mc13783.o
 snd-soc-ml26124-objs := ml26124.o
+snd-soc-hdmi-codec-objs := hdmi-codec.o

[PATCH RFC v2 6/7] drm/i2c: tda998x: Register ASoC HDMI codec for audio functionality DO NOT MERGE

2015-05-26 Thread Jyri Sarha
This patch is here to demonstrate how to use the ASoC hdmi-codec to
implement ASoC codec API in tda998x driver.

I do not have proper documentation for tda998x family chips so I lack
the necessary information for making a decent binding for audio part
of the chip. In stead I use binding from Jean-Francois Moine's ASoC:
tda998x: add a codec to the HDMI transmitter patch series.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/gpu/drm/i2c/Kconfig   |   1 +
 drivers/gpu/drm/i2c/tda998x_drv.c | 238 ++
 2 files changed, 239 insertions(+)

diff --git a/drivers/gpu/drm/i2c/Kconfig b/drivers/gpu/drm/i2c/Kconfig
index 22c7ed6..088f278 100644
--- a/drivers/gpu/drm/i2c/Kconfig
+++ b/drivers/gpu/drm/i2c/Kconfig
@@ -28,6 +28,7 @@ config DRM_I2C_SIL164
 config DRM_I2C_NXP_TDA998X
tristate NXP Semiconductors TDA998X HDMI encoder
default m if DRM_TILCDC
+   select SND_SOC_HDMI_CODEC if SND_SOC
help
  Support for NXP Semiconductors TDA998X HDMI encoders.
 
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index bcf96f7..3c38911 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -20,6 +20,7 @@
 #include linux/module.h
 #include linux/irq.h
 #include sound/asoundef.h
+#include sound/hdmi-codec.h
 
 #include drm/drmP.h
 #include drm/drm_crtc_helper.h
@@ -45,6 +46,9 @@ struct tda998x_priv {
u8 vip_cntrl_2;
struct tda998x_encoder_params params;
 
+   struct platform_device *audio_pdev;
+   uint8_t eld[MAX_ELD_BYTES];
+
wait_queue_head_t wq_edid;
volatile int wq_edid_wait;
struct drm_encoder *encoder;
@@ -1120,6 +1124,9 @@ tda998x_encoder_get_modes(struct tda998x_priv *priv,
drm_mode_connector_update_edid_property(connector, edid);
n = drm_add_edid_modes(connector, edid);
priv-is_hdmi_sink = drm_detect_hdmi_monitor(edid);
+   drm_edid_to_eld(connector, edid);
+   memcpy(priv-eld, connector-eld, sizeof(priv-eld));
+
kfree(edid);
 
return n;
@@ -1156,6 +1163,9 @@ static void tda998x_destroy(struct tda998x_priv *priv)
}
 
i2c_unregister_device(priv-cec);
+
+   if (priv-audio_pdev)
+   platform_device_unregister(priv-audio_pdev);
 }
 
 /* Slave encoder support */
@@ -1230,6 +1240,230 @@ static struct drm_encoder_slave_funcs 
tda998x_encoder_slave_funcs = {
.set_property = tda998x_encoder_set_property,
 };
 
+static int
+tda998x_configure_audio2(struct tda998x_priv *priv,
+   int mode_clock,
+   int ena_ap,
+   struct hdmi_codec_params *params,
+   struct hdmi_codec_daifmt *daifmt)
+{
+   uint8_t buf[6], clksel_aip, clksel_fs, cts_n, adiv;
+   uint8_t infoframe_buf[HDMI_INFOFRAME_SIZE(AUDIO)];
+   int infoframe_len;
+   uint32_t n;
+
+   infoframe_len = hdmi_audio_infoframe_pack(params-cea, infoframe_buf,
+ sizeof(infoframe_buf));
+   if (infoframe_len  0) {
+   dev_err(priv-hdmi-dev,
+   Failed to pack audio infoframe: %d\n,
+   infoframe_len);
+   return infoframe_len;
+   }
+
+   /* Enable audio ports */
+   reg_write(priv, REG_ENA_AP, ena_ap);
+   reg_write(priv, REG_ENA_ACLK, daifmt-fmt == HDMI_SPDIF ? 0 : 1);
+
+   /* Set audio input source */
+   switch (daifmt-fmt) {
+   case HDMI_SPDIF:
+   reg_write(priv, REG_MUX_AP, MUX_AP_SELECT_SPDIF);
+   clksel_aip = AIP_CLKSEL_AIP_SPDIF;
+   clksel_fs = AIP_CLKSEL_FS_FS64SPDIF;
+   cts_n = CTS_N_M(3) | CTS_N_K(3);
+   break;
+
+   case HDMI_I2S:
+   reg_write(priv, REG_MUX_AP, MUX_AP_SELECT_I2S);
+   clksel_aip = AIP_CLKSEL_AIP_I2S;
+   clksel_fs = AIP_CLKSEL_FS_ACLK;
+   switch (params-sample_width) {
+   case 16:
+   cts_n = CTS_N_M(3) | CTS_N_K(1);
+   break;
+   case 18:
+   case 20:
+   case 24:
+   cts_n = CTS_N_M(3) | CTS_N_K(2);
+   break;
+   default:
+   case 32:
+   cts_n = CTS_N_M(3) | CTS_N_K(3);
+   break;
+   }
+   break;
+
+   default:
+   dev_err(priv-hdmi-dev, Unsupported I2S format\n);
+   return -EINVAL;
+   }
+
+   reg_write(priv, REG_AIP_CLKSEL, clksel_aip);
+   reg_clear(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_LAYOUT |
+   AIP_CNTRL_0_ACR_MAN);   /* auto CTS */
+   reg_write(priv, REG_CTS_N, cts_n);
+
+   /*
+* Audio input somehow depends on HDMI line rate which is
+* related to pixclk. Testing showed that modes

[PATCH RFC v2 0/7] Implement generic ASoC HDMI codec

2015-05-26 Thread Jyri Sarha
Only the first three patches are meant for serious review.

The ASoC part should be ready for review in other respects but the
EDID SADs handling is waiting for Russell King's DRM ELD helper
patches. There is a copy-pasted not-to-be-merged patch with the same
functionality in the patch series.

The tda998x part is not complete and I do not think Jean-Francois'
binding are ready as such either. At least the usage of reg property in
a port node for something that is not an address or even guaranteed to
be unique is not a good idea. Some documentation of how to configure
AP0-AP4 pins (REG_ENA_AP?) would help in making a proper binding for
the tda998x audio configuration.

These patches, my tilcdc refactoring[1], and my latest BCLK fixes for
davinci-mcasp driver [2], can be found in a branch that produces
working HDMI audio on Beaglebone-Black here:

https://github.com/jsarha/linux.git linux-master-bbb-hdmi-20150512

[1] http://lists.freedesktop.org/archives/dri-devel/2015-May/082537.html
[2] http://mailman.alsa-project.org/pipermail/alsa-devel/2015-April/090974.html

Jean-Francois Moine (1):
  drm/i2c: tda998x: Add support of a DT graph of ports DO NOT MERGE

Jyri Sarha (6):
  ASoC: core: If component doesn't have of_node use parent's node
instead
  ASoC: hdmi: Remove obsolete dummy HDMI codec
  ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders
  ASoC: hdmi-codec: Add ELD based audio pcm rules DO NOT MERGE
  drm/i2c: tda998x: Register ASoC HDMI codec for audio functionality DO
NOT MERGE
  ARM: dts: am335x-boneblack: Add HDMI audio support DO NOT MERGE

 .../devicetree/bindings/drm/i2c/tda998x.txt|  51 ++
 arch/arm/boot/dts/am335x-boneblack.dts |  78 ++-
 drivers/gpu/drm/i2c/Kconfig|   1 +
 drivers/gpu/drm/i2c/tda998x_drv.c  | 328 +++-
 include/sound/hdmi-codec.h |  99 
 include/sound/tda998x.h|   8 +
 sound/soc/codecs/Kconfig   |   2 +-
 sound/soc/codecs/Makefile  |   4 +-
 sound/soc/codecs/hdmi-codec.c  | 560 +
 sound/soc/codecs/hdmi.c| 109 
 sound/soc/soc-core.c   |  14 +-
 11 files changed, 1129 insertions(+), 125 deletions(-)
 create mode 100644 include/sound/hdmi-codec.h
 create mode 100644 include/sound/tda998x.h
 create mode 100644 sound/soc/codecs/hdmi-codec.c
 delete mode 100644 sound/soc/codecs/hdmi.c

-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC v2 1/7] ASoC: core: If component doesn't have of_node use parent's node instead

2015-05-26 Thread Jyri Sarha
If an ASoC component device does not have a device tree node, use its
parent's node instead, when looking for a matching DAI based on a
device tree reference.

This allows video device drivers to register a separate child device
for their ASoC side audio functionality.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 sound/soc/soc-core.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 2373252..b1bcff2 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -904,12 +904,17 @@ static struct snd_soc_dai *snd_soc_find_dai(
 {
struct snd_soc_component *component;
struct snd_soc_dai *dai;
+   struct device_node *component_of_node;
 
lockdep_assert_held(client_mutex);
 
/* Find CPU DAI from registered DAIs*/
list_for_each_entry(component, component_list, list) {
-   if (dlc-of_node  component-dev-of_node != dlc-of_node)
+   component_of_node = component-dev-of_node;
+   if (!component_of_node  component-dev-parent)
+   component_of_node = component-dev-parent-of_node;
+
+   if (dlc-of_node  component_of_node != dlc-of_node)
continue;
if (dlc-name  strcmp(component-name, dlc-name))
continue;
@@ -3488,11 +3493,16 @@ static int snd_soc_get_dai_name(struct of_phandle_args 
*args,
const char **dai_name)
 {
struct snd_soc_component *pos;
+   struct device_node *component_of_node;
int ret = -EPROBE_DEFER;
 
mutex_lock(client_mutex);
list_for_each_entry(pos, component_list, list) {
-   if (pos-dev-of_node != args-np)
+   component_of_node = pos-dev-of_node;
+   if (!component_of_node  pos-dev-parent)
+   component_of_node = pos-dev-parent-of_node;
+
+   if (component_of_node != args-np)
continue;
 
if (pos-driver-of_xlate_dai_name) {
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC v2 2/7] ASoC: hdmi: Remove obsolete dummy HDMI codec

2015-05-26 Thread Jyri Sarha
The hdmi stub codec has not been used since refactoring of OMAP HDMI
audio support.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 sound/soc/codecs/Kconfig  |   4 --
 sound/soc/codecs/Makefile |   2 -
 sound/soc/codecs/hdmi.c   | 109 --
 3 files changed, 115 deletions(-)
 delete mode 100644 sound/soc/codecs/hdmi.c

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 061c465..fb7f978 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -76,7 +76,6 @@ config SND_SOC_ALL_CODECS
select SND_SOC_MAX9877 if I2C
select SND_SOC_MC13783 if MFD_MC13XXX
select SND_SOC_ML26124 if I2C
-   select SND_SOC_HDMI_CODEC
select SND_SOC_PCM1681 if I2C
select SND_SOC_PCM1792A if SPI_MASTER
select SND_SOC_PCM3008
@@ -430,9 +429,6 @@ config SND_SOC_BT_SCO
 config SND_SOC_DMIC
tristate
 
-config SND_SOC_HDMI_CODEC
-   tristate HDMI stub CODEC
-
 config SND_SOC_ES8328
tristate Everest Semi ES8328 CODEC
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index abe2d7e..4e5d17c 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -69,7 +69,6 @@ snd-soc-max98925-objs := max98925.o
 snd-soc-max9850-objs := max9850.o
 snd-soc-mc13783-objs := mc13783.o
 snd-soc-ml26124-objs := ml26124.o
-snd-soc-hdmi-codec-objs := hdmi.o
 snd-soc-pcm1681-objs := pcm1681.o
 snd-soc-pcm1792a-codec-objs := pcm1792a.o
 snd-soc-pcm3008-objs := pcm3008.o
@@ -254,7 +253,6 @@ obj-$(CONFIG_SND_SOC_MAX98925)  += snd-soc-max98925.o
 obj-$(CONFIG_SND_SOC_MAX9850)  += snd-soc-max9850.o
 obj-$(CONFIG_SND_SOC_MC13783)  += snd-soc-mc13783.o
 obj-$(CONFIG_SND_SOC_ML26124)  += snd-soc-ml26124.o
-obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o
 obj-$(CONFIG_SND_SOC_PCM1681)  += snd-soc-pcm1681.o
 obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o
 obj-$(CONFIG_SND_SOC_PCM3008)  += snd-soc-pcm3008.o
diff --git a/sound/soc/codecs/hdmi.c b/sound/soc/codecs/hdmi.c
deleted file mode 100644
index bd42ad3..000
--- a/sound/soc/codecs/hdmi.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * ALSA SoC codec driver for HDMI audio codecs.
- * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
- * Author: Ricardo Neri ricardo.n...@ti.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#include linux/module.h
-#include sound/soc.h
-#include linux/of.h
-#include linux/of_device.h
-
-#define DRV_NAME hdmi-audio-codec
-
-static const struct snd_soc_dapm_widget hdmi_widgets[] = {
-   SND_SOC_DAPM_INPUT(RX),
-   SND_SOC_DAPM_OUTPUT(TX),
-};
-
-static const struct snd_soc_dapm_route hdmi_routes[] = {
-   { Capture, NULL, RX },
-   { TX, NULL, Playback },
-};
-
-static struct snd_soc_dai_driver hdmi_codec_dai = {
-   .name = hdmi-hifi,
-   .playback = {
-   .stream_name = Playback,
-   .channels_min = 2,
-   .channels_max = 8,
-   .rates = SNDRV_PCM_RATE_32000 |
-   SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
-   SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
-   SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
-   .formats = SNDRV_PCM_FMTBIT_S16_LE |
-   SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
-   .sig_bits = 24,
-   },
-   .capture = {
-   .stream_name = Capture,
-   .channels_min = 2,
-   .channels_max = 2,
-   .rates = SNDRV_PCM_RATE_32000 |
-   SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
-   SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
-   SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
-   .formats = SNDRV_PCM_FMTBIT_S16_LE |
-   SNDRV_PCM_FMTBIT_S24_LE,
-   },
-
-};
-
-#ifdef CONFIG_OF
-static const struct of_device_id hdmi_audio_codec_ids[] = {
-   { .compatible = linux,hdmi-audio, },
-   { }
-};
-MODULE_DEVICE_TABLE(of, hdmi_audio_codec_ids);
-#endif
-
-static struct snd_soc_codec_driver hdmi_codec = {
-   .dapm_widgets = hdmi_widgets,
-   .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),
-   .dapm_routes = hdmi_routes,
-   .num_dapm_routes = ARRAY_SIZE(hdmi_routes),
-   .ignore_pmdown_time

[PATCH RFC v2 5/7] drm/i2c: tda998x: Add support of a DT graph of ports DO NOT MERGE

2015-05-26 Thread Jyri Sarha
From: Jean-Francois Moine moin...@free.fr

Two kinds of ports may be declared in a DT graph of ports: video and audio.
This patch accepts the port value from a video port as an alternative
to the video-ports property.
It also accepts audio ports in the case the transmitter is not used as
a slave encoder.
The new file include/sound/tda998x.h prepares to the definition of
a tda998x CODEC.

Signed-off-by: Jean-Francois Moine moin...@free.fr
Signed-off-by: Jyri Sarha jsa...@ti.com
---
 .../devicetree/bindings/drm/i2c/tda998x.txt| 51 
 drivers/gpu/drm/i2c/tda998x_drv.c  | 90 +++---
 include/sound/tda998x.h|  8 ++
 3 files changed, 140 insertions(+), 9 deletions(-)
 create mode 100644 include/sound/tda998x.h

diff --git a/Documentation/devicetree/bindings/drm/i2c/tda998x.txt 
b/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
index e9e4bce..386b6c3 100644
--- a/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
+++ b/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
@@ -16,6 +16,35 @@ Optional properties:
 
   - video-ports: 24 bits value which defines how the video controller
output is wired to the TDA998x input - default: 0x230145
+   This property is not used when ports are defined.
+
+Optional nodes:
+
+  - port: up to three ports.
+   The ports are defined according to [1].
+
+Video port.
+   There may be only one video port.
+   This one must contain the following property:
+
+   - port-type: must be rgb
+
+   and may contain the optional property:
+
+   - reg: 24 bits value which defines how the video controller
+   output is wired to the TDA998x input (video pins)
+   When absent, the default value is 0x230145.
+
+Audio ports.
+   There may be one or two audio ports.
+   These ones must contain the following properties:
+
+   - port-type: must be i2s or spdif
+
+   - reg: 8 bits value which defines how the audio controller
+   output is wired to the TDA998x input (audio pins)
+
+[1] Documentation/devicetree/bindings/graph.txt
 
 Example:
 
@@ -26,4 +55,26 @@ Example:
interrupts = 27 2;/* falling edge */
pinctrl-0 = pmx_camera;
pinctrl-names = default;
+
+   port at 230145 {
+   port-type = rgb;
+   reg = 0x230145;
+   hdmi_0: endpoint {
+   remote-endpoint = lcd0_0;
+   };
+   };
+   port at 3 { /* AP1 = I2S */
+   port-type = i2s;
+   reg = 0x03;
+   tda998x_i2s: endpoint {
+   remote-endpoint = audio1_i2s;
+   };
+   };
+   port at 4 {  /* AP2 = S/PDIF */
+   port-type = spdif;
+   reg = 0x04;
+   tda998x_spdif: endpoint {
+   remote-endpoint = audio1_spdif1;
+   };
+   };
};
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 5febffd..bcf96f7 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -27,6 +27,7 @@
 #include drm/drm_edid.h
 #include drm/drm_of.h
 #include drm/i2c/tda998x.h
+#include sound/tda998x.h
 
 #define DBG(fmt, ...) DRM_DEBUG(fmt\n, ##__VA_ARGS__)
 
@@ -47,6 +48,8 @@ struct tda998x_priv {
wait_queue_head_t wq_edid;
volatile int wq_edid_wait;
struct drm_encoder *encoder;
+
+   struct tda998x_audio_s audio;
 };
 
 #define to_tda998x_priv(x)  ((struct tda998x_priv 
*)to_encoder_slave(x)-slave_priv)
@@ -771,6 +774,8 @@ static void tda998x_encoder_set_config(struct tda998x_priv 
*priv,
(p-mirr_f ? VIP_CNTRL_2_MIRR_F : 0);
 
priv-params = *p;
+   priv-audio.port_types[0] = p-audio_format;
+   priv-audio.ports[0] = p-audio_cfg;
 }
 
 static void tda998x_encoder_dpms(struct tda998x_priv *priv, int mode)
@@ -1227,9 +1232,57 @@ static struct drm_encoder_slave_funcs 
tda998x_encoder_slave_funcs = {
 
 /* I2C driver functions */
 
+static int tda998x_parse_ports(struct tda998x_priv *priv,
+   struct device_node *np)
+{
+   struct device_node *of_port;
+   const char *port_type;
+   int ret, audio_index, reg, afmt;
+
+   audio_index = 0;
+   for_each_child_of_node(np, of_port) {
+   if (!of_port-name
+|| of_node_cmp(of_port-name, port) != 0)
+   continue;
+   ret = of_property_read_string(of_port, port-type,
+   port_type);
+   if (ret  0)
+   continue;
+   ret = of_property_read_u32

[PATCH RFC v2 7/7] ARM: dts: am335x-boneblack: Add HDMI audio support DO NOT MERGE

2015-05-26 Thread Jyri Sarha
This patch is here only to demonstrate HDMI codec functionality on
Beaglebone-Black.

Adds mcasp0_pins, clk_mcasp0_fixed, clk_mcasp0, mcasp0, sound node,
and changes the tda19988 node to follow the new binding.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 arch/arm/boot/dts/am335x-boneblack.dts | 78 +-
 1 file changed, 76 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/am335x-boneblack.dts 
b/arch/arm/boot/dts/am335x-boneblack.dts
index eadbba3..8a8abf5 100644
--- a/arch/arm/boot/dts/am335x-boneblack.dts
+++ b/arch/arm/boot/dts/am335x-boneblack.dts
@@ -64,6 +64,16 @@
0x1b0 0x03  /* xdma_event_intr0, OMAP_MUX_MODE3 | 
AM33XX_PIN_OUTPUT */
;
};
+
+   mcasp0_pins: mcasp0_pins {
+   pinctrl-single,pins = 
+   0x1ac (PIN_INPUT_PULLUP | MUX_MODE0)/* 
mcasp0_ahclkx.mcasp0_ahclkx */
+   0x19c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* 
mcasp0_ahclkr.mcasp0_axr2 */
+   0x194 (PIN_OUTPUT_PULLUP | MUX_MODE0)   /* 
mcasp0_fsx.mcasp0_fsx */
+   0x190 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* 
mcasp0_aclkx.mcasp0_aclkx */
+   0x06c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* 
gpmc_a11.GPIO1_27 */
+   ;
+   };
 };
 
 lcdc {
@@ -76,21 +86,85 @@
 };
 
 i2c0 {
-   tda19988 {
+   tda19988: tda19988 {
compatible = nxp,tda998x;
reg = 0x70;
+
+   #sound-dai-cells = 0;
+
pinctrl-names = default, off;
pinctrl-0 = nxp_hdmi_bonelt_pins;
pinctrl-1 = nxp_hdmi_bonelt_off_pins;
 
-   port {
+   port@0 {
+   port-type = rgb;
+   reg = 0x230145;
hdmi_0: endpoint@0 {
remote-endpoint = lcdc_0;
};
};
+   port@1 {
+   port-type = i2s;
+   reg = 0x03;
+   tda19988_i2s: endpoint {
+   remote-endpoint = mcasp0_i2s;
+   };
+   };
};
 };
 
 rtc {
system-power-controller;
 };
+
+mcasp0{
+   #sound-dai-cells = 0;
+   pinctrl-names = default;
+   pinctrl-0 = mcasp0_pins;
+   status = okay;
+   op-mode = 0;  /* MCASP_IIS_MODE */
+   tdm-slots = 2;
+   serial-dir =   /* 0: INACTIVE, 1: TX, 2: RX */
+   0 0 1 0
+   ;
+   tx-num-evt = 1;
+   rx-num-evt = 1;
+
+   port {
+   mcasp0_i2s: endpoint {
+   remote-endpoint = tda19988_i2s;
+   };
+   };
+};
+
+/ {
+   clk_mcasp0_fixed: clk_mcasp0_fixed {
+   #clock-cells = 0;
+   compatible = fixed-clock;
+   clock-frequency = 24576000;
+   };
+
+   clk_mcasp0: clk_mcasp0 {
+   #clock-cells = 0;
+   compatible = gpio-gate-clock;
+   clocks = clk_mcasp0_fixed;
+   enable-gpios = gpio1 27 0; /* BeagleBone Black Clk enable on 
GPIO1_27 */
+   };
+
+   sound {
+   compatible = simple-audio-card;
+   simple-audio-card,name = TI BeagleBone Black;
+   simple-audio-card,format = i2s;
+   simple-audio-card,bitclock-master = dailink0_master;
+   simple-audio-card,frame-master = dailink0_master;
+
+   dailink0_master: simple-audio-card,cpu {
+   sound-dai = mcasp0;
+   clocks = clk_mcasp0;
+   };
+
+   simple-audio-card,codec {
+   sound-dai = tda19988;
+   };
+   };
+};
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH early RFC 2/2] drm/i2c: tda998x: HACK Implement primitive HDMI audio with ASoC hdmi-code-lib

2015-05-13 Thread Jyri Sarha
This patch is to demonstrate how to use the ASoC hdmi-codec-lib to
implement ASoC codec API in tda998x driver.

I do not have proper documentation for tda998x family chips so I lack
the necessary information for making a proper binding for audio part
of the chip. The configuration is hard coded to work on
Beaglebone-Black.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/gpu/drm/i2c/Kconfig   |   1 +
 drivers/gpu/drm/i2c/tda998x_drv.c | 238 ++
 2 files changed, 239 insertions(+)

diff --git a/drivers/gpu/drm/i2c/Kconfig b/drivers/gpu/drm/i2c/Kconfig
index 22c7ed6..92302e9 100644
--- a/drivers/gpu/drm/i2c/Kconfig
+++ b/drivers/gpu/drm/i2c/Kconfig
@@ -28,6 +28,7 @@ config DRM_I2C_SIL164
 config DRM_I2C_NXP_TDA998X
tristate NXP Semiconductors TDA998X HDMI encoder
default m if DRM_TILCDC
+   select SND_SOC_HDMI_CODEC_LIB if SND_SOC
help
  Support for NXP Semiconductors TDA998X HDMI encoders.
 
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 5febffd..797b4d5 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -20,6 +20,7 @@
 #include linux/module.h
 #include linux/irq.h
 #include sound/asoundef.h
+#include sound/hdmi-codec-lib.h
 
 #include drm/drmP.h
 #include drm/drm_crtc_helper.h
@@ -31,6 +32,7 @@
 #define DBG(fmt, ...) DRM_DEBUG(fmt\n, ##__VA_ARGS__)
 
 struct tda998x_priv {
+   struct hdmi_codec_drvdata audio_data;
struct i2c_client *cec;
struct i2c_client *hdmi;
struct mutex mutex;
@@ -44,6 +46,10 @@ struct tda998x_priv {
u8 vip_cntrl_2;
struct tda998x_encoder_params params;
 
+   struct mutex sads_mutex;
+   struct cea_sad *sads;
+   int sads_count;
+
wait_queue_head_t wq_edid;
volatile int wq_edid_wait;
struct drm_encoder *encoder;
@@ -1115,6 +1121,13 @@ tda998x_encoder_get_modes(struct tda998x_priv *priv,
drm_mode_connector_update_edid_property(connector, edid);
n = drm_add_edid_modes(connector, edid);
priv-is_hdmi_sink = drm_detect_hdmi_monitor(edid);
+
+   mutex_lock(priv-sads_mutex);
+   kfree(priv-sads);
+   priv-sads = NULL;
+   priv-sads_count = drm_edid_to_sad(edid, priv-sads);
+   mutex_unlock(priv-sads_mutex);
+
kfree(edid);
 
return n;
@@ -1151,6 +1164,14 @@ static void tda998x_destroy(struct tda998x_priv *priv)
}
 
i2c_unregister_device(priv-cec);
+
+   asoc_hdmi_codec_unregister(priv-hdmi-dev);
+
+   mutex_lock(priv-sads_mutex);
+   kfree(priv-sads);
+   priv-sads = NULL;
+   priv-sads_count = -ENODEV;
+   mutex_unlock(priv-sads_mutex);
 }
 
 /* Slave encoder support */
@@ -1225,6 +1246,217 @@ static struct drm_encoder_slave_funcs 
tda998x_encoder_slave_funcs = {
.set_property = tda998x_encoder_set_property,
 };
 
+static int
+tda998x_configure_audio2(struct tda998x_priv *priv,
+   int mode_clock,
+   int audio_ena,
+   struct hdmi_codec_params *params,
+   struct hdmi_codec_daifmt *daifmt)
+{
+   uint8_t buf[6], clksel_aip, clksel_fs, cts_n, adiv;
+   uint8_t infoframe_buf[HDMI_INFOFRAME_SIZE(AUDIO)];
+   int infoframe_len;
+   uint32_t n;
+
+   infoframe_len = hdmi_audio_infoframe_pack(params-cea, infoframe_buf,
+ sizeof(infoframe_buf));
+   if (infoframe_len  0) {
+   dev_err(priv-hdmi-dev,
+   Failed to pack audio infoframe: %d\n,
+   infoframe_len);
+   return infoframe_len;
+   }
+
+   /* Enable audio ports */
+   reg_write(priv, REG_ENA_AP, audio_ena);
+   reg_write(priv, REG_ENA_ACLK, daifmt-fmt == HDMI_SPDIF ? 0 : 1);
+
+   /* Set audio input source */
+   switch (daifmt-fmt) {
+   case HDMI_SPDIF:
+   reg_write(priv, REG_MUX_AP, MUX_AP_SELECT_SPDIF);
+   clksel_aip = AIP_CLKSEL_AIP_SPDIF;
+   clksel_fs = AIP_CLKSEL_FS_FS64SPDIF;
+   cts_n = CTS_N_M(3) | CTS_N_K(3);
+   break;
+
+   case HDMI_I2S:
+   reg_write(priv, REG_MUX_AP, MUX_AP_SELECT_I2S);
+   clksel_aip = AIP_CLKSEL_AIP_I2S;
+   clksel_fs = AIP_CLKSEL_FS_ACLK;
+   switch (params-sample_width) {
+   case 16:
+   cts_n = CTS_N_M(3) | CTS_N_K(1);
+   break;
+   case 18:
+   case 20:
+   case 24:
+   cts_n = CTS_N_M(3) | CTS_N_K(2);
+   break;
+   default:
+   case 32:
+   cts_n = CTS_N_M(3) | CTS_N_K(3);
+   break;
+   }
+   break;
+
+   default:
+   dev_err(priv-hdmi-dev, Unsupported I2S format\n

[PATCH early RFC 0/2] Implement ASoC HDMI codec library

2015-05-13 Thread Jyri Sarha
This is on early RFC and should not be merged yet. The idea is just
to share my ideas early on as there has been a lot of development
going on around HDMI audio.

The I2S DAI of the ASoC side patch is usable already, the spdif
support has not been tested and the EDID SADs handling should use
Russel's DRM ELD helper when it is ready.

The tda998x patch is just to demonstrate the usage of the
HDMI-codec-lib. At least the audio related DT-bindings are missing
completely and the configuration is hard coded to work on
Beaglebone-Black.

Jean-Francois, would you consider trying the generic ASoC patch with
your HW, as I can not test the spdif functionality with mine?

The library could also be implemented as a separate platform driver,
but then adding a pointer for private data to struct
snd_soc_dai_driver, snd_soc_codec, or to snd_soc_component would be of
great help.

These patches, my tilcdc refactoring[1], and my latest BCLK fixes for
davinci-mcasp diver [2], can found in a branch that produces a working
HDMI audio on Beaglebone-Black here:

https://github.com/jsarha/linux.git linux-master-bbb-hdmi-20150512

[1] http://lists.freedesktop.org/archives/dri-devel/2015-May/082537.html
[2] http://mailman.alsa-project.org/pipermail/alsa-devel/2015-April/090974.html

Jyri Sarha (2):
  ASoC: hdmi-codec-lib: Add hdmi-codec-lib for external HDMI-encoders
  drm/i2c: tda998x: HACK Implement primitive HDMI audio with ASoC
hdmi-code-lib

 drivers/gpu/drm/i2c/Kconfig   |   1 +
 drivers/gpu/drm/i2c/tda998x_drv.c | 238 +
 include/sound/hdmi-codec-lib.h| 105 
 sound/soc/codecs/Kconfig  |   4 +
 sound/soc/codecs/Makefile |   2 +
 sound/soc/codecs/hdmi-codec-lib.c | 536 ++
 6 files changed, 886 insertions(+)
 create mode 100644 include/sound/hdmi-codec-lib.h
 create mode 100644 sound/soc/codecs/hdmi-codec-lib.c

-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 5/6] drm/tilcdc: Force building of DRM_TILCDC_SLAVE_COMPAT

2015-05-08 Thread Jyri Sarha
If I read Documentation/kbuild/makefiles.txt section 3.6 right, this
patch should not be needed. However, without this patch the objects
needed for DRM_TILCDC_SLAVE_COMPAT are not linked, if DRM_TILCDC is
built as module.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/gpu/drm/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 7d4944e..6081fa6 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -60,7 +60,7 @@ obj-$(CONFIG_DRM_ATMEL_HLCDC) += atmel-hlcdc/
 obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/
 obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
 obj-$(CONFIG_DRM_OMAP) += omapdrm/
-obj-$(CONFIG_DRM_TILCDC)   += tilcdc/
+obj-y  += tilcdc/
 obj-$(CONFIG_DRM_QXL) += qxl/
 obj-$(CONFIG_DRM_BOCHS) += bochs/
 obj-$(CONFIG_DRM_MSM) += msm/
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/7] Use DRM component API in tilcdc to connect to tda998x

2015-05-07 Thread Jyri Sarha

On 05/07/15 12:44, Tomi Valkeinen wrote:


On 01/04/15 11:49, Jyri Sarha wrote:

Ok, let's do one more full review round. The mode filtering issue was
the main reason for this new patch series version. However, I found
couple other things to fix too after scrutinizing the patches once
more.

Changes since v3 version of the patch-set:
* drm/tilcdc: Add support for external tda998x encoder
  - Hijack external connectors helper functions
  - Remove select of nonexistent DRM_TILCDC_INIT in tilcdc Kconfig
  - Correct author mail address to tilcdc_exteral.h
* drm/tilcdc: Add DRM_TILCDC_SLAVE_COMPAT for ti,tilcdc,slave binding
  - Add a header file for tilcdc_slave_compat.dtb symbol declarations

Changes since v2 version of the patch-set:
- use obj-y in Makefle for tilcdc subdir in:
   drm/tilcdc: Force building of DRM_TILCDC_SLAVE_COMPAT
- move to last:
   drm/tilcdc: Decrement refcount of ep-node from of_graph_get_next_endpoint

Changes since first version of the patch-set:
- Rename DRM_TILCDC_INIT to DRM_TILCDC_SLAVE_COMPAT and make it visible
- Add separate:
   drm/tilcdc: Decrement refcount of ep-node from of_graph_get_next_endpoint
- Reduce info-level spam
- Use component_master_add_with_match()
- Be more explicit about tda998x being the only supported external encoder

Remove tilcdc slave support and connect to tda998x trough its
component DRM API. For dtb backward compatibility the code creates at
boot time a DT overlay based on the earlier binding. The overlay
conforms to the new graph based binding.

The drm/tilcdc: Decrement refcount of ep-node from
of_graph_get_next_endpoint should probably not be merged. The of:
Decrement refcount of previous endpoint in of_graph_get_next_endpoint
is eventually going to be merged and before that leaking of two
of-node refcount increments each time the module is loaded is not that
serious. The of-nodes live forever anyway.

The merge of the dts patch can be delayed until the next merger
window, when the other patches are already in. The
DRM_TILCDC_SLAVE_COMPAT should keep the bbb HDMI operational until
then.


I made a quick test on v4.1-rc2, and:



What did you do to get this dump. The tilcdc driver has not done much at 
this point. There is basically noting before calling this function:


int tilcdc_get_external_components(struct device *dev,
   struct component_match **match)
{
struct device_node *ep = NULL;
int count = 0;

while ((ep = of_graph_get_next_endpoint(dev-of_node, ep))) {
struct device_node *node;

node = of_graph_get_remote_port_parent(ep);
if (!node  !of_device_is_available(node)) {
of_node_put(node);
continue;
}

dev_dbg(dev, Subdevice node '%s' found\n, node-name);
if (match)
component_match_add(dev, match, dev_match_of, node);
of_node_put(node);
count++;
}

if (count  1) {
dev_err(dev, Only one external encoder is supported\n);
return -EINVAL;
}

return count;
}

If there is something wrong with the function I would certainly like to 
know what. Or is the bug somewhere else?


Best regards,
Jyri


[   15.199584] [drm] Initialized drm 1.1.0 20060810
[   15.319496] BUG: sleeping function called from invalid context at
kernel/locking/mutex.c:616
[   15.328339] in_atomic(): 1, irqs_disabled(): 128, pid: 130, name: insmod
[   15.335336] 3 locks held by insmod/130:
[   15.339339]  #0:  (dev-mutex){..}, at: [c044d8d0]
__driver_attach+0x50/0xa0
[   15.347389]  #1:  (dev-mutex){..}, at: [c044d8e0]
__driver_attach+0x60/0xa0
[   15.355420]  #2:  (devtree_lock){..}, at: [c05e2888]
of_get_next_child+0x20/0x4c
[   15.363731] irq event stamp: 5750
[   15.367189] hardirqs last  enabled at (5749): [c0719f14]
_raw_spin_unlock_irqrestore+0x38/0x64
[   15.376377] hardirqs last disabled at (5750): [c0719730]
_raw_spin_lock_irqsave+0x24/0x6c
[   15.385104] softirqs last  enabled at (5200): [c004b7c8]
__do_softirq+0x318/0x710
[   15.393111] softirqs last disabled at (5147): [c004bf1c]
irq_exit+0xc4/0x138
[   15.400668] CPU: 0 PID: 130 Comm: insmod Not tainted
4.1.0-rc2-7-g877542591d33-dirty #22
[   15.409477] Hardware name: Generic AM33XX (Flattened Device Tree)
[   15.415837] Backtrace:
[   15.418403] [c00140a8] (dump_backtrace) from [c0014244]
(show_stack+0x18/0x1c)
[   15.426306]  r6:c08d04b0 r5:dd652000 r4: r3:
[   15.432257] [c001422c] (show_stack) from [c0711b44]
(dump_stack+0x94/0xc8)
[   15.439810] [c0711ab0] (dump_stack) from [c0070768]
(___might_sleep+0x18c/0x294)
[   15.447893]  r5:0268 r4:
[   15.451643] [c00705dc] (___might_sleep) from [c00708d4]
(__might_sleep+0x64/0xa4)
[   15.459816]  r7:dd119280 r6: r5:0268 r4:c08d04b0
[   15.465759] [c0070870] (__might_sleep) from [c0715934

[PATCH 2/5] OMAPDSS: HDMI5: Set valid sample order

2015-04-22 Thread Jyri Sarha
From: Misael Lopez Cruz misael.lo...@ti.com

As per TRM, HDMI_WP_AUDIO_CFG[2] LEFT_BEFORE = 0 is reserved,
so it must always be set to 1 (the first sample is the left).

Signed-off-by: Misael Lopez Cruz misael.lo...@ti.com
Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/video/fbdev/omap2/dss/hdmi5_core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/video/fbdev/omap2/dss/hdmi5_core.c 
b/drivers/video/fbdev/omap2/dss/hdmi5_core.c
index a3cfe3d..7a80beb 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5_core.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5_core.c
@@ -870,6 +870,7 @@ int hdmi5_audio_config(struct hdmi_core_data *core, struct 
hdmi_wp_data *wp,
audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES;
audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS;
audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT;
+   audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST;
 
/* only LPCM atm */
audio_format.type = HDMI_AUDIO_TYPE_LPCM;
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/5] OMAPDSS: HDMI4: Set correct CC for 8-channels layout

2015-04-22 Thread Jyri Sarha
From: Misael Lopez Cruz misael.lo...@ti.com

OMAP4 HDMI IP uses the 8-channel layout with 8-channel speaker
allocation mask when transmitting more than two channels.  But
the channel count field (CC) of the Audio InfoFrame's DB1 is
not updated for 8-channels.

As per HDMI Compliance Test 7.31 Audio InfoFrame, CC = 7 is
required for 8-channels CA masks (0x13 and 0x1F).

Signed-off-by: Misael Lopez Cruz misael.lo...@ti.com
Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/video/fbdev/omap2/dss/hdmi4_core.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/omap2/dss/hdmi4_core.c 
b/drivers/video/fbdev/omap2/dss/hdmi4_core.c
index 7eafea5..2b8bd22 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4_core.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.c
@@ -795,7 +795,9 @@ int hdmi4_audio_config(struct hdmi_core_data *core, struct 
hdmi_wp_data *wp,
 
/*
 * the HDMI IP needs to enable four stereo channels when transmitting
-* more than 2 audio channels
+* more than 2 audio channels.  Similarly, the channel count in the
+* Audio InfoFrame has to match the sample_present bits (some channels
+* are padded with zeroes)
 */
if (channel_count == 2) {
audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL;
@@ -807,6 +809,7 @@ int hdmi4_audio_config(struct hdmi_core_data *core, struct 
hdmi_wp_data *wp,
HDMI_AUDIO_I2S_SD1_EN | HDMI_AUDIO_I2S_SD2_EN |
HDMI_AUDIO_I2S_SD3_EN;
acore.layout = HDMI_AUDIO_LAYOUT_8CH;
+   audio-cea-db1_ct_cc = 7;
}
 
acore.en_spdif = false;
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/5] ASoC: omap-hdmi-audio: Fix invalid combination of DM_INH and CA

2015-04-22 Thread Jyri Sarha
From: Misael Lopez Cruz misael.lo...@ti.com

DM_INH = 1 (stereo downmix prohibited) and CA = 0x00 (Channel
Allocation: FR, FL) is an invalid combination according to the
HDMI Compliance Test 7.31 Audio InfoFrame.

Signed-off-by: Misael Lopez Cruz misael.lo...@ti.com
Signed-off-by: Jyri Sarha jsa...@ti.com
---
 sound/soc/omap/omap-hdmi-audio.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/omap/omap-hdmi-audio.c
index 8df303f..aeef25c 100644
--- a/sound/soc/omap/omap-hdmi-audio.c
+++ b/sound/soc/omap/omap-hdmi-audio.c
@@ -217,7 +217,11 @@ static int hdmi_dai_hw_params(struct snd_pcm_substream 
*substream,
else
cea-db4_ca = 0x13;
 
-   cea-db5_dminh_lsv = CEA861_AUDIO_INFOFRAME_DB5_DM_INH_PROHIBITED;
+   if (cea-db4_ca == 0x00)
+   cea-db5_dminh_lsv = 
CEA861_AUDIO_INFOFRAME_DB5_DM_INH_PERMITTED;
+   else
+   cea-db5_dminh_lsv = 
CEA861_AUDIO_INFOFRAME_DB5_DM_INH_PROHIBITED;
+
/* the expression is trivial but makes clear what we are doing */
cea-db5_dminh_lsv |= (0  CEA861_AUDIO_INFOFRAME_DB5_LSV);
 
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/5] OMAPDSS: HDMI audio compliance fixes

2015-04-22 Thread Jyri Sarha
I have rebased these patches from ti-linux-3.14.y on top of Linux
4.0.0. I tested them briefly on OMAP4 and OMAP5 in my environment, but
I could not test any channel count beyond stereo. However, there were
no conflicts in the rebase and each fix makes sense when looking at
the chip TRM and the relevant HDMI specs.

All the changes are really minor, but most of them apply to OMAPDSS side,
so it is probably best to merge them trough there.

Best regards,
Jyri

Misael Lopez Cruz (5):
  OMAPDSS: HDMI4: Set correct CC for 8-channels layout
  OMAPDSS: HDMI5: Set valid sample order
  OMAPDSS: HDMI5: Fix AUDICONF3 bitfield offsets
  ASoC: omap-hdmi-audio: Force channel allocation only for OMAP4
  ASoC: omap-hdmi-audio: Fix invalid combination of DM_INH and CA

 drivers/video/fbdev/omap2/dss/hdmi4_core.c | 12 +++-
 drivers/video/fbdev/omap2/dss/hdmi5_core.c |  5 -
 sound/soc/omap/omap-hdmi-audio.c   | 12 +++-
 3 files changed, 22 insertions(+), 7 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/5] OMAPDSS: HDMI5: Fix AUDICONF3 bitfield offsets

2015-04-22 Thread Jyri Sarha
From: Misael Lopez Cruz misael.lo...@ti.com

Downmix inhibit in HDMI_CORE_FC_AUDICONF3 register is in
bit 4 while CEA861_AUDIO_INFOFRAME_DB5_DM_INH sets bit 7.

Signed-off-by: Misael Lopez Cruz misael.lo...@ti.com
Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/video/fbdev/omap2/dss/hdmi5_core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/omap2/dss/hdmi5_core.c 
b/drivers/video/fbdev/omap2/dss/hdmi5_core.c
index 7a80beb..c3286bd 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5_core.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5_core.c
@@ -790,7 +790,9 @@ static void hdmi5_core_audio_infoframe_cfg(struct 
hdmi_core_data *core,
 
hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF1, info_aud-db2_sf_ss);
hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF2, info_aud-db4_ca);
-   hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF3, info_aud-db5_dminh_lsv);
+   hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF3,
+ (info_aud-db5_dminh_lsv  CEA861_AUDIO_INFOFRAME_DB5_DM_INH)  3 |
+ (info_aud-db5_dminh_lsv  CEA861_AUDIO_INFOFRAME_DB5_LSV));
 }
 
 int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/5] ASoC: omap-hdmi-audio: Force channel allocation only for OMAP4

2015-04-22 Thread Jyri Sarha
From: Misael Lopez Cruz misael.lo...@ti.com

There is a constraint in the OMAP4 HDMI IP that requires to use
the 8-channel code when transmitting more than two channels.

The constraint doesn't apply for OMAP5 so don't force the channel
allocation in the sound driver as it can be done specifically for
OMAP4 later in the hdmi4 core.

Signed-off-by: Misael Lopez Cruz misael.lo...@ti.com
Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/video/fbdev/omap2/dss/hdmi4_core.c | 7 +++
 sound/soc/omap/omap-hdmi-audio.c   | 6 ++
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/hdmi4_core.c 
b/drivers/video/fbdev/omap2/dss/hdmi4_core.c
index 2b8bd22..fa72e73 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4_core.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.c
@@ -654,6 +654,13 @@ static void hdmi_core_audio_infoframe_cfg(struct 
hdmi_core_data *core,
hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(2), info_aud-db3);
sum += info_aud-db3;
 
+   /*
+* The OMAP HDMI IP requires to use the 8-channel channel code when
+* transmitting more than two channels.
+*/
+   if (info_aud-db4_ca != 0x00)
+   info_aud-db4_ca = 0x13;
+
hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(3), info_aud-db4_ca);
sum += info_aud-db4_ca;
 
diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/omap/omap-hdmi-audio.c
index 4775da4..8df303f 100644
--- a/sound/soc/omap/omap-hdmi-audio.c
+++ b/sound/soc/omap/omap-hdmi-audio.c
@@ -210,12 +210,10 @@ static int hdmi_dai_hw_params(struct snd_pcm_substream 
*substream,
 
cea-db3 = 0; /* not used, all zeros */
 
-   /*
-* The OMAP HDMI IP requires to use the 8-channel channel code when
-* transmitting more than two channels.
-*/
if (params_channels(params) == 2)
cea-db4_ca = 0x0;
+   else if (params_channels(params) == 6)
+   cea-db4_ca = 0xb;
else
cea-db4_ca = 0x13;
 
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


  1   2   3   4   5   6   >