Re: [RFC 0/4] media: meson: add video decoder driver

2018-08-02 Thread Neil Armstrong
On 01/08/2018 21:33, Maxime Jourdan wrote:
> This is a Request for Comments for the amlogic (meson) video decoder driver.
> It is written around the V4L2 M2M framework without using the Request
> API as there are a hardware bitstream parser and firmwares.
> 
> It features decoding for:
> - MPEG 1/2/4, H.263, H.264, MJPEG, HEVC 8-bit (partial)
> 
> Even though they are supported in hardware, it doesn't leverage support for:
> - HEVC 10-bit, VP9, VC1 (all those are in TODOs)
> 
> The output is multiplanar NV12 (V4L2_PIX_FMT_NV12M).
> Supported SoCs are: GXBB (S905), GXL (S905X/W/D), GXM (S912)
> It was tested primarily with FFmpeg, GStreamer and kodi.
> 
> The file hierarchy can be boiled down to:
> 
>   | codec_h264.c
>   | codec_mjpeg.c
>   | codec_mpeg4.c
>   | vdec_1.c -->| codec_mpeg12.c
> vdec.c -->| vdec_hevc.c -->| codec_hevc.c
> | esparser.c
> 
> The V4L2 code is handled mostly in vdec.c.
> Each VDEC and CODEC unit is accessed via ops structs to facilitate the code.
> 
> The arrangement between vdecs and codecs can be seen in vdec_platform.c
> This file also declares things like pixfmts, min/max buffers and firmware 
> paths
> for each SoC.
> 
> Specific questions about the code:
> 
> - While I do use the platform's general clks and resets tied to the vdec in
> a nice way (dts + clock/reset controller with clk/reset frameworks),
> there are some subclocks and resets that I use in the driver by writing
> directly to registers. e.g:
> 
>   - writel_relaxed((1<<7) | (1<<6), core->dos_base + DOS_SW_RESET0);

This seems to be internal resets

>   - writel_relaxed(0x3ff, core->dos_base + DOS_GCLK_EN0);

This seems to be internal gates

If it's in the VDEC/DO registers space, you can keep this internaly, no need to 
use
the clk or reset framework.

Neil

> 
> and a few other instances where that happens.
> 
> Is it okay to not create specific controllers for those ? The main issue is
> the lack of documentation so I don't know which resets/clocks are impacted by
> those writes.
> The only thing I'm certain of is that they only apply to the vdec/esparser.
> 
> - I tend to call vdec_* functions from the codec handlers.
> 
> For instance, codec_h264 will call vdec_dst_buf_done_idx to DONE
> a capture buffer. vdec_dst_buf_done_idx is as such a public symbol.
> 
> Should I use an ops struct for those instead, so that the codec handlers
> don't depend directly on the vdec general code ?
> 
> - Naming: my public symbols either start with vdec_* or esparser_*
> 
> Should I change that to something meson/amlogic specific ?
> 
> - I have a _lot_ of writel_relaxed calls.
> 
> Can I leave them be or is there a nicer way to do it ?
> 
> - Since the decoder is single instance, I only allow one _open at a time.
> 
> However the v4l2 compliance suite complains about this.
> How should I safely make it single instance ? Not allowing multiple 
> start_streaming ?
> 
> - I am getting these 2 fails, but unsure what they are about:
> 
> Buffer ioctls:
>   fail: 
> ../../../v4l-utils-1.12.3/utils/v4l2-compliance/v4l2-test-buffers.cpp(428): 
> node->node2 == NULL
>   test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: FAIL
>   fail: 
> ../../../v4l-utils-1.12.3/utils/v4l2-compliance/v4l2-test-buffers.cpp(571): 
> q.has_expbuf(node)
>   test VIDIOC_EXPBUF: FAIL
> 
> 
> 
> And of course, I will gladly accept any kind of other feedback you would have.
> 
> Thanks!
> 
> 
> Maxime Jourdan (4):
>   media: meson: add v4l2 m2m video decoder driver
>   ARM64: dts: meson-gx: add vdec entry
>   ARM64: dts: meson: add vdec entries
>   dt-bindings: media: add Amlogic Meson Video Decoder Bindings
> 
>  .../bindings/media/amlogic,meson-vdec.txt |   60 +
>  arch/arm64/boot/dts/amlogic/meson-gx.dtsi |   14 +
>  arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi   |8 +
>  arch/arm64/boot/dts/amlogic/meson-gxl.dtsi|8 +
>  arch/arm64/boot/dts/amlogic/meson-gxm.dtsi|4 +
>  drivers/media/platform/Kconfig|   10 +
>  drivers/media/platform/meson/Makefile |1 +
>  drivers/media/platform/meson/vdec/Makefile|7 +
>  drivers/media/platform/meson/vdec/canvas.c|   69 +
>  drivers/media/platform/meson/vdec/canvas.h|   42 +
>  .../media/platform/meson/vdec/codec_h264.c|  376 +
>  .../media/platform/meson/vdec/codec_h264.h|   13 +
>  .../media/platform/meson/vdec/codec_helpers.c |   45 +
>  .../media/platform/meson/vdec/codec_helpers.h |8 +
>  .../media/platform/meson/vdec/codec_hevc.c| 1383 +
>  .../media/platform/meson/vdec/codec_hevc.h|   13 +
>  .../media/platform/meson/vdec/codec_mjpeg.c   |  203 +++
>  .../media/platform/meson/vdec/codec_mjpeg.h   |   13 +
>  .../media/platform/meson/vdec/codec_mpeg12.c  |  183 +++
>  .../media/platform/meson/vdec/codec_mpeg12.h  |   13 +
>  .../media/platform/meson/vdec/codec_mpeg4.c   |  213 +++
>  

Re: [PATCH v7 0/6] Add ChromeOS EC CEC Support

2018-06-11 Thread Neil Armstrong
Hi Lee,

On 11/06/2018 08:03, Lee Jones wrote:
> On Fri, 08 Jun 2018, Hans Verkuil wrote:
>> On 08/06/18 10:17, Neil Armstrong wrote:
>>> On 08/06/2018 09:53, Hans Verkuil wrote:
>>>> On 06/01/2018 10:19 AM, Neil Armstrong wrote:
>>>>> Hi All,
>>>>>
>>>>> The new Google "Fizz" Intel-based ChromeOS device is gaining CEC support
>>>>> through it's Embedded Controller, to enable the Linux CEC Core to 
>>>>> communicate
>>>>> with it and get the CEC Physical Address from the correct HDMI Connector, 
>>>>> the
>>>>> following must be added/changed:
>>>>> - Add the CEC sub-device registration in the ChromeOS EC MFD Driver
>>>>> - Add the CEC related commands and events definitions into the EC MFD 
>>>>> driver
>>>>> - Add a way to get a CEC notifier with it's (optional) connector name
>>>>> - Add the CEC notifier to the i915 HDMI driver
>>>>> - Add the proper ChromeOS EC CEC Driver
>>>>>
>>>>> The CEC notifier with the connector name is the tricky point, since even 
>>>>> on
>>>>> Device-Tree platforms, there is no way to distinguish between multiple 
>>>>> HDMI
>>>>> connectors from the same DRM driver. The solution I implemented is pretty
>>>>> simple and only adds an optional connector name to eventually distinguish
>>>>> an HDMI connector notifier from another if they share the same device.
>>>>
>>>> This looks good to me, which brings me to the next question: how to merge
>>>> this?
>>>>
>>>> It touches on three subsystems (media, drm, mfd), so that makes this
>>>> tricky.
>>>>
>>>> I think there are two options: either the whole series goes through the
>>>> media tree, or patches 1+2 go through drm and 3-6 through media. If there
>>>> is a high chance of conflicts in the mfd code, then it is also an option to
>>>> have patches 3-6 go through the mfd subsystem.
>>>
>>> I think patches 3-6 should go in the mfd tree, Lee is used to handle this,
>>> then I think the rest could go in the media tree.
>>>
>>> Lee, do you think it would be possible to have an immutable branch with 
>>> patches 3-6 ?
>>>
>>> Could we have an immutable branch from media tree with patch 1 to be merged 
>>> in
>>> the i915 tree for patch 2 ?
>>>
>>> Or patch 1+2 could me merged into the i915 tree and generate an immutable 
>>> branch
>>
>> I think patches 1+2 can just go to the i915 tree. The i915 driver changes 
>> often,
>> so going through that tree makes sense. The cec-notifier code is unlikely to 
>> change,
>> and I am fine with that patch going through i915.
>>
>>> for media to merge the mfd branch + patch 7 ?
>>
>> Patch 7? I only count 6?
>>
>> If 1+2 go through drm and 3-6 go through mfd, then media isn't affected at 
>> all.
>> There is chance of a conflict when this is eventually pushed to mainline for
>> the media Kconfig, but that's all.
> 
> What are the *build* dependencies within the set?

Here are the hard the build dependency :

Patch 2 depends on Patch 1
Patch 5 depends on Patch 4
Patch 6 depends on Patches 1 & 4

> 
> I'd be happy to send out a pull-request for either all of the patches,
> or just the MFD changes once I've had chance to review them.
> 

Great, thanks !

Neil


Re: [Intel-gfx] [PATCH v6 2/6] drm/i915: hdmi: add CEC notifier to intel_hdmi

2018-05-31 Thread Neil Armstrong
On 31/05/2018 01:26, Rodrigo Vivi wrote:
> On Wed, May 30, 2018 at 06:29:36PM +0300, Ville Syrjälä wrote:
>> On Thu, May 24, 2018 at 11:57:17AM +0200, Neil Armstrong wrote:
>>> This patchs adds the cec_notifier feature to the intel_hdmi part
>>> of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate
>>> between each HDMI ports.
>>> The changes will allow the i915 HDMI code to notify EDID and HPD changes
>>> to an eventual CEC adapter.
>>>
>>> Signed-off-by: Neil Armstrong 
>>> Reviewed-by: Hans Verkuil 
>>> ---
>>>  drivers/gpu/drm/i915/Kconfig |  1 +
>>>  drivers/gpu/drm/i915/intel_display.h | 20 
>>>  drivers/gpu/drm/i915/intel_drv.h |  2 ++
>>>  drivers/gpu/drm/i915/intel_hdmi.c| 13 +
>>>  4 files changed, 36 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
>>> index dfd9588..2d65d56 100644
>>> --- a/drivers/gpu/drm/i915/Kconfig
>>> +++ b/drivers/gpu/drm/i915/Kconfig
>>> @@ -23,6 +23,7 @@ config DRM_I915
>>> select SYNC_FILE
>>> select IOSF_MBI
>>> select CRC32
>>> +   select CEC_CORE if CEC_NOTIFIER
>>> help
>>>   Choose this option if you have a system that has "Intel Graphics
>>>   Media Accelerator" or "HD Graphics" integrated graphics,
>>> diff --git a/drivers/gpu/drm/i915/intel_display.h 
>>> b/drivers/gpu/drm/i915/intel_display.h
>>> index 4e7418b..c68d1c8 100644
>>> --- a/drivers/gpu/drm/i915/intel_display.h
>>> +++ b/drivers/gpu/drm/i915/intel_display.h
>>> @@ -126,6 +126,26 @@ enum port {
>>>  
>>>  #define port_name(p) ((p) + 'A')
>>>  
>>> +static inline const char *port_identifier(enum port port)
>>> +{
>>> +   switch (port) {
>>> +   case PORT_A:
>>> +   return "Port A";
>>> +   case PORT_B:
>>> +   return "Port B";
>>> +   case PORT_C:
>>> +   return "Port C";
>>> +   case PORT_D:
>>> +   return "Port D";
>>> +   case PORT_E:
>>> +   return "Port E";
>>> +   case PORT_F:
>>> +   return "Port F";
>>> +   default:
>>> +   return "";
>>> +   }
>>> +}
>>
>> Could use a comment to make it clear that this identifier is
>> expected to remain stable since it's referenced from other drivers.
>>
>>> +
>>>  enum dpio_channel {
>>> DPIO_CH0,
>>> DPIO_CH1
>>> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
>>> b/drivers/gpu/drm/i915/intel_drv.h
>>> index d436858..b50e51b 100644
>>> --- a/drivers/gpu/drm/i915/intel_drv.h
>>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>>> @@ -39,6 +39,7 @@
>>>  #include 
>>>  #include 
>>>  #include 
>>> +#include 
>>>  
>>>  /**
>>>   * __wait_for - magic wait macro
>>> @@ -1001,6 +1002,7 @@ struct intel_hdmi {
>>> bool has_audio;
>>> bool rgb_quant_range_selectable;
>>> struct intel_connector *attached_connector;
>>> +   struct cec_notifier *notifier;
>>
>> "notifier" seems a bit too generic a name. "cec_notifier" would be
>> better.
>>
>> Apart from that this seems OK to me
>> Reviewed-by: Ville Syrjälä 
> 
> It seems that you will need to push this to other trees right?
> Feel free to use:
> 
> Acked-by: Rodrigo Vivi 

You are right, it will useful, thanks !

Neil

> 
>>
>>>  };
>>>  
>>>  struct intel_dp_mst_encoder;
>>> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
>>> b/drivers/gpu/drm/i915/intel_hdmi.c
>>> index 1baef4a..d522b5b 100644
>>> --- a/drivers/gpu/drm/i915/intel_hdmi.c
>>> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
>>> @@ -1868,6 +1868,8 @@ intel_hdmi_set_edid(struct drm_connector *connector)
>>> connected = true;
>>> }
>>>  
>>> +   cec_notifier_set_phys_addr_from_edid(intel_hdmi->notifier, edid);
>>> +
>>> return connected;
>>>  }
>>>  
>>> @@ -1876,6 +1878,7 @@ intel_hdmi_detect(struct drm_connector *connector, 
>>> bool force)
>>>  {
>>> enum drm_connector_status status;
>>> struct drm_i915_private *dev_priv = to_i915(connector-&g

[PATCH v6 5/6] mfd: cros_ec_dev: Add CEC sub-device registration

2018-05-24 Thread Neil Armstrong
The EC can expose a CEC bus, thus add the cros-ec-cec MFD sub-device
when the CEC feature bit is present.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
Reviewed-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
---
 drivers/mfd/cros_ec_dev.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c
index 1d6dc5c..272969e 100644
--- a/drivers/mfd/cros_ec_dev.c
+++ b/drivers/mfd/cros_ec_dev.c
@@ -383,6 +383,10 @@ static void cros_ec_sensors_register(struct cros_ec_dev 
*ec)
kfree(msg);
 }
 
+static const struct mfd_cell cros_ec_cec_cells[] = {
+   { .name = "cros-ec-cec" }
+};
+
 static const struct mfd_cell cros_ec_rtc_cells[] = {
{ .name = "cros-ec-rtc" }
 };
@@ -426,6 +430,18 @@ static int ec_device_probe(struct platform_device *pdev)
if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE))
cros_ec_sensors_register(ec);
 
+   /* Check whether this EC instance has CEC host command support */
+   if (cros_ec_check_features(ec, EC_FEATURE_CEC)) {
+   retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO,
+cros_ec_cec_cells,
+ARRAY_SIZE(cros_ec_cec_cells),
+NULL, 0, NULL);
+   if (retval)
+   dev_err(ec->dev,
+   "failed to add cros-ec-cec device: %d\n",
+   retval);
+   }
+
/* Check whether this EC instance has RTC host command support */
if (cros_ec_check_features(ec, EC_FEATURE_RTC)) {
retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO,
-- 
2.7.4



[PATCH v6 2/6] drm/i915: hdmi: add CEC notifier to intel_hdmi

2018-05-24 Thread Neil Armstrong
This patchs adds the cec_notifier feature to the intel_hdmi part
of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate
between each HDMI ports.
The changes will allow the i915 HDMI code to notify EDID and HPD changes
to an eventual CEC adapter.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
Reviewed-by: Hans Verkuil <hans.verk...@cisco.com>
---
 drivers/gpu/drm/i915/Kconfig |  1 +
 drivers/gpu/drm/i915/intel_display.h | 20 
 drivers/gpu/drm/i915/intel_drv.h |  2 ++
 drivers/gpu/drm/i915/intel_hdmi.c| 13 +
 4 files changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index dfd9588..2d65d56 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -23,6 +23,7 @@ config DRM_I915
select SYNC_FILE
select IOSF_MBI
select CRC32
+   select CEC_CORE if CEC_NOTIFIER
help
  Choose this option if you have a system that has "Intel Graphics
  Media Accelerator" or "HD Graphics" integrated graphics,
diff --git a/drivers/gpu/drm/i915/intel_display.h 
b/drivers/gpu/drm/i915/intel_display.h
index 4e7418b..c68d1c8 100644
--- a/drivers/gpu/drm/i915/intel_display.h
+++ b/drivers/gpu/drm/i915/intel_display.h
@@ -126,6 +126,26 @@ enum port {
 
 #define port_name(p) ((p) + 'A')
 
+static inline const char *port_identifier(enum port port)
+{
+   switch (port) {
+   case PORT_A:
+   return "Port A";
+   case PORT_B:
+   return "Port B";
+   case PORT_C:
+   return "Port C";
+   case PORT_D:
+   return "Port D";
+   case PORT_E:
+   return "Port E";
+   case PORT_F:
+   return "Port F";
+   default:
+   return "";
+   }
+}
+
 enum dpio_channel {
DPIO_CH0,
DPIO_CH1
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d436858..b50e51b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -39,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /**
  * __wait_for - magic wait macro
@@ -1001,6 +1002,7 @@ struct intel_hdmi {
bool has_audio;
bool rgb_quant_range_selectable;
struct intel_connector *attached_connector;
+   struct cec_notifier *notifier;
 };
 
 struct intel_dp_mst_encoder;
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
b/drivers/gpu/drm/i915/intel_hdmi.c
index 1baef4a..d522b5b 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1868,6 +1868,8 @@ intel_hdmi_set_edid(struct drm_connector *connector)
connected = true;
}
 
+   cec_notifier_set_phys_addr_from_edid(intel_hdmi->notifier, edid);
+
return connected;
 }
 
@@ -1876,6 +1878,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool 
force)
 {
enum drm_connector_status status;
struct drm_i915_private *dev_priv = to_i915(connector->dev);
+   struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
  connector->base.id, connector->name);
@@ -1891,6 +1894,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool 
force)
 
intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
 
+   if (status != connector_status_connected)
+   cec_notifier_phys_addr_invalidate(intel_hdmi->notifier);
+
return status;
 }
 
@@ -2031,6 +2037,8 @@ static void chv_hdmi_pre_enable(struct intel_encoder 
*encoder,
 
 static void intel_hdmi_destroy(struct drm_connector *connector)
 {
+   if (intel_attached_hdmi(connector)->notifier)
+   cec_notifier_put(intel_attached_hdmi(connector)->notifier);
kfree(to_intel_connector(connector)->detect_edid);
drm_connector_cleanup(connector);
kfree(connector);
@@ -2358,6 +2366,11 @@ void intel_hdmi_init_connector(struct intel_digital_port 
*intel_dig_port,
u32 temp = I915_READ(PEG_BAND_GAP_DATA);
I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
}
+
+   intel_hdmi->notifier = cec_notifier_get_conn(dev->dev,
+port_identifier(port));
+   if (!intel_hdmi->notifier)
+   DRM_DEBUG_KMS("CEC notifier get failed\n");
 }
 
 void intel_hdmi_init(struct drm_i915_private *dev_priv,
-- 
2.7.4



[PATCH v6 3/6] mfd: cros-ec: Increase maximum mkbp event size

2018-05-24 Thread Neil Armstrong
Having a 16 byte mkbp event size makes it possible to send CEC
messages from the EC to the AP directly inside the mkbp event
instead of first doing a notification and then a read.

Signed-off-by: Stefan Adolfsson <sadolfs...@chromium.org>
Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
Tested-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
---
 drivers/platform/chrome/cros_ec_proto.c | 40 +
 include/linux/mfd/cros_ec.h |  2 +-
 include/linux/mfd/cros_ec_commands.h| 19 
 3 files changed, 51 insertions(+), 10 deletions(-)

diff --git a/drivers/platform/chrome/cros_ec_proto.c 
b/drivers/platform/chrome/cros_ec_proto.c
index e7bbdf9..c4f6c44 100644
--- a/drivers/platform/chrome/cros_ec_proto.c
+++ b/drivers/platform/chrome/cros_ec_proto.c
@@ -504,10 +504,31 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev,
 }
 EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
 
+static int get_next_event_xfer(struct cros_ec_device *ec_dev,
+  struct cros_ec_command *msg,
+  int version, uint32_t size)
+{
+   int ret;
+
+   msg->version = version;
+   msg->command = EC_CMD_GET_NEXT_EVENT;
+   msg->insize = size;
+   msg->outsize = 0;
+
+   ret = cros_ec_cmd_xfer(ec_dev, msg);
+   if (ret > 0) {
+   ec_dev->event_size = ret - 1;
+   memcpy(_dev->event_data, msg->data, ec_dev->event_size);
+   }
+
+   return ret;
+}
+
 static int get_next_event(struct cros_ec_device *ec_dev)
 {
u8 buffer[sizeof(struct cros_ec_command) + sizeof(ec_dev->event_data)];
struct cros_ec_command *msg = (struct cros_ec_command *)
+   static int cmd_version = 1;
int ret;
 
if (ec_dev->suspended) {
@@ -515,18 +536,19 @@ static int get_next_event(struct cros_ec_device *ec_dev)
return -EHOSTDOWN;
}
 
-   msg->version = 0;
-   msg->command = EC_CMD_GET_NEXT_EVENT;
-   msg->insize = sizeof(ec_dev->event_data);
-   msg->outsize = 0;
+   if (cmd_version == 1) {
+   ret = get_next_event_xfer(ec_dev, msg, cmd_version,
+   sizeof(struct ec_response_get_next_event_v1));
+   if (ret < 0 || msg->result != EC_RES_INVALID_VERSION)
+   return ret;
 
-   ret = cros_ec_cmd_xfer(ec_dev, msg);
-   if (ret > 0) {
-   ec_dev->event_size = ret - 1;
-   memcpy(_dev->event_data, msg->data,
-  sizeof(ec_dev->event_data));
+   /* Fallback to version 0 for future send attempts */
+   cmd_version = 0;
}
 
+   ret = get_next_event_xfer(ec_dev, msg, cmd_version,
+ sizeof(struct ec_response_get_next_event));
+
return ret;
 }
 
diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h
index f36125e..32caef3 100644
--- a/include/linux/mfd/cros_ec.h
+++ b/include/linux/mfd/cros_ec.h
@@ -147,7 +147,7 @@ struct cros_ec_device {
bool mkbp_event_supported;
struct blocking_notifier_head event_notifier;
 
-   struct ec_response_get_next_event event_data;
+   struct ec_response_get_next_event_v1 event_data;
int event_size;
u32 host_event_wake_mask;
 };
diff --git a/include/linux/mfd/cros_ec_commands.h 
b/include/linux/mfd/cros_ec_commands.h
index f2edd99..cc0768e 100644
--- a/include/linux/mfd/cros_ec_commands.h
+++ b/include/linux/mfd/cros_ec_commands.h
@@ -2093,12 +2093,31 @@ union ec_response_get_next_data {
uint32_t   sysrq;
 } __packed;
 
+union ec_response_get_next_data_v1 {
+   uint8_t   key_matrix[16];
+
+   /* Unaligned */
+   uint32_t  host_event;
+
+   uint32_t   buttons;
+   uint32_t   switches;
+   uint32_t   sysrq;
+   uint32_t   cec_events;
+   uint8_tcec_message[16];
+} __packed;
+
 struct ec_response_get_next_event {
uint8_t event_type;
/* Followed by event data if any */
union ec_response_get_next_data data;
 } __packed;
 
+struct ec_response_get_next_event_v1 {
+   uint8_t event_type;
+   /* Followed by event data if any */
+   union ec_response_get_next_data_v1 data;
+} __packed;
+
 /* Bit indices for buttons and switches.*/
 /* Buttons */
 #define EC_MKBP_POWER_BUTTON   0
-- 
2.7.4



[PATCH v6 4/6] mfd: cros-ec: Introduce CEC commands and events definitions.

2018-05-24 Thread Neil Armstrong
The EC can expose a CEC bus, this patch adds the CEC related definitions
needed by the cros-ec-cec driver.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
Tested-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
---
 include/linux/mfd/cros_ec_commands.h | 81 
 1 file changed, 81 insertions(+)

diff --git a/include/linux/mfd/cros_ec_commands.h 
b/include/linux/mfd/cros_ec_commands.h
index cc0768e..fe33a81 100644
--- a/include/linux/mfd/cros_ec_commands.h
+++ b/include/linux/mfd/cros_ec_commands.h
@@ -804,6 +804,8 @@ enum ec_feature_code {
EC_FEATURE_MOTION_SENSE_FIFO = 24,
/* EC has RTC feature that can be controlled by host commands */
EC_FEATURE_RTC = 27,
+   /* EC supports CEC commands */
+   EC_FEATURE_CEC = 35,
 };
 
 #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32))
@@ -2078,6 +2080,12 @@ enum ec_mkbp_event {
/* EC sent a sysrq command */
EC_MKBP_EVENT_SYSRQ = 6,
 
+   /* Notify the AP that something happened on CEC */
+   EC_MKBP_EVENT_CEC_EVENT = 8,
+
+   /* Send an incoming CEC message to the AP */
+   EC_MKBP_EVENT_CEC_MESSAGE = 9,
+
/* Number of MKBP events */
EC_MKBP_EVENT_COUNT,
 };
@@ -2850,6 +2858,79 @@ struct ec_params_reboot_ec {
 
 /*/
 /*
+ * HDMI CEC commands
+ *
+ * These commands are for sending and receiving message via HDMI CEC
+ */
+#define EC_MAX_CEC_MSG_LEN 16
+
+/* CEC message from the AP to be written on the CEC bus */
+#define EC_CMD_CEC_WRITE_MSG 0x00B8
+
+/**
+ * struct ec_params_cec_write - Message to write to the CEC bus
+ * @msg: message content to write to the CEC bus
+ */
+struct ec_params_cec_write {
+   uint8_t msg[EC_MAX_CEC_MSG_LEN];
+} __packed;
+
+/* Set various CEC parameters */
+#define EC_CMD_CEC_SET 0x00BA
+
+/**
+ * struct ec_params_cec_set - CEC parameters set
+ * @cmd: parameter type, can be CEC_CMD_ENABLE or CEC_CMD_LOGICAL_ADDRESS
+ * @val: in case cmd is CEC_CMD_ENABLE, this field can be 0 to disable CEC
+ * or 1 to enable CEC functionnality, in case cmd is 
CEC_CMD_LOGICAL_ADDRESS,
+ * this field encodes the requested logical address between 0 and 15
+ * or 0xff to unregister
+ */
+struct ec_params_cec_set {
+   uint8_t cmd; /* enum cec_command */
+   uint8_t val;
+} __packed;
+
+/* Read various CEC parameters */
+#define EC_CMD_CEC_GET 0x00BB
+
+/**
+ * struct ec_params_cec_get - CEC parameters get
+ * @cmd: parameter type, can be CEC_CMD_ENABLE or CEC_CMD_LOGICAL_ADDRESS
+ */
+struct ec_params_cec_get {
+   uint8_t cmd; /* enum cec_command */
+} __packed;
+
+/**
+ * struct ec_response_cec_get - CEC parameters get response
+ * @val: in case cmd was CEC_CMD_ENABLE, this field will 0 if CEC is
+ * disabled or 1 if CEC functionnality is enabled,
+ * in case cmd was CEC_CMD_LOGICAL_ADDRESS, this will encode the
+ * configured logical address between 0 and 15 or 0xff if unregistered
+ */
+struct ec_response_cec_get {
+   uint8_t val;
+} __packed;
+
+/* CEC parameters command */
+enum ec_cec_command {
+   /* CEC reading, writing and events enable */
+   CEC_CMD_ENABLE,
+   /* CEC logical address  */
+   CEC_CMD_LOGICAL_ADDRESS,
+};
+
+/* Events from CEC to AP */
+enum mkbp_cec_event {
+   /* Outgoing message was acknowledged by a follower */
+   EC_MKBP_CEC_SEND_OK = BIT(0),
+   /* Outgoing message was not acknowledged */
+   EC_MKBP_CEC_SEND_FAILED = BIT(1),
+};
+
+/*/
+/*
  * Special commands
  *
  * These do not follow the normal rules for commands.  See each command for
-- 
2.7.4



[PATCH v6 1/6] media: cec-notifier: Get notifier by device and connector name

2018-05-24 Thread Neil Armstrong
In non device-tree world, we can need to get the notifier by the driver
name directly and eventually defer probe if not yet created.

This patch adds a variant of the get function by using the device name
instead and will not create a notifier if not yet created.

But the i915 driver exposes at least 2 HDMI connectors, this patch also
adds the possibility to add a connector name tied to the notifier device
to form a tuple and associate different CEC controllers for each HDMI
connectors.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
Reviewed-by: Hans Verkuil <hans.verk...@cisco.com>
---
 drivers/media/cec/cec-notifier.c | 11 ---
 include/media/cec-notifier.h | 27 ---
 2 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c
index 16dffa0..dd2078b 100644
--- a/drivers/media/cec/cec-notifier.c
+++ b/drivers/media/cec/cec-notifier.c
@@ -21,6 +21,7 @@ struct cec_notifier {
struct list_head head;
struct kref kref;
struct device *dev;
+   const char *conn;
struct cec_adapter *cec_adap;
void (*callback)(struct cec_adapter *adap, u16 pa);
 
@@ -30,13 +31,14 @@ struct cec_notifier {
 static LIST_HEAD(cec_notifiers);
 static DEFINE_MUTEX(cec_notifiers_lock);
 
-struct cec_notifier *cec_notifier_get(struct device *dev)
+struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char 
*conn)
 {
struct cec_notifier *n;
 
mutex_lock(_notifiers_lock);
list_for_each_entry(n, _notifiers, head) {
-   if (n->dev == dev) {
+   if (n->dev == dev &&
+   (!conn || !strcmp(n->conn, conn))) {
kref_get(>kref);
mutex_unlock(_notifiers_lock);
return n;
@@ -46,6 +48,8 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
if (!n)
goto unlock;
n->dev = dev;
+   if (conn)
+   n->conn = kstrdup(conn, GFP_KERNEL);
n->phys_addr = CEC_PHYS_ADDR_INVALID;
mutex_init(>lock);
kref_init(>kref);
@@ -54,7 +58,7 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
mutex_unlock(_notifiers_lock);
return n;
 }
-EXPORT_SYMBOL_GPL(cec_notifier_get);
+EXPORT_SYMBOL_GPL(cec_notifier_get_conn);
 
 static void cec_notifier_release(struct kref *kref)
 {
@@ -62,6 +66,7 @@ static void cec_notifier_release(struct kref *kref)
container_of(kref, struct cec_notifier, kref);
 
list_del(>head);
+   kfree(n->conn);
kfree(n);
 }
 
diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h
index cf0add7..814eeef 100644
--- a/include/media/cec-notifier.h
+++ b/include/media/cec-notifier.h
@@ -20,8 +20,10 @@ struct cec_notifier;
 #if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER)
 
 /**
- * cec_notifier_get - find or create a new cec_notifier for the given device.
+ * cec_notifier_get_conn - find or create a new cec_notifier for the given
+ * device and connector tuple.
  * @dev: device that sends the events.
+ * @conn: the connector name from which the event occurs
  *
  * If a notifier for device @dev already exists, then increase the refcount
  * and return that notifier.
@@ -31,7 +33,8 @@ struct cec_notifier;
  *
  * Return NULL if the memory could not be allocated.
  */
-struct cec_notifier *cec_notifier_get(struct device *dev);
+struct cec_notifier *cec_notifier_get_conn(struct device *dev,
+  const char *conn);
 
 /**
  * cec_notifier_put - decrease refcount and delete when the refcount reaches 0.
@@ -85,7 +88,8 @@ void cec_register_cec_notifier(struct cec_adapter *adap,
   struct cec_notifier *notifier);
 
 #else
-static inline struct cec_notifier *cec_notifier_get(struct device *dev)
+static inline struct cec_notifier *cec_notifier_get_conn(struct device *dev,
+const char *conn)
 {
/* A non-NULL pointer is expected on success */
return (struct cec_notifier *)0xdeadfeed;
@@ -121,6 +125,23 @@ static inline void cec_register_cec_notifier(struct 
cec_adapter *adap,
 #endif
 
 /**
+ * cec_notifier_get - find or create a new cec_notifier for the given device.
+ * @dev: device that sends the events.
+ *
+ * If a notifier for device @dev already exists, then increase the refcount
+ * and return that notifier.
+ *
+ * If it doesn't exist, then allocate a new notifier struct and return a
+ * pointer to that new struct.
+ *
+ * Return NULL if the memory could not be allocated.
+ */
+static inline struct cec_notifier *cec_notifier_get(struct device *dev)
+{
+   return cec_notifier_get_conn(dev, NULL);
+}
+
+/**
  * cec_notifier_phys_addr_invalidate() - set the physical address to INVALID
  *
  * @n: the CEC notifier
-- 
2.7.4



[PATCH v6 6/6] media: platform: Add ChromeOS EC CEC driver

2018-05-24 Thread Neil Armstrong
The ChromeOS Embedded Controller can expose a CEC bus, this patch add the
driver for such feature of the Embedded Controller.

This driver is part of the cros-ec MFD and will be add as a sub-device when
the feature bit is exposed by the EC.

The controller will only handle a single logical address and handles
all the messages retries and will only expose Success or Error.

The controller will be tied to the HDMI CEC notifier by using the platform
DMI Data and the i915 device name and connector name.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
Reviewed-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Reviewed-by: Hans Verkuil <hans.verk...@cisco.com>
---
 drivers/media/platform/Kconfig   |  11 +
 drivers/media/platform/Makefile  |   2 +
 drivers/media/platform/cros-ec-cec/Makefile  |   1 +
 drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 347 +++
 4 files changed, 361 insertions(+)
 create mode 100644 drivers/media/platform/cros-ec-cec/Makefile
 create mode 100644 drivers/media/platform/cros-ec-cec/cros-ec-cec.c

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index c7a1cf8..bc37ecf 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -546,6 +546,17 @@ menuconfig CEC_PLATFORM_DRIVERS
 
 if CEC_PLATFORM_DRIVERS
 
+config VIDEO_CROS_EC_CEC
+   tristate "ChromeOS EC CEC driver"
+   depends on MFD_CROS_EC || COMPILE_TEST
+   select CEC_CORE
+   select CEC_NOTIFIER
+   ---help---
+ If you say yes here you will get support for the
+ ChromeOS Embedded Controller's CEC.
+ The CEC bus is present in the HDMI connector and enables communication
+ between compatible devices.
+
 config VIDEO_MESON_AO_CEC
tristate "Amlogic Meson AO CEC driver"
depends on ARCH_MESON || COMPILE_TEST
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 932515d..830696f 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -92,3 +92,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS)+= 
qcom/camss-8x16/
 obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/
 
 obj-y  += meson/
+
+obj-y  += cros-ec-cec/
diff --git a/drivers/media/platform/cros-ec-cec/Makefile 
b/drivers/media/platform/cros-ec-cec/Makefile
new file mode 100644
index 000..9ce97f9
--- /dev/null
+++ b/drivers/media/platform/cros-ec-cec/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VIDEO_CROS_EC_CEC) += cros-ec-cec.o
diff --git a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c 
b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
new file mode 100644
index 000..7bc4d8a
--- /dev/null
+++ b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
@@ -0,0 +1,347 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * CEC driver for ChromeOS Embedded Controller
+ *
+ * Copyright (c) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstr...@baylibre.com>
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DRV_NAME   "cros-ec-cec"
+
+/**
+ * struct cros_ec_cec - Driver data for EC CEC
+ *
+ * @cros_ec: Pointer to EC device
+ * @notifier: Notifier info for responding to EC events
+ * @adap: CEC adapter
+ * @notify: CEC notifier pointer
+ * @rx_msg: storage for a received message
+ */
+struct cros_ec_cec {
+   struct cros_ec_device *cros_ec;
+   struct notifier_block notifier;
+   struct cec_adapter *adap;
+   struct cec_notifier *notify;
+   struct cec_msg rx_msg;
+};
+
+static void handle_cec_message(struct cros_ec_cec *cros_ec_cec)
+{
+   struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
+   uint8_t *cec_message = cros_ec->event_data.data.cec_message;
+   unsigned int len = cros_ec->event_size;
+
+   cros_ec_cec->rx_msg.len = len;
+   memcpy(cros_ec_cec->rx_msg.msg, cec_message, len);
+
+   cec_received_msg(cros_ec_cec->adap, _ec_cec->rx_msg);
+}
+
+static void handle_cec_event(struct cros_ec_cec *cros_ec_cec)
+{
+   struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
+   uint32_t events = cros_ec->event_data.data.cec_events;
+
+   if (events & EC_MKBP_CEC_SEND_OK)
+   cec_transmit_attempt_done(cros_ec_cec->adap,
+ CEC_TX_STATUS_OK);
+
+   /* FW takes care of all retries, tell core to avoid more retries */
+   if (events & EC_MKBP_CEC_SEND_FAILED)
+   cec_transmit_attempt_done(cros_ec_cec->adap,
+ CEC_TX_STATUS_MAX_RETRIES |
+ CEC_TX_STATUS_NACK);
+}
+
+static int cros_ec_cec_event(struct notifier_block *nb,
+unsigned long queued_during_

[PATCH v6 0/6] Add ChromeOS EC CEC Support

2018-05-24 Thread Neil Armstrong
Hi All,

The new Google "Fizz" Intel-based ChromeOS device is gaining CEC support
through it's Embedded Controller, to enable the Linux CEC Core to communicate
with it and get the CEC Physical Address from the correct HDMI Connector, the
following must be added/changed:
- Add the CEC sub-device registration in the ChromeOS EC MFD Driver
- Add the CEC related commands and events definitions into the EC MFD driver
- Add a way to get a CEC notifier with it's (optional) connector name
- Add the CEC notifier to the i915 HDMI driver
- Add the proper ChromeOS EC CEC Driver

The CEC notifier with the connector name is the tricky point, since even on
Device-Tree platforms, there is no way to distinguish between multiple HDMI
connectors from the same DRM driver. The solution I implemented is pretty
simple and only adds an optional connector name to eventually distinguish
an HDMI connector notifier from another if they share the same device.

Feel free to comment this patchset !

Changes since v5:
 - Small fixups on include/linux/mfd/cros_ec_commands.h
 - Fixed on cros-ec-cec driver accordingly
 - Added Reviewed-By tags

Changes since v4:
 - Split patch 3 to move the mkbp event size change into a separate patch

Changes since v3 (incorrectly reported as v2):
 - Renamed "Chrome OS" to "ChromeOS"
 - Updated cros_ec_commands.h new structs definitions to kernel doc format
 - Added Reviewed-By tags

Changes since v2:
 - Add i915 port_identifier() and use this stable name as cec_notifier conn name
 - Fixed and cleaned up the CEC commands and events handling
 - Rebased the CEC sub-device registration on top of Enric's serie
 - Fixed comments typo on cec driver
 - Protected the DMI match only with PCI and DMI Kconfigs

Changes since v1:
 - Added cec_notifier_put to intel_hdmi
 - Fixed all small reported issues on the EC CEC driver
 - Moved the cec_notifier_get out of the #if .. #else .. #endif

Changes since RFC:
 - Moved CEC sub-device registration after CEC commands and events definitions 
patch
 - Removed get_notifier_get_byname
 - Added CEC_CORE select into i915 Kconfig
 - Removed CEC driver fallback if notifier is not configured on HW, added 
explicit warn
 - Fixed CEC core return type on error
 - Moved to cros-ec-cec media platform directory
 - Use bus_find_device() to find the pci i915 device instead of 
get_notifier_get_byname()
 - Fix Logical Address setup
 - Added comment about HW support
 - Removed memset of msg structures

Neil Armstrong (6):
  media: cec-notifier: Get notifier by device and connector name
  drm/i915: hdmi: add CEC notifier to intel_hdmi
  mfd: cros-ec: Increase maximum mkbp event size
  mfd: cros-ec: Introduce CEC commands and events definitions.
  mfd: cros_ec_dev: Add CEC sub-device registration
  media: platform: Add ChromeOS EC CEC driver

 drivers/gpu/drm/i915/Kconfig |   1 +
 drivers/gpu/drm/i915/intel_display.h |  20 ++
 drivers/gpu/drm/i915/intel_drv.h |   2 +
 drivers/gpu/drm/i915/intel_hdmi.c|  13 +
 drivers/media/cec/cec-notifier.c |  11 +-
 drivers/media/platform/Kconfig   |  11 +
 drivers/media/platform/Makefile  |   2 +
 drivers/media/platform/cros-ec-cec/Makefile  |   1 +
 drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 347 +++
 drivers/mfd/cros_ec_dev.c|  16 ++
 drivers/platform/chrome/cros_ec_proto.c  |  40 ++-
 include/linux/mfd/cros_ec.h  |   2 +-
 include/linux/mfd/cros_ec_commands.h | 100 +++
 include/media/cec-notifier.h |  27 +-
 14 files changed, 577 insertions(+), 16 deletions(-)
 create mode 100644 drivers/media/platform/cros-ec-cec/Makefile
 create mode 100644 drivers/media/platform/cros-ec-cec/cros-ec-cec.c

-- 
2.7.4



Re: [PATCH v5 4/6] mfd: cros-ec: Introduce CEC commands and events definitions.

2018-05-24 Thread Neil Armstrong
On 24/05/2018 11:11, Hans Verkuil wrote:
> On 24/05/18 10:54, Neil Armstrong wrote:
>> The EC can expose a CEC bus, this patch adds the CEC related definitions
>> needed by the cros-ec-cec driver.
>>
>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
>> Tested-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
>> ---
>>  include/linux/mfd/cros_ec_commands.h | 85 
>> 
>>  1 file changed, 85 insertions(+)
>>
>> diff --git a/include/linux/mfd/cros_ec_commands.h 
>> b/include/linux/mfd/cros_ec_commands.h
>> index cc0768e..ea9646f 100644
>> --- a/include/linux/mfd/cros_ec_commands.h
>> +++ b/include/linux/mfd/cros_ec_commands.h
>> @@ -804,6 +804,8 @@ enum ec_feature_code {
>>  EC_FEATURE_MOTION_SENSE_FIFO = 24,
>>  /* EC has RTC feature that can be controlled by host commands */
>>  EC_FEATURE_RTC = 27,
>> +/* EC supports CEC commands */
>> +EC_FEATURE_CEC = 35,
>>  };
>>  
>>  #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32))
>> @@ -2078,6 +2080,12 @@ enum ec_mkbp_event {
>>  /* EC sent a sysrq command */
>>  EC_MKBP_EVENT_SYSRQ = 6,
>>  
>> +/* Notify the AP that something happened on CEC */
>> +EC_MKBP_CEC_EVENT = 8,
>> +
>> +/* Send an incoming CEC message to the AP */
>> +EC_MKBP_EVENT_CEC_MESSAGE = 9,
>> +
>>  /* Number of MKBP events */
>>  EC_MKBP_EVENT_COUNT,
>>  };
>> @@ -2850,6 +2858,83 @@ struct ec_params_reboot_ec {
>>  
>>  
>> /*/
>>  /*
>> + * HDMI CEC commands
>> + *
>> + * These commands are for sending and receiving message via HDMI CEC
>> + */
>> +#define MAX_CEC_MSG_LEN 16
> 
> Can you rename this to EC_MAX_CEC_MSG_LEN? It is way too similar to the
> CEC_MAX_MSG_LEN defined in cec.h. Since this is a property of the EC hw/fw
> it makes sense to prefix it accordingly.

Yes, it will make sense.

> 
>> +
>> +/* CEC message from the AP to be written on the CEC bus */
>> +#define EC_CMD_CEC_WRITE_MSG 0x00B8
>> +
>> +/**
>> + * struct ec_params_cec_write - Message to write to the CEC bus
>> + * @msg: message content to write to the CEC bus
>> + */
>> +struct ec_params_cec_write {
>> +uint8_t msg[MAX_CEC_MSG_LEN];
>> +} __packed;
>> +
>> +/* Set various CEC parameters */
>> +#define EC_CMD_CEC_SET 0x00BA
>> +
>> +/**
>> + * struct ec_params_cec_set - CEC parameters set
>> + * @cmd: parameter type, can be CEC_CMD_ENABLE or CEC_CMD_LOGICAL_ADDRESS
>> + * @enable: in case cmd is CEC_CMD_ENABLE, this field can be 0 to disable 
>> CEC
>> + *  or 1 to enable CEC functionnality
>> + * @address: in case cmd is CEC_CMD_LOGICAL_ADDRESS, this field encodes the
>> + *  requested logical address between 0 and 15 or 0xff to unregister
>> + */
>> +struct ec_params_cec_set {
>> +uint8_t cmd; /* enum cec_command */
>> +union {
>> +uint8_t enable;
>> +uint8_t address;
>> +};
>> +} __packed;
>> +
>> +/* Read various CEC parameters */
>> +#define EC_CMD_CEC_GET 0x00BB
>> +
>> +/**
>> + * struct ec_params_cec_get - CEC parameters get
>> + * @cmd: parameter type, can be CEC_CMD_ENABLE or CEC_CMD_LOGICAL_ADDRESS
>> + */
>> +struct ec_params_cec_get {
>> +uint8_t cmd; /* enum cec_command */
>> +} __packed;
>> +
>> +/**
>> + * struct ec_response_cec_get - CEC parameters get response
>> + * @enable: in case cmd was CEC_CMD_ENABLE, this field will 0 if CEC is
>> + *  disabled or 1 if CEC functionnality is enabled
>> + * @address: in case cmd was CEC_CMD_LOGICAL_ADDRESS, this will encode the
>> + *  configured logical address between 0 and 15 or 0xff if unregistered
>> + */
>> +struct ec_response_cec_get {
>> +union {
>> +uint8_t enable;
>> +uint8_t address;
>> +};
>> +} __packed;
>> +
>> +/* CEC parameters command */
>> +enum cec_command {
> 
> Same here: shouldn't all of this be prefixed with ec_ or EC_?

Exact, I will prefix them.

Thanks,
Neil

> 
> Regards,
> 
>   Hans
> 
>> +/* CEC reading, writing and events enable */
>> +CEC_CMD_ENABLE,
>> +/* CEC logical address  */
>> +CEC_CMD_LOGICAL_ADDRESS,
>> +};
>> +
>> +/* Events from CEC to AP */
>> +enum mkbp_cec_event {
>> +EC_MKBP_CEC_SEND_OK = BIT(0),
>> +EC_MKBP_CEC_SEND_FAILED = BIT(1),
>> +};
>> +
>> +/*/
>> +/*
>>   * Special commands
>>   *
>>   * These do not follow the normal rules for commands.  See each command for
>>
> 



[PATCH v5 2/6] drm/i915: hdmi: add CEC notifier to intel_hdmi

2018-05-24 Thread Neil Armstrong
This patchs adds the cec_notifier feature to the intel_hdmi part
of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate
between each HDMI ports.
The changes will allow the i915 HDMI code to notify EDID and HPD changes
to an eventual CEC adapter.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
Reviewed-by: Hans Verkuil <hans.verk...@cisco.com>
---
 drivers/gpu/drm/i915/Kconfig |  1 +
 drivers/gpu/drm/i915/intel_display.h | 20 
 drivers/gpu/drm/i915/intel_drv.h |  2 ++
 drivers/gpu/drm/i915/intel_hdmi.c| 13 +
 4 files changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index dfd9588..2d65d56 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -23,6 +23,7 @@ config DRM_I915
select SYNC_FILE
select IOSF_MBI
select CRC32
+   select CEC_CORE if CEC_NOTIFIER
help
  Choose this option if you have a system that has "Intel Graphics
  Media Accelerator" or "HD Graphics" integrated graphics,
diff --git a/drivers/gpu/drm/i915/intel_display.h 
b/drivers/gpu/drm/i915/intel_display.h
index 4e7418b..c68d1c8 100644
--- a/drivers/gpu/drm/i915/intel_display.h
+++ b/drivers/gpu/drm/i915/intel_display.h
@@ -126,6 +126,26 @@ enum port {
 
 #define port_name(p) ((p) + 'A')
 
+static inline const char *port_identifier(enum port port)
+{
+   switch (port) {
+   case PORT_A:
+   return "Port A";
+   case PORT_B:
+   return "Port B";
+   case PORT_C:
+   return "Port C";
+   case PORT_D:
+   return "Port D";
+   case PORT_E:
+   return "Port E";
+   case PORT_F:
+   return "Port F";
+   default:
+   return "";
+   }
+}
+
 enum dpio_channel {
DPIO_CH0,
DPIO_CH1
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d436858..b50e51b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -39,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /**
  * __wait_for - magic wait macro
@@ -1001,6 +1002,7 @@ struct intel_hdmi {
bool has_audio;
bool rgb_quant_range_selectable;
struct intel_connector *attached_connector;
+   struct cec_notifier *notifier;
 };
 
 struct intel_dp_mst_encoder;
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
b/drivers/gpu/drm/i915/intel_hdmi.c
index 1baef4a..d522b5b 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1868,6 +1868,8 @@ intel_hdmi_set_edid(struct drm_connector *connector)
connected = true;
}
 
+   cec_notifier_set_phys_addr_from_edid(intel_hdmi->notifier, edid);
+
return connected;
 }
 
@@ -1876,6 +1878,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool 
force)
 {
enum drm_connector_status status;
struct drm_i915_private *dev_priv = to_i915(connector->dev);
+   struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
  connector->base.id, connector->name);
@@ -1891,6 +1894,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool 
force)
 
intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
 
+   if (status != connector_status_connected)
+   cec_notifier_phys_addr_invalidate(intel_hdmi->notifier);
+
return status;
 }
 
@@ -2031,6 +2037,8 @@ static void chv_hdmi_pre_enable(struct intel_encoder 
*encoder,
 
 static void intel_hdmi_destroy(struct drm_connector *connector)
 {
+   if (intel_attached_hdmi(connector)->notifier)
+   cec_notifier_put(intel_attached_hdmi(connector)->notifier);
kfree(to_intel_connector(connector)->detect_edid);
drm_connector_cleanup(connector);
kfree(connector);
@@ -2358,6 +2366,11 @@ void intel_hdmi_init_connector(struct intel_digital_port 
*intel_dig_port,
u32 temp = I915_READ(PEG_BAND_GAP_DATA);
I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
}
+
+   intel_hdmi->notifier = cec_notifier_get_conn(dev->dev,
+port_identifier(port));
+   if (!intel_hdmi->notifier)
+   DRM_DEBUG_KMS("CEC notifier get failed\n");
 }
 
 void intel_hdmi_init(struct drm_i915_private *dev_priv,
-- 
2.7.4



[PATCH v5 1/6] media: cec-notifier: Get notifier by device and connector name

2018-05-24 Thread Neil Armstrong
In non device-tree world, we can need to get the notifier by the driver
name directly and eventually defer probe if not yet created.

This patch adds a variant of the get function by using the device name
instead and will not create a notifier if not yet created.

But the i915 driver exposes at least 2 HDMI connectors, this patch also
adds the possibility to add a connector name tied to the notifier device
to form a tuple and associate different CEC controllers for each HDMI
connectors.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/media/cec/cec-notifier.c | 11 ---
 include/media/cec-notifier.h | 27 ---
 2 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c
index 16dffa0..dd2078b 100644
--- a/drivers/media/cec/cec-notifier.c
+++ b/drivers/media/cec/cec-notifier.c
@@ -21,6 +21,7 @@ struct cec_notifier {
struct list_head head;
struct kref kref;
struct device *dev;
+   const char *conn;
struct cec_adapter *cec_adap;
void (*callback)(struct cec_adapter *adap, u16 pa);
 
@@ -30,13 +31,14 @@ struct cec_notifier {
 static LIST_HEAD(cec_notifiers);
 static DEFINE_MUTEX(cec_notifiers_lock);
 
-struct cec_notifier *cec_notifier_get(struct device *dev)
+struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char 
*conn)
 {
struct cec_notifier *n;
 
mutex_lock(_notifiers_lock);
list_for_each_entry(n, _notifiers, head) {
-   if (n->dev == dev) {
+   if (n->dev == dev &&
+   (!conn || !strcmp(n->conn, conn))) {
kref_get(>kref);
mutex_unlock(_notifiers_lock);
return n;
@@ -46,6 +48,8 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
if (!n)
goto unlock;
n->dev = dev;
+   if (conn)
+   n->conn = kstrdup(conn, GFP_KERNEL);
n->phys_addr = CEC_PHYS_ADDR_INVALID;
mutex_init(>lock);
kref_init(>kref);
@@ -54,7 +58,7 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
mutex_unlock(_notifiers_lock);
return n;
 }
-EXPORT_SYMBOL_GPL(cec_notifier_get);
+EXPORT_SYMBOL_GPL(cec_notifier_get_conn);
 
 static void cec_notifier_release(struct kref *kref)
 {
@@ -62,6 +66,7 @@ static void cec_notifier_release(struct kref *kref)
container_of(kref, struct cec_notifier, kref);
 
list_del(>head);
+   kfree(n->conn);
kfree(n);
 }
 
diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h
index cf0add7..814eeef 100644
--- a/include/media/cec-notifier.h
+++ b/include/media/cec-notifier.h
@@ -20,8 +20,10 @@ struct cec_notifier;
 #if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER)
 
 /**
- * cec_notifier_get - find or create a new cec_notifier for the given device.
+ * cec_notifier_get_conn - find or create a new cec_notifier for the given
+ * device and connector tuple.
  * @dev: device that sends the events.
+ * @conn: the connector name from which the event occurs
  *
  * If a notifier for device @dev already exists, then increase the refcount
  * and return that notifier.
@@ -31,7 +33,8 @@ struct cec_notifier;
  *
  * Return NULL if the memory could not be allocated.
  */
-struct cec_notifier *cec_notifier_get(struct device *dev);
+struct cec_notifier *cec_notifier_get_conn(struct device *dev,
+  const char *conn);
 
 /**
  * cec_notifier_put - decrease refcount and delete when the refcount reaches 0.
@@ -85,7 +88,8 @@ void cec_register_cec_notifier(struct cec_adapter *adap,
   struct cec_notifier *notifier);
 
 #else
-static inline struct cec_notifier *cec_notifier_get(struct device *dev)
+static inline struct cec_notifier *cec_notifier_get_conn(struct device *dev,
+const char *conn)
 {
/* A non-NULL pointer is expected on success */
return (struct cec_notifier *)0xdeadfeed;
@@ -121,6 +125,23 @@ static inline void cec_register_cec_notifier(struct 
cec_adapter *adap,
 #endif
 
 /**
+ * cec_notifier_get - find or create a new cec_notifier for the given device.
+ * @dev: device that sends the events.
+ *
+ * If a notifier for device @dev already exists, then increase the refcount
+ * and return that notifier.
+ *
+ * If it doesn't exist, then allocate a new notifier struct and return a
+ * pointer to that new struct.
+ *
+ * Return NULL if the memory could not be allocated.
+ */
+static inline struct cec_notifier *cec_notifier_get(struct device *dev)
+{
+   return cec_notifier_get_conn(dev, NULL);
+}
+
+/**
  * cec_notifier_phys_addr_invalidate() - set the physical address to INVALID
  *
  * @n: the CEC notifier
-- 
2.7.4



[PATCH v5 6/6] media: platform: Add ChromeOS EC CEC driver

2018-05-24 Thread Neil Armstrong
The ChromeOS Embedded Controller can expose a CEC bus, this patch add the
driver for such feature of the Embedded Controller.

This driver is part of the cros-ec MFD and will be add as a sub-device when
the feature bit is exposed by the EC.

The controller will only handle a single logical address and handles
all the messages retries and will only expose Success or Error.

The controller will be tied to the HDMI CEC notifier by using the platform
DMI Data and the i915 device name and connector name.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
Reviewed-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
---
 drivers/media/platform/Kconfig   |  11 +
 drivers/media/platform/Makefile  |   2 +
 drivers/media/platform/cros-ec-cec/Makefile  |   1 +
 drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 347 +++
 4 files changed, 361 insertions(+)
 create mode 100644 drivers/media/platform/cros-ec-cec/Makefile
 create mode 100644 drivers/media/platform/cros-ec-cec/cros-ec-cec.c

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index c7a1cf8..bc37ecf 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -546,6 +546,17 @@ menuconfig CEC_PLATFORM_DRIVERS
 
 if CEC_PLATFORM_DRIVERS
 
+config VIDEO_CROS_EC_CEC
+   tristate "ChromeOS EC CEC driver"
+   depends on MFD_CROS_EC || COMPILE_TEST
+   select CEC_CORE
+   select CEC_NOTIFIER
+   ---help---
+ If you say yes here you will get support for the
+ ChromeOS Embedded Controller's CEC.
+ The CEC bus is present in the HDMI connector and enables communication
+ between compatible devices.
+
 config VIDEO_MESON_AO_CEC
tristate "Amlogic Meson AO CEC driver"
depends on ARCH_MESON || COMPILE_TEST
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 932515d..830696f 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -92,3 +92,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS)+= 
qcom/camss-8x16/
 obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/
 
 obj-y  += meson/
+
+obj-y  += cros-ec-cec/
diff --git a/drivers/media/platform/cros-ec-cec/Makefile 
b/drivers/media/platform/cros-ec-cec/Makefile
new file mode 100644
index 000..9ce97f9
--- /dev/null
+++ b/drivers/media/platform/cros-ec-cec/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VIDEO_CROS_EC_CEC) += cros-ec-cec.o
diff --git a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c 
b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
new file mode 100644
index 000..7f897a2
--- /dev/null
+++ b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
@@ -0,0 +1,347 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * CEC driver for ChromeOS Embedded Controller
+ *
+ * Copyright (c) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstr...@baylibre.com>
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DRV_NAME   "cros-ec-cec"
+
+/**
+ * struct cros_ec_cec - Driver data for EC CEC
+ *
+ * @cros_ec: Pointer to EC device
+ * @notifier: Notifier info for responding to EC events
+ * @adap: CEC adapter
+ * @notify: CEC notifier pointer
+ * @rx_msg: storage for a received message
+ */
+struct cros_ec_cec {
+   struct cros_ec_device *cros_ec;
+   struct notifier_block notifier;
+   struct cec_adapter *adap;
+   struct cec_notifier *notify;
+   struct cec_msg rx_msg;
+};
+
+static void handle_cec_message(struct cros_ec_cec *cros_ec_cec)
+{
+   struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
+   uint8_t *cec_message = cros_ec->event_data.data.cec_message;
+   unsigned int len = cros_ec->event_size;
+
+   cros_ec_cec->rx_msg.len = len;
+   memcpy(cros_ec_cec->rx_msg.msg, cec_message, len);
+
+   cec_received_msg(cros_ec_cec->adap, _ec_cec->rx_msg);
+}
+
+static void handle_cec_event(struct cros_ec_cec *cros_ec_cec)
+{
+   struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
+   uint32_t events = cros_ec->event_data.data.cec_events;
+
+   if (events & EC_MKBP_CEC_SEND_OK)
+   cec_transmit_attempt_done(cros_ec_cec->adap,
+ CEC_TX_STATUS_OK);
+
+   /* FW takes care of all retries, tell core to avoid more retries */
+   if (events & EC_MKBP_CEC_SEND_FAILED)
+   cec_transmit_attempt_done(cros_ec_cec->adap,
+ CEC_TX_STATUS_MAX_RETRIES |
+ CEC_TX_STATUS_NACK);
+}
+
+static int cros_ec_cec_event(struct notifier_block *nb,
+unsigned long queued_during_suspend,
+void *_n

[PATCH v5 0/6] Add ChromeOS EC CEC Support

2018-05-24 Thread Neil Armstrong
Hi All,

The new Google "Fizz" Intel-based ChromeOS device is gaining CEC support
through it's Embedded Controller, to enable the Linux CEC Core to communicate
with it and get the CEC Physical Address from the correct HDMI Connector, the
following must be added/changed:
- Add the CEC sub-device registration in the ChromeOS EC MFD Driver
- Add the CEC related commands and events definitions into the EC MFD driver
- Add a way to get a CEC notifier with it's (optional) connector name
- Add the CEC notifier to the i915 HDMI driver
- Add the proper ChromeOS EC CEC Driver

The CEC notifier with the connector name is the tricky point, since even on
Device-Tree platforms, there is no way to distinguish between multiple HDMI
connectors from the same DRM driver. The solution I implemented is pretty
simple and only adds an optional connector name to eventually distinguish
an HDMI connector notifier from another if they share the same device.

Feel free to comment this patchset !

Changes since v4:
 - Split patch 3 to move the mkbp event size change into a separate patch

Changes since v3 (incorrectly reported as v2):
 - Renamed "Chrome OS" to "ChromeOS"
 - Updated cros_ec_commands.h new structs definitions to kernel doc format
 - Added Reviwed-By tags

Changes since v2:
 - Add i915 port_identifier() and use this stable name as cec_notifier conn name
 - Fixed and cleaned up the CEC commands and events handling
 - Rebased the CEC sub-device registration on top of Enric's serie
 - Fixed comments typo on cec driver
 - Protected the DMI match only with PCI and DMI Kconfigs

Changes since v1:
 - Added cec_notifier_put to intel_hdmi
 - Fixed all small reported issues on the EC CEC driver
 - Moved the cec_notifier_get out of the #if .. #else .. #endif

Changes since RFC:
 - Moved CEC sub-device registration after CEC commands and events definitions 
patch
 - Removed get_notifier_get_byname
 - Added CEC_CORE select into i915 Kconfig
 - Removed CEC driver fallback if notifier is not configured on HW, added 
explicit warn
 - Fixed CEC core return type on error
 - Moved to cros-ec-cec media platform directory
 - Use bus_find_device() to find the pci i915 device instead of 
get_notifier_get_byname()
 - Fix Logical Address setup
 - Added comment about HW support
 - Removed memset of msg structures

Neil Armstrong (6):
  media: cec-notifier: Get notifier by device and connector name
  drm/i915: hdmi: add CEC notifier to intel_hdmi
  mfd: cros-ec: Increase maximum mkbp event size
  mfd: cros-ec: Introduce CEC commands and events definitions.
  mfd: cros_ec_dev: Add CEC sub-device registration
  media: platform: Add ChromeOS EC CEC driver

 drivers/gpu/drm/i915/Kconfig |   1 +
 drivers/gpu/drm/i915/intel_display.h |  20 ++
 drivers/gpu/drm/i915/intel_drv.h |   2 +
 drivers/gpu/drm/i915/intel_hdmi.c|  13 +
 drivers/media/cec/cec-notifier.c |  11 +-
 drivers/media/platform/Kconfig   |  11 +
 drivers/media/platform/Makefile  |   2 +
 drivers/media/platform/cros-ec-cec/Makefile  |   1 +
 drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 347 +++
 drivers/mfd/cros_ec_dev.c|  16 ++
 drivers/platform/chrome/cros_ec_proto.c  |  40 ++-
 include/linux/mfd/cros_ec.h  |   2 +-
 include/linux/mfd/cros_ec_commands.h | 104 +++
 include/media/cec-notifier.h |  27 +-
 14 files changed, 581 insertions(+), 16 deletions(-)
 create mode 100644 drivers/media/platform/cros-ec-cec/Makefile
 create mode 100644 drivers/media/platform/cros-ec-cec/cros-ec-cec.c

-- 
2.7.4



[PATCH v5 5/6] mfd: cros_ec_dev: Add CEC sub-device registration

2018-05-24 Thread Neil Armstrong
The EC can expose a CEC bus, thus add the cros-ec-cec MFD sub-device
when the CEC feature bit is present.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
Reviewed-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
---
 drivers/mfd/cros_ec_dev.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c
index 1d6dc5c..272969e 100644
--- a/drivers/mfd/cros_ec_dev.c
+++ b/drivers/mfd/cros_ec_dev.c
@@ -383,6 +383,10 @@ static void cros_ec_sensors_register(struct cros_ec_dev 
*ec)
kfree(msg);
 }
 
+static const struct mfd_cell cros_ec_cec_cells[] = {
+   { .name = "cros-ec-cec" }
+};
+
 static const struct mfd_cell cros_ec_rtc_cells[] = {
{ .name = "cros-ec-rtc" }
 };
@@ -426,6 +430,18 @@ static int ec_device_probe(struct platform_device *pdev)
if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE))
cros_ec_sensors_register(ec);
 
+   /* Check whether this EC instance has CEC host command support */
+   if (cros_ec_check_features(ec, EC_FEATURE_CEC)) {
+   retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO,
+cros_ec_cec_cells,
+ARRAY_SIZE(cros_ec_cec_cells),
+NULL, 0, NULL);
+   if (retval)
+   dev_err(ec->dev,
+   "failed to add cros-ec-cec device: %d\n",
+   retval);
+   }
+
/* Check whether this EC instance has RTC host command support */
if (cros_ec_check_features(ec, EC_FEATURE_RTC)) {
retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO,
-- 
2.7.4



[PATCH v5 3/6] mfd: cros-ec: Increase maximum mkbp event size

2018-05-24 Thread Neil Armstrong
Having a 16 byte mkbp event size makes it possible to send CEC
messages from the EC to the AP directly inside the mkbp event
instead of first doing a notification and then a read.

Signed-off-by: Stefan Adolfsson <sadolfs...@chromium.org>
Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
Tested-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
---
 drivers/platform/chrome/cros_ec_proto.c | 40 +
 include/linux/mfd/cros_ec.h |  2 +-
 include/linux/mfd/cros_ec_commands.h| 19 
 3 files changed, 51 insertions(+), 10 deletions(-)

diff --git a/drivers/platform/chrome/cros_ec_proto.c 
b/drivers/platform/chrome/cros_ec_proto.c
index e7bbdf9..c4f6c44 100644
--- a/drivers/platform/chrome/cros_ec_proto.c
+++ b/drivers/platform/chrome/cros_ec_proto.c
@@ -504,10 +504,31 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev,
 }
 EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
 
+static int get_next_event_xfer(struct cros_ec_device *ec_dev,
+  struct cros_ec_command *msg,
+  int version, uint32_t size)
+{
+   int ret;
+
+   msg->version = version;
+   msg->command = EC_CMD_GET_NEXT_EVENT;
+   msg->insize = size;
+   msg->outsize = 0;
+
+   ret = cros_ec_cmd_xfer(ec_dev, msg);
+   if (ret > 0) {
+   ec_dev->event_size = ret - 1;
+   memcpy(_dev->event_data, msg->data, ec_dev->event_size);
+   }
+
+   return ret;
+}
+
 static int get_next_event(struct cros_ec_device *ec_dev)
 {
u8 buffer[sizeof(struct cros_ec_command) + sizeof(ec_dev->event_data)];
struct cros_ec_command *msg = (struct cros_ec_command *)
+   static int cmd_version = 1;
int ret;
 
if (ec_dev->suspended) {
@@ -515,18 +536,19 @@ static int get_next_event(struct cros_ec_device *ec_dev)
return -EHOSTDOWN;
}
 
-   msg->version = 0;
-   msg->command = EC_CMD_GET_NEXT_EVENT;
-   msg->insize = sizeof(ec_dev->event_data);
-   msg->outsize = 0;
+   if (cmd_version == 1) {
+   ret = get_next_event_xfer(ec_dev, msg, cmd_version,
+   sizeof(struct ec_response_get_next_event_v1));
+   if (ret < 0 || msg->result != EC_RES_INVALID_VERSION)
+   return ret;
 
-   ret = cros_ec_cmd_xfer(ec_dev, msg);
-   if (ret > 0) {
-   ec_dev->event_size = ret - 1;
-   memcpy(_dev->event_data, msg->data,
-  sizeof(ec_dev->event_data));
+   /* Fallback to version 0 for future send attempts */
+   cmd_version = 0;
}
 
+   ret = get_next_event_xfer(ec_dev, msg, cmd_version,
+ sizeof(struct ec_response_get_next_event));
+
return ret;
 }
 
diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h
index f36125e..32caef3 100644
--- a/include/linux/mfd/cros_ec.h
+++ b/include/linux/mfd/cros_ec.h
@@ -147,7 +147,7 @@ struct cros_ec_device {
bool mkbp_event_supported;
struct blocking_notifier_head event_notifier;
 
-   struct ec_response_get_next_event event_data;
+   struct ec_response_get_next_event_v1 event_data;
int event_size;
u32 host_event_wake_mask;
 };
diff --git a/include/linux/mfd/cros_ec_commands.h 
b/include/linux/mfd/cros_ec_commands.h
index f2edd99..cc0768e 100644
--- a/include/linux/mfd/cros_ec_commands.h
+++ b/include/linux/mfd/cros_ec_commands.h
@@ -2093,12 +2093,31 @@ union ec_response_get_next_data {
uint32_t   sysrq;
 } __packed;
 
+union ec_response_get_next_data_v1 {
+   uint8_t   key_matrix[16];
+
+   /* Unaligned */
+   uint32_t  host_event;
+
+   uint32_t   buttons;
+   uint32_t   switches;
+   uint32_t   sysrq;
+   uint32_t   cec_events;
+   uint8_tcec_message[16];
+} __packed;
+
 struct ec_response_get_next_event {
uint8_t event_type;
/* Followed by event data if any */
union ec_response_get_next_data data;
 } __packed;
 
+struct ec_response_get_next_event_v1 {
+   uint8_t event_type;
+   /* Followed by event data if any */
+   union ec_response_get_next_data_v1 data;
+} __packed;
+
 /* Bit indices for buttons and switches.*/
 /* Buttons */
 #define EC_MKBP_POWER_BUTTON   0
-- 
2.7.4



[PATCH v5 4/6] mfd: cros-ec: Introduce CEC commands and events definitions.

2018-05-24 Thread Neil Armstrong
The EC can expose a CEC bus, this patch adds the CEC related definitions
needed by the cros-ec-cec driver.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
Tested-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
---
 include/linux/mfd/cros_ec_commands.h | 85 
 1 file changed, 85 insertions(+)

diff --git a/include/linux/mfd/cros_ec_commands.h 
b/include/linux/mfd/cros_ec_commands.h
index cc0768e..ea9646f 100644
--- a/include/linux/mfd/cros_ec_commands.h
+++ b/include/linux/mfd/cros_ec_commands.h
@@ -804,6 +804,8 @@ enum ec_feature_code {
EC_FEATURE_MOTION_SENSE_FIFO = 24,
/* EC has RTC feature that can be controlled by host commands */
EC_FEATURE_RTC = 27,
+   /* EC supports CEC commands */
+   EC_FEATURE_CEC = 35,
 };
 
 #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32))
@@ -2078,6 +2080,12 @@ enum ec_mkbp_event {
/* EC sent a sysrq command */
EC_MKBP_EVENT_SYSRQ = 6,
 
+   /* Notify the AP that something happened on CEC */
+   EC_MKBP_CEC_EVENT = 8,
+
+   /* Send an incoming CEC message to the AP */
+   EC_MKBP_EVENT_CEC_MESSAGE = 9,
+
/* Number of MKBP events */
EC_MKBP_EVENT_COUNT,
 };
@@ -2850,6 +2858,83 @@ struct ec_params_reboot_ec {
 
 /*/
 /*
+ * HDMI CEC commands
+ *
+ * These commands are for sending and receiving message via HDMI CEC
+ */
+#define MAX_CEC_MSG_LEN 16
+
+/* CEC message from the AP to be written on the CEC bus */
+#define EC_CMD_CEC_WRITE_MSG 0x00B8
+
+/**
+ * struct ec_params_cec_write - Message to write to the CEC bus
+ * @msg: message content to write to the CEC bus
+ */
+struct ec_params_cec_write {
+   uint8_t msg[MAX_CEC_MSG_LEN];
+} __packed;
+
+/* Set various CEC parameters */
+#define EC_CMD_CEC_SET 0x00BA
+
+/**
+ * struct ec_params_cec_set - CEC parameters set
+ * @cmd: parameter type, can be CEC_CMD_ENABLE or CEC_CMD_LOGICAL_ADDRESS
+ * @enable: in case cmd is CEC_CMD_ENABLE, this field can be 0 to disable CEC
+ * or 1 to enable CEC functionnality
+ * @address: in case cmd is CEC_CMD_LOGICAL_ADDRESS, this field encodes the
+ * requested logical address between 0 and 15 or 0xff to unregister
+ */
+struct ec_params_cec_set {
+   uint8_t cmd; /* enum cec_command */
+   union {
+   uint8_t enable;
+   uint8_t address;
+   };
+} __packed;
+
+/* Read various CEC parameters */
+#define EC_CMD_CEC_GET 0x00BB
+
+/**
+ * struct ec_params_cec_get - CEC parameters get
+ * @cmd: parameter type, can be CEC_CMD_ENABLE or CEC_CMD_LOGICAL_ADDRESS
+ */
+struct ec_params_cec_get {
+   uint8_t cmd; /* enum cec_command */
+} __packed;
+
+/**
+ * struct ec_response_cec_get - CEC parameters get response
+ * @enable: in case cmd was CEC_CMD_ENABLE, this field will 0 if CEC is
+ * disabled or 1 if CEC functionnality is enabled
+ * @address: in case cmd was CEC_CMD_LOGICAL_ADDRESS, this will encode the
+ * configured logical address between 0 and 15 or 0xff if unregistered
+ */
+struct ec_response_cec_get {
+   union {
+   uint8_t enable;
+   uint8_t address;
+   };
+} __packed;
+
+/* CEC parameters command */
+enum cec_command {
+   /* CEC reading, writing and events enable */
+   CEC_CMD_ENABLE,
+   /* CEC logical address  */
+   CEC_CMD_LOGICAL_ADDRESS,
+};
+
+/* Events from CEC to AP */
+enum mkbp_cec_event {
+   EC_MKBP_CEC_SEND_OK = BIT(0),
+   EC_MKBP_CEC_SEND_FAILED = BIT(1),
+};
+
+/*/
+/*
  * Special commands
  *
  * These do not follow the normal rules for commands.  See each command for
-- 
2.7.4



Re: [PATCH v2 3/5] mfd: cros-ec: Introduce CEC commands and events definitions.

2018-05-24 Thread Neil Armstrong
Hi Benson,

On 24/05/2018 07:47, Benson Leung wrote:
> Hi Neil, Hi Stefan,
> 
> On Fri, May 18, 2018 at 03:05:02PM +0200, Neil Armstrong wrote:
>> The EC can expose a CEC bus, this patch adds the CEC related definitions
>> needed by the cros-ec-cec driver.
>> Having a 16 byte mkbp event size makes it possible to send CEC
>> messages from the EC to the AP directly inside the mkbp event
>> instead of first doing a notification and then a read.
>>
>> Signed-off-by: Stefan Adolfsson <sadolfs...@chromium.org>
>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
> 
> It looks like this change squashes together this chromeos-4.4 CL
> https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/1061879
> and some other new changes to add cec to cros_ec_commands.
> 
> Could you separate the two? One patch that's as close to Stefan's
> which introduces the 16 byte mkbp, and a second one that
> adds the HDMI CEC commands? 

OK, will split.

Neil

> 
> Thanks,
> Benson
>> ---
>>  drivers/platform/chrome/cros_ec_proto.c | 40 +
>>  include/linux/mfd/cros_ec.h |  2 +-
>>  include/linux/mfd/cros_ec_commands.h| 80 
>> +
>>  3 files changed, 112 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/platform/chrome/cros_ec_proto.c 
>> b/drivers/platform/chrome/cros_ec_proto.c
>> index e7bbdf9..c4f6c44 100644
>> --- a/drivers/platform/chrome/cros_ec_proto.c
>> +++ b/drivers/platform/chrome/cros_ec_proto.c
>> @@ -504,10 +504,31 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device 
>> *ec_dev,
>>  }
>>  EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
>>  
>> +static int get_next_event_xfer(struct cros_ec_device *ec_dev,
>> +   struct cros_ec_command *msg,
>> +   int version, uint32_t size)
>> +{
>> +int ret;
>> +
>> +msg->version = version;
>> +msg->command = EC_CMD_GET_NEXT_EVENT;
>> +msg->insize = size;
>> +msg->outsize = 0;
>> +
>> +ret = cros_ec_cmd_xfer(ec_dev, msg);
>> +if (ret > 0) {
>> +ec_dev->event_size = ret - 1;
>> +memcpy(_dev->event_data, msg->data, ec_dev->event_size);
>> +}
>> +
>> +return ret;
>> +}
>> +
>>  static int get_next_event(struct cros_ec_device *ec_dev)
>>  {
>>  u8 buffer[sizeof(struct cros_ec_command) + sizeof(ec_dev->event_data)];
>>  struct cros_ec_command *msg = (struct cros_ec_command *)
>> +static int cmd_version = 1;
>>  int ret;
>>  
>>  if (ec_dev->suspended) {
>> @@ -515,18 +536,19 @@ static int get_next_event(struct cros_ec_device 
>> *ec_dev)
>>  return -EHOSTDOWN;
>>  }
>>  
>> -msg->version = 0;
>> -msg->command = EC_CMD_GET_NEXT_EVENT;
>> -msg->insize = sizeof(ec_dev->event_data);
>> -msg->outsize = 0;
>> +if (cmd_version == 1) {
>> +ret = get_next_event_xfer(ec_dev, msg, cmd_version,
>> +sizeof(struct ec_response_get_next_event_v1));
>> +if (ret < 0 || msg->result != EC_RES_INVALID_VERSION)
>> +return ret;
>>  
>> -ret = cros_ec_cmd_xfer(ec_dev, msg);
>> -if (ret > 0) {
>> -ec_dev->event_size = ret - 1;
>> -memcpy(_dev->event_data, msg->data,
>> -   sizeof(ec_dev->event_data));
>> +/* Fallback to version 0 for future send attempts */
>> +cmd_version = 0;
>>  }
>>  
>> +ret = get_next_event_xfer(ec_dev, msg, cmd_version,
>> +  sizeof(struct ec_response_get_next_event));
>> +
>>  return ret;
>>  }
>>  
>> diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h
>> index f36125e..32caef3 100644
>> --- a/include/linux/mfd/cros_ec.h
>> +++ b/include/linux/mfd/cros_ec.h
>> @@ -147,7 +147,7 @@ struct cros_ec_device {
>>  bool mkbp_event_supported;
>>  struct blocking_notifier_head event_notifier;
>>  
>> -struct ec_response_get_next_event event_data;
>> +struct ec_response_get_next_event_v1 event_data;
>>  int event_size;
>>  u32 host_event_wake_mask;
>>  };
>> diff --git a/include/linux/mfd/cros_ec_commands.h 
>> b/include/linux/mfd/cros_ec_commands.h
>> index f2edd99..16c3a2b 100644
>> --- a/include/

[PATCH v4 0/5] Add ChromeOS EC CEC Support

2018-05-21 Thread Neil Armstrong
Hi All,

The new Google "Fizz" Intel-based ChromeOS device is gaining CEC support
through it's Embedded Controller, to enable the Linux CEC Core to communicate
with it and get the CEC Physical Address from the correct HDMI Connector, the
following must be added/changed:
- Add the CEC sub-device registration in the ChromeOS EC MFD Driver
- Add the CEC related commands and events definitions into the EC MFD driver
- Add a way to get a CEC notifier with it's (optional) connector name
- Add the CEC notifier to the i915 HDMI driver
- Add the proper ChromeOS EC CEC Driver

The CEC notifier with the connector name is the tricky point, since even on
Device-Tree platforms, there is no way to distinguish between multiple HDMI
connectors from the same DRM driver. The solution I implemented is pretty
simple and only adds an optional connector name to eventually distinguish
an HDMI connector notifier from another if they share the same device.

Feel free to comment this patchset !

Changes since v3 (incorrectly reported as v2):
 - Renamed "Chrome OS" to "ChromeOS"
 - Updated cros_ec_commands.h new structs definitions to kernel doc format
 - Added Reviwed-By tags

Changes since v2:
 - Add i915 port_identifier() and use this stable name as cec_notifier conn name
 - Fixed and cleaned up the CEC commands and events handling
 - Rebased the CEC sub-device registration on top of Enric's serie
 - Fixed comments typo on cec driver
 - Protected the DMI match only with PCI and DMI Kconfigs

Changes since v1:
 - Added cec_notifier_put to intel_hdmi
 - Fixed all small reported issues on the EC CEC driver
 - Moved the cec_notifier_get out of the #if .. #else .. #endif

Changes since RFC:
 - Moved CEC sub-device registration after CEC commands and events definitions 
patch
 - Removed get_notifier_get_byname
 - Added CEC_CORE select into i915 Kconfig
 - Removed CEC driver fallback if notifier is not configured on HW, added 
explicit warn
 - Fixed CEC core return type on error
 - Moved to cros-ec-cec media platform directory
 - Use bus_find_device() to find the pci i915 device instead of 
get_notifier_get_byname()
 - Fix Logical Address setup
 - Added comment about HW support
 - Removed memset of msg structures

Neil Armstrong (5):
  media: cec-notifier: Get notifier by device and connector name
  drm/i915: hdmi: add CEC notifier to intel_hdmi
  mfd: cros-ec: Introduce CEC commands and events definitions.
  mfd: cros_ec_dev: Add CEC sub-device registration
  media: platform: Add ChromeOS EC CEC driver

 drivers/gpu/drm/i915/Kconfig |   1 +
 drivers/gpu/drm/i915/intel_display.h |  20 ++
 drivers/gpu/drm/i915/intel_drv.h |   2 +
 drivers/gpu/drm/i915/intel_hdmi.c|  13 +
 drivers/media/cec/cec-notifier.c |  11 +-
 drivers/media/platform/Kconfig   |  11 +
 drivers/media/platform/Makefile  |   2 +
 drivers/media/platform/cros-ec-cec/Makefile  |   1 +
 drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 347 +++
 drivers/mfd/cros_ec_dev.c|  16 ++
 drivers/platform/chrome/cros_ec_proto.c  |  40 ++-
 include/linux/mfd/cros_ec.h  |   2 +-
 include/linux/mfd/cros_ec_commands.h | 103 +++
 include/media/cec-notifier.h |  27 +-
 14 files changed, 580 insertions(+), 16 deletions(-)
 create mode 100644 drivers/media/platform/cros-ec-cec/Makefile
 create mode 100644 drivers/media/platform/cros-ec-cec/cros-ec-cec.c

-- 
2.7.4



[PATCH v4 3/5] mfd: cros-ec: Introduce CEC commands and events definitions.

2018-05-21 Thread Neil Armstrong
The EC can expose a CEC bus, this patch adds the CEC related definitions
needed by the cros-ec-cec driver.
Having a 16 byte mkbp event size makes it possible to send CEC
messages from the EC to the AP directly inside the mkbp event
instead of first doing a notification and then a read.

Signed-off-by: Stefan Adolfsson <sadolfs...@chromium.org>
Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/platform/chrome/cros_ec_proto.c |  40 ++---
 include/linux/mfd/cros_ec.h |   2 +-
 include/linux/mfd/cros_ec_commands.h| 103 
 3 files changed, 135 insertions(+), 10 deletions(-)

diff --git a/drivers/platform/chrome/cros_ec_proto.c 
b/drivers/platform/chrome/cros_ec_proto.c
index e7bbdf9..c4f6c44 100644
--- a/drivers/platform/chrome/cros_ec_proto.c
+++ b/drivers/platform/chrome/cros_ec_proto.c
@@ -504,10 +504,31 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev,
 }
 EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
 
+static int get_next_event_xfer(struct cros_ec_device *ec_dev,
+  struct cros_ec_command *msg,
+  int version, uint32_t size)
+{
+   int ret;
+
+   msg->version = version;
+   msg->command = EC_CMD_GET_NEXT_EVENT;
+   msg->insize = size;
+   msg->outsize = 0;
+
+   ret = cros_ec_cmd_xfer(ec_dev, msg);
+   if (ret > 0) {
+   ec_dev->event_size = ret - 1;
+   memcpy(_dev->event_data, msg->data, ec_dev->event_size);
+   }
+
+   return ret;
+}
+
 static int get_next_event(struct cros_ec_device *ec_dev)
 {
u8 buffer[sizeof(struct cros_ec_command) + sizeof(ec_dev->event_data)];
struct cros_ec_command *msg = (struct cros_ec_command *)
+   static int cmd_version = 1;
int ret;
 
if (ec_dev->suspended) {
@@ -515,18 +536,19 @@ static int get_next_event(struct cros_ec_device *ec_dev)
return -EHOSTDOWN;
}
 
-   msg->version = 0;
-   msg->command = EC_CMD_GET_NEXT_EVENT;
-   msg->insize = sizeof(ec_dev->event_data);
-   msg->outsize = 0;
+   if (cmd_version == 1) {
+   ret = get_next_event_xfer(ec_dev, msg, cmd_version,
+   sizeof(struct ec_response_get_next_event_v1));
+   if (ret < 0 || msg->result != EC_RES_INVALID_VERSION)
+   return ret;
 
-   ret = cros_ec_cmd_xfer(ec_dev, msg);
-   if (ret > 0) {
-   ec_dev->event_size = ret - 1;
-   memcpy(_dev->event_data, msg->data,
-  sizeof(ec_dev->event_data));
+   /* Fallback to version 0 for future send attempts */
+   cmd_version = 0;
}
 
+   ret = get_next_event_xfer(ec_dev, msg, cmd_version,
+ sizeof(struct ec_response_get_next_event));
+
return ret;
 }
 
diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h
index f36125e..32caef3 100644
--- a/include/linux/mfd/cros_ec.h
+++ b/include/linux/mfd/cros_ec.h
@@ -147,7 +147,7 @@ struct cros_ec_device {
bool mkbp_event_supported;
struct blocking_notifier_head event_notifier;
 
-   struct ec_response_get_next_event event_data;
+   struct ec_response_get_next_event_v1 event_data;
int event_size;
u32 host_event_wake_mask;
 };
diff --git a/include/linux/mfd/cros_ec_commands.h 
b/include/linux/mfd/cros_ec_commands.h
index f2edd99..9b8bc4a 100644
--- a/include/linux/mfd/cros_ec_commands.h
+++ b/include/linux/mfd/cros_ec_commands.h
@@ -804,6 +804,8 @@ enum ec_feature_code {
EC_FEATURE_MOTION_SENSE_FIFO = 24,
/* EC has RTC feature that can be controlled by host commands */
EC_FEATURE_RTC = 27,
+   /* EC supports CEC commands */
+   EC_FEATURE_CEC = 35,
 };
 
 #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32))
@@ -2078,6 +2080,12 @@ enum ec_mkbp_event {
/* EC sent a sysrq command */
EC_MKBP_EVENT_SYSRQ = 6,
 
+   /* Notify the AP that something happened on CEC */
+   EC_MKBP_CEC_EVENT = 8,
+
+   /* Send an incoming CEC message to the AP */
+   EC_MKBP_EVENT_CEC_MESSAGE = 9,
+
/* Number of MKBP events */
EC_MKBP_EVENT_COUNT,
 };
@@ -2093,12 +2101,31 @@ union ec_response_get_next_data {
uint32_t   sysrq;
 } __packed;
 
+union ec_response_get_next_data_v1 {
+   uint8_t   key_matrix[16];
+
+   /* Unaligned */
+   uint32_t  host_event;
+
+   uint32_t   buttons;
+   uint32_t   switches;
+   uint32_t   sysrq;
+   uint32_t   cec_events;
+   uint8_tcec_message[16];
+} __packed;
+
 struct ec_response_get_next_event {
uint8_t event_type;
/* Followed by event data if any */
union ec_response_get_next_data data;
 } __packed;
 
+struct ec_response_get_next_event_v1 

[PATCH v4 5/5] media: platform: Add ChromeOS EC CEC driver

2018-05-21 Thread Neil Armstrong
The ChromeOS Embedded Controller can expose a CEC bus, this patch add the
driver for such feature of the Embedded Controller.

This driver is part of the cros-ec MFD and will be add as a sub-device when
the feature bit is exposed by the EC.

The controller will only handle a single logical address and handles
all the messages retries and will only expose Success or Error.

The controller will be tied to the HDMI CEC notifier by using the platform
DMI Data and the i915 device name and connector name.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
Reviewed-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
---
 drivers/media/platform/Kconfig   |  11 +
 drivers/media/platform/Makefile  |   2 +
 drivers/media/platform/cros-ec-cec/Makefile  |   1 +
 drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 347 +++
 4 files changed, 361 insertions(+)
 create mode 100644 drivers/media/platform/cros-ec-cec/Makefile
 create mode 100644 drivers/media/platform/cros-ec-cec/cros-ec-cec.c

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index c7a1cf8..bc37ecf 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -546,6 +546,17 @@ menuconfig CEC_PLATFORM_DRIVERS
 
 if CEC_PLATFORM_DRIVERS
 
+config VIDEO_CROS_EC_CEC
+   tristate "ChromeOS EC CEC driver"
+   depends on MFD_CROS_EC || COMPILE_TEST
+   select CEC_CORE
+   select CEC_NOTIFIER
+   ---help---
+ If you say yes here you will get support for the
+ ChromeOS Embedded Controller's CEC.
+ The CEC bus is present in the HDMI connector and enables communication
+ between compatible devices.
+
 config VIDEO_MESON_AO_CEC
tristate "Amlogic Meson AO CEC driver"
depends on ARCH_MESON || COMPILE_TEST
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 932515d..830696f 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -92,3 +92,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS)+= 
qcom/camss-8x16/
 obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/
 
 obj-y  += meson/
+
+obj-y  += cros-ec-cec/
diff --git a/drivers/media/platform/cros-ec-cec/Makefile 
b/drivers/media/platform/cros-ec-cec/Makefile
new file mode 100644
index 000..9ce97f9
--- /dev/null
+++ b/drivers/media/platform/cros-ec-cec/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VIDEO_CROS_EC_CEC) += cros-ec-cec.o
diff --git a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c 
b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
new file mode 100644
index 000..7f897a2
--- /dev/null
+++ b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
@@ -0,0 +1,347 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * CEC driver for ChromeOS Embedded Controller
+ *
+ * Copyright (c) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstr...@baylibre.com>
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DRV_NAME   "cros-ec-cec"
+
+/**
+ * struct cros_ec_cec - Driver data for EC CEC
+ *
+ * @cros_ec: Pointer to EC device
+ * @notifier: Notifier info for responding to EC events
+ * @adap: CEC adapter
+ * @notify: CEC notifier pointer
+ * @rx_msg: storage for a received message
+ */
+struct cros_ec_cec {
+   struct cros_ec_device *cros_ec;
+   struct notifier_block notifier;
+   struct cec_adapter *adap;
+   struct cec_notifier *notify;
+   struct cec_msg rx_msg;
+};
+
+static void handle_cec_message(struct cros_ec_cec *cros_ec_cec)
+{
+   struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
+   uint8_t *cec_message = cros_ec->event_data.data.cec_message;
+   unsigned int len = cros_ec->event_size;
+
+   cros_ec_cec->rx_msg.len = len;
+   memcpy(cros_ec_cec->rx_msg.msg, cec_message, len);
+
+   cec_received_msg(cros_ec_cec->adap, _ec_cec->rx_msg);
+}
+
+static void handle_cec_event(struct cros_ec_cec *cros_ec_cec)
+{
+   struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
+   uint32_t events = cros_ec->event_data.data.cec_events;
+
+   if (events & EC_MKBP_CEC_SEND_OK)
+   cec_transmit_attempt_done(cros_ec_cec->adap,
+ CEC_TX_STATUS_OK);
+
+   /* FW takes care of all retries, tell core to avoid more retries */
+   if (events & EC_MKBP_CEC_SEND_FAILED)
+   cec_transmit_attempt_done(cros_ec_cec->adap,
+ CEC_TX_STATUS_MAX_RETRIES |
+ CEC_TX_STATUS_NACK);
+}
+
+static int cros_ec_cec_event(struct notifier_block *nb,
+unsigned long queued_during_suspend,
+void *_n

[PATCH v4 2/5] drm/i915: hdmi: add CEC notifier to intel_hdmi

2018-05-21 Thread Neil Armstrong
This patchs adds the cec_notifier feature to the intel_hdmi part
of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate
between each HDMI ports.
The changes will allow the i915 HDMI code to notify EDID and HPD changes
to an eventual CEC adapter.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
Reviewed-by: Hans Verkuil <hans.verk...@cisco.com>
---
 drivers/gpu/drm/i915/Kconfig |  1 +
 drivers/gpu/drm/i915/intel_display.h | 20 
 drivers/gpu/drm/i915/intel_drv.h |  2 ++
 drivers/gpu/drm/i915/intel_hdmi.c| 13 +
 4 files changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index dfd9588..2d65d56 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -23,6 +23,7 @@ config DRM_I915
select SYNC_FILE
select IOSF_MBI
select CRC32
+   select CEC_CORE if CEC_NOTIFIER
help
  Choose this option if you have a system that has "Intel Graphics
  Media Accelerator" or "HD Graphics" integrated graphics,
diff --git a/drivers/gpu/drm/i915/intel_display.h 
b/drivers/gpu/drm/i915/intel_display.h
index 4e7418b..c68d1c8 100644
--- a/drivers/gpu/drm/i915/intel_display.h
+++ b/drivers/gpu/drm/i915/intel_display.h
@@ -126,6 +126,26 @@ enum port {
 
 #define port_name(p) ((p) + 'A')
 
+static inline const char *port_identifier(enum port port)
+{
+   switch (port) {
+   case PORT_A:
+   return "Port A";
+   case PORT_B:
+   return "Port B";
+   case PORT_C:
+   return "Port C";
+   case PORT_D:
+   return "Port D";
+   case PORT_E:
+   return "Port E";
+   case PORT_F:
+   return "Port F";
+   default:
+   return "";
+   }
+}
+
 enum dpio_channel {
DPIO_CH0,
DPIO_CH1
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d436858..b50e51b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -39,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /**
  * __wait_for - magic wait macro
@@ -1001,6 +1002,7 @@ struct intel_hdmi {
bool has_audio;
bool rgb_quant_range_selectable;
struct intel_connector *attached_connector;
+   struct cec_notifier *notifier;
 };
 
 struct intel_dp_mst_encoder;
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
b/drivers/gpu/drm/i915/intel_hdmi.c
index 1baef4a..d522b5b 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1868,6 +1868,8 @@ intel_hdmi_set_edid(struct drm_connector *connector)
connected = true;
}
 
+   cec_notifier_set_phys_addr_from_edid(intel_hdmi->notifier, edid);
+
return connected;
 }
 
@@ -1876,6 +1878,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool 
force)
 {
enum drm_connector_status status;
struct drm_i915_private *dev_priv = to_i915(connector->dev);
+   struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
  connector->base.id, connector->name);
@@ -1891,6 +1894,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool 
force)
 
intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
 
+   if (status != connector_status_connected)
+   cec_notifier_phys_addr_invalidate(intel_hdmi->notifier);
+
return status;
 }
 
@@ -2031,6 +2037,8 @@ static void chv_hdmi_pre_enable(struct intel_encoder 
*encoder,
 
 static void intel_hdmi_destroy(struct drm_connector *connector)
 {
+   if (intel_attached_hdmi(connector)->notifier)
+   cec_notifier_put(intel_attached_hdmi(connector)->notifier);
kfree(to_intel_connector(connector)->detect_edid);
drm_connector_cleanup(connector);
kfree(connector);
@@ -2358,6 +2366,11 @@ void intel_hdmi_init_connector(struct intel_digital_port 
*intel_dig_port,
u32 temp = I915_READ(PEG_BAND_GAP_DATA);
I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
}
+
+   intel_hdmi->notifier = cec_notifier_get_conn(dev->dev,
+port_identifier(port));
+   if (!intel_hdmi->notifier)
+   DRM_DEBUG_KMS("CEC notifier get failed\n");
 }
 
 void intel_hdmi_init(struct drm_i915_private *dev_priv,
-- 
2.7.4



[PATCH v4 4/5] mfd: cros_ec_dev: Add CEC sub-device registration

2018-05-21 Thread Neil Armstrong
The EC can expose a CEC bus, thus add the cros-ec-cec MFD sub-device
when the CEC feature bit is present.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
Reviewed-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
---
 drivers/mfd/cros_ec_dev.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c
index 1d6dc5c..272969e 100644
--- a/drivers/mfd/cros_ec_dev.c
+++ b/drivers/mfd/cros_ec_dev.c
@@ -383,6 +383,10 @@ static void cros_ec_sensors_register(struct cros_ec_dev 
*ec)
kfree(msg);
 }
 
+static const struct mfd_cell cros_ec_cec_cells[] = {
+   { .name = "cros-ec-cec" }
+};
+
 static const struct mfd_cell cros_ec_rtc_cells[] = {
{ .name = "cros-ec-rtc" }
 };
@@ -426,6 +430,18 @@ static int ec_device_probe(struct platform_device *pdev)
if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE))
cros_ec_sensors_register(ec);
 
+   /* Check whether this EC instance has CEC host command support */
+   if (cros_ec_check_features(ec, EC_FEATURE_CEC)) {
+   retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO,
+cros_ec_cec_cells,
+ARRAY_SIZE(cros_ec_cec_cells),
+NULL, 0, NULL);
+   if (retval)
+   dev_err(ec->dev,
+   "failed to add cros-ec-cec device: %d\n",
+   retval);
+   }
+
/* Check whether this EC instance has RTC host command support */
if (cros_ec_check_features(ec, EC_FEATURE_RTC)) {
retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO,
-- 
2.7.4



[PATCH v4 1/5] media: cec-notifier: Get notifier by device and connector name

2018-05-21 Thread Neil Armstrong
In non device-tree world, we can need to get the notifier by the driver
name directly and eventually defer probe if not yet created.

This patch adds a variant of the get function by using the device name
instead and will not create a notifier if not yet created.

But the i915 driver exposes at least 2 HDMI connectors, this patch also
adds the possibility to add a connector name tied to the notifier device
to form a tuple and associate different CEC controllers for each HDMI
connectors.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/media/cec/cec-notifier.c | 11 ---
 include/media/cec-notifier.h | 27 ---
 2 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c
index 16dffa0..dd2078b 100644
--- a/drivers/media/cec/cec-notifier.c
+++ b/drivers/media/cec/cec-notifier.c
@@ -21,6 +21,7 @@ struct cec_notifier {
struct list_head head;
struct kref kref;
struct device *dev;
+   const char *conn;
struct cec_adapter *cec_adap;
void (*callback)(struct cec_adapter *adap, u16 pa);
 
@@ -30,13 +31,14 @@ struct cec_notifier {
 static LIST_HEAD(cec_notifiers);
 static DEFINE_MUTEX(cec_notifiers_lock);
 
-struct cec_notifier *cec_notifier_get(struct device *dev)
+struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char 
*conn)
 {
struct cec_notifier *n;
 
mutex_lock(_notifiers_lock);
list_for_each_entry(n, _notifiers, head) {
-   if (n->dev == dev) {
+   if (n->dev == dev &&
+   (!conn || !strcmp(n->conn, conn))) {
kref_get(>kref);
mutex_unlock(_notifiers_lock);
return n;
@@ -46,6 +48,8 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
if (!n)
goto unlock;
n->dev = dev;
+   if (conn)
+   n->conn = kstrdup(conn, GFP_KERNEL);
n->phys_addr = CEC_PHYS_ADDR_INVALID;
mutex_init(>lock);
kref_init(>kref);
@@ -54,7 +58,7 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
mutex_unlock(_notifiers_lock);
return n;
 }
-EXPORT_SYMBOL_GPL(cec_notifier_get);
+EXPORT_SYMBOL_GPL(cec_notifier_get_conn);
 
 static void cec_notifier_release(struct kref *kref)
 {
@@ -62,6 +66,7 @@ static void cec_notifier_release(struct kref *kref)
container_of(kref, struct cec_notifier, kref);
 
list_del(>head);
+   kfree(n->conn);
kfree(n);
 }
 
diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h
index cf0add7..814eeef 100644
--- a/include/media/cec-notifier.h
+++ b/include/media/cec-notifier.h
@@ -20,8 +20,10 @@ struct cec_notifier;
 #if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER)
 
 /**
- * cec_notifier_get - find or create a new cec_notifier for the given device.
+ * cec_notifier_get_conn - find or create a new cec_notifier for the given
+ * device and connector tuple.
  * @dev: device that sends the events.
+ * @conn: the connector name from which the event occurs
  *
  * If a notifier for device @dev already exists, then increase the refcount
  * and return that notifier.
@@ -31,7 +33,8 @@ struct cec_notifier;
  *
  * Return NULL if the memory could not be allocated.
  */
-struct cec_notifier *cec_notifier_get(struct device *dev);
+struct cec_notifier *cec_notifier_get_conn(struct device *dev,
+  const char *conn);
 
 /**
  * cec_notifier_put - decrease refcount and delete when the refcount reaches 0.
@@ -85,7 +88,8 @@ void cec_register_cec_notifier(struct cec_adapter *adap,
   struct cec_notifier *notifier);
 
 #else
-static inline struct cec_notifier *cec_notifier_get(struct device *dev)
+static inline struct cec_notifier *cec_notifier_get_conn(struct device *dev,
+const char *conn)
 {
/* A non-NULL pointer is expected on success */
return (struct cec_notifier *)0xdeadfeed;
@@ -121,6 +125,23 @@ static inline void cec_register_cec_notifier(struct 
cec_adapter *adap,
 #endif
 
 /**
+ * cec_notifier_get - find or create a new cec_notifier for the given device.
+ * @dev: device that sends the events.
+ *
+ * If a notifier for device @dev already exists, then increase the refcount
+ * and return that notifier.
+ *
+ * If it doesn't exist, then allocate a new notifier struct and return a
+ * pointer to that new struct.
+ *
+ * Return NULL if the memory could not be allocated.
+ */
+static inline struct cec_notifier *cec_notifier_get(struct device *dev)
+{
+   return cec_notifier_get_conn(dev, NULL);
+}
+
+/**
  * cec_notifier_phys_addr_invalidate() - set the physical address to INVALID
  *
  * @n: the CEC notifier
-- 
2.7.4



Re: [PATCH v2 0/5] Add ChromeOS EC CEC Support

2018-05-21 Thread Neil Armstrong
On 18/05/2018 16:04, Enric Balletbo Serra wrote:
> Hi Neil,
> 
> 2018-05-18 15:04 GMT+02:00 Neil Armstrong <narmstr...@baylibre.com>:
>> Hi All,
>>
>> The new Google "Fizz" Intel-based ChromeOS device is gaining CEC support
>> through it's Embedded Controller, to enable the Linux CEC Core to communicate
>> with it and get the CEC Physical Address from the correct HDMI Connector, the
>> following must be added/changed:
>> - Add the CEC sub-device registration in the ChromeOS EC MFD Driver
>> - Add the CEC related commands and events definitions into the EC MFD driver
>> - Add a way to get a CEC notifier with it's (optional) connector name
>> - Add the CEC notifier to the i915 HDMI driver
>> - Add the proper ChromeOS EC CEC Driver
>>
>> The CEC notifier with the connector name is the tricky point, since even on
>> Device-Tree platforms, there is no way to distinguish between multiple HDMI
>> connectors from the same DRM driver. The solution I implemented is pretty
>> simple and only adds an optional connector name to eventually distinguish
>> an HDMI connector notifier from another if they share the same device.
>>
>> Feel free to comment this patchset !
>>
>> Changes since v2:
>>  - Add i915 port_identifier() and use this stable name as cec_notifier conn 
>> name
>>  - Fixed and cleaned up the CEC commands and events handling
>>  - Rebased the CEC sub-device registration on top of Enric's serie
>>  - Fixed comments typo on cec driver
>>  - Protected the DMI match only with PCI and DMI Kconfigs
>>
> 
> Just because I got confused when I saw two v2 in my inbox. This is v3, right?

Yes, sorry it's v3... next will be v4.

> 
>> Changes since v1:
>>  - Added cec_notifier_put to intel_hdmi
>>  - Fixed all small reported issues on the EC CEC driver
>>  - Moved the cec_notifier_get out of the #if .. #else .. #endif
>>
>> Changes since RFC:
>>  - Moved CEC sub-device registration after CEC commands and events 
>> definitions patch
>>  - Removed get_notifier_get_byname
>>  - Added CEC_CORE select into i915 Kconfig
>>  - Removed CEC driver fallback if notifier is not configured on HW, added 
>> explicit warn
>>  - Fixed CEC core return type on error
>>  - Moved to cros-ec-cec media platform directory
>>  - Use bus_find_device() to find the pci i915 device instead of 
>> get_notifier_get_byname()
>>  - Fix Logical Address setup
>>  - Added comment about HW support
>>  - Removed memset of msg structures
>>
>> Neil Armstrong (5):
>>   media: cec-notifier: Get notifier by device and connector name
>>   drm/i915: hdmi: add CEC notifier to intel_hdmi
>>   mfd: cros-ec: Introduce CEC commands and events definitions.
>>   mfd: cros_ec_dev: Add CEC sub-device registration
>>   media: platform: Add Chrome OS EC CEC driver
>>
>>  drivers/gpu/drm/i915/Kconfig |   1 +
>>  drivers/gpu/drm/i915/intel_display.h |  20 ++
>>  drivers/gpu/drm/i915/intel_drv.h |   2 +
>>  drivers/gpu/drm/i915/intel_hdmi.c|  13 +
>>  drivers/media/cec/cec-notifier.c |  11 +-
>>  drivers/media/platform/Kconfig   |  11 +
>>  drivers/media/platform/Makefile  |   2 +
>>  drivers/media/platform/cros-ec-cec/Makefile  |   1 +
>>  drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 347 
>> +++
>>  drivers/mfd/cros_ec_dev.c|  16 ++
>>  drivers/platform/chrome/cros_ec_proto.c  |  40 ++-
>>  include/linux/mfd/cros_ec.h  |   2 +-
>>  include/linux/mfd/cros_ec_commands.h |  80 ++
>>  include/media/cec-notifier.h |  27 +-
>>  14 files changed, 557 insertions(+), 16 deletions(-)
>>  create mode 100644 drivers/media/platform/cros-ec-cec/Makefile
>>  create mode 100644 drivers/media/platform/cros-ec-cec/cros-ec-cec.c
>>
>> --
>> 2.7.4
>>



Re: [PATCH v2 5/5] media: platform: Add Chrome OS EC CEC driver

2018-05-21 Thread Neil Armstrong
Hi Enric,

On 18/05/2018 17:02, Enric Balletbo Serra wrote:
> Hi Neil,
> 
> 2018-05-18 15:05 GMT+02:00 Neil Armstrong <narmstr...@baylibre.com>:
>> The Chrome OS Embedded Controller can expose a CEC bus, this patch add the
> 
> A minor nit, there is a "consensus" on tell cros-ec as "ChromeOS
> Embedded Controller" or "ChromeOS EC". Yes, I know that you can see in
> the kernel many other ways to refer to the ChromeOS EC, but to
> standardize a little bit, could you replace all occurrences s/Chrome
> OS/ChromeOS/. Thanks.

Ok, I'll do a cleanup.

> 
>> driver for such feature of the Embedded Controller.
>>
>> This driver is part of the cros-ec MFD and will be add as a sub-device when
>> the feature bit is exposed by the EC.
>>
>> The controller will only handle a single logical address and handles
>> all the messages retries and will only expose Success or Error.
>>
>> The controller will be tied to the HDMI CEC notifier by using the platform
>> DMI Data and the i915 device name and connector name.
>>
>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
>> ---
>>  drivers/media/platform/Kconfig   |  11 +
>>  drivers/media/platform/Makefile  |   2 +
>>  drivers/media/platform/cros-ec-cec/Makefile  |   1 +
>>  drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 347 
>> +++
>>  4 files changed, 361 insertions(+)
>>  create mode 100644 drivers/media/platform/cros-ec-cec/Makefile
>>  create mode 100644 drivers/media/platform/cros-ec-cec/cros-ec-cec.c
>>
>> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
>> index c7a1cf8..e55a8ed2 100644
>> --- a/drivers/media/platform/Kconfig
>> +++ b/drivers/media/platform/Kconfig
>> @@ -546,6 +546,17 @@ menuconfig CEC_PLATFORM_DRIVERS
>>
>>  if CEC_PLATFORM_DRIVERS
>>
>> +config VIDEO_CROS_EC_CEC
>> +   tristate "Chrome OS EC CEC driver"
> 
> here
> 
>> +   depends on MFD_CROS_EC || COMPILE_TEST
>> +   select CEC_CORE
>> +   select CEC_NOTIFIER
>> +   ---help---
>> + If you say yes here you will get support for the
>> + Chrome OS Embedded Controller's CEC.
> 
> here
> 
>> + The CEC bus is present in the HDMI connector and enables 
>> communication
>> + between compatible devices.
>> +
>>  config VIDEO_MESON_AO_CEC
>> tristate "Amlogic Meson AO CEC driver"
>> depends on ARCH_MESON || COMPILE_TEST
>> diff --git a/drivers/media/platform/Makefile 
>> b/drivers/media/platform/Makefile
>> index 932515d..830696f 100644
>> --- a/drivers/media/platform/Makefile
>> +++ b/drivers/media/platform/Makefile
>> @@ -92,3 +92,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS)+= 
>> qcom/camss-8x16/
>>  obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/
>>
>>  obj-y  += meson/
>> +
>> +obj-y  += cros-ec-cec/
>> diff --git a/drivers/media/platform/cros-ec-cec/Makefile 
>> b/drivers/media/platform/cros-ec-cec/Makefile
>> new file mode 100644
>> index 000..9ce97f9
>> --- /dev/null
>> +++ b/drivers/media/platform/cros-ec-cec/Makefile
>> @@ -0,0 +1 @@
>> +obj-$(CONFIG_VIDEO_CROS_EC_CEC) += cros-ec-cec.o
>> diff --git a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c 
>> b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
>> new file mode 100644
>> index 000..7e1e275
>> --- /dev/null
>> +++ b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
>> @@ -0,0 +1,347 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * CEC driver for Chrome OS Embedded Controller
> 
> and here
> 
>> + *
>> + * Copyright (c) 2018 BayLibre, SAS
>> + * Author: Neil Armstrong <narmstr...@baylibre.com>
>> + */
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#define DRV_NAME   "cros-ec-cec"
>> +
>> +/**
>> + * struct cros_ec_cec - Driver data for EC CEC
>> + *
>> + * @cros_ec: Pointer to EC device
>> + * @notifier: Notifier info for responding to EC events
>> + * @adap: CEC adapter
>> + * @notify: CEC notifier pointer
>> + * @rx_msg: storage for a received message
>> + */
>> +struct cros_ec_cec {
>

Re: [PATCH v2 3/5] mfd: cros-ec: Introduce CEC commands and events definitions.

2018-05-21 Thread Neil Armstrong
Hi Enric,

On 18/05/2018 18:19, Enric Balletbo Serra wrote:
> Hi Neil,
> 
> 2018-05-18 15:05 GMT+02:00 Neil Armstrong <narmstr...@baylibre.com>:
>> The EC can expose a CEC bus, this patch adds the CEC related definitions
>> needed by the cros-ec-cec driver.
>> Having a 16 byte mkbp event size makes it possible to send CEC
>> messages from the EC to the AP directly inside the mkbp event
>> instead of first doing a notification and then a read.
>>
>> Signed-off-by: Stefan Adolfsson <sadolfs...@chromium.org>
>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
>> ---
>>  drivers/platform/chrome/cros_ec_proto.c | 40 +
>>  include/linux/mfd/cros_ec.h |  2 +-
>>  include/linux/mfd/cros_ec_commands.h| 80 
>> +
>>  3 files changed, 112 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/platform/chrome/cros_ec_proto.c 
>> b/drivers/platform/chrome/cros_ec_proto.c
>> index e7bbdf9..c4f6c44 100644
>> --- a/drivers/platform/chrome/cros_ec_proto.c
>> +++ b/drivers/platform/chrome/cros_ec_proto.c
>> @@ -504,10 +504,31 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device 
>> *ec_dev,
>>  }
>>  EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
>>
>> +static int get_next_event_xfer(struct cros_ec_device *ec_dev,
>> +  struct cros_ec_command *msg,
>> +  int version, uint32_t size)
>> +{
>> +   int ret;
>> +
>> +   msg->version = version;
>> +   msg->command = EC_CMD_GET_NEXT_EVENT;
>> +   msg->insize = size;
>> +   msg->outsize = 0;
>> +
>> +   ret = cros_ec_cmd_xfer(ec_dev, msg);
>> +   if (ret > 0) {
>> +   ec_dev->event_size = ret - 1;
>> +   memcpy(_dev->event_data, msg->data, ec_dev->event_size);
>> +   }
>> +
>> +   return ret;
>> +}
>> +
>>  static int get_next_event(struct cros_ec_device *ec_dev)
>>  {
>> u8 buffer[sizeof(struct cros_ec_command) + 
>> sizeof(ec_dev->event_data)];
>> struct cros_ec_command *msg = (struct cros_ec_command *)
>> +   static int cmd_version = 1;
> 
> Personal opinion, but I don't like this static here, and also I don't
> think this is scalable. Could we ask for the command version?

I don't have an opinion, I only followed how it was implemented on the
chromeos kernel and adapted to mainline. If you have a better way, I'll use it !

> 
>> int ret;
>>
>> if (ec_dev->suspended) {
>> @@ -515,18 +536,19 @@ static int get_next_event(struct cros_ec_device 
>> *ec_dev)
>> return -EHOSTDOWN;
>> }
>>
>> -   msg->version = 0;
>> -   msg->command = EC_CMD_GET_NEXT_EVENT;
>> -   msg->insize = sizeof(ec_dev->event_data);
>> -   msg->outsize = 0;
>> +   if (cmd_version == 1) {
>> +   ret = get_next_event_xfer(ec_dev, msg, cmd_version,
>> +   sizeof(struct 
>> ec_response_get_next_event_v1));
>> +   if (ret < 0 || msg->result != EC_RES_INVALID_VERSION)
>> +   return ret;
>>
>> -   ret = cros_ec_cmd_xfer(ec_dev, msg);
>> -   if (ret > 0) {
>> -   ec_dev->event_size = ret - 1;
>> -   memcpy(_dev->event_data, msg->data,
>> -  sizeof(ec_dev->event_data));
>> +   /* Fallback to version 0 for future send attempts */
>> +   cmd_version = 0;
>> }
>>
> 
> So we always do a failed transfer on all these EC devices that does
> not support CEC. I am wondering if wouldn't be better pass the command
> version to the cros_ec_get_next_event function. The driver should know
> which version to use, just a random idea.

No, the driver cannot know the command version, this depends on the FW version
and the platform. AFAIK this must be discovered.

> 
>> +   ret = get_next_event_xfer(ec_dev, msg, cmd_version,
>> + sizeof(struct ec_response_get_next_event));
>> +
>> return ret;
>>  }
>>
>> diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h
>> index f36125e..32caef3 100644
>> --- a/include/linux/mfd/cros_ec.h
>> +++ b/include/linux/mfd/cros_ec.h
>> @@ -147,7 +147,7 @@ struct cros_ec_device {
>> bool mkbp_event_supported;
>> struct blocking_notifier_head event_noti

Re: [PATCH v2 2/5] drm/i915: hdmi: add CEC notifier to intel_hdmi

2018-05-21 Thread Neil Armstrong
Hi Ville,

On 18/05/2018 15:24, Ville Syrjälä wrote:
> On Fri, May 18, 2018 at 03:05:01PM +0200, Neil Armstrong wrote:
>> This patchs adds the cec_notifier feature to the intel_hdmi part
>> of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate
>> between each HDMI ports.
>> The changes will allow the i915 HDMI code to notify EDID and HPD changes
>> to an eventual CEC adapter.
>>
>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
>> ---
>>  drivers/gpu/drm/i915/Kconfig |  1 +
>>  drivers/gpu/drm/i915/intel_display.h | 20 
>>  drivers/gpu/drm/i915/intel_drv.h |  2 ++
>>  drivers/gpu/drm/i915/intel_hdmi.c| 13 +
>>  4 files changed, 36 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
>> index dfd9588..2d65d56 100644
>> --- a/drivers/gpu/drm/i915/Kconfig
>> +++ b/drivers/gpu/drm/i915/Kconfig
>> @@ -23,6 +23,7 @@ config DRM_I915
>>  select SYNC_FILE
>>  select IOSF_MBI
>>  select CRC32
>> +select CEC_CORE if CEC_NOTIFIER
>>  help
>>Choose this option if you have a system that has "Intel Graphics
>>Media Accelerator" or "HD Graphics" integrated graphics,
>> diff --git a/drivers/gpu/drm/i915/intel_display.h 
>> b/drivers/gpu/drm/i915/intel_display.h
>> index 4e7418b..c68d1c8 100644
>> --- a/drivers/gpu/drm/i915/intel_display.h
>> +++ b/drivers/gpu/drm/i915/intel_display.h
>> @@ -126,6 +126,26 @@ enum port {
>>  
>>  #define port_name(p) ((p) + 'A')
>>  
>> +static inline const char *port_identifier(enum port port)
>> +{
>> +switch (port) {
>> +case PORT_A:
>> +return "Port A";
>> +case PORT_B:
>> +return "Port B";
>> +case PORT_C:
>> +return "Port C";
>> +case PORT_D:
>> +return "Port D";
>> +case PORT_E:
>> +return "Port E";
>> +case PORT_F:
>> +return "Port F";
>> +default:
>> +return "";
>> +}
>> +}
> 
> I don't think we need this in the header. A static function will do.

I just followed how other functions were declared, in the same way.

> And I was actually thinking something a bit fancier like:
> snprintf("%s/port-%s", dev_name(dev), port_id(port));
> 
> Oh, I see you already pass the device in so I guess we don't need
> that in the port id?

Indeed, my bad I forgot to answer your last question, we already pass a struct
device which provides the device bus, name and id, so it's unneeded here.

> 
>> +
>>  enum dpio_channel {
>>  DPIO_CH0,
>>  DPIO_CH1
>> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
>> b/drivers/gpu/drm/i915/intel_drv.h
>> index d436858..b50e51b 100644
>> --- a/drivers/gpu/drm/i915/intel_drv.h
>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>> @@ -39,6 +39,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  
>>  /**
>>   * __wait_for - magic wait macro
>> @@ -1001,6 +1002,7 @@ struct intel_hdmi {
>>  bool has_audio;
>>  bool rgb_quant_range_selectable;
>>  struct intel_connector *attached_connector;
>> +struct cec_notifier *notifier;
> 
> I was wondering if we need any ifdefs around this stuff, but I guess not
> since it's just a pointer and all the functions seem to have empty
> static inlines for the CEC=n case.
> 
>>  };
>>  
>>  struct intel_dp_mst_encoder;
>> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
>> b/drivers/gpu/drm/i915/intel_hdmi.c
>> index 1baef4a..d522b5b 100644
>> --- a/drivers/gpu/drm/i915/intel_hdmi.c
>> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
>> @@ -1868,6 +1868,8 @@ intel_hdmi_set_edid(struct drm_connector *connector)
>>  connected = true;
>>  }
>>  
>> +cec_notifier_set_phys_addr_from_edid(intel_hdmi->notifier, edid);
>> +
>>  return connected;
>>  }
>>  
>> @@ -1876,6 +1878,7 @@ intel_hdmi_detect(struct drm_connector *connector, 
>> bool force)
>>  {
>>  enum drm_connector_status status;
>>  struct drm_i915_private *dev_priv = to_i915(connector->dev);
>> +struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
>>  
>>  DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
>>connector->base.id, connector->name);
>> @@ -1891,6 +1894,9 @

Re: [PATCH v2 1/5] media: cec-notifier: Get notifier by device and connector name

2018-05-21 Thread Neil Armstrong
Hi Sean,

On 18/05/2018 17:48, Sean Paul wrote:
> On Fri, May 18, 2018 at 03:05:00PM +0200, Neil Armstrong wrote:
>> In non device-tree world, we can need to get the notifier by the driver
>> name directly and eventually defer probe if not yet created.
>>
>> This patch adds a variant of the get function by using the device name
>> instead and will not create a notifier if not yet created.
>>
>> But the i915 driver exposes at least 2 HDMI connectors, this patch also
>> adds the possibility to add a connector name tied to the notifier device
>> to form a tuple and associate different CEC controllers for each HDMI
>> connectors.
>>
>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
> 
> Hi Neil,
> Thanks for posting these!
> 
>> ---
>>  drivers/media/cec/cec-notifier.c | 11 ---
>>  include/media/cec-notifier.h | 27 ---
>>  2 files changed, 32 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/media/cec/cec-notifier.c 
>> b/drivers/media/cec/cec-notifier.c
>> index 16dffa0..dd2078b 100644
>> --- a/drivers/media/cec/cec-notifier.c
>> +++ b/drivers/media/cec/cec-notifier.c
>> @@ -21,6 +21,7 @@ struct cec_notifier {
>>  struct list_head head;
>>  struct kref kref;
>>  struct device *dev;
>> +const char *conn;
>>  struct cec_adapter *cec_adap;
>>  void (*callback)(struct cec_adapter *adap, u16 pa);
>>  
>> @@ -30,13 +31,14 @@ struct cec_notifier {
>>  static LIST_HEAD(cec_notifiers);
>>  static DEFINE_MUTEX(cec_notifiers_lock);
>>  
>> -struct cec_notifier *cec_notifier_get(struct device *dev)
>> +struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char 
>> *conn)
>>  {
>>  struct cec_notifier *n;
>>  
>>  mutex_lock(_notifiers_lock);
>>  list_for_each_entry(n, _notifiers, head) {
>> -if (n->dev == dev) {
>> +if (n->dev == dev &&
>> +(!conn || !strcmp(n->conn, conn))) {
>>  kref_get(>kref);
>>  mutex_unlock(_notifiers_lock);
>>  return n;
>> @@ -46,6 +48,8 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
>>  if (!n)
>>  goto unlock;
>>  n->dev = dev;
>> +if (conn)
>> +n->conn = kstrdup(conn, GFP_KERNEL);
>>  n->phys_addr = CEC_PHYS_ADDR_INVALID;
>>  mutex_init(>lock);
>>  kref_init(>kref);
>> @@ -54,7 +58,7 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
>>  mutex_unlock(_notifiers_lock);
>>  return n;
>>  }
>> -EXPORT_SYMBOL_GPL(cec_notifier_get);
>> +EXPORT_SYMBOL_GPL(cec_notifier_get_conn);
>>  
>>  static void cec_notifier_release(struct kref *kref)
>>  {
>> @@ -62,6 +66,7 @@ static void cec_notifier_release(struct kref *kref)
>>  container_of(kref, struct cec_notifier, kref);
>>  
>>  list_del(>head);
>> +kfree(n->conn);
>>  kfree(n);
>>  }
>>  
>> diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h
>> index cf0add7..814eeef 100644
>> --- a/include/media/cec-notifier.h
>> +++ b/include/media/cec-notifier.h
>> @@ -20,8 +20,10 @@ struct cec_notifier;
>>  #if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER)
>>  
>>  /**
>> - * cec_notifier_get - find or create a new cec_notifier for the given 
>> device.
>> + * cec_notifier_get_conn - find or create a new cec_notifier for the given
>> + * device and connector tuple.
>>   * @dev: device that sends the events.
>> + * @conn: the connector name from which the event occurs
> 
> Probably best to use "name" instead of connector, since it doesn't necessarily
> _have_ to be a connector name. So, cec_notifier_get_by_name(dev, name)

I don't have a stong opinion, but since the CEC is tied to a connector, it 
should
mention connector, maybe conn_name ?

> 
>>   *
>>   * If a notifier for device @dev already exists, then increase the refcount
>>   * and return that notifier.
>> @@ -31,7 +33,8 @@ struct cec_notifier;
>>   *
>>   * Return NULL if the memory could not be allocated.
>>   */
>> -struct cec_notifier *cec_notifier_get(struct device *dev);
>> +struct cec_notifier *cec_notifier_get_conn(struct device *dev,
>> +   const char *conn);
>>  
>>  /**
>>   * cec_notifier_put - decrease refcount and delete when

[PATCH v2 1/5] media: cec-notifier: Get notifier by device and connector name

2018-05-18 Thread Neil Armstrong
In non device-tree world, we can need to get the notifier by the driver
name directly and eventually defer probe if not yet created.

This patch adds a variant of the get function by using the device name
instead and will not create a notifier if not yet created.

But the i915 driver exposes at least 2 HDMI connectors, this patch also
adds the possibility to add a connector name tied to the notifier device
to form a tuple and associate different CEC controllers for each HDMI
connectors.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/media/cec/cec-notifier.c | 11 ---
 include/media/cec-notifier.h | 27 ---
 2 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c
index 16dffa0..dd2078b 100644
--- a/drivers/media/cec/cec-notifier.c
+++ b/drivers/media/cec/cec-notifier.c
@@ -21,6 +21,7 @@ struct cec_notifier {
struct list_head head;
struct kref kref;
struct device *dev;
+   const char *conn;
struct cec_adapter *cec_adap;
void (*callback)(struct cec_adapter *adap, u16 pa);
 
@@ -30,13 +31,14 @@ struct cec_notifier {
 static LIST_HEAD(cec_notifiers);
 static DEFINE_MUTEX(cec_notifiers_lock);
 
-struct cec_notifier *cec_notifier_get(struct device *dev)
+struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char 
*conn)
 {
struct cec_notifier *n;
 
mutex_lock(_notifiers_lock);
list_for_each_entry(n, _notifiers, head) {
-   if (n->dev == dev) {
+   if (n->dev == dev &&
+   (!conn || !strcmp(n->conn, conn))) {
kref_get(>kref);
mutex_unlock(_notifiers_lock);
return n;
@@ -46,6 +48,8 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
if (!n)
goto unlock;
n->dev = dev;
+   if (conn)
+   n->conn = kstrdup(conn, GFP_KERNEL);
n->phys_addr = CEC_PHYS_ADDR_INVALID;
mutex_init(>lock);
kref_init(>kref);
@@ -54,7 +58,7 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
mutex_unlock(_notifiers_lock);
return n;
 }
-EXPORT_SYMBOL_GPL(cec_notifier_get);
+EXPORT_SYMBOL_GPL(cec_notifier_get_conn);
 
 static void cec_notifier_release(struct kref *kref)
 {
@@ -62,6 +66,7 @@ static void cec_notifier_release(struct kref *kref)
container_of(kref, struct cec_notifier, kref);
 
list_del(>head);
+   kfree(n->conn);
kfree(n);
 }
 
diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h
index cf0add7..814eeef 100644
--- a/include/media/cec-notifier.h
+++ b/include/media/cec-notifier.h
@@ -20,8 +20,10 @@ struct cec_notifier;
 #if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER)
 
 /**
- * cec_notifier_get - find or create a new cec_notifier for the given device.
+ * cec_notifier_get_conn - find or create a new cec_notifier for the given
+ * device and connector tuple.
  * @dev: device that sends the events.
+ * @conn: the connector name from which the event occurs
  *
  * If a notifier for device @dev already exists, then increase the refcount
  * and return that notifier.
@@ -31,7 +33,8 @@ struct cec_notifier;
  *
  * Return NULL if the memory could not be allocated.
  */
-struct cec_notifier *cec_notifier_get(struct device *dev);
+struct cec_notifier *cec_notifier_get_conn(struct device *dev,
+  const char *conn);
 
 /**
  * cec_notifier_put - decrease refcount and delete when the refcount reaches 0.
@@ -85,7 +88,8 @@ void cec_register_cec_notifier(struct cec_adapter *adap,
   struct cec_notifier *notifier);
 
 #else
-static inline struct cec_notifier *cec_notifier_get(struct device *dev)
+static inline struct cec_notifier *cec_notifier_get_conn(struct device *dev,
+const char *conn)
 {
/* A non-NULL pointer is expected on success */
return (struct cec_notifier *)0xdeadfeed;
@@ -121,6 +125,23 @@ static inline void cec_register_cec_notifier(struct 
cec_adapter *adap,
 #endif
 
 /**
+ * cec_notifier_get - find or create a new cec_notifier for the given device.
+ * @dev: device that sends the events.
+ *
+ * If a notifier for device @dev already exists, then increase the refcount
+ * and return that notifier.
+ *
+ * If it doesn't exist, then allocate a new notifier struct and return a
+ * pointer to that new struct.
+ *
+ * Return NULL if the memory could not be allocated.
+ */
+static inline struct cec_notifier *cec_notifier_get(struct device *dev)
+{
+   return cec_notifier_get_conn(dev, NULL);
+}
+
+/**
  * cec_notifier_phys_addr_invalidate() - set the physical address to INVALID
  *
  * @n: the CEC notifier
-- 
2.7.4



[PATCH v2 0/5] Add ChromeOS EC CEC Support

2018-05-18 Thread Neil Armstrong
Hi All,

The new Google "Fizz" Intel-based ChromeOS device is gaining CEC support
through it's Embedded Controller, to enable the Linux CEC Core to communicate
with it and get the CEC Physical Address from the correct HDMI Connector, the
following must be added/changed:
- Add the CEC sub-device registration in the ChromeOS EC MFD Driver
- Add the CEC related commands and events definitions into the EC MFD driver
- Add a way to get a CEC notifier with it's (optional) connector name
- Add the CEC notifier to the i915 HDMI driver
- Add the proper ChromeOS EC CEC Driver

The CEC notifier with the connector name is the tricky point, since even on
Device-Tree platforms, there is no way to distinguish between multiple HDMI
connectors from the same DRM driver. The solution I implemented is pretty
simple and only adds an optional connector name to eventually distinguish
an HDMI connector notifier from another if they share the same device.

Feel free to comment this patchset !

Changes since v2:
 - Add i915 port_identifier() and use this stable name as cec_notifier conn name
 - Fixed and cleaned up the CEC commands and events handling
 - Rebased the CEC sub-device registration on top of Enric's serie
 - Fixed comments typo on cec driver
 - Protected the DMI match only with PCI and DMI Kconfigs

Changes since v1:
 - Added cec_notifier_put to intel_hdmi
 - Fixed all small reported issues on the EC CEC driver
 - Moved the cec_notifier_get out of the #if .. #else .. #endif

Changes since RFC:
 - Moved CEC sub-device registration after CEC commands and events definitions 
patch
 - Removed get_notifier_get_byname
 - Added CEC_CORE select into i915 Kconfig
 - Removed CEC driver fallback if notifier is not configured on HW, added 
explicit warn
 - Fixed CEC core return type on error
 - Moved to cros-ec-cec media platform directory
 - Use bus_find_device() to find the pci i915 device instead of 
get_notifier_get_byname()
 - Fix Logical Address setup
 - Added comment about HW support
 - Removed memset of msg structures

Neil Armstrong (5):
  media: cec-notifier: Get notifier by device and connector name
  drm/i915: hdmi: add CEC notifier to intel_hdmi
  mfd: cros-ec: Introduce CEC commands and events definitions.
  mfd: cros_ec_dev: Add CEC sub-device registration
  media: platform: Add Chrome OS EC CEC driver

 drivers/gpu/drm/i915/Kconfig |   1 +
 drivers/gpu/drm/i915/intel_display.h |  20 ++
 drivers/gpu/drm/i915/intel_drv.h |   2 +
 drivers/gpu/drm/i915/intel_hdmi.c|  13 +
 drivers/media/cec/cec-notifier.c |  11 +-
 drivers/media/platform/Kconfig   |  11 +
 drivers/media/platform/Makefile  |   2 +
 drivers/media/platform/cros-ec-cec/Makefile  |   1 +
 drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 347 +++
 drivers/mfd/cros_ec_dev.c|  16 ++
 drivers/platform/chrome/cros_ec_proto.c  |  40 ++-
 include/linux/mfd/cros_ec.h  |   2 +-
 include/linux/mfd/cros_ec_commands.h |  80 ++
 include/media/cec-notifier.h |  27 +-
 14 files changed, 557 insertions(+), 16 deletions(-)
 create mode 100644 drivers/media/platform/cros-ec-cec/Makefile
 create mode 100644 drivers/media/platform/cros-ec-cec/cros-ec-cec.c

-- 
2.7.4



[PATCH v2 2/5] drm/i915: hdmi: add CEC notifier to intel_hdmi

2018-05-18 Thread Neil Armstrong
This patchs adds the cec_notifier feature to the intel_hdmi part
of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate
between each HDMI ports.
The changes will allow the i915 HDMI code to notify EDID and HPD changes
to an eventual CEC adapter.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/gpu/drm/i915/Kconfig |  1 +
 drivers/gpu/drm/i915/intel_display.h | 20 
 drivers/gpu/drm/i915/intel_drv.h |  2 ++
 drivers/gpu/drm/i915/intel_hdmi.c| 13 +
 4 files changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index dfd9588..2d65d56 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -23,6 +23,7 @@ config DRM_I915
select SYNC_FILE
select IOSF_MBI
select CRC32
+   select CEC_CORE if CEC_NOTIFIER
help
  Choose this option if you have a system that has "Intel Graphics
  Media Accelerator" or "HD Graphics" integrated graphics,
diff --git a/drivers/gpu/drm/i915/intel_display.h 
b/drivers/gpu/drm/i915/intel_display.h
index 4e7418b..c68d1c8 100644
--- a/drivers/gpu/drm/i915/intel_display.h
+++ b/drivers/gpu/drm/i915/intel_display.h
@@ -126,6 +126,26 @@ enum port {
 
 #define port_name(p) ((p) + 'A')
 
+static inline const char *port_identifier(enum port port)
+{
+   switch (port) {
+   case PORT_A:
+   return "Port A";
+   case PORT_B:
+   return "Port B";
+   case PORT_C:
+   return "Port C";
+   case PORT_D:
+   return "Port D";
+   case PORT_E:
+   return "Port E";
+   case PORT_F:
+   return "Port F";
+   default:
+   return "";
+   }
+}
+
 enum dpio_channel {
DPIO_CH0,
DPIO_CH1
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d436858..b50e51b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -39,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /**
  * __wait_for - magic wait macro
@@ -1001,6 +1002,7 @@ struct intel_hdmi {
bool has_audio;
bool rgb_quant_range_selectable;
struct intel_connector *attached_connector;
+   struct cec_notifier *notifier;
 };
 
 struct intel_dp_mst_encoder;
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
b/drivers/gpu/drm/i915/intel_hdmi.c
index 1baef4a..d522b5b 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1868,6 +1868,8 @@ intel_hdmi_set_edid(struct drm_connector *connector)
connected = true;
}
 
+   cec_notifier_set_phys_addr_from_edid(intel_hdmi->notifier, edid);
+
return connected;
 }
 
@@ -1876,6 +1878,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool 
force)
 {
enum drm_connector_status status;
struct drm_i915_private *dev_priv = to_i915(connector->dev);
+   struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
  connector->base.id, connector->name);
@@ -1891,6 +1894,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool 
force)
 
intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
 
+   if (status != connector_status_connected)
+   cec_notifier_phys_addr_invalidate(intel_hdmi->notifier);
+
return status;
 }
 
@@ -2031,6 +2037,8 @@ static void chv_hdmi_pre_enable(struct intel_encoder 
*encoder,
 
 static void intel_hdmi_destroy(struct drm_connector *connector)
 {
+   if (intel_attached_hdmi(connector)->notifier)
+   cec_notifier_put(intel_attached_hdmi(connector)->notifier);
kfree(to_intel_connector(connector)->detect_edid);
drm_connector_cleanup(connector);
kfree(connector);
@@ -2358,6 +2366,11 @@ void intel_hdmi_init_connector(struct intel_digital_port 
*intel_dig_port,
u32 temp = I915_READ(PEG_BAND_GAP_DATA);
I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
}
+
+   intel_hdmi->notifier = cec_notifier_get_conn(dev->dev,
+port_identifier(port));
+   if (!intel_hdmi->notifier)
+   DRM_DEBUG_KMS("CEC notifier get failed\n");
 }
 
 void intel_hdmi_init(struct drm_i915_private *dev_priv,
-- 
2.7.4



[PATCH v2 3/5] mfd: cros-ec: Introduce CEC commands and events definitions.

2018-05-18 Thread Neil Armstrong
The EC can expose a CEC bus, this patch adds the CEC related definitions
needed by the cros-ec-cec driver.
Having a 16 byte mkbp event size makes it possible to send CEC
messages from the EC to the AP directly inside the mkbp event
instead of first doing a notification and then a read.

Signed-off-by: Stefan Adolfsson <sadolfs...@chromium.org>
Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/platform/chrome/cros_ec_proto.c | 40 +
 include/linux/mfd/cros_ec.h |  2 +-
 include/linux/mfd/cros_ec_commands.h| 80 +
 3 files changed, 112 insertions(+), 10 deletions(-)

diff --git a/drivers/platform/chrome/cros_ec_proto.c 
b/drivers/platform/chrome/cros_ec_proto.c
index e7bbdf9..c4f6c44 100644
--- a/drivers/platform/chrome/cros_ec_proto.c
+++ b/drivers/platform/chrome/cros_ec_proto.c
@@ -504,10 +504,31 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev,
 }
 EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
 
+static int get_next_event_xfer(struct cros_ec_device *ec_dev,
+  struct cros_ec_command *msg,
+  int version, uint32_t size)
+{
+   int ret;
+
+   msg->version = version;
+   msg->command = EC_CMD_GET_NEXT_EVENT;
+   msg->insize = size;
+   msg->outsize = 0;
+
+   ret = cros_ec_cmd_xfer(ec_dev, msg);
+   if (ret > 0) {
+   ec_dev->event_size = ret - 1;
+   memcpy(_dev->event_data, msg->data, ec_dev->event_size);
+   }
+
+   return ret;
+}
+
 static int get_next_event(struct cros_ec_device *ec_dev)
 {
u8 buffer[sizeof(struct cros_ec_command) + sizeof(ec_dev->event_data)];
struct cros_ec_command *msg = (struct cros_ec_command *)
+   static int cmd_version = 1;
int ret;
 
if (ec_dev->suspended) {
@@ -515,18 +536,19 @@ static int get_next_event(struct cros_ec_device *ec_dev)
return -EHOSTDOWN;
}
 
-   msg->version = 0;
-   msg->command = EC_CMD_GET_NEXT_EVENT;
-   msg->insize = sizeof(ec_dev->event_data);
-   msg->outsize = 0;
+   if (cmd_version == 1) {
+   ret = get_next_event_xfer(ec_dev, msg, cmd_version,
+   sizeof(struct ec_response_get_next_event_v1));
+   if (ret < 0 || msg->result != EC_RES_INVALID_VERSION)
+   return ret;
 
-   ret = cros_ec_cmd_xfer(ec_dev, msg);
-   if (ret > 0) {
-   ec_dev->event_size = ret - 1;
-   memcpy(_dev->event_data, msg->data,
-  sizeof(ec_dev->event_data));
+   /* Fallback to version 0 for future send attempts */
+   cmd_version = 0;
}
 
+   ret = get_next_event_xfer(ec_dev, msg, cmd_version,
+ sizeof(struct ec_response_get_next_event));
+
return ret;
 }
 
diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h
index f36125e..32caef3 100644
--- a/include/linux/mfd/cros_ec.h
+++ b/include/linux/mfd/cros_ec.h
@@ -147,7 +147,7 @@ struct cros_ec_device {
bool mkbp_event_supported;
struct blocking_notifier_head event_notifier;
 
-   struct ec_response_get_next_event event_data;
+   struct ec_response_get_next_event_v1 event_data;
int event_size;
u32 host_event_wake_mask;
 };
diff --git a/include/linux/mfd/cros_ec_commands.h 
b/include/linux/mfd/cros_ec_commands.h
index f2edd99..16c3a2b 100644
--- a/include/linux/mfd/cros_ec_commands.h
+++ b/include/linux/mfd/cros_ec_commands.h
@@ -804,6 +804,8 @@ enum ec_feature_code {
EC_FEATURE_MOTION_SENSE_FIFO = 24,
/* EC has RTC feature that can be controlled by host commands */
EC_FEATURE_RTC = 27,
+   /* EC supports CEC commands */
+   EC_FEATURE_CEC = 35,
 };
 
 #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32))
@@ -2078,6 +2080,12 @@ enum ec_mkbp_event {
/* EC sent a sysrq command */
EC_MKBP_EVENT_SYSRQ = 6,
 
+   /* Notify the AP that something happened on CEC */
+   EC_MKBP_CEC_EVENT = 8,
+
+   /* Send an incoming CEC message to the AP */
+   EC_MKBP_EVENT_CEC_MESSAGE = 9,
+
/* Number of MKBP events */
EC_MKBP_EVENT_COUNT,
 };
@@ -2093,12 +2101,31 @@ union ec_response_get_next_data {
uint32_t   sysrq;
 } __packed;
 
+union ec_response_get_next_data_v1 {
+   uint8_t   key_matrix[16];
+
+   /* Unaligned */
+   uint32_t  host_event;
+
+   uint32_t   buttons;
+   uint32_t   switches;
+   uint32_t   sysrq;
+   uint32_t   cec_events;
+   uint8_tcec_message[16];
+} __packed;
+
 struct ec_response_get_next_event {
uint8_t event_type;
/* Followed by event data if any */
union ec_response_get_next_data data;
 } __packed;
 
+struct ec_response_get_next_event_v1 

[PATCH v2 4/5] mfd: cros_ec_dev: Add CEC sub-device registration

2018-05-18 Thread Neil Armstrong
The EC can expose a CEC bus, thus add the cros-ec-cec MFD sub-device
when the CEC feature bit is present.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/mfd/cros_ec_dev.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c
index 1d6dc5c..272969e 100644
--- a/drivers/mfd/cros_ec_dev.c
+++ b/drivers/mfd/cros_ec_dev.c
@@ -383,6 +383,10 @@ static void cros_ec_sensors_register(struct cros_ec_dev 
*ec)
kfree(msg);
 }
 
+static const struct mfd_cell cros_ec_cec_cells[] = {
+   { .name = "cros-ec-cec" }
+};
+
 static const struct mfd_cell cros_ec_rtc_cells[] = {
{ .name = "cros-ec-rtc" }
 };
@@ -426,6 +430,18 @@ static int ec_device_probe(struct platform_device *pdev)
if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE))
cros_ec_sensors_register(ec);
 
+   /* Check whether this EC instance has CEC host command support */
+   if (cros_ec_check_features(ec, EC_FEATURE_CEC)) {
+   retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO,
+cros_ec_cec_cells,
+ARRAY_SIZE(cros_ec_cec_cells),
+NULL, 0, NULL);
+   if (retval)
+   dev_err(ec->dev,
+   "failed to add cros-ec-cec device: %d\n",
+   retval);
+   }
+
/* Check whether this EC instance has RTC host command support */
if (cros_ec_check_features(ec, EC_FEATURE_RTC)) {
retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO,
-- 
2.7.4



[PATCH v2 5/5] media: platform: Add Chrome OS EC CEC driver

2018-05-18 Thread Neil Armstrong
The Chrome OS Embedded Controller can expose a CEC bus, this patch add the
driver for such feature of the Embedded Controller.

This driver is part of the cros-ec MFD and will be add as a sub-device when
the feature bit is exposed by the EC.

The controller will only handle a single logical address and handles
all the messages retries and will only expose Success or Error.

The controller will be tied to the HDMI CEC notifier by using the platform
DMI Data and the i915 device name and connector name.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/media/platform/Kconfig   |  11 +
 drivers/media/platform/Makefile  |   2 +
 drivers/media/platform/cros-ec-cec/Makefile  |   1 +
 drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 347 +++
 4 files changed, 361 insertions(+)
 create mode 100644 drivers/media/platform/cros-ec-cec/Makefile
 create mode 100644 drivers/media/platform/cros-ec-cec/cros-ec-cec.c

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index c7a1cf8..e55a8ed2 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -546,6 +546,17 @@ menuconfig CEC_PLATFORM_DRIVERS
 
 if CEC_PLATFORM_DRIVERS
 
+config VIDEO_CROS_EC_CEC
+   tristate "Chrome OS EC CEC driver"
+   depends on MFD_CROS_EC || COMPILE_TEST
+   select CEC_CORE
+   select CEC_NOTIFIER
+   ---help---
+ If you say yes here you will get support for the
+ Chrome OS Embedded Controller's CEC.
+ The CEC bus is present in the HDMI connector and enables communication
+ between compatible devices.
+
 config VIDEO_MESON_AO_CEC
tristate "Amlogic Meson AO CEC driver"
depends on ARCH_MESON || COMPILE_TEST
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 932515d..830696f 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -92,3 +92,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS)+= 
qcom/camss-8x16/
 obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/
 
 obj-y  += meson/
+
+obj-y  += cros-ec-cec/
diff --git a/drivers/media/platform/cros-ec-cec/Makefile 
b/drivers/media/platform/cros-ec-cec/Makefile
new file mode 100644
index 000..9ce97f9
--- /dev/null
+++ b/drivers/media/platform/cros-ec-cec/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VIDEO_CROS_EC_CEC) += cros-ec-cec.o
diff --git a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c 
b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
new file mode 100644
index 000..7e1e275
--- /dev/null
+++ b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
@@ -0,0 +1,347 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * CEC driver for Chrome OS Embedded Controller
+ *
+ * Copyright (c) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstr...@baylibre.com>
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DRV_NAME   "cros-ec-cec"
+
+/**
+ * struct cros_ec_cec - Driver data for EC CEC
+ *
+ * @cros_ec: Pointer to EC device
+ * @notifier: Notifier info for responding to EC events
+ * @adap: CEC adapter
+ * @notify: CEC notifier pointer
+ * @rx_msg: storage for a received message
+ */
+struct cros_ec_cec {
+   struct cros_ec_device *cros_ec;
+   struct notifier_block notifier;
+   struct cec_adapter *adap;
+   struct cec_notifier *notify;
+   struct cec_msg rx_msg;
+};
+
+static void handle_cec_message(struct cros_ec_cec *cros_ec_cec)
+{
+   struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
+   uint8_t *cec_message = cros_ec->event_data.data.cec_message;
+   unsigned int len = cros_ec->event_size;
+
+   cros_ec_cec->rx_msg.len = len;
+   memcpy(cros_ec_cec->rx_msg.msg, cec_message, len);
+
+   cec_received_msg(cros_ec_cec->adap, _ec_cec->rx_msg);
+}
+
+static void handle_cec_event(struct cros_ec_cec *cros_ec_cec)
+{
+   struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
+   uint32_t events = cros_ec->event_data.data.cec_events;
+
+   if (events & EC_MKBP_CEC_SEND_OK)
+   cec_transmit_attempt_done(cros_ec_cec->adap,
+ CEC_TX_STATUS_OK);
+
+   /* FW takes care of all retries, tell core to avoid more retries */
+   if (events & EC_MKBP_CEC_SEND_FAILED)
+   cec_transmit_attempt_done(cros_ec_cec->adap,
+ CEC_TX_STATUS_MAX_RETRIES |
+ CEC_TX_STATUS_NACK);
+}
+
+static int cros_ec_cec_event(struct notifier_block *nb,
+unsigned long queued_during_suspend,
+void *_notify)
+{
+   struct cros_ec_cec *cros_ec_cec;
+   struct cros_ec_dev

Re: [Intel-gfx] [PATCH v2 2/5] drm/i915: hdmi: add CEC notifier to intel_hdmi

2018-05-16 Thread Neil Armstrong
Hi Ville,

On 16/05/2018 16:07, Ville Syrjälä wrote:
> On Wed, May 16, 2018 at 09:40:17AM +0200, Neil Armstrong wrote:
>> On 16/05/2018 09:31, Neil Armstrong wrote:
>>> Hi Ville,
>>>
>>> On 15/05/2018 17:35, Ville Syrjälä wrote:
>>>> On Tue, May 15, 2018 at 04:42:19PM +0200, Neil Armstrong wrote:
>>>>> This patchs adds the cec_notifier feature to the intel_hdmi part
>>>>> of the i915 DRM driver. It uses the HDMI DRM connector name to 
>>>>> differentiate
>>>>> between each HDMI ports.
>>>>> The changes will allow the i915 HDMI code to notify EDID and HPD changes
>>>>> to an eventual CEC adapter.
>>>>>
>>>>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
>>>>> ---
>>>>>  drivers/gpu/drm/i915/Kconfig  |  1 +
>>>>>  drivers/gpu/drm/i915/intel_drv.h  |  2 ++
>>>>>  drivers/gpu/drm/i915/intel_hdmi.c | 12 
>>>>>  3 files changed, 15 insertions(+)
>>>>>
>>>
>>> [..]
>>>
>>>>>  }
>>>>>  
>>>>> @@ -2031,6 +2037,8 @@ static void chv_hdmi_pre_enable(struct 
>>>>> intel_encoder *encoder,
>>>>>  
>>>>>  static void intel_hdmi_destroy(struct drm_connector *connector)
>>>>>  {
>>>>> + if (intel_attached_hdmi(connector)->notifier)
>>>>> + cec_notifier_put(intel_attached_hdmi(connector)->notifier);
>>>>>   kfree(to_intel_connector(connector)->detect_edid);
>>>>>   drm_connector_cleanup(connector);
>>>>>   kfree(connector);
>>>>> @@ -2358,6 +2366,10 @@ void intel_hdmi_init_connector(struct 
>>>>> intel_digital_port *intel_dig_port,
>>>>>   u32 temp = I915_READ(PEG_BAND_GAP_DATA);
>>>>>   I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
>>>>>   }
>>>>> +
>>>>> + intel_hdmi->notifier = cec_notifier_get_conn(dev->dev, connector->name);
>>>>
>>>> What are we doing with the connector name here? Those are not actually
>>>> guaranteed to be stable, and any change in the connector probe order
>>>> may cause the name to change.
>>>
>>> The i915 driver can expose multiple HDMI connectors, but each connected will
>>> have a different EDID and CEC physical address, so we will need a different 
>>> notifier
>>> for each connector.
>>>
>>> The connector name is DRM dependent, but user-space actually uses this name 
>>> for
>>> operations, so I supposed it was kind of stable.
>>>
>>> Anyway, is there another stable id/name/whatever that can be used to make a 
>>> name to
>>> distinguish the HDMI connectors ?
>>
>> Would "HDMI %c", port_name(port) be OK to use ?
> 
> Yeah, something like seems like a reasonable approach. That does mean
> we have to be a little careful with changing enum port or port_name()
> in the future, but I guess we could just add a small function to
> generated the name/id specifically for this thing.
> 
> We're also going to have to think what to do with enum port and
> port_name() on ICL+ though. There we won't just have A-F but also
> TC1-TC. Hmm. Looks like what we have for those ports in our
> codebase ATM is a bit wonky since we haven't even changed
> port_name() to give us the TC type names.
> 
> Also we might not want "HDMI" in the identifier since the physical
> port is not HDMI specific. There are different things we could call
> these but I think we could just go with a generic "Port A-F" and
> "Port TC1-TC" approach. I think something like that should work
> fine for current and upcoming hardware. And in theory that could
> then be used for other things as well which need a stable
> identifier.
> 
> Oh, and now I recall that input subsystem at least has some kind
> of "physical path" property on devices. So I guess what we're
> dicussing is a somewhat similar idea. I think input drivers
> generally include the pci/usb/etc. device in the path as well.
> Even though we currently only ever have the one pci device it
> would seem like decent idea to include that information in our
> identifiers as well. Or what do you think?
> 

Thanks for the clarifications !

Having a "Port " will be great indeed, no need to specify HDMI since
only HDMI connectors will get a CEC notifier anyway.

The issue is that port_name() returns a character, which is lame.
Would it be acceptable to introduce a :

const char *port_identifier(struct drm_i915_private *dev_priv,
enum port port)
{
char *id = devm_kzalloc(dev_priv->drm->dev, 16, GFP_KERNEL);

if (id)
return NULL;

snprintf("Port %c", port_name(port));

return id;
}

and use the result of this for the cec_notifier connector name ?

Neil


Re: [PATCH v2 3/5] mfd: cros-ec: Introduce CEC commands and events definitions.

2018-05-16 Thread Neil Armstrong
Hi Hans,

On 15/05/2018 17:28, Hans Verkuil wrote:
> On 05/15/2018 04:42 PM, Neil Armstrong wrote:
>> The EC can expose a CEC bus, this patch adds the CEC related definitions
>> needed by the cros-ec-cec driver.
>> Having a 16 byte mkbp event size makes it possible to send CEC
>> messages from the EC to the AP directly inside the mkbp event
>> instead of first doing a notification and then a read.
>>
>> Signed-off-by: Stefan Adolfsson <sadolfs...@chromium.org>
>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
>> ---
>>  drivers/platform/chrome/cros_ec_proto.c | 42 +
>>  include/linux/mfd/cros_ec.h |  2 +-
>>  include/linux/mfd/cros_ec_commands.h| 80 
>> +
>>  3 files changed, 114 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/platform/chrome/cros_ec_proto.c 
>> b/drivers/platform/chrome/cros_ec_proto.c
>> index e7bbdf9..ba47f79 100644
>> --- a/drivers/platform/chrome/cros_ec_proto.c
>> +++ b/drivers/platform/chrome/cros_ec_proto.c
>> @@ -504,29 +504,53 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device 
>> *ec_dev,
>>  }
>>  EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
>>  
>> +static int get_next_event_xfer(struct cros_ec_device *ec_dev,
>> +   struct cros_ec_command *msg,
>> +   int version, uint32_t size)
>> +{
>> +int ret;
>> +
>> +msg->version = version;
>> +msg->command = EC_CMD_GET_NEXT_EVENT;
>> +msg->insize = size;
>> +msg->outsize = 0;
>> +
>> +ret = cros_ec_cmd_xfer(ec_dev, msg);
>> +if (ret > 0) {
>> +ec_dev->event_size = ret - 1;
>> +memcpy(_dev->event_data, msg->data, size);
>> +}
>> +
>> +return ret;
>> +}
>> +
>>  static int get_next_event(struct cros_ec_device *ec_dev)
>>  {
>>  u8 buffer[sizeof(struct cros_ec_command) + sizeof(ec_dev->event_data)];
>>  struct cros_ec_command *msg = (struct cros_ec_command *)
>> +static int cmd_version = 1;
>>  int ret;
>>  
>> +BUILD_BUG_ON(sizeof(union ec_response_get_next_data_v1) != 16);
> 
> Use the define instead of hardcoding 16. I'm not really sure why you need 
> this.
> If cec_message uses the right define for the array size (see my comment 
> below),
> then this really can't go wrong, can it?

This is taken from the chrome kernelk, to be sure the size is ok, but yes it 
should be 16, I'll see
if I can drop this.

> 
>> +
>>  if (ec_dev->suspended) {
>>  dev_dbg(ec_dev->dev, "Device suspended.\n");
>>  return -EHOSTDOWN;
>>  }
>>  
>> -msg->version = 0;
>> -msg->command = EC_CMD_GET_NEXT_EVENT;
>> -msg->insize = sizeof(ec_dev->event_data);
>> -msg->outsize = 0;
>> +if (cmd_version == 1) {
>> +ret = get_next_event_xfer(ec_dev, msg, cmd_version,
>> +  sizeof(ec_dev->event_data));
>> +if (ret != EC_RES_INVALID_VERSION)
>> +return ret;
>>  
>> -ret = cros_ec_cmd_xfer(ec_dev, msg);
>> -if (ret > 0) {
>> -ec_dev->event_size = ret - 1;
>> -memcpy(_dev->event_data, msg->data,
>> -   sizeof(ec_dev->event_data));
>> +/* Fallback to version 0 for future send attempts */
>> +cmd_version = 0;
>>  }
>>  
>> +ret = get_next_event_xfer(ec_dev, msg, cmd_version,
>> +  sizeof(struct ec_response_get_next_event));
>> +
>>  return ret;
>>  }
>>  
>> diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h
>> index 2d4e23c..f3415eb 100644
>> --- a/include/linux/mfd/cros_ec.h
>> +++ b/include/linux/mfd/cros_ec.h
>> @@ -147,7 +147,7 @@ struct cros_ec_device {
>>  bool mkbp_event_supported;
>>  struct blocking_notifier_head event_notifier;
>>  
>> -struct ec_response_get_next_event event_data;
>> +struct ec_response_get_next_event_v1 event_data;
>>  int event_size;
>>  u32 host_event_wake_mask;
>>  };
>> diff --git a/include/linux/mfd/cros_ec_commands.h 
>> b/include/linux/mfd/cros_ec_commands.h
>> index f2edd99..18df466 100644
>> --- a/include/linux/mfd/cros_ec_commands.h
>> +++ b/include/linux/mfd/cros_ec_commands.h
>> @@ -804,6 +804,8 @@ enum ec_feature_code {
>> 

Re: [PATCH v2 4/5] mfd: cros_ec_dev: Add CEC sub-device registration

2018-05-16 Thread Neil Armstrong
Hi Enric,

On 15/05/2018 18:40, Enric Balletbo Serra wrote:
> Hi Neil,
> 
> I suspect that this patch will conflict with some patches that will be
> queued for 4.18 that also introduces new devices, well, for now I
> don't see these merged in the Lee's tree.

Indeed, I found your patches, I'll rebase this one when Lee pushes them in his 
tree.

> 
> Based on some reviews I got when I send a patch to this file ...
> 
> 2018-05-15 17:29 GMT+02:00 Hans Verkuil <hverk...@xs4all.nl>:
>> On 05/15/2018 04:42 PM, Neil Armstrong wrote:
>>> The EC can expose a CEC bus, thus add the cros-ec-cec MFD sub-device
>>> when the CEC feature bit is present.
>>>
>>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
>>
>> For what it is worth (not an MFD expert):
>>
>> Acked-by: Hans Verkuil <hans.verk...@cisco.com>
>>
>> Thanks!
>>
>> Hans
>>
>>> ---
>>>  drivers/mfd/cros_ec_dev.c | 16 
>>>  1 file changed, 16 insertions(+)
>>>
>>> diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c
>>> index eafd06f..57064ec 100644
>>> --- a/drivers/mfd/cros_ec_dev.c
>>> +++ b/drivers/mfd/cros_ec_dev.c
>>> @@ -383,6 +383,18 @@ static void cros_ec_sensors_register(struct 
>>> cros_ec_dev *ec)
>>>   kfree(msg);
>>>  }
>>>
>>> +static void cros_ec_cec_register(struct cros_ec_dev *ec)
>>> +{
>>> + int ret;
>>> + struct mfd_cell cec_cell = {
>>> + .name = "cros-ec-cec",
>>> + };
>>> +
>>> + ret = mfd_add_devices(ec->dev, 0, _cell, 1, NULL, 0, NULL);
>>> + if (ret)
>>> + dev_err(ec->dev, "failed to add EC CEC\n");
>>> +}
>>> +
> 
> Do not create a single function to only call mfd_add_devices, instead
> do the following on top:
> 
> static const struct mfd_cell cros_ec_cec_cells[] = {
> { .name = "cros-ec-cec" }
> };

OK

> 
> 
>>>  static int ec_device_probe(struct platform_device *pdev)
>>>  {
>>>   int retval = -ENOMEM;
>>> @@ -422,6 +434,10 @@ static int ec_device_probe(struct platform_device 
>>> *pdev)
>>>   if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE))
>>>   cros_ec_sensors_register(ec);
>>>
>>> + /* check whether this EC handles CEC. */
>>> + if (cros_ec_check_features(ec, EC_FEATURE_CEC))
>>> + cros_ec_cec_register(ec);
>>> +
> 
> and use PLATFORM_DEVID_AUTO and the ARRAY_SIZE macro, something like this.
> 
> /* Check whether this EC instance handles CEC */
> if (cros_ec_check_features(ec, EC_FEATURE_CEC)) {
> retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO,
>   cros_ec_cec_cells,
>   
> ARRAY_SIZE(cros_ec_cec_cells),
>   NULL, 0, NULL);
> if (retval)
> dev_err(ec->dev, "failed to add cros-ec-cec device: %d\n",
>  retval);
> }

Ok, like the RTC registration.

Thanks,
Neil

> 
> Best regards,
>   Enric
> 
>>>   /* Take control of the lightbar from the EC. */
>>>   lb_manual_suspend_ctrl(ec, 1);
>>>
>>>
>>
>> ___
>> dri-devel mailing list
>> dri-de...@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel



Re: [Intel-gfx] [PATCH v2 2/5] drm/i915: hdmi: add CEC notifier to intel_hdmi

2018-05-16 Thread Neil Armstrong
On 16/05/2018 09:31, Neil Armstrong wrote:
> Hi Ville,
> 
> On 15/05/2018 17:35, Ville Syrjälä wrote:
>> On Tue, May 15, 2018 at 04:42:19PM +0200, Neil Armstrong wrote:
>>> This patchs adds the cec_notifier feature to the intel_hdmi part
>>> of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate
>>> between each HDMI ports.
>>> The changes will allow the i915 HDMI code to notify EDID and HPD changes
>>> to an eventual CEC adapter.
>>>
>>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
>>> ---
>>>  drivers/gpu/drm/i915/Kconfig  |  1 +
>>>  drivers/gpu/drm/i915/intel_drv.h  |  2 ++
>>>  drivers/gpu/drm/i915/intel_hdmi.c | 12 
>>>  3 files changed, 15 insertions(+)
>>>
> 
> [..]
> 
>>>  }
>>>  
>>> @@ -2031,6 +2037,8 @@ static void chv_hdmi_pre_enable(struct intel_encoder 
>>> *encoder,
>>>  
>>>  static void intel_hdmi_destroy(struct drm_connector *connector)
>>>  {
>>> +   if (intel_attached_hdmi(connector)->notifier)
>>> +   cec_notifier_put(intel_attached_hdmi(connector)->notifier);
>>> kfree(to_intel_connector(connector)->detect_edid);
>>> drm_connector_cleanup(connector);
>>> kfree(connector);
>>> @@ -2358,6 +2366,10 @@ void intel_hdmi_init_connector(struct 
>>> intel_digital_port *intel_dig_port,
>>> u32 temp = I915_READ(PEG_BAND_GAP_DATA);
>>> I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
>>> }
>>> +
>>> +   intel_hdmi->notifier = cec_notifier_get_conn(dev->dev, connector->name);
>>
>> What are we doing with the connector name here? Those are not actually
>> guaranteed to be stable, and any change in the connector probe order
>> may cause the name to change.
> 
> The i915 driver can expose multiple HDMI connectors, but each connected will
> have a different EDID and CEC physical address, so we will need a different 
> notifier
> for each connector.
> 
> The connector name is DRM dependent, but user-space actually uses this name 
> for
> operations, so I supposed it was kind of stable.
> 
> Anyway, is there another stable id/name/whatever that can be used to make a 
> name to
> distinguish the HDMI connectors ?

Would "HDMI %c", port_name(port) be OK to use ?

Neil

> 
> Neil
> 
>>
>>> +   if (!intel_hdmi->notifier)
>>> +   DRM_DEBUG_KMS("CEC notifier get failed\n");
>>>  }
>>>  
>>>  void intel_hdmi_init(struct drm_i915_private *dev_priv,
>>> -- 
>>> 2.7.4
>>>
>>> ___
>>> Intel-gfx mailing list
>>> intel-...@lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>
> 



Re: [Intel-gfx] [PATCH v2 2/5] drm/i915: hdmi: add CEC notifier to intel_hdmi

2018-05-16 Thread Neil Armstrong
Hi Ville,

On 15/05/2018 17:35, Ville Syrjälä wrote:
> On Tue, May 15, 2018 at 04:42:19PM +0200, Neil Armstrong wrote:
>> This patchs adds the cec_notifier feature to the intel_hdmi part
>> of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate
>> between each HDMI ports.
>> The changes will allow the i915 HDMI code to notify EDID and HPD changes
>> to an eventual CEC adapter.
>>
>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
>> ---
>>  drivers/gpu/drm/i915/Kconfig  |  1 +
>>  drivers/gpu/drm/i915/intel_drv.h  |  2 ++
>>  drivers/gpu/drm/i915/intel_hdmi.c | 12 
>>  3 files changed, 15 insertions(+)
>>

[..]

>>  }
>>  
>> @@ -2031,6 +2037,8 @@ static void chv_hdmi_pre_enable(struct intel_encoder 
>> *encoder,
>>  
>>  static void intel_hdmi_destroy(struct drm_connector *connector)
>>  {
>> +if (intel_attached_hdmi(connector)->notifier)
>> +cec_notifier_put(intel_attached_hdmi(connector)->notifier);
>>  kfree(to_intel_connector(connector)->detect_edid);
>>  drm_connector_cleanup(connector);
>>  kfree(connector);
>> @@ -2358,6 +2366,10 @@ void intel_hdmi_init_connector(struct 
>> intel_digital_port *intel_dig_port,
>>  u32 temp = I915_READ(PEG_BAND_GAP_DATA);
>>  I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
>>  }
>> +
>> +intel_hdmi->notifier = cec_notifier_get_conn(dev->dev, connector->name);
> 
> What are we doing with the connector name here? Those are not actually
> guaranteed to be stable, and any change in the connector probe order
> may cause the name to change.

The i915 driver can expose multiple HDMI connectors, but each connected will
have a different EDID and CEC physical address, so we will need a different 
notifier
for each connector.

The connector name is DRM dependent, but user-space actually uses this name for
operations, so I supposed it was kind of stable.

Anyway, is there another stable id/name/whatever that can be used to make a 
name to
distinguish the HDMI connectors ?

Neil

> 
>> +if (!intel_hdmi->notifier)
>> +DRM_DEBUG_KMS("CEC notifier get failed\n");
>>  }
>>  
>>  void intel_hdmi_init(struct drm_i915_private *dev_priv,
>> -- 
>> 2.7.4
>>
>> ___
>> Intel-gfx mailing list
>> intel-...@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 



Re: [PATCH v2 1/5] media: cec-notifier: Get notifier by device and connector name

2018-05-15 Thread Neil Armstrong
On 15/05/2018 17:22, Hans Verkuil wrote:
> On 05/15/2018 04:42 PM, Neil Armstrong wrote:
>> In non device-tree world, we can need to get the notifier by the driver
>> name directly and eventually defer probe if not yet created.
>>
>> This patch adds a variant of the get function by using the device name
>> instead and will not create a notifier if not yet created.
>>
>> But the i915 driver exposes at least 2 HDMI connectors, this patch also
>> adds the possibility to add a connector name tied to the notifier device
>> to form a tuple and associate different CEC controllers for each HDMI
>> connectors.
> 
> The patch looks good, but I'm curious about this paragraph above.
> 
> Was this tested with devices with more than one HDMI output? Or only on
> laptops with a single physical HDMI output? If there are two or more
> outputs then I guess it is the HW designer that decides with output gets
> CEC support?

The driver exposes 2 HDMI connectors (I suspect one is connected to the USB-C 
alt mode mux along the DP port),
and only one connected has the CEC line connected to the Embedded Controller.

Neil

> 
> Regards,
> 
>   Hans
> 
>>
>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
>> ---
>>  drivers/media/cec/cec-notifier.c | 11 ---
>>  include/media/cec-notifier.h | 27 ---
>>  2 files changed, 32 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/media/cec/cec-notifier.c 
>> b/drivers/media/cec/cec-notifier.c
>> index 16dffa0..dd2078b 100644
>> --- a/drivers/media/cec/cec-notifier.c
>> +++ b/drivers/media/cec/cec-notifier.c
>> @@ -21,6 +21,7 @@ struct cec_notifier {
>>  struct list_head head;
>>  struct kref kref;
>>  struct device *dev;
>> +const char *conn;
>>  struct cec_adapter *cec_adap;
>>  void (*callback)(struct cec_adapter *adap, u16 pa);
>>  
>> @@ -30,13 +31,14 @@ struct cec_notifier {
>>  static LIST_HEAD(cec_notifiers);
>>  static DEFINE_MUTEX(cec_notifiers_lock);
>>  
>> -struct cec_notifier *cec_notifier_get(struct device *dev)
>> +struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char 
>> *conn)
>>  {
>>  struct cec_notifier *n;
>>  
>>  mutex_lock(_notifiers_lock);
>>  list_for_each_entry(n, _notifiers, head) {
>> -if (n->dev == dev) {
>> +if (n->dev == dev &&
>> +(!conn || !strcmp(n->conn, conn))) {
>>  kref_get(>kref);
>>  mutex_unlock(_notifiers_lock);
>>  return n;
>> @@ -46,6 +48,8 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
>>  if (!n)
>>  goto unlock;
>>  n->dev = dev;
>> +if (conn)
>> +n->conn = kstrdup(conn, GFP_KERNEL);
>>  n->phys_addr = CEC_PHYS_ADDR_INVALID;
>>  mutex_init(>lock);
>>  kref_init(>kref);
>> @@ -54,7 +58,7 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
>>  mutex_unlock(_notifiers_lock);
>>  return n;
>>  }
>> -EXPORT_SYMBOL_GPL(cec_notifier_get);
>> +EXPORT_SYMBOL_GPL(cec_notifier_get_conn);
>>  
>>  static void cec_notifier_release(struct kref *kref)
>>  {
>> @@ -62,6 +66,7 @@ static void cec_notifier_release(struct kref *kref)
>>  container_of(kref, struct cec_notifier, kref);
>>  
>>  list_del(>head);
>> +kfree(n->conn);
>>  kfree(n);
>>  }
>>  
>> diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h
>> index cf0add7..814eeef 100644
>> --- a/include/media/cec-notifier.h
>> +++ b/include/media/cec-notifier.h
>> @@ -20,8 +20,10 @@ struct cec_notifier;
>>  #if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER)
>>  
>>  /**
>> - * cec_notifier_get - find or create a new cec_notifier for the given 
>> device.
>> + * cec_notifier_get_conn - find or create a new cec_notifier for the given
>> + * device and connector tuple.
>>   * @dev: device that sends the events.
>> + * @conn: the connector name from which the event occurs
>>   *
>>   * If a notifier for device @dev already exists, then increase the refcount
>>   * and return that notifier.
>> @@ -31,7 +33,8 @@ struct cec_notifier;
>>   *
>>   * Return NULL if the memory could not be allocated.
>>   */
>> -struct cec_notifier *cec_notifier_get(struct device *dev);
>> +struct cec_notifier *cec_notifier_g

[PATCH v2 0/5] Add ChromeOS EC CEC Support

2018-05-15 Thread Neil Armstrong
Hi All,

The new Google "Fizz" Intel-based ChromeOS device is gaining CEC support
through it's Embedded Controller, to enable the Linux CEC Core to communicate
with it and get the CEC Physical Address from the correct HDMI Connector, the
following must be added/changed:
- Add the CEC sub-device registration in the ChromeOS EC MFD Driver
- Add the CEC related commands and events definitions into the EC MFD driver
- Add a way to get a CEC notifier with it's (optional) connector name
- Add the CEC notifier to the i915 HDMI driver
- Add the proper ChromeOS EC CEC Driver

The CEC notifier with the connector name is the tricky point, since even on
Device-Tree platforms, there is no way to distinguish between multiple HDMI
connectors from the same DRM driver. The solution I implemented is pretty
simple and only adds an optional connector name to eventually distinguish
an HDMI connector notifier from another if they share the same device.

Feel free to comment this patchset !

Changes since v1:
 - Added cec_notifier_put to intel_hdmi
 - Fixed all small reported issues on the EC CEC driver
 - Moved the cec_notifier_get out of the #if .. #else .. #endif

Changes since RFC:
 - Moved CEC sub-device registration after CEC commands and events definitions 
patch
 - Removed get_notifier_get_byname
 - Added CEC_CORE select into i915 Kconfig
 - Removed CEC driver fallback if notifier is not configured on HW, added 
explicit warn
 - Fixed CEC core return type on error
 - Moved to cros-ec-cec media platform directory
 - Use bus_find_device() to find the pci i915 device instead of 
get_notifier_get_byname()
 - Fix Logical Address setup
 - Added comment about HW support
 - Removed memset of msg structures

Neil Armstrong (5):
  media: cec-notifier: Get notifier by device and connector name
  drm/i915: hdmi: add CEC notifier to intel_hdmi
  mfd: cros-ec: Introduce CEC commands and events definitions.
  mfd: cros_ec_dev: Add CEC sub-device registration
  media: platform: Add Chrome OS EC CEC driver

 drivers/gpu/drm/i915/Kconfig |   1 +
 drivers/gpu/drm/i915/intel_drv.h |   2 +
 drivers/gpu/drm/i915/intel_hdmi.c|  12 +
 drivers/media/cec/cec-notifier.c |  11 +-
 drivers/media/platform/Kconfig   |  11 +
 drivers/media/platform/Makefile  |   2 +
 drivers/media/platform/cros-ec-cec/Makefile  |   1 +
 drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 335 +++
 drivers/mfd/cros_ec_dev.c|  16 ++
 drivers/platform/chrome/cros_ec_proto.c  |  42 ++-
 include/linux/mfd/cros_ec.h  |   2 +-
 include/linux/mfd/cros_ec_commands.h |  80 ++
 include/media/cec-notifier.h |  27 +-
 13 files changed, 526 insertions(+), 16 deletions(-)
 create mode 100644 drivers/media/platform/cros-ec-cec/Makefile
 create mode 100644 drivers/media/platform/cros-ec-cec/cros-ec-cec.c

-- 
2.7.4



[PATCH v2 1/5] media: cec-notifier: Get notifier by device and connector name

2018-05-15 Thread Neil Armstrong
In non device-tree world, we can need to get the notifier by the driver
name directly and eventually defer probe if not yet created.

This patch adds a variant of the get function by using the device name
instead and will not create a notifier if not yet created.

But the i915 driver exposes at least 2 HDMI connectors, this patch also
adds the possibility to add a connector name tied to the notifier device
to form a tuple and associate different CEC controllers for each HDMI
connectors.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/media/cec/cec-notifier.c | 11 ---
 include/media/cec-notifier.h | 27 ---
 2 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c
index 16dffa0..dd2078b 100644
--- a/drivers/media/cec/cec-notifier.c
+++ b/drivers/media/cec/cec-notifier.c
@@ -21,6 +21,7 @@ struct cec_notifier {
struct list_head head;
struct kref kref;
struct device *dev;
+   const char *conn;
struct cec_adapter *cec_adap;
void (*callback)(struct cec_adapter *adap, u16 pa);
 
@@ -30,13 +31,14 @@ struct cec_notifier {
 static LIST_HEAD(cec_notifiers);
 static DEFINE_MUTEX(cec_notifiers_lock);
 
-struct cec_notifier *cec_notifier_get(struct device *dev)
+struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char 
*conn)
 {
struct cec_notifier *n;
 
mutex_lock(_notifiers_lock);
list_for_each_entry(n, _notifiers, head) {
-   if (n->dev == dev) {
+   if (n->dev == dev &&
+   (!conn || !strcmp(n->conn, conn))) {
kref_get(>kref);
mutex_unlock(_notifiers_lock);
return n;
@@ -46,6 +48,8 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
if (!n)
goto unlock;
n->dev = dev;
+   if (conn)
+   n->conn = kstrdup(conn, GFP_KERNEL);
n->phys_addr = CEC_PHYS_ADDR_INVALID;
mutex_init(>lock);
kref_init(>kref);
@@ -54,7 +58,7 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
mutex_unlock(_notifiers_lock);
return n;
 }
-EXPORT_SYMBOL_GPL(cec_notifier_get);
+EXPORT_SYMBOL_GPL(cec_notifier_get_conn);
 
 static void cec_notifier_release(struct kref *kref)
 {
@@ -62,6 +66,7 @@ static void cec_notifier_release(struct kref *kref)
container_of(kref, struct cec_notifier, kref);
 
list_del(>head);
+   kfree(n->conn);
kfree(n);
 }
 
diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h
index cf0add7..814eeef 100644
--- a/include/media/cec-notifier.h
+++ b/include/media/cec-notifier.h
@@ -20,8 +20,10 @@ struct cec_notifier;
 #if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER)
 
 /**
- * cec_notifier_get - find or create a new cec_notifier for the given device.
+ * cec_notifier_get_conn - find or create a new cec_notifier for the given
+ * device and connector tuple.
  * @dev: device that sends the events.
+ * @conn: the connector name from which the event occurs
  *
  * If a notifier for device @dev already exists, then increase the refcount
  * and return that notifier.
@@ -31,7 +33,8 @@ struct cec_notifier;
  *
  * Return NULL if the memory could not be allocated.
  */
-struct cec_notifier *cec_notifier_get(struct device *dev);
+struct cec_notifier *cec_notifier_get_conn(struct device *dev,
+  const char *conn);
 
 /**
  * cec_notifier_put - decrease refcount and delete when the refcount reaches 0.
@@ -85,7 +88,8 @@ void cec_register_cec_notifier(struct cec_adapter *adap,
   struct cec_notifier *notifier);
 
 #else
-static inline struct cec_notifier *cec_notifier_get(struct device *dev)
+static inline struct cec_notifier *cec_notifier_get_conn(struct device *dev,
+const char *conn)
 {
/* A non-NULL pointer is expected on success */
return (struct cec_notifier *)0xdeadfeed;
@@ -121,6 +125,23 @@ static inline void cec_register_cec_notifier(struct 
cec_adapter *adap,
 #endif
 
 /**
+ * cec_notifier_get - find or create a new cec_notifier for the given device.
+ * @dev: device that sends the events.
+ *
+ * If a notifier for device @dev already exists, then increase the refcount
+ * and return that notifier.
+ *
+ * If it doesn't exist, then allocate a new notifier struct and return a
+ * pointer to that new struct.
+ *
+ * Return NULL if the memory could not be allocated.
+ */
+static inline struct cec_notifier *cec_notifier_get(struct device *dev)
+{
+   return cec_notifier_get_conn(dev, NULL);
+}
+
+/**
  * cec_notifier_phys_addr_invalidate() - set the physical address to INVALID
  *
  * @n: the CEC notifier
-- 
2.7.4



[PATCH v2 2/5] drm/i915: hdmi: add CEC notifier to intel_hdmi

2018-05-15 Thread Neil Armstrong
This patchs adds the cec_notifier feature to the intel_hdmi part
of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate
between each HDMI ports.
The changes will allow the i915 HDMI code to notify EDID and HPD changes
to an eventual CEC adapter.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/gpu/drm/i915/Kconfig  |  1 +
 drivers/gpu/drm/i915/intel_drv.h  |  2 ++
 drivers/gpu/drm/i915/intel_hdmi.c | 12 
 3 files changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index dfd9588..2d65d56 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -23,6 +23,7 @@ config DRM_I915
select SYNC_FILE
select IOSF_MBI
select CRC32
+   select CEC_CORE if CEC_NOTIFIER
help
  Choose this option if you have a system that has "Intel Graphics
  Media Accelerator" or "HD Graphics" integrated graphics,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d436858..b50e51b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -39,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /**
  * __wait_for - magic wait macro
@@ -1001,6 +1002,7 @@ struct intel_hdmi {
bool has_audio;
bool rgb_quant_range_selectable;
struct intel_connector *attached_connector;
+   struct cec_notifier *notifier;
 };
 
 struct intel_dp_mst_encoder;
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
b/drivers/gpu/drm/i915/intel_hdmi.c
index 1baef4a..e98103d 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1868,6 +1868,8 @@ intel_hdmi_set_edid(struct drm_connector *connector)
connected = true;
}
 
+   cec_notifier_set_phys_addr_from_edid(intel_hdmi->notifier, edid);
+
return connected;
 }
 
@@ -1876,6 +1878,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool 
force)
 {
enum drm_connector_status status;
struct drm_i915_private *dev_priv = to_i915(connector->dev);
+   struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
  connector->base.id, connector->name);
@@ -1891,6 +1894,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool 
force)
 
intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
 
+   if (status != connector_status_connected)
+   cec_notifier_phys_addr_invalidate(intel_hdmi->notifier);
+
return status;
 }
 
@@ -2031,6 +2037,8 @@ static void chv_hdmi_pre_enable(struct intel_encoder 
*encoder,
 
 static void intel_hdmi_destroy(struct drm_connector *connector)
 {
+   if (intel_attached_hdmi(connector)->notifier)
+   cec_notifier_put(intel_attached_hdmi(connector)->notifier);
kfree(to_intel_connector(connector)->detect_edid);
drm_connector_cleanup(connector);
kfree(connector);
@@ -2358,6 +2366,10 @@ void intel_hdmi_init_connector(struct intel_digital_port 
*intel_dig_port,
u32 temp = I915_READ(PEG_BAND_GAP_DATA);
I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
}
+
+   intel_hdmi->notifier = cec_notifier_get_conn(dev->dev, connector->name);
+   if (!intel_hdmi->notifier)
+   DRM_DEBUG_KMS("CEC notifier get failed\n");
 }
 
 void intel_hdmi_init(struct drm_i915_private *dev_priv,
-- 
2.7.4



[PATCH v2 3/5] mfd: cros-ec: Introduce CEC commands and events definitions.

2018-05-15 Thread Neil Armstrong
The EC can expose a CEC bus, this patch adds the CEC related definitions
needed by the cros-ec-cec driver.
Having a 16 byte mkbp event size makes it possible to send CEC
messages from the EC to the AP directly inside the mkbp event
instead of first doing a notification and then a read.

Signed-off-by: Stefan Adolfsson <sadolfs...@chromium.org>
Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/platform/chrome/cros_ec_proto.c | 42 +
 include/linux/mfd/cros_ec.h |  2 +-
 include/linux/mfd/cros_ec_commands.h| 80 +
 3 files changed, 114 insertions(+), 10 deletions(-)

diff --git a/drivers/platform/chrome/cros_ec_proto.c 
b/drivers/platform/chrome/cros_ec_proto.c
index e7bbdf9..ba47f79 100644
--- a/drivers/platform/chrome/cros_ec_proto.c
+++ b/drivers/platform/chrome/cros_ec_proto.c
@@ -504,29 +504,53 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev,
 }
 EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
 
+static int get_next_event_xfer(struct cros_ec_device *ec_dev,
+  struct cros_ec_command *msg,
+  int version, uint32_t size)
+{
+   int ret;
+
+   msg->version = version;
+   msg->command = EC_CMD_GET_NEXT_EVENT;
+   msg->insize = size;
+   msg->outsize = 0;
+
+   ret = cros_ec_cmd_xfer(ec_dev, msg);
+   if (ret > 0) {
+   ec_dev->event_size = ret - 1;
+   memcpy(_dev->event_data, msg->data, size);
+   }
+
+   return ret;
+}
+
 static int get_next_event(struct cros_ec_device *ec_dev)
 {
u8 buffer[sizeof(struct cros_ec_command) + sizeof(ec_dev->event_data)];
struct cros_ec_command *msg = (struct cros_ec_command *)
+   static int cmd_version = 1;
int ret;
 
+   BUILD_BUG_ON(sizeof(union ec_response_get_next_data_v1) != 16);
+
if (ec_dev->suspended) {
dev_dbg(ec_dev->dev, "Device suspended.\n");
return -EHOSTDOWN;
}
 
-   msg->version = 0;
-   msg->command = EC_CMD_GET_NEXT_EVENT;
-   msg->insize = sizeof(ec_dev->event_data);
-   msg->outsize = 0;
+   if (cmd_version == 1) {
+   ret = get_next_event_xfer(ec_dev, msg, cmd_version,
+ sizeof(ec_dev->event_data));
+   if (ret != EC_RES_INVALID_VERSION)
+   return ret;
 
-   ret = cros_ec_cmd_xfer(ec_dev, msg);
-   if (ret > 0) {
-   ec_dev->event_size = ret - 1;
-   memcpy(_dev->event_data, msg->data,
-  sizeof(ec_dev->event_data));
+   /* Fallback to version 0 for future send attempts */
+   cmd_version = 0;
}
 
+   ret = get_next_event_xfer(ec_dev, msg, cmd_version,
+ sizeof(struct ec_response_get_next_event));
+
return ret;
 }
 
diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h
index 2d4e23c..f3415eb 100644
--- a/include/linux/mfd/cros_ec.h
+++ b/include/linux/mfd/cros_ec.h
@@ -147,7 +147,7 @@ struct cros_ec_device {
bool mkbp_event_supported;
struct blocking_notifier_head event_notifier;
 
-   struct ec_response_get_next_event event_data;
+   struct ec_response_get_next_event_v1 event_data;
int event_size;
u32 host_event_wake_mask;
 };
diff --git a/include/linux/mfd/cros_ec_commands.h 
b/include/linux/mfd/cros_ec_commands.h
index f2edd99..18df466 100644
--- a/include/linux/mfd/cros_ec_commands.h
+++ b/include/linux/mfd/cros_ec_commands.h
@@ -804,6 +804,8 @@ enum ec_feature_code {
EC_FEATURE_MOTION_SENSE_FIFO = 24,
/* EC has RTC feature that can be controlled by host commands */
EC_FEATURE_RTC = 27,
+   /* EC supports CEC commands */
+   EC_FEATURE_CEC = 35,
 };
 
 #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32))
@@ -2078,6 +2080,12 @@ enum ec_mkbp_event {
/* EC sent a sysrq command */
EC_MKBP_EVENT_SYSRQ = 6,
 
+   /* Notify the AP that something happened on CEC */
+   EC_MKBP_CEC_EVENT = 8,
+
+   /* Send an incoming CEC message to the AP */
+   EC_MKBP_EVENT_CEC_MESSAGE = 9,
+
/* Number of MKBP events */
EC_MKBP_EVENT_COUNT,
 };
@@ -2093,12 +2101,31 @@ union ec_response_get_next_data {
uint32_t   sysrq;
 } __packed;
 
+union ec_response_get_next_data_v1 {
+   uint8_t   key_matrix[16];
+
+   /* Unaligned */
+   uint32_t  host_event;
+
+   uint32_t   buttons;
+   uint32_t   switches;
+   uint32_t   sysrq;
+   uint32_t   cec_events;
+   uint8_tcec_message[16];
+} __packed;
+
 struct ec_response_get_next_event {
uint8_t event_type;
/* Followed by event data if any */
union ec_response_get_next_data data;
 } __packed;
 
+struct ec_res

[PATCH v2 4/5] mfd: cros_ec_dev: Add CEC sub-device registration

2018-05-15 Thread Neil Armstrong
The EC can expose a CEC bus, thus add the cros-ec-cec MFD sub-device
when the CEC feature bit is present.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/mfd/cros_ec_dev.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c
index eafd06f..57064ec 100644
--- a/drivers/mfd/cros_ec_dev.c
+++ b/drivers/mfd/cros_ec_dev.c
@@ -383,6 +383,18 @@ static void cros_ec_sensors_register(struct cros_ec_dev 
*ec)
kfree(msg);
 }
 
+static void cros_ec_cec_register(struct cros_ec_dev *ec)
+{
+   int ret;
+   struct mfd_cell cec_cell = {
+   .name = "cros-ec-cec",
+   };
+
+   ret = mfd_add_devices(ec->dev, 0, _cell, 1, NULL, 0, NULL);
+   if (ret)
+   dev_err(ec->dev, "failed to add EC CEC\n");
+}
+
 static int ec_device_probe(struct platform_device *pdev)
 {
int retval = -ENOMEM;
@@ -422,6 +434,10 @@ static int ec_device_probe(struct platform_device *pdev)
if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE))
cros_ec_sensors_register(ec);
 
+   /* check whether this EC handles CEC. */
+   if (cros_ec_check_features(ec, EC_FEATURE_CEC))
+   cros_ec_cec_register(ec);
+
/* Take control of the lightbar from the EC. */
lb_manual_suspend_ctrl(ec, 1);
 
-- 
2.7.4



[PATCH v2 5/5] media: platform: Add Chrome OS EC CEC driver

2018-05-15 Thread Neil Armstrong
The Chrome OS Embedded Controller can expose a CEC bus, this patch add the
driver for such feature of the Embedded Controller.

This driver is part of the cros-ec MFD and will be add as a sub-device when
the feature bit is exposed by the EC.

The controller will only handle a single logical address and handles
all the messages retries and will only expose Success or Error.

The controller will be tied to the HDMI CEC notifier by using the platform
DMI Data and the i915 device name and connector name.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/media/platform/Kconfig   |  11 +
 drivers/media/platform/Makefile  |   2 +
 drivers/media/platform/cros-ec-cec/Makefile  |   1 +
 drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 335 +++
 4 files changed, 349 insertions(+)
 create mode 100644 drivers/media/platform/cros-ec-cec/Makefile
 create mode 100644 drivers/media/platform/cros-ec-cec/cros-ec-cec.c

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index c7a1cf8..e55a8ed2 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -546,6 +546,17 @@ menuconfig CEC_PLATFORM_DRIVERS
 
 if CEC_PLATFORM_DRIVERS
 
+config VIDEO_CROS_EC_CEC
+   tristate "Chrome OS EC CEC driver"
+   depends on MFD_CROS_EC || COMPILE_TEST
+   select CEC_CORE
+   select CEC_NOTIFIER
+   ---help---
+ If you say yes here you will get support for the
+ Chrome OS Embedded Controller's CEC.
+ The CEC bus is present in the HDMI connector and enables communication
+ between compatible devices.
+
 config VIDEO_MESON_AO_CEC
tristate "Amlogic Meson AO CEC driver"
depends on ARCH_MESON || COMPILE_TEST
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 932515d..830696f 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -92,3 +92,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS)+= 
qcom/camss-8x16/
 obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/
 
 obj-y  += meson/
+
+obj-y  += cros-ec-cec/
diff --git a/drivers/media/platform/cros-ec-cec/Makefile 
b/drivers/media/platform/cros-ec-cec/Makefile
new file mode 100644
index 000..9ce97f9
--- /dev/null
+++ b/drivers/media/platform/cros-ec-cec/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VIDEO_CROS_EC_CEC) += cros-ec-cec.o
diff --git a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c 
b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
new file mode 100644
index 000..aed3368
--- /dev/null
+++ b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * CEC driver for Chrome OS Embedded Controller
+ *
+ * Copyright (c) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstr...@baylibre.com>
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DRV_NAME   "cros-ec-cec"
+
+/**
+ * struct cros_ec_cec - Driver data for EC CEC
+ *
+ * @cros_ec: Pointer to EC device
+ * @notifier: Notifier info for responding to EC events
+ * @adap: CEC adapter
+ * @notify: CEC notifier pointer
+ * @rx_msg: storage for a received message
+ */
+struct cros_ec_cec {
+   struct cros_ec_device *cros_ec;
+   struct notifier_block notifier;
+   struct cec_adapter *adap;
+   struct cec_notifier *notify;
+   struct cec_msg rx_msg;
+};
+
+static void handle_cec_message(struct cros_ec_cec *cros_ec_cec)
+{
+   struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
+   uint8_t *cec_message = cros_ec->event_data.data.cec_message;
+   unsigned int len = cros_ec->event_size;
+
+   cros_ec_cec->rx_msg.len = len;
+   memcpy(cros_ec_cec->rx_msg.msg, cec_message, len);
+
+   cec_received_msg(cros_ec_cec->adap, _ec_cec->rx_msg);
+}
+
+static void handle_cec_event(struct cros_ec_cec *cros_ec_cec)
+{
+   struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
+   uint32_t events = cros_ec->event_data.data.cec_events;
+
+   if (events & EC_MKBP_CEC_SEND_OK)
+   cec_transmit_attempt_done(cros_ec_cec->adap,
+ CEC_TX_STATUS_OK);
+
+   /* FW takes care of all retries, tell core to avoid more retries */
+   if (events & EC_MKBP_CEC_SEND_FAILED)
+   cec_transmit_attempt_done(cros_ec_cec->adap,
+ CEC_TX_STATUS_MAX_RETRIES |
+ CEC_TX_STATUS_NACK);
+}
+
+static int cros_ec_cec_event(struct notifier_block *nb,
+unsigned long queued_during_suspend,
+void *_notify)
+{
+   struct cros_ec_cec *cros_ec_cec;
+   struct cros_ec_dev

Re: [PATCH 2/5] drm/i915: hdmi: add CEC notifier to intel_hdmi

2018-05-15 Thread Neil Armstrong
Hi,

On 15/05/2018 14:56, Hans Verkuil wrote:
> On 05/15/18 14:46, Neil Armstrong wrote:
>> This patchs adds the cec_notifier feature to the intel_hdmi part
>> of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate
>> between each HDMI ports.
>> The changes will allow the i915 HDMI code to notify EDID and HPD changes
>> to an eventual CEC adapter.
> 
> You haven't figured yet out where to place the cec_notifier_put() call?
> Or did you forget?

I just figured it out, I was busy on the CEC driver and notifier, will re-spin 
a v2 with this and the other small fixes you requested.

Thanks,
Neil

> 
> Regards,
> 
>   Hans
> 
>>
>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
>> ---
>>  drivers/gpu/drm/i915/Kconfig  |  1 +
>>  drivers/gpu/drm/i915/intel_drv.h  |  2 ++
>>  drivers/gpu/drm/i915/intel_hdmi.c | 10 ++
>>  3 files changed, 13 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
>> index dfd9588..2d65d56 100644
>> --- a/drivers/gpu/drm/i915/Kconfig
>> +++ b/drivers/gpu/drm/i915/Kconfig
>> @@ -23,6 +23,7 @@ config DRM_I915
>>  select SYNC_FILE
>>  select IOSF_MBI
>>  select CRC32
>> +select CEC_CORE if CEC_NOTIFIER
>>  help
>>Choose this option if you have a system that has "Intel Graphics
>>Media Accelerator" or "HD Graphics" integrated graphics,
>> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
>> b/drivers/gpu/drm/i915/intel_drv.h
>> index d436858..b50e51b 100644
>> --- a/drivers/gpu/drm/i915/intel_drv.h
>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>> @@ -39,6 +39,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  
>>  /**
>>   * __wait_for - magic wait macro
>> @@ -1001,6 +1002,7 @@ struct intel_hdmi {
>>  bool has_audio;
>>  bool rgb_quant_range_selectable;
>>  struct intel_connector *attached_connector;
>> +struct cec_notifier *notifier;
>>  };
>>  
>>  struct intel_dp_mst_encoder;
>> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
>> b/drivers/gpu/drm/i915/intel_hdmi.c
>> index 1baef4a..9b94d72 100644
>> --- a/drivers/gpu/drm/i915/intel_hdmi.c
>> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
>> @@ -1868,6 +1868,8 @@ intel_hdmi_set_edid(struct drm_connector *connector)
>>  connected = true;
>>  }
>>  
>> +cec_notifier_set_phys_addr_from_edid(intel_hdmi->notifier, edid);
>> +
>>  return connected;
>>  }
>>  
>> @@ -1876,6 +1878,7 @@ intel_hdmi_detect(struct drm_connector *connector, 
>> bool force)
>>  {
>>  enum drm_connector_status status;
>>  struct drm_i915_private *dev_priv = to_i915(connector->dev);
>> +struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
>>  
>>  DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
>>connector->base.id, connector->name);
>> @@ -1891,6 +1894,9 @@ intel_hdmi_detect(struct drm_connector *connector, 
>> bool force)
>>  
>>  intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
>>  
>> +if (status != connector_status_connected)
>> +cec_notifier_phys_addr_invalidate(intel_hdmi->notifier);
>> +
>>  return status;
>>  }
>>  
>> @@ -2358,6 +2364,10 @@ void intel_hdmi_init_connector(struct 
>> intel_digital_port *intel_dig_port,
>>  u32 temp = I915_READ(PEG_BAND_GAP_DATA);
>>  I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
>>  }
>> +
>> +intel_hdmi->notifier = cec_notifier_get_conn(dev->dev, connector->name);
>> +if (!intel_hdmi->notifier)
>> +DRM_DEBUG_KMS("CEC notifier get failed\n");
>>  }
>>  
>>  void intel_hdmi_init(struct drm_i915_private *dev_priv,
>>
> 



[PATCH 0/5] Add ChromeOS EC CEC Support

2018-05-15 Thread Neil Armstrong
Hi All,

The new Google "Fizz" Intel-based ChromeOS device is gaining CEC support
throught it's Embedded Controller, to enable the Linux CEC Core to communicate
with it and get the CEC Physical Address from the correct HDMI Connector, the
following must be added/changed:
- Add the CEC sub-device registration in the ChromeOS EC MFD Driver
- Add the CEC related commands and events definitions into the EC MFD driver
- Add a way to get a CEC notifier with it's (optional) connector name
- Add the CEC notifier to the i915 HDMI driver
- Add the proper ChromeOS EC CEC Driver

The CEC notifier with the connector name is the tricky point, since even on
Device-Tree platforms, there is no way to distinguish between multiple HDMI
connectors from the same DRM driver. The solution I implemented is pretty
simple and only adds an optional connector name to eventually distinguish
an HDMI connector notifier from another if they share the same device.

Feel free to comment this patchset !

Changes since RFC:
 - Moved CEC sub-device registration after CEC commands and events definitions 
patch
 - Removed get_notifier_get_byname
 - Added CEC_CORE select into i915 Kconfig
 - Removed CEC driver fallback if notifier is not configured on HW, added 
explicit warn
 - Fixed CEC core return type on error
 - Moved to cros-ec-cec media platform directory
 - Use bus_find_device() to find the pci i915 device instead of 
get_notifier_get_byname()
 - Fix Logical Address setup
 - Added comment about HW support
 - Removed memset of msg structures

Neil Armstrong (5):
  media: cec-notifier: Get notifier by device and connector name
  drm/i915: hdmi: add CEC notifier to intel_hdmi
  mfd: cros-ec: Introduce CEC commands and events definitions.
  mfd: cros_ec_dev: Add CEC sub-device registration
  media: platform: Add Chrome OS EC CEC driver

 drivers/gpu/drm/i915/Kconfig |   1 +
 drivers/gpu/drm/i915/intel_drv.h |   2 +
 drivers/gpu/drm/i915/intel_hdmi.c|  10 +
 drivers/media/cec/cec-notifier.c |  12 +-
 drivers/media/platform/Kconfig   |  11 +
 drivers/media/platform/Makefile  |   2 +
 drivers/media/platform/cros-ec-cec/Makefile  |   1 +
 drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 336 +++
 drivers/mfd/cros_ec_dev.c|  16 ++
 drivers/platform/chrome/cros_ec_proto.c  |  42 ++-
 include/linux/mfd/cros_ec.h  |   2 +-
 include/linux/mfd/cros_ec_commands.h |  80 ++
 include/media/cec-notifier.h |  30 +-
 13 files changed, 530 insertions(+), 15 deletions(-)
 create mode 100644 drivers/media/platform/cros-ec-cec/Makefile
 create mode 100644 drivers/media/platform/cros-ec-cec/cros-ec-cec.c

-- 
2.7.4



[PATCH 5/5] media: platform: Add Chrome OS EC CEC driver

2018-05-15 Thread Neil Armstrong
The Chrome OS Embedded Controller can expose a CEC bus, this patch add the
driver for such feature of the Embedded Controller.

This driver is part of the cros-ec MFD and will be add as a sub-device when
the feature bit is exposed by the EC.

The controller will only handle a single logical address and handles
all the messages retries and will only expose Success or Error.

The controller will be tied to the HDMI CEC notifier by using the platform
DMI Data and the i915 device name and connector name.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/media/platform/Kconfig   |  11 +
 drivers/media/platform/Makefile  |   2 +
 drivers/media/platform/cros-ec-cec/Makefile  |   1 +
 drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 336 +++
 4 files changed, 350 insertions(+)
 create mode 100644 drivers/media/platform/cros-ec-cec/Makefile
 create mode 100644 drivers/media/platform/cros-ec-cec/cros-ec-cec.c

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index c7a1cf8..e55a8ed2 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -546,6 +546,17 @@ menuconfig CEC_PLATFORM_DRIVERS
 
 if CEC_PLATFORM_DRIVERS
 
+config VIDEO_CROS_EC_CEC
+   tristate "Chrome OS EC CEC driver"
+   depends on MFD_CROS_EC || COMPILE_TEST
+   select CEC_CORE
+   select CEC_NOTIFIER
+   ---help---
+ If you say yes here you will get support for the
+ Chrome OS Embedded Controller's CEC.
+ The CEC bus is present in the HDMI connector and enables communication
+ between compatible devices.
+
 config VIDEO_MESON_AO_CEC
tristate "Amlogic Meson AO CEC driver"
depends on ARCH_MESON || COMPILE_TEST
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 932515d..830696f 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -92,3 +92,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS)+= 
qcom/camss-8x16/
 obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/
 
 obj-y  += meson/
+
+obj-y  += cros-ec-cec/
diff --git a/drivers/media/platform/cros-ec-cec/Makefile 
b/drivers/media/platform/cros-ec-cec/Makefile
new file mode 100644
index 000..9ce97f9
--- /dev/null
+++ b/drivers/media/platform/cros-ec-cec/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VIDEO_CROS_EC_CEC) += cros-ec-cec.o
diff --git a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c 
b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
new file mode 100644
index 000..bbff5d6
--- /dev/null
+++ b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
@@ -0,0 +1,336 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * CEC driver for Chrome OS Embedded Controller
+ *
+ * Copyright (c) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstr...@baylibre.com>
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * This handles the CEC interface to the ChromeOS Embedded Controller,
+ * but only a single CEC line tied to a single HDMI output is handled now.
+ */
+
+#define DRV_NAME   "cros-ec-cec"
+
+/**
+ * struct cros_ec_cec - Driver data for EC CEC
+ *
+ * @cros_ec: Pointer to EC device
+ * @notifier: Notifier info for responding to EC events
+ * @adap: CEC adapter
+ * @notify: CEC notifier pointer
+ * @rx_msg: storage for a received message
+ */
+struct cros_ec_cec {
+   struct cros_ec_device *cros_ec;
+   struct notifier_block notifier;
+   struct cec_adapter *adap;
+   struct cec_notifier *notify;
+   struct cec_msg rx_msg;
+};
+
+static void handle_cec_message(struct cros_ec_cec *cros_ec_cec)
+{
+   struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
+   uint8_t *cec_message = cros_ec->event_data.data.cec_message;
+   unsigned int len = cros_ec->event_size;
+
+   cros_ec_cec->rx_msg.len = len;
+   memcpy(cros_ec_cec->rx_msg.msg, cec_message, len);
+
+   cec_received_msg(cros_ec_cec->adap, _ec_cec->rx_msg);
+}
+
+static void handle_cec_event(struct cros_ec_cec *cros_ec_cec)
+{
+   struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
+   uint32_t events = cros_ec->event_data.data.cec_events;
+
+   if (events & EC_MKBP_CEC_SEND_OK)
+   cec_transmit_attempt_done(cros_ec_cec->adap,
+ CEC_TX_STATUS_OK);
+
+   /* FW takes care of all retries, tell core to avoid more retries */
+   if (events & EC_MKBP_CEC_SEND_FAILED)
+   cec_transmit_attempt_done(cros_ec_cec->adap,
+ CEC_TX_STATUS_MAX_RETRIES |
+ CEC_TX_STATUS_NACK);
+}
+
+static int cros_ec_cec_event(struct notifier_block *nb,
+   unsigned lo

[PATCH 1/5] media: cec-notifier: Get notifier by device and connector name

2018-05-15 Thread Neil Armstrong
In non device-tree world, we can need to get the notifier by the driver
name directly and eventually defer probe if not yet created.

This patch adds a variant of the get function by using the device name
instead and will not create a notifier if not yet created.

But the i915 driver exposes at least 2 HDMI connectors, this patch also
adds the possibility to add a connector name tied to the notifier device
to form a tuple and associate different CEC controllers for each HDMI
connectors.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/media/cec/cec-notifier.c | 12 +---
 include/media/cec-notifier.h | 30 --
 2 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c
index 16dffa0..7038abae1 100644
--- a/drivers/media/cec/cec-notifier.c
+++ b/drivers/media/cec/cec-notifier.c
@@ -21,6 +21,7 @@ struct cec_notifier {
struct list_head head;
struct kref kref;
struct device *dev;
+   const char *conn;
struct cec_adapter *cec_adap;
void (*callback)(struct cec_adapter *adap, u16 pa);
 
@@ -30,13 +31,14 @@ struct cec_notifier {
 static LIST_HEAD(cec_notifiers);
 static DEFINE_MUTEX(cec_notifiers_lock);
 
-struct cec_notifier *cec_notifier_get(struct device *dev)
+struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char 
*conn)
 {
struct cec_notifier *n;
 
mutex_lock(_notifiers_lock);
list_for_each_entry(n, _notifiers, head) {
-   if (n->dev == dev) {
+   if (n->dev == dev &&
+   (!conn || !strcmp(n->conn, conn))) {
kref_get(>kref);
mutex_unlock(_notifiers_lock);
return n;
@@ -46,6 +48,8 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
if (!n)
goto unlock;
n->dev = dev;
+   if (conn)
+   n->conn = kstrdup(conn, GFP_KERNEL);
n->phys_addr = CEC_PHYS_ADDR_INVALID;
mutex_init(>lock);
kref_init(>kref);
@@ -54,7 +58,7 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
mutex_unlock(_notifiers_lock);
return n;
 }
-EXPORT_SYMBOL_GPL(cec_notifier_get);
+EXPORT_SYMBOL_GPL(cec_notifier_get_conn);
 
 static void cec_notifier_release(struct kref *kref)
 {
@@ -62,6 +66,8 @@ static void cec_notifier_release(struct kref *kref)
container_of(kref, struct cec_notifier, kref);
 
list_del(>head);
+   if (n->conn)
+   kfree(n->conn);
kfree(n);
 }
 
diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h
index cf0add7..73f92c7 100644
--- a/include/media/cec-notifier.h
+++ b/include/media/cec-notifier.h
@@ -20,6 +20,23 @@ struct cec_notifier;
 #if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER)
 
 /**
+ * cec_notifier_get_conn - find or create a new cec_notifier for the given
+ * device and connector tuple.
+ * @dev: device that sends the events.
+ * @conn: the connector name from which the event occurs
+ *
+ * If a notifier for device @dev already exists, then increase the refcount
+ * and return that notifier.
+ *
+ * If it doesn't exist, then allocate a new notifier struct and return a
+ * pointer to that new struct.
+ *
+ * Return NULL if the memory could not be allocated.
+ */
+struct cec_notifier *cec_notifier_get_conn(struct device *dev,
+  const char *conn);
+
+/**
  * cec_notifier_get - find or create a new cec_notifier for the given device.
  * @dev: device that sends the events.
  *
@@ -31,7 +48,10 @@ struct cec_notifier;
  *
  * Return NULL if the memory could not be allocated.
  */
-struct cec_notifier *cec_notifier_get(struct device *dev);
+static inline struct cec_notifier *cec_notifier_get(struct device *dev)
+{
+   return cec_notifier_get_conn(dev, NULL);
+}
 
 /**
  * cec_notifier_put - decrease refcount and delete when the refcount reaches 0.
@@ -85,12 +105,18 @@ void cec_register_cec_notifier(struct cec_adapter *adap,
   struct cec_notifier *notifier);
 
 #else
-static inline struct cec_notifier *cec_notifier_get(struct device *dev)
+static inline struct cec_notifier *cec_notifier_get_conn(struct device *dev,
+const char *conn)
 {
/* A non-NULL pointer is expected on success */
return (struct cec_notifier *)0xdeadfeed;
 }
 
+static inline struct cec_notifier *cec_notifier_get(struct device *dev)
+{
+   return cec_notifier_get_conn(dev, NULL);
+}
+
 static inline void cec_notifier_put(struct cec_notifier *n)
 {
 }
-- 
2.7.4



[PATCH 2/5] drm/i915: hdmi: add CEC notifier to intel_hdmi

2018-05-15 Thread Neil Armstrong
This patchs adds the cec_notifier feature to the intel_hdmi part
of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate
between each HDMI ports.
The changes will allow the i915 HDMI code to notify EDID and HPD changes
to an eventual CEC adapter.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/gpu/drm/i915/Kconfig  |  1 +
 drivers/gpu/drm/i915/intel_drv.h  |  2 ++
 drivers/gpu/drm/i915/intel_hdmi.c | 10 ++
 3 files changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index dfd9588..2d65d56 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -23,6 +23,7 @@ config DRM_I915
select SYNC_FILE
select IOSF_MBI
select CRC32
+   select CEC_CORE if CEC_NOTIFIER
help
  Choose this option if you have a system that has "Intel Graphics
  Media Accelerator" or "HD Graphics" integrated graphics,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d436858..b50e51b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -39,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /**
  * __wait_for - magic wait macro
@@ -1001,6 +1002,7 @@ struct intel_hdmi {
bool has_audio;
bool rgb_quant_range_selectable;
struct intel_connector *attached_connector;
+   struct cec_notifier *notifier;
 };
 
 struct intel_dp_mst_encoder;
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
b/drivers/gpu/drm/i915/intel_hdmi.c
index 1baef4a..9b94d72 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1868,6 +1868,8 @@ intel_hdmi_set_edid(struct drm_connector *connector)
connected = true;
}
 
+   cec_notifier_set_phys_addr_from_edid(intel_hdmi->notifier, edid);
+
return connected;
 }
 
@@ -1876,6 +1878,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool 
force)
 {
enum drm_connector_status status;
struct drm_i915_private *dev_priv = to_i915(connector->dev);
+   struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
  connector->base.id, connector->name);
@@ -1891,6 +1894,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool 
force)
 
intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
 
+   if (status != connector_status_connected)
+   cec_notifier_phys_addr_invalidate(intel_hdmi->notifier);
+
return status;
 }
 
@@ -2358,6 +2364,10 @@ void intel_hdmi_init_connector(struct intel_digital_port 
*intel_dig_port,
u32 temp = I915_READ(PEG_BAND_GAP_DATA);
I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
}
+
+   intel_hdmi->notifier = cec_notifier_get_conn(dev->dev, connector->name);
+   if (!intel_hdmi->notifier)
+   DRM_DEBUG_KMS("CEC notifier get failed\n");
 }
 
 void intel_hdmi_init(struct drm_i915_private *dev_priv,
-- 
2.7.4



[PATCH 3/5] mfd: cros-ec: Introduce CEC commands and events definitions.

2018-05-15 Thread Neil Armstrong
The EC can expose a CEC bus, this patch adds the CEC related definitions
needed by the cros-ec-cec driver.
Having a 16 byte mkbp event size makes it possible to send CEC
messages from the EC to the AP directly inside the mkbp event
instead of first doing a notification and then a read.

Signed-off-by: Stefan Adolfsson <sadolfs...@chromium.org>
Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/platform/chrome/cros_ec_proto.c | 42 +
 include/linux/mfd/cros_ec.h |  2 +-
 include/linux/mfd/cros_ec_commands.h| 80 +
 3 files changed, 114 insertions(+), 10 deletions(-)

diff --git a/drivers/platform/chrome/cros_ec_proto.c 
b/drivers/platform/chrome/cros_ec_proto.c
index e7bbdf9..ba47f79 100644
--- a/drivers/platform/chrome/cros_ec_proto.c
+++ b/drivers/platform/chrome/cros_ec_proto.c
@@ -504,29 +504,53 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev,
 }
 EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
 
+static int get_next_event_xfer(struct cros_ec_device *ec_dev,
+  struct cros_ec_command *msg,
+  int version, uint32_t size)
+{
+   int ret;
+
+   msg->version = version;
+   msg->command = EC_CMD_GET_NEXT_EVENT;
+   msg->insize = size;
+   msg->outsize = 0;
+
+   ret = cros_ec_cmd_xfer(ec_dev, msg);
+   if (ret > 0) {
+   ec_dev->event_size = ret - 1;
+   memcpy(_dev->event_data, msg->data, size);
+   }
+
+   return ret;
+}
+
 static int get_next_event(struct cros_ec_device *ec_dev)
 {
u8 buffer[sizeof(struct cros_ec_command) + sizeof(ec_dev->event_data)];
struct cros_ec_command *msg = (struct cros_ec_command *)
+   static int cmd_version = 1;
int ret;
 
+   BUILD_BUG_ON(sizeof(union ec_response_get_next_data_v1) != 16);
+
if (ec_dev->suspended) {
dev_dbg(ec_dev->dev, "Device suspended.\n");
return -EHOSTDOWN;
}
 
-   msg->version = 0;
-   msg->command = EC_CMD_GET_NEXT_EVENT;
-   msg->insize = sizeof(ec_dev->event_data);
-   msg->outsize = 0;
+   if (cmd_version == 1) {
+   ret = get_next_event_xfer(ec_dev, msg, cmd_version,
+ sizeof(ec_dev->event_data));
+   if (ret != EC_RES_INVALID_VERSION)
+   return ret;
 
-   ret = cros_ec_cmd_xfer(ec_dev, msg);
-   if (ret > 0) {
-   ec_dev->event_size = ret - 1;
-   memcpy(_dev->event_data, msg->data,
-  sizeof(ec_dev->event_data));
+   /* Fallback to version 0 for future send attempts */
+   cmd_version = 0;
}
 
+   ret = get_next_event_xfer(ec_dev, msg, cmd_version,
+ sizeof(struct ec_response_get_next_event));
+
return ret;
 }
 
diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h
index 2d4e23c..f3415eb 100644
--- a/include/linux/mfd/cros_ec.h
+++ b/include/linux/mfd/cros_ec.h
@@ -147,7 +147,7 @@ struct cros_ec_device {
bool mkbp_event_supported;
struct blocking_notifier_head event_notifier;
 
-   struct ec_response_get_next_event event_data;
+   struct ec_response_get_next_event_v1 event_data;
int event_size;
u32 host_event_wake_mask;
 };
diff --git a/include/linux/mfd/cros_ec_commands.h 
b/include/linux/mfd/cros_ec_commands.h
index f2edd99..18df466 100644
--- a/include/linux/mfd/cros_ec_commands.h
+++ b/include/linux/mfd/cros_ec_commands.h
@@ -804,6 +804,8 @@ enum ec_feature_code {
EC_FEATURE_MOTION_SENSE_FIFO = 24,
/* EC has RTC feature that can be controlled by host commands */
EC_FEATURE_RTC = 27,
+   /* EC supports CEC commands */
+   EC_FEATURE_CEC = 35,
 };
 
 #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32))
@@ -2078,6 +2080,12 @@ enum ec_mkbp_event {
/* EC sent a sysrq command */
EC_MKBP_EVENT_SYSRQ = 6,
 
+   /* Notify the AP that something happened on CEC */
+   EC_MKBP_CEC_EVENT = 8,
+
+   /* Send an incoming CEC message to the AP */
+   EC_MKBP_EVENT_CEC_MESSAGE = 9,
+
/* Number of MKBP events */
EC_MKBP_EVENT_COUNT,
 };
@@ -2093,12 +2101,31 @@ union ec_response_get_next_data {
uint32_t   sysrq;
 } __packed;
 
+union ec_response_get_next_data_v1 {
+   uint8_t   key_matrix[16];
+
+   /* Unaligned */
+   uint32_t  host_event;
+
+   uint32_t   buttons;
+   uint32_t   switches;
+   uint32_t   sysrq;
+   uint32_t   cec_events;
+   uint8_tcec_message[16];
+} __packed;
+
 struct ec_response_get_next_event {
uint8_t event_type;
/* Followed by event data if any */
union ec_response_get_next_data data;
 } __packed;
 
+struct ec_res

[PATCH 4/5] mfd: cros_ec_dev: Add CEC sub-device registration

2018-05-15 Thread Neil Armstrong
The EC can expose a CEC bus, thus add the cros-ec-cec MFD sub-device
when the CEC feature bit is present.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/mfd/cros_ec_dev.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c
index eafd06f..57064ec 100644
--- a/drivers/mfd/cros_ec_dev.c
+++ b/drivers/mfd/cros_ec_dev.c
@@ -383,6 +383,18 @@ static void cros_ec_sensors_register(struct cros_ec_dev 
*ec)
kfree(msg);
 }
 
+static void cros_ec_cec_register(struct cros_ec_dev *ec)
+{
+   int ret;
+   struct mfd_cell cec_cell = {
+   .name = "cros-ec-cec",
+   };
+
+   ret = mfd_add_devices(ec->dev, 0, _cell, 1, NULL, 0, NULL);
+   if (ret)
+   dev_err(ec->dev, "failed to add EC CEC\n");
+}
+
 static int ec_device_probe(struct platform_device *pdev)
 {
int retval = -ENOMEM;
@@ -422,6 +434,10 @@ static int ec_device_probe(struct platform_device *pdev)
if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE))
cros_ec_sensors_register(ec);
 
+   /* check whether this EC handles CEC. */
+   if (cros_ec_check_features(ec, EC_FEATURE_CEC))
+   cros_ec_cec_register(ec);
+
/* Take control of the lightbar from the EC. */
lb_manual_suspend_ctrl(ec, 1);
 
-- 
2.7.4



Re: [RFC PATCH 5/5] media: platform: Add Chrome OS EC CEC driver

2018-05-15 Thread Neil Armstrong
On 15/05/2018 10:10, Hans Verkuil wrote:
> On 05/15/18 09:25, Neil Armstrong wrote:
>> Hi Hans,
>>
>> Thanks for the extensive review.
>>
>> On 15/05/2018 08:58, Hans Verkuil wrote:
>>> On 05/15/2018 12:40 AM, Neil Armstrong wrote:
>>>> The Chrome OS Embedded Controller can expose a CEC bus, this patch add the
>>>> driver for such feature of the Embedded Controller.
>>>>
>>>> This driver is part of the cros-ec MFD and will be add as a sub-device when
>>>> the feature bit is exposed by the EC.
>>>>
>>>> The controller will only handle a single logical address and handles
>>>> all the messages retries and will only expose Success or Error.
>>>>
>>>> When the logical address is invalid, the controller will act as a CEC 
>>>> sniffer
>>>> and transfer all messages on the bus.
>>>
>>> I did not see any support for this. If this works as you state here, then 
>>> adding
>>> support for CEC_CAP_MONITOR_ALL is highly recommended.
>>
>> Oops, I forgot to remove this phrase, the FW will maybe support it, but it 
>> has been
>> dropped for the first revision.
>>
>>>
>>>>
>>>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
>>>> ---
>>>>  drivers/media/platform/Kconfig   |  11 +
>>>>  drivers/media/platform/Makefile  |   2 +
>>>>  drivers/media/platform/cros-ec/Makefile  |   1 +
>>>>  drivers/media/platform/cros-ec/cros-ec-cec.c | 331 
>>>> +++
>>>>  4 files changed, 345 insertions(+)
>>>>  create mode 100644 drivers/media/platform/cros-ec/Makefile
>>>>  create mode 100644 drivers/media/platform/cros-ec/cros-ec-cec.c
>>>
>>> Shouldn't the directory be called cros-ec-cec?

Forgot this one, moved to cros-ec-cec directory.

>>>
>>>>
>>>> diff --git a/drivers/media/platform/Kconfig 
>>>> b/drivers/media/platform/Kconfig
>>>> index c7a1cf8..e55a8ed2 100644
>>>> --- a/drivers/media/platform/Kconfig
>>>> +++ b/drivers/media/platform/Kconfig
>>>> @@ -546,6 +546,17 @@ menuconfig CEC_PLATFORM_DRIVERS
>>>>  
>>>>  if CEC_PLATFORM_DRIVERS
>>>>  
>>>> +config VIDEO_CROS_EC_CEC
>>>> +  tristate "Chrome OS EC CEC driver"
>>>> +  depends on MFD_CROS_EC || COMPILE_TEST
>>>> +  select CEC_CORE
>>>> +  select CEC_NOTIFIER
>>>> +  ---help---
>>>> +If you say yes here you will get support for the
>>>> +Chrome OS Embedded Controller's CEC.
>>>> +The CEC bus is present in the HDMI connector and enables communication
>>>> +between compatible devices.
>>>> +
>>>>  config VIDEO_MESON_AO_CEC
>>>>tristate "Amlogic Meson AO CEC driver"
>>>>depends on ARCH_MESON || COMPILE_TEST
>>>> diff --git a/drivers/media/platform/Makefile 
>>>> b/drivers/media/platform/Makefile
>>>> index 932515d..0e0582e 100644
>>>> --- a/drivers/media/platform/Makefile
>>>> +++ b/drivers/media/platform/Makefile
>>>> @@ -92,3 +92,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS)   += 
>>>> qcom/camss-8x16/
>>>>  obj-$(CONFIG_VIDEO_QCOM_VENUS)+= qcom/venus/
>>>>  
>>>>  obj-y     += meson/
>>>> +
>>>> +obj-y += cros-ec/
>>>> diff --git a/drivers/media/platform/cros-ec/Makefile 
>>>> b/drivers/media/platform/cros-ec/Makefile
>>>> new file mode 100644
>>>> index 000..9ce97f9
>>>> --- /dev/null
>>>> +++ b/drivers/media/platform/cros-ec/Makefile
>>>> @@ -0,0 +1 @@
>>>> +obj-$(CONFIG_VIDEO_CROS_EC_CEC) += cros-ec-cec.o
>>>> diff --git a/drivers/media/platform/cros-ec/cros-ec-cec.c 
>>>> b/drivers/media/platform/cros-ec/cros-ec-cec.c
>>>> new file mode 100644
>>>> index 000..fea90da
>>>> --- /dev/null
>>>> +++ b/drivers/media/platform/cros-ec/cros-ec-cec.c
>>>> @@ -0,0 +1,331 @@
>>>> +// SPDX-License-Identifier: GPL-2.0+
>>>> +/*
>>>> + * CEC driver for Chrome OS Embedded Controller
>>>> + *
>>>> + * Copyright (c) 2018 BayLibre, SAS
>>>> + * Author: Neil Armstrong <narmstr...@baylibre.com>
>&g

Re: [RFC PATCH 3/5] drm/i915: hdmi: add CEC notifier to intel_hdmi

2018-05-15 Thread Neil Armstrong
On 15/05/2018 08:29, Hans Verkuil wrote:
> On 05/15/2018 12:40 AM, Neil Armstrong wrote:
>> This patchs adds the cec_notifier feature to the intel_hdmi part
>> of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate
>> between each HDMI ports.
>> The changes will allow the i915 HDMI code to notify EDID and HPD changes
>> to an eventual CEC adapter.
>>
>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
>> ---
>>  drivers/gpu/drm/i915/intel_drv.h  |  2 ++
>>  drivers/gpu/drm/i915/intel_hdmi.c | 10 ++
>>  2 files changed, 12 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
>> b/drivers/gpu/drm/i915/intel_drv.h
>> index d436858..b50e51b 100644
>> --- a/drivers/gpu/drm/i915/intel_drv.h
>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>> @@ -39,6 +39,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  
>>  /**
>>   * __wait_for - magic wait macro
>> @@ -1001,6 +1002,7 @@ struct intel_hdmi {
>>  bool has_audio;
>>  bool rgb_quant_range_selectable;
>>  struct intel_connector *attached_connector;
>> +struct cec_notifier *notifier;
>>  };
>>  
>>  struct intel_dp_mst_encoder;
>> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
>> b/drivers/gpu/drm/i915/intel_hdmi.c
>> index 1baef4a..9b94d72 100644
>> --- a/drivers/gpu/drm/i915/intel_hdmi.c
>> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
>> @@ -1868,6 +1868,8 @@ intel_hdmi_set_edid(struct drm_connector *connector)
>>  connected = true;
>>  }
>>  
>> +cec_notifier_set_phys_addr_from_edid(intel_hdmi->notifier, edid);
>> +
>>  return connected;
>>  }
>>  
>> @@ -1876,6 +1878,7 @@ intel_hdmi_detect(struct drm_connector *connector, 
>> bool force)
>>  {
>>  enum drm_connector_status status;
>>  struct drm_i915_private *dev_priv = to_i915(connector->dev);
>> +struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
>>  
>>  DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
>>connector->base.id, connector->name);
>> @@ -1891,6 +1894,9 @@ intel_hdmi_detect(struct drm_connector *connector, 
>> bool force)
>>  
>>  intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
>>  
>> +if (status != connector_status_connected)
>> +cec_notifier_phys_addr_invalidate(intel_hdmi->notifier);
>> +
>>  return status;
>>  }
>>  
>> @@ -2358,6 +2364,10 @@ void intel_hdmi_init_connector(struct 
>> intel_digital_port *intel_dig_port,
>>  u32 temp = I915_READ(PEG_BAND_GAP_DATA);
>>  I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
>>  }
>> +
>> +intel_hdmi->notifier = cec_notifier_get_conn(dev->dev, connector->name);
>> +if (!intel_hdmi->notifier)
>> +DRM_DEBUG_KMS("CEC notifier get failed\n");
> 
> You 'get' the notifier here, but where is the cec_notifier_put when the 
> connector is deleted?

Because I failed to find a safe place for this !

I will have a second look...

> 
> Regards,
> 
>   Hans
> 
>>  }
>>  
>>  void intel_hdmi_init(struct drm_i915_private *dev_priv,
>>
> 



Re: [RFC PATCH 3/5] drm/i915: hdmi: add CEC notifier to intel_hdmi

2018-05-15 Thread Neil Armstrong
On 15/05/2018 08:34, Hans Verkuil wrote:
> On 05/15/2018 12:40 AM, Neil Armstrong wrote:
>> This patchs adds the cec_notifier feature to the intel_hdmi part
>> of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate
>> between each HDMI ports.
>> The changes will allow the i915 HDMI code to notify EDID and HPD changes
>> to an eventual CEC adapter.
>>
>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
>> ---
>>  drivers/gpu/drm/i915/intel_drv.h  |  2 ++
>>  drivers/gpu/drm/i915/intel_hdmi.c | 10 ++
> 
> The Kconfig also needs to be changed. In the DRM_I915 you need to add:
> 
>   select CEC_CORE if CEC_NOTIFIER

OK, thanks

> 
> Otherwise you'll get problems if the cec driver is a module and i915 is 
> built-in.
> 
> Regards,
> 
>   Hans
> 



Re: [RFC PATCH 2/5] media: cec-notifier: Get notifier by device and connector name

2018-05-15 Thread Neil Armstrong
On 15/05/2018 08:27, Hans Verkuil wrote:
> Hi Neil,
> 
> Thanks for this patch series!
> 
> Some comments below:
> 
> On 05/15/2018 12:40 AM, Neil Armstrong wrote:
>> In non device-tree world, we can need to get the notifier by the driver
>> name directly and eventually defer probe if not yet created.
>>
>> This patch adds a variant of the get function by using the device name
>> instead and will not create a notifier if not yet created.
>>
>> But the i915 driver exposes at least 2 HDMI connectors, this patch also
>> adds the possibility to add a connector name tied to the notifier device
>> to form a tuple and associate different CEC controllers for each HDMI
>> connectors.
>>
>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
>> ---
>>  drivers/media/cec/cec-notifier.c | 30 ---
>>  include/media/cec-notifier.h | 44 
>> ++--
>>  2 files changed, 69 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/media/cec/cec-notifier.c 
>> b/drivers/media/cec/cec-notifier.c
>> index 16dffa0..716070a 100644
>> --- a/drivers/media/cec/cec-notifier.c
>> +++ b/drivers/media/cec/cec-notifier.c
>> @@ -21,6 +21,7 @@ struct cec_notifier {
>>  struct list_head head;
>>  struct kref kref;
>>  struct device *dev;
>> +const char *conn;
>>  struct cec_adapter *cec_adap;
>>  void (*callback)(struct cec_adapter *adap, u16 pa);
>>  
>> @@ -30,13 +31,34 @@ struct cec_notifier {
>>  static LIST_HEAD(cec_notifiers);
>>  static DEFINE_MUTEX(cec_notifiers_lock);
>>  
>> -struct cec_notifier *cec_notifier_get(struct device *dev)
>> +struct cec_notifier *cec_notifier_get_byname(const char *name,
>> + const char *conn)
>>  {
>>  struct cec_notifier *n;
>>  
>>  mutex_lock(_notifiers_lock);
>>  list_for_each_entry(n, _notifiers, head) {
>> -if (n->dev == dev) {
>> +if (!strcmp(dev_name(n->dev), name) &&
>> +(!conn || !strcmp(n->conn, conn))) {
>> +kref_get(>kref);
>> +mutex_unlock(_notifiers_lock);
>> +return n;
>> +}
>> +}
>> +mutex_unlock(_notifiers_lock);
>> +
>> +return NULL;
> 
> This doesn't seem right. For one it doesn't act like the other 
> cec_notifier_get*
> functions in that it doesn't make a new notifier if it wasn't found yet in the
> list.
> 
> For another, I think this function shouldn't be here at all. How about calling
> bus_find_device_by_name(), then use cec_notifier_get_conn()?

Yes, it's safer and will keep the original cec_notifier_get() behavior.

> 
>> +}
>> +EXPORT_SYMBOL_GPL(cec_notifier_get_byname);
>> +
>> +struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char 
>> *conn)
>> +{
>> +struct cec_notifier *n;
>> +
>> +mutex_lock(_notifiers_lock);
>> +list_for_each_entry(n, _notifiers, head) {
>> +if (n->dev == dev &&
>> +(!conn || !strcmp(n->conn, conn))) {
>>  kref_get(>kref);
>>  mutex_unlock(_notifiers_lock);
>>  return n;
>> @@ -46,6 +68,8 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
>>  if (!n)
>>  goto unlock;
>>  n->dev = dev;
>> +if (conn)
>> +n->conn = devm_kstrdup(dev, conn, GFP_KERNEL);
> 
> The use of devm_kstrdup worries me. The problem is that when the 'dev' device
> is removed, this memory is also automatically freed. But the notifier might
> still have a reference through the CEC driver, so you end up with a n->conn
> pointer that points to freed memory.
> 
> I think it is better to just use kstrdup and kfree it when the last notifier
> reference is released.

Ok

> 
>>  n->phys_addr = CEC_PHYS_ADDR_INVALID;
>>  mutex_init(>lock);
>>  kref_init(>kref);
>> @@ -54,7 +78,7 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
>>  mutex_unlock(_notifiers_lock);
>>  return n;
>>  }
>> -EXPORT_SYMBOL_GPL(cec_notifier_get);
>> +EXPORT_SYMBOL_GPL(cec_notifier_get_conn);
>>  
>>  static void cec_notifier_release(struct kref *kref)
>>  {
>> diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h
>> index cf0add7..70f2974 100644
>> --- a/include/media/cec-notifier.

Re: [RFC PATCH 5/5] media: platform: Add Chrome OS EC CEC driver

2018-05-15 Thread Neil Armstrong
Hi Hans,

Thanks for the extensive review.

On 15/05/2018 08:58, Hans Verkuil wrote:
> On 05/15/2018 12:40 AM, Neil Armstrong wrote:
>> The Chrome OS Embedded Controller can expose a CEC bus, this patch add the
>> driver for such feature of the Embedded Controller.
>>
>> This driver is part of the cros-ec MFD and will be add as a sub-device when
>> the feature bit is exposed by the EC.
>>
>> The controller will only handle a single logical address and handles
>> all the messages retries and will only expose Success or Error.
>>
>> When the logical address is invalid, the controller will act as a CEC sniffer
>> and transfer all messages on the bus.
> 
> I did not see any support for this. If this works as you state here, then 
> adding
> support for CEC_CAP_MONITOR_ALL is highly recommended.

Oops, I forgot to remove this phrase, the FW will maybe support it, but it has 
been
dropped for the first revision.

> 
>>
>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
>> ---
>>  drivers/media/platform/Kconfig   |  11 +
>>  drivers/media/platform/Makefile  |   2 +
>>  drivers/media/platform/cros-ec/Makefile  |   1 +
>>  drivers/media/platform/cros-ec/cros-ec-cec.c | 331 
>> +++
>>  4 files changed, 345 insertions(+)
>>  create mode 100644 drivers/media/platform/cros-ec/Makefile
>>  create mode 100644 drivers/media/platform/cros-ec/cros-ec-cec.c
> 
> Shouldn't the directory be called cros-ec-cec?
> 
>>
>> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
>> index c7a1cf8..e55a8ed2 100644
>> --- a/drivers/media/platform/Kconfig
>> +++ b/drivers/media/platform/Kconfig
>> @@ -546,6 +546,17 @@ menuconfig CEC_PLATFORM_DRIVERS
>>  
>>  if CEC_PLATFORM_DRIVERS
>>  
>> +config VIDEO_CROS_EC_CEC
>> +tristate "Chrome OS EC CEC driver"
>> +depends on MFD_CROS_EC || COMPILE_TEST
>> +select CEC_CORE
>> +select CEC_NOTIFIER
>> +---help---
>> +  If you say yes here you will get support for the
>> +  Chrome OS Embedded Controller's CEC.
>> +  The CEC bus is present in the HDMI connector and enables communication
>> +  between compatible devices.
>> +
>>  config VIDEO_MESON_AO_CEC
>>  tristate "Amlogic Meson AO CEC driver"
>>  depends on ARCH_MESON || COMPILE_TEST
>> diff --git a/drivers/media/platform/Makefile 
>> b/drivers/media/platform/Makefile
>> index 932515d..0e0582e 100644
>> --- a/drivers/media/platform/Makefile
>> +++ b/drivers/media/platform/Makefile
>> @@ -92,3 +92,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS) += 
>> qcom/camss-8x16/
>>  obj-$(CONFIG_VIDEO_QCOM_VENUS)  += qcom/venus/
>>  
>>  obj-y   += meson/
>> +
>> +obj-y   += cros-ec/
>> diff --git a/drivers/media/platform/cros-ec/Makefile 
>> b/drivers/media/platform/cros-ec/Makefile
>> new file mode 100644
>> index 000..9ce97f9
>> --- /dev/null
>> +++ b/drivers/media/platform/cros-ec/Makefile
>> @@ -0,0 +1 @@
>> +obj-$(CONFIG_VIDEO_CROS_EC_CEC) += cros-ec-cec.o
>> diff --git a/drivers/media/platform/cros-ec/cros-ec-cec.c 
>> b/drivers/media/platform/cros-ec/cros-ec-cec.c
>> new file mode 100644
>> index 000..fea90da
>> --- /dev/null
>> +++ b/drivers/media/platform/cros-ec/cros-ec-cec.c
>> @@ -0,0 +1,331 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * CEC driver for Chrome OS Embedded Controller
>> + *
>> + * Copyright (c) 2018 BayLibre, SAS
>> + * Author: Neil Armstrong <narmstr...@baylibre.com>
>> + */
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#define DRV_NAME"cros-ec-cec"
>> +
>> +/**
>> + * struct cros_ec_cec - Driver data for EC CEC
>> + *
>> + * @cros_ec: Pointer to EC device
>> + * @notifier: Notifier info for responding to EC events
>> + * @adap: CEC adapter
>> + * @notify: CEC notifier pointer
>> + * @rc_msg: storage for a received message
>> + */
>> +struct cros_ec_cec {
>> +struct cros_ec_device *cros_ec;
>> +struct notifier_block notifier;
>> +struct cec_adapter *adap;
>> +struct cec_notifier *notify;
>> +struct cec_msg rx_msg;
>> +};
>> +
>> +st

[RFC PATCH 0/5] Add ChromeOS EC CEC Support

2018-05-14 Thread Neil Armstrong
Hi All,

The new Google "Fizz" Intel-based ChromeOS device is gaining CEC support
throught it's Embedded Controller, to enable the Linux CEC Core to communicate
with it and get the CEC Physical Address from the correct HDMI Connector, the
following must be added/changed:
- Add the CEC sub-device registration in the ChromeOS EC MFD Driver
- Add the CEC related commands and events definitions into the EC MFD driver
- Add a way to get a CEC notifier with it's (optional) connector name
- Add the CEC notifier to the i915 HDMI driver
- Add the proper ChromeOS EC CEC Driver

The CEC notifier with the connector name is the tricky point, since even on
Device-Tree platforms, there is no way to distinguish between multiple HDMI
connectors from the same DRM driver. The solution I implemented is pretty
simple and only adds an optional connector name to eventually distinguish
an HDMI connector notifier from another if they share the same device.

Feel free to comment this patchset !

Neil Armstrong (5):
  mfd: cros_ec_dev: Add CEC sub-device registration
  media: cec-notifier: Get notifier by device and connector name
  drm/i915: hdmi: add CEC notifier to intel_hdmi
  mfd: cros-ec: Introduce CEC commands and events definitions.
  media: platform: Add Chrome OS EC CEC driver

 drivers/gpu/drm/i915/intel_drv.h |   2 +
 drivers/gpu/drm/i915/intel_hdmi.c|  10 +
 drivers/media/cec/cec-notifier.c |  30 ++-
 drivers/media/platform/Kconfig   |  11 +
 drivers/media/platform/Makefile  |   2 +
 drivers/media/platform/cros-ec/Makefile  |   1 +
 drivers/media/platform/cros-ec/cros-ec-cec.c | 331 +++
 drivers/mfd/cros_ec_dev.c|  16 ++
 drivers/platform/chrome/cros_ec_proto.c  |  42 +++-
 include/linux/mfd/cros_ec.h  |   2 +-
 include/linux/mfd/cros_ec_commands.h |  80 +++
 include/media/cec-notifier.h |  44 +++-
 12 files changed, 556 insertions(+), 15 deletions(-)
 create mode 100644 drivers/media/platform/cros-ec/Makefile
 create mode 100644 drivers/media/platform/cros-ec/cros-ec-cec.c

-- 
2.7.4



[RFC PATCH 1/5] mfd: cros_ec_dev: Add CEC sub-device registration

2018-05-14 Thread Neil Armstrong
The EC can expose a CEC bus, thus add the cros-ec-cec MFD sub-device
when the CEC feature bit is present.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/mfd/cros_ec_dev.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c
index eafd06f..57064ec 100644
--- a/drivers/mfd/cros_ec_dev.c
+++ b/drivers/mfd/cros_ec_dev.c
@@ -383,6 +383,18 @@ static void cros_ec_sensors_register(struct cros_ec_dev 
*ec)
kfree(msg);
 }
 
+static void cros_ec_cec_register(struct cros_ec_dev *ec)
+{
+   int ret;
+   struct mfd_cell cec_cell = {
+   .name = "cros-ec-cec",
+   };
+
+   ret = mfd_add_devices(ec->dev, 0, _cell, 1, NULL, 0, NULL);
+   if (ret)
+   dev_err(ec->dev, "failed to add EC CEC\n");
+}
+
 static int ec_device_probe(struct platform_device *pdev)
 {
int retval = -ENOMEM;
@@ -422,6 +434,10 @@ static int ec_device_probe(struct platform_device *pdev)
if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE))
cros_ec_sensors_register(ec);
 
+   /* check whether this EC handles CEC. */
+   if (cros_ec_check_features(ec, EC_FEATURE_CEC))
+   cros_ec_cec_register(ec);
+
/* Take control of the lightbar from the EC. */
lb_manual_suspend_ctrl(ec, 1);
 
-- 
2.7.4



[RFC PATCH 4/5] mfd: cros-ec: Introduce CEC commands and events definitions.

2018-05-14 Thread Neil Armstrong
From: Stefan Adolfsson <sadolfs...@chromium.org>

The EC can expose a CEC bus, this patch adds the CEC related definitions
needed by the cros-ec-cec driver.
Having a 16 byte mkbp event size makes it possible to send CEC
messages from the EC to the AP directly inside the mkbp event
instead of first doing a notification and then a read.

Signed-off-by: Stefan Adolfsson <sadolfs...@chromium.org>
Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/platform/chrome/cros_ec_proto.c | 42 +
 include/linux/mfd/cros_ec.h |  2 +-
 include/linux/mfd/cros_ec_commands.h| 80 +
 3 files changed, 114 insertions(+), 10 deletions(-)

diff --git a/drivers/platform/chrome/cros_ec_proto.c 
b/drivers/platform/chrome/cros_ec_proto.c
index e7bbdf9..ba47f79 100644
--- a/drivers/platform/chrome/cros_ec_proto.c
+++ b/drivers/platform/chrome/cros_ec_proto.c
@@ -504,29 +504,53 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev,
 }
 EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
 
+static int get_next_event_xfer(struct cros_ec_device *ec_dev,
+  struct cros_ec_command *msg,
+  int version, uint32_t size)
+{
+   int ret;
+
+   msg->version = version;
+   msg->command = EC_CMD_GET_NEXT_EVENT;
+   msg->insize = size;
+   msg->outsize = 0;
+
+   ret = cros_ec_cmd_xfer(ec_dev, msg);
+   if (ret > 0) {
+   ec_dev->event_size = ret - 1;
+   memcpy(_dev->event_data, msg->data, size);
+   }
+
+   return ret;
+}
+
 static int get_next_event(struct cros_ec_device *ec_dev)
 {
u8 buffer[sizeof(struct cros_ec_command) + sizeof(ec_dev->event_data)];
struct cros_ec_command *msg = (struct cros_ec_command *)
+   static int cmd_version = 1;
int ret;
 
+   BUILD_BUG_ON(sizeof(union ec_response_get_next_data_v1) != 16);
+
if (ec_dev->suspended) {
dev_dbg(ec_dev->dev, "Device suspended.\n");
return -EHOSTDOWN;
}
 
-   msg->version = 0;
-   msg->command = EC_CMD_GET_NEXT_EVENT;
-   msg->insize = sizeof(ec_dev->event_data);
-   msg->outsize = 0;
+   if (cmd_version == 1) {
+   ret = get_next_event_xfer(ec_dev, msg, cmd_version,
+ sizeof(ec_dev->event_data));
+   if (ret != EC_RES_INVALID_VERSION)
+   return ret;
 
-   ret = cros_ec_cmd_xfer(ec_dev, msg);
-   if (ret > 0) {
-   ec_dev->event_size = ret - 1;
-   memcpy(_dev->event_data, msg->data,
-  sizeof(ec_dev->event_data));
+   /* Fallback to version 0 for future send attempts */
+   cmd_version = 0;
}
 
+   ret = get_next_event_xfer(ec_dev, msg, cmd_version,
+ sizeof(struct ec_response_get_next_event));
+
return ret;
 }
 
diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h
index 2d4e23c..f3415eb 100644
--- a/include/linux/mfd/cros_ec.h
+++ b/include/linux/mfd/cros_ec.h
@@ -147,7 +147,7 @@ struct cros_ec_device {
bool mkbp_event_supported;
struct blocking_notifier_head event_notifier;
 
-   struct ec_response_get_next_event event_data;
+   struct ec_response_get_next_event_v1 event_data;
int event_size;
u32 host_event_wake_mask;
 };
diff --git a/include/linux/mfd/cros_ec_commands.h 
b/include/linux/mfd/cros_ec_commands.h
index f2edd99..18df466 100644
--- a/include/linux/mfd/cros_ec_commands.h
+++ b/include/linux/mfd/cros_ec_commands.h
@@ -804,6 +804,8 @@ enum ec_feature_code {
EC_FEATURE_MOTION_SENSE_FIFO = 24,
/* EC has RTC feature that can be controlled by host commands */
EC_FEATURE_RTC = 27,
+   /* EC supports CEC commands */
+   EC_FEATURE_CEC = 35,
 };
 
 #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32))
@@ -2078,6 +2080,12 @@ enum ec_mkbp_event {
/* EC sent a sysrq command */
EC_MKBP_EVENT_SYSRQ = 6,
 
+   /* Notify the AP that something happened on CEC */
+   EC_MKBP_CEC_EVENT = 8,
+
+   /* Send an incoming CEC message to the AP */
+   EC_MKBP_EVENT_CEC_MESSAGE = 9,
+
/* Number of MKBP events */
EC_MKBP_EVENT_COUNT,
 };
@@ -2093,12 +2101,31 @@ union ec_response_get_next_data {
uint32_t   sysrq;
 } __packed;
 
+union ec_response_get_next_data_v1 {
+   uint8_t   key_matrix[16];
+
+   /* Unaligned */
+   uint32_t  host_event;
+
+   uint32_t   buttons;
+   uint32_t   switches;
+   uint32_t   sysrq;
+   uint32_t   cec_events;
+   uint8_tcec_message[16];
+} __packed;
+
 struct ec_response_get_next_event {
uint8_t event_type;
/* Followed by event data if any */
union ec_response_g

[RFC PATCH 3/5] drm/i915: hdmi: add CEC notifier to intel_hdmi

2018-05-14 Thread Neil Armstrong
This patchs adds the cec_notifier feature to the intel_hdmi part
of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate
between each HDMI ports.
The changes will allow the i915 HDMI code to notify EDID and HPD changes
to an eventual CEC adapter.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/gpu/drm/i915/intel_drv.h  |  2 ++
 drivers/gpu/drm/i915/intel_hdmi.c | 10 ++
 2 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d436858..b50e51b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -39,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /**
  * __wait_for - magic wait macro
@@ -1001,6 +1002,7 @@ struct intel_hdmi {
bool has_audio;
bool rgb_quant_range_selectable;
struct intel_connector *attached_connector;
+   struct cec_notifier *notifier;
 };
 
 struct intel_dp_mst_encoder;
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
b/drivers/gpu/drm/i915/intel_hdmi.c
index 1baef4a..9b94d72 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1868,6 +1868,8 @@ intel_hdmi_set_edid(struct drm_connector *connector)
connected = true;
}
 
+   cec_notifier_set_phys_addr_from_edid(intel_hdmi->notifier, edid);
+
return connected;
 }
 
@@ -1876,6 +1878,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool 
force)
 {
enum drm_connector_status status;
struct drm_i915_private *dev_priv = to_i915(connector->dev);
+   struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
  connector->base.id, connector->name);
@@ -1891,6 +1894,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool 
force)
 
intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
 
+   if (status != connector_status_connected)
+   cec_notifier_phys_addr_invalidate(intel_hdmi->notifier);
+
return status;
 }
 
@@ -2358,6 +2364,10 @@ void intel_hdmi_init_connector(struct intel_digital_port 
*intel_dig_port,
u32 temp = I915_READ(PEG_BAND_GAP_DATA);
I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
}
+
+   intel_hdmi->notifier = cec_notifier_get_conn(dev->dev, connector->name);
+   if (!intel_hdmi->notifier)
+   DRM_DEBUG_KMS("CEC notifier get failed\n");
 }
 
 void intel_hdmi_init(struct drm_i915_private *dev_priv,
-- 
2.7.4



[RFC PATCH 2/5] media: cec-notifier: Get notifier by device and connector name

2018-05-14 Thread Neil Armstrong
In non device-tree world, we can need to get the notifier by the driver
name directly and eventually defer probe if not yet created.

This patch adds a variant of the get function by using the device name
instead and will not create a notifier if not yet created.

But the i915 driver exposes at least 2 HDMI connectors, this patch also
adds the possibility to add a connector name tied to the notifier device
to form a tuple and associate different CEC controllers for each HDMI
connectors.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/media/cec/cec-notifier.c | 30 ---
 include/media/cec-notifier.h | 44 ++--
 2 files changed, 69 insertions(+), 5 deletions(-)

diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c
index 16dffa0..716070a 100644
--- a/drivers/media/cec/cec-notifier.c
+++ b/drivers/media/cec/cec-notifier.c
@@ -21,6 +21,7 @@ struct cec_notifier {
struct list_head head;
struct kref kref;
struct device *dev;
+   const char *conn;
struct cec_adapter *cec_adap;
void (*callback)(struct cec_adapter *adap, u16 pa);
 
@@ -30,13 +31,34 @@ struct cec_notifier {
 static LIST_HEAD(cec_notifiers);
 static DEFINE_MUTEX(cec_notifiers_lock);
 
-struct cec_notifier *cec_notifier_get(struct device *dev)
+struct cec_notifier *cec_notifier_get_byname(const char *name,
+const char *conn)
 {
struct cec_notifier *n;
 
mutex_lock(_notifiers_lock);
list_for_each_entry(n, _notifiers, head) {
-   if (n->dev == dev) {
+   if (!strcmp(dev_name(n->dev), name) &&
+   (!conn || !strcmp(n->conn, conn))) {
+   kref_get(>kref);
+   mutex_unlock(_notifiers_lock);
+   return n;
+   }
+   }
+   mutex_unlock(_notifiers_lock);
+
+   return NULL;
+}
+EXPORT_SYMBOL_GPL(cec_notifier_get_byname);
+
+struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char 
*conn)
+{
+   struct cec_notifier *n;
+
+   mutex_lock(_notifiers_lock);
+   list_for_each_entry(n, _notifiers, head) {
+   if (n->dev == dev &&
+   (!conn || !strcmp(n->conn, conn))) {
kref_get(>kref);
mutex_unlock(_notifiers_lock);
return n;
@@ -46,6 +68,8 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
if (!n)
goto unlock;
n->dev = dev;
+   if (conn)
+   n->conn = devm_kstrdup(dev, conn, GFP_KERNEL);
n->phys_addr = CEC_PHYS_ADDR_INVALID;
mutex_init(>lock);
kref_init(>kref);
@@ -54,7 +78,7 @@ struct cec_notifier *cec_notifier_get(struct device *dev)
mutex_unlock(_notifiers_lock);
return n;
 }
-EXPORT_SYMBOL_GPL(cec_notifier_get);
+EXPORT_SYMBOL_GPL(cec_notifier_get_conn);
 
 static void cec_notifier_release(struct kref *kref)
 {
diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h
index cf0add7..70f2974 100644
--- a/include/media/cec-notifier.h
+++ b/include/media/cec-notifier.h
@@ -20,6 +20,37 @@ struct cec_notifier;
 #if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER)
 
 /**
+ * cec_notifier_get_byname - find a cec_notifier for the given device name
+ * and connector tuple.
+ * @name: device name that sends the events.
+ * @conn: the connector name from which the event occurs
+ *
+ * If a notifier for device @name exists, then increase the refcount and
+ * return that notifier.
+ *
+ * If it doesn't exist, return NULL
+ */
+struct cec_notifier *cec_notifier_get_byname(const char *name,
+const char *conn);
+
+/**
+ * cec_notifier_get_conn - find or create a new cec_notifier for the given
+ * device and connector tuple.
+ * @dev: device that sends the events.
+ * @conn: the connector name from which the event occurs
+ *
+ * If a notifier for device @dev already exists, then increase the refcount
+ * and return that notifier.
+ *
+ * If it doesn't exist, then allocate a new notifier struct and return a
+ * pointer to that new struct.
+ *
+ * Return NULL if the memory could not be allocated.
+ */
+struct cec_notifier *cec_notifier_get_conn(struct device *dev,
+  const char *conn);
+
+/**
  * cec_notifier_get - find or create a new cec_notifier for the given device.
  * @dev: device that sends the events.
  *
@@ -31,7 +62,10 @@ struct cec_notifier;
  *
  * Return NULL if the memory could not be allocated.
  */
-struct cec_notifier *cec_notifier_get(struct device *dev);
+static inline struct cec_notifier *cec_notifier_get(struct device *dev)
+{
+   return cec_notifier_get_conn(dev, NULL);
+}
 
 /**
  * cec_notifier_put - decrease 

[RFC PATCH 5/5] media: platform: Add Chrome OS EC CEC driver

2018-05-14 Thread Neil Armstrong
The Chrome OS Embedded Controller can expose a CEC bus, this patch add the
driver for such feature of the Embedded Controller.

This driver is part of the cros-ec MFD and will be add as a sub-device when
the feature bit is exposed by the EC.

The controller will only handle a single logical address and handles
all the messages retries and will only expose Success or Error.

When the logical address is invalid, the controller will act as a CEC sniffer
and transfer all messages on the bus.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/media/platform/Kconfig   |  11 +
 drivers/media/platform/Makefile  |   2 +
 drivers/media/platform/cros-ec/Makefile  |   1 +
 drivers/media/platform/cros-ec/cros-ec-cec.c | 331 +++
 4 files changed, 345 insertions(+)
 create mode 100644 drivers/media/platform/cros-ec/Makefile
 create mode 100644 drivers/media/platform/cros-ec/cros-ec-cec.c

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index c7a1cf8..e55a8ed2 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -546,6 +546,17 @@ menuconfig CEC_PLATFORM_DRIVERS
 
 if CEC_PLATFORM_DRIVERS
 
+config VIDEO_CROS_EC_CEC
+   tristate "Chrome OS EC CEC driver"
+   depends on MFD_CROS_EC || COMPILE_TEST
+   select CEC_CORE
+   select CEC_NOTIFIER
+   ---help---
+ If you say yes here you will get support for the
+ Chrome OS Embedded Controller's CEC.
+ The CEC bus is present in the HDMI connector and enables communication
+ between compatible devices.
+
 config VIDEO_MESON_AO_CEC
tristate "Amlogic Meson AO CEC driver"
depends on ARCH_MESON || COMPILE_TEST
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 932515d..0e0582e 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -92,3 +92,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS)+= 
qcom/camss-8x16/
 obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/
 
 obj-y  += meson/
+
+obj-y  += cros-ec/
diff --git a/drivers/media/platform/cros-ec/Makefile 
b/drivers/media/platform/cros-ec/Makefile
new file mode 100644
index 000..9ce97f9
--- /dev/null
+++ b/drivers/media/platform/cros-ec/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VIDEO_CROS_EC_CEC) += cros-ec-cec.o
diff --git a/drivers/media/platform/cros-ec/cros-ec-cec.c 
b/drivers/media/platform/cros-ec/cros-ec-cec.c
new file mode 100644
index 000..fea90da
--- /dev/null
+++ b/drivers/media/platform/cros-ec/cros-ec-cec.c
@@ -0,0 +1,331 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * CEC driver for Chrome OS Embedded Controller
+ *
+ * Copyright (c) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstr...@baylibre.com>
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DRV_NAME   "cros-ec-cec"
+
+/**
+ * struct cros_ec_cec - Driver data for EC CEC
+ *
+ * @cros_ec: Pointer to EC device
+ * @notifier: Notifier info for responding to EC events
+ * @adap: CEC adapter
+ * @notify: CEC notifier pointer
+ * @rc_msg: storage for a received message
+ */
+struct cros_ec_cec {
+   struct cros_ec_device *cros_ec;
+   struct notifier_block notifier;
+   struct cec_adapter *adap;
+   struct cec_notifier *notify;
+   struct cec_msg rx_msg;
+};
+
+static void handle_cec_message(struct cros_ec_cec *cros_ec_cec)
+{
+   struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
+   uint8_t *cec_message = cros_ec->event_data.data.cec_message;
+   unsigned int len = cros_ec->event_size;
+
+   cros_ec_cec->rx_msg.len = len;
+   memcpy(cros_ec_cec->rx_msg.msg, cec_message, len);
+
+   cec_received_msg(cros_ec_cec->adap, _ec_cec->rx_msg);
+}
+
+static void handle_cec_event(struct cros_ec_cec *cros_ec_cec)
+{
+   struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
+   uint32_t events = cros_ec->event_data.data.cec_events;
+
+   if (events & EC_MKBP_CEC_SEND_OK)
+   cec_transmit_attempt_done(cros_ec_cec->adap,
+ CEC_TX_STATUS_OK);
+
+   if (events & EC_MKBP_CEC_SEND_FAILED)
+   cec_transmit_attempt_done(cros_ec_cec->adap,
+ CEC_TX_STATUS_ERROR);
+}
+
+static int cros_ec_cec_event(struct notifier_block *nb,
+   unsigned long queued_during_suspend, void *_notify)
+{
+   struct cros_ec_cec *cros_ec_cec;
+   struct cros_ec_device *cros_ec;
+
+   cros_ec_cec = container_of(nb, struct cros_ec_cec, notifier);
+   cros_ec = cros_ec_cec->cros_ec;
+
+   if (cros_ec->event_data.event_type == EC_MKBP_CEC_EVENT) {
+   handle_cec_event(cros_ec_cec);

Re: [PATCHv2 0/3] dw-hdmi: add property to disable CEC

2018-03-24 Thread Neil Armstrong
Hi Martin,

> Le 24 mars 2018 à 12:00, Martin Blumenstingl 
>  a écrit :
> 
> Hello Hans, Hi Neil,
> 
> (apologies in advance if any of this is wrong, I don't have any CEC
> capable TV so I can't test it)
> 
> On Fri, Mar 23, 2018 at 1:59 PM, Hans Verkuil  wrote:
>> From: Hans Verkuil 
>> 
>> Some boards (amlogic) have two CEC controllers: the DesignWare controller
>> and their own CEC controller (meson ao-cec).
> as far as I understand the Amlogic Meson SoCs have two domains:
> - AO (always-on, powered even in suspend mode) where meson-ao-cec can
> wake up the system from suspend
> - EE (everything else, not powered during suspend) where dw-hdmi-cec lives
> 

Exact, except … the EE CEC is not hooked to the DW-HDMI TX but the RX, and thus 
cannot be used on GXBB/GXL/GXM.

> this far everything is OK
> 
>> Since the CEC line is not hooked up to the DW controller we need a way
>> to disable that controller. This patch series adds the cec-disable
>> property for that purpose.
> drivers/pinctrl/meson/pinctrl-meson-gxbb.c has ao_cec_pins and
> ee_cec_pins, both use GPIOAO_12
> drivers/pinctrl/meson/pinctrl-meson-gxl.c has ao_cec_pins and
> ee_cec_pins, both use GPIOAO_8
> 
> @Neil: do you know if the CEC signal routing is:
> ao_cec_pins -> meson-ao-cec
> ee_cec_pins -> dw-hdmi-cec

It’s hooked to the DW-HDMI RX IP used in the TV SoCs.

> 
> I'm curious because if both CEC controllers can be used then it might
> be worth mentioning this in the cover-letter and patch description
> 

Initially I thought it was hooked to the DW-HDMI TX, but no, I guess I should 
remove the ee_cec pinmux…

Neil

> 
> Regards
> Martin



Re: [PATCH 3/3] arm64: dts: meson-gxl-s905x-libretech-cc: add cec-disable

2018-03-19 Thread Neil Armstrong
On 19/03/2018 12:43, Hans Verkuil wrote:
> From: Hans Verkuil <hans.verk...@cisco.com>
> 
> This board has two CEC controllers: the DesignWare controller and
> a meson-specific controller. Disable the DW controller since the
> CEC line is hooked up to the meson controller.
> 
> Signed-off-by: Hans Verkuil <hans.verk...@cisco.com>
> ---
>  arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts 
> b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
> index 9671f1e3c74a..271bd486fd65 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
> @@ -155,6 +155,7 @@
>   status = "okay";
>   pinctrl-0 = <_hpd_pins>, <_i2c_pins>;
>   pinctrl-names = "default";
> + cec-disable;
>  };
>  
>  _tx_tmds_port {
> 

Acked-by: Neil Armstrong <narmstr...@baylibre.com>


Re: [PATCH 2/3] drm: bridge: dw-hdmi: check the cec-disable property

2018-03-19 Thread Neil Armstrong
On 19/03/2018 12:43, Hans Verkuil wrote:
> From: Hans Verkuil <hans.verk...@cisco.com>
> 
> If the cec-disable property was set, then disable the DW CEC
> controller. This is needed for boards that have their own
> CEC controller.
> 
> Signed-off-by: Hans Verkuil <hans.verk...@cisco.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index a38db40ce990..597220e40541 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2508,7 +2508,8 @@ __dw_hdmi_probe(struct platform_device *pdev,
>   hdmi->audio = platform_device_register_full();
>   }
>  
> - if (config0 & HDMI_CONFIG0_CEC) {
> + if ((config0 & HDMI_CONFIG0_CEC) &&
> + !of_property_read_bool(np, "cec-disable")) {
>   cec.hdmi = hdmi;
>   cec.ops = _hdmi_cec_ops;
>   cec.irq = irq;
> 

I suspected the bit was off for the Amlogic GX SoCs, I was wrong...

Reviewed-by: Neil Armstrong <narmstr...@baylibre.com>


Re: [PATCH 0/3] dw-hdmi: add property to disable CEC

2018-03-19 Thread Neil Armstrong
Hi Hans,

On 19/03/2018 12:43, Hans Verkuil wrote:
> From: Hans Verkuil 
> 
> Some boards (amlogic) have two CEC controllers: the DesignWare controller
> and their own CEC controller (meson ao-cec).
> 
> Since the CEC line is not hooked up to the DW controller we need a way
> to disable that controller. This patch series adds the cec-disable
> property for that purpose.
> 
> Neil, I have added cec-disable to meson-gxl-s905x-libretech-cc.dts
> only, but I suspect it is probably valid for all meson-glx devices?
> Should I move it to meson-gxl.dtsi?

It's valid on all GX devices, so you can add to meson-gx.dtsi

Neil

> 
> Regards,
> 
>   Hans
> 
> Hans Verkuil (3):
>   dt-bindings: display: dw_hdmi.txt
>   drm: bridge: dw-hdmi: check the cec-disable property
>   arm64: dts: meson-gxl-s905x-libretech-cc: add cec-disable
> 
>  Documentation/devicetree/bindings/display/bridge/dw_hdmi.txt | 3 +++
>  arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts | 1 +
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c| 3 ++-
>  3 files changed, 6 insertions(+), 1 deletion(-)
> 



Re: [PATCH 1/3] dt-bindings: display: dw_hdmi.txt

2018-03-19 Thread Neil Armstrong
On 19/03/2018 12:43, Hans Verkuil wrote:
> From: Hans Verkuil <hans.verk...@cisco.com>
> 
> Some boards have both a DesignWare and their own CEC controller.
> The CEC pin is only hooked up to their own CEC controller and not
> to the DW controller.
> 
> Add the cec-disable property to disable the DW CEC controller.
> 
> This particular situation happens on Amlogic boards that have their
> own meson CEC controller.
> 
> Signed-off-by: Hans Verkuil <hans.verk...@cisco.com>
> ---
>  Documentation/devicetree/bindings/display/bridge/dw_hdmi.txt | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/bridge/dw_hdmi.txt 
> b/Documentation/devicetree/bindings/display/bridge/dw_hdmi.txt
> index 33bf981fbe33..4a13f4858bc0 100644
> --- a/Documentation/devicetree/bindings/display/bridge/dw_hdmi.txt
> +++ b/Documentation/devicetree/bindings/display/bridge/dw_hdmi.txt
> @@ -27,6 +27,9 @@ responsible for defining whether each property is required 
> or optional.
>- "isfr" is the internal register configuration clock (mandatory).
>- "cec" is the HDMI CEC controller main clock (optional).
>  
> +- cec-disable: Do not use the DWC CEC controller since the CEC line is not
> +  hooked up even though the CEC DWC IP is present.
> +
>  - ports: The connectivity of the DWC HDMI TX with the rest of the system is
>expressed in using ports as specified in the device graph bindings defined
>in Documentation/devicetree/bindings/graph.txt. The numbering of the ports
> 

Acked-by: Neil Armstrong <narmstr...@baylibre.com>


Re: iMX6q/coda encoder failures with ffmpeg/gstreamer m2m encoders

2017-12-19 Thread Neil Armstrong
On 19/12/2017 12:17, Philipp Zabel wrote:
> Hi Neil,
> 
> On Tue, 2017-11-21 at 10:50 +0100, Neil Armstrong wrote:
>> Hi,
>>
>> I'm trying to make the coda960 h.264 encoder work on an i.MX6q SoC with 
>> Linux 4.14 and the 3.1.1 firmware.
>>
>> # dmesg | grep coda
>> [4.846574] coda 204.vpu: Direct firmware load for vpu_fw_imx6q.bin 
>> failed with error -2
>> [4.901351] coda 204.vpu: Using fallback firmware vpu/vpu_fw_imx6q.bin
>> [4.916039] coda 204.vpu: Firmware code revision: 46072
>> [4.921641] coda 204.vpu: Initialized CODA960.
>> [4.926589] coda 204.vpu: Firmware version: 3.1.1
>> [4.932223] coda 204.vpu: codec registered as /dev/video[8-9]
>>
>> Using gstreamer-plugins-good and the m2m v4l2 encoder, I have :
>>
>> # gst-launch-1.0 videotestsrc num-buffers=1000 pattern=snow ! video/x-raw, 
>> framerate=30/1, width=1280, height=720 ! v4l2h264enc ! h264parse ! mp4mux ! 
>> filesink location=/dev/null
>> Setting pipeline to PAUSED ...
>> Pipeline is PREROLLING ...
>> Redistribute latency...
>> [ 1569.473717] coda 204.vpu: coda_s_fmt queue busy
>> ERROR: from element /GstPipeline:pipeline0/v4l2h264enc:v4l2h264enc0: Device 
>> '/dev/video8' is busy
>> Additional debug info:
>> ../../../gst-plugins-good-1.12.3/sys/v4l2/gstv4l2object.c(3609): 
>> gst_v4l2_object_set_format_full (): 
>> /GstPipeline:pipeline0/v4l2h264enc:v4l2h264enc0:
>> Call to S_FMT failed for YU12 @ 1280x720: Device or resource busy
>> ERROR: pipeline doesn't want to preroll.
>> Setting pipeline to NULL ...
>> Freeing pipeline ...
> 
> The coda driver does not allow S_FMT anymore, as soon as the buffers are
> allocated with REQBUFS:
> 
> https://bugzilla.gnome.org/show_bug.cgi?id=791338
> 
> regards
> Philipp
> 

Thanks Philipp,

It solves the gstreamer encoding.

Neil


Re: [PATCH/RFC 1/4] drm: Add colorkey properties

2017-12-19 Thread Neil Armstrong
_plane *plane,
> +  const struct drm_prop_enum_list *modes,
> +  unsigned int num_modes, bool replace);
>  #endif
> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
> index 8185e3468a23..a5804a4ea5c3 100644
> --- a/include/drm/drm_plane.h
> +++ b/include/drm/drm_plane.h
> @@ -52,6 +52,13 @@ struct drm_modeset_acquire_ctx;
>   *   where N is the number of active planes for given crtc. Note that
>   *   the driver must call drm_atomic_normalize_zpos() to update this before
>   *   it can be trusted.
> + * @colorkey.mode: color key mode. 0 disabled color keying, other values are
> + *   driver-specific.
> + * @colorkey.min: color key range minimum. The value is stored in 
> AXYZ16161616
> + *   format, where A is the alpha value and X, Y and Z correspond to the
> + *   color components of the plane's pixel format (usually RGB or YUV).
> + * @colorkey.max: color key range maximum (in AXYZ16161616 format)
> + * @colorkey.value: color key replacement value (in in AXYZ16161616 format)
>   * @src: clipped source coordinates of the plane (in 16.16)
>   * @dst: clipped destination coordinates of the plane
>   * @state: backpointer to global drm_atomic_state
> @@ -112,6 +119,14 @@ struct drm_plane_state {
>   unsigned int zpos;
>   unsigned int normalized_zpos;
>  
> + /* Plane colorkey */
> + struct {
> + unsigned int mode;
> + u64 min;
> + u64 max;
> + u64 value;
> + } colorkey;
> +
>   /* Clipped coordinates */
>   struct drm_rect src, dst;
>  
> @@ -481,9 +496,13 @@ enum drm_plane_type {
>   * @funcs: helper functions
>   * @properties: property tracking for this plane
>   * @type: type of plane (overlay, primary, cursor)
> + * @helper_private: mid-layer private data
>   * @zpos_property: zpos property for this plane
>   * @rotation_property: rotation property for this plane
> - * @helper_private: mid-layer private data
> + * @colorkey.mode_property: color key mode property
> + * @colorkey.min_property: color key range minimum property
> + * @colorkey.max_property: color key range maximum property
> + * @colorkey.value_property: color key replacement value property
>   */
>  struct drm_plane {
>   struct drm_device *dev;
> @@ -558,6 +577,13 @@ struct drm_plane {
>  
>   struct drm_property *zpos_property;
>   struct drm_property *rotation_property;
> +
> + struct {
> + struct drm_property *mode_property;
> + struct drm_property *min_property;
> + struct drm_property *max_property;
> + struct drm_property *value_property;
> + } colorkey;
>  };
>  
>  #define obj_to_plane(x) container_of(x, struct drm_plane, base)
> 

Apart from that,

Reviewed-by: Neil Armstrong <narmstr...@baylibre.com>


iMX6q/coda encoder failures with ffmpeg/gstreamer m2m encoders

2017-11-21 Thread Neil Armstrong
Hi,

I'm trying to make the coda960 h.264 encoder work on an i.MX6q SoC with Linux 
4.14 and the 3.1.1 firmware.

# dmesg | grep coda
[4.846574] coda 204.vpu: Direct firmware load for vpu_fw_imx6q.bin 
failed with error -2
[4.901351] coda 204.vpu: Using fallback firmware vpu/vpu_fw_imx6q.bin
[4.916039] coda 204.vpu: Firmware code revision: 46072
[4.921641] coda 204.vpu: Initialized CODA960.
[4.926589] coda 204.vpu: Firmware version: 3.1.1
[4.932223] coda 204.vpu: codec registered as /dev/video[8-9]

Using gstreamer-plugins-good and the m2m v4l2 encoder, I have :

# gst-launch-1.0 videotestsrc num-buffers=1000 pattern=snow ! video/x-raw, 
framerate=30/1, width=1280, height=720 ! v4l2h264enc ! h264parse ! mp4mux ! 
filesink location=/dev/null
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
Redistribute latency...
[ 1569.473717] coda 204.vpu: coda_s_fmt queue busy
ERROR: from element /GstPipeline:pipeline0/v4l2h264enc:v4l2h264enc0: Device 
'/dev/video8' is busy
Additional debug info:
../../../gst-plugins-good-1.12.3/sys/v4l2/gstv4l2object.c(3609): 
gst_v4l2_object_set_format_full (): 
/GstPipeline:pipeline0/v4l2h264enc:v4l2h264enc0:
Call to S_FMT failed for YU12 @ 1280x720: Device or resource busy
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
Freeing pipeline ...

And with ffmpeg :

# ffmpeg -f lavfi -i nullsrc=s=1280x720:d=5 -vf "geq=random(1)*255:128:128" 
-vcodec h264_v4l2m2m -f null -
Input #0, lavfi, from 'nullsrc=s=1280x720:d=5':
  Duration: N/A, start: 0.00, bitrate: N/A
Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 1280x720 [SAR 
1:1 DAR 16:9], 25 tbr, 25 tbn, 25 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (h264_v4l2m2m))
Press [q] to stop, [?] for help
[h264_v4l2m2m @ 0x146f700] driver 'coda' on card 'CODA960'
Last message repeated 1 times
[h264_v4l2m2m @ 0x146f700] Using device /dev/video8
[h264_v4l2m2m @ 0x146f700] driver 'coda' on card 'CODA960'
[h264_v4l2m2m @ 0x146f700] Failed to set number of B-frames
Last message repeated 1 times
[h264_v4l2m2m @ 0x146f700] Failed to set header mode
[h264_v4l2m2m @ 0x146f700] h264 profile not found
[h264_v4l2m2m[  787.690832] coda 204.vpu: CODA_COMMAND_SEQ_INIT failed
 @ 0x146f700] Encoder adjusted: qmin (0), qmax (51)
[h264_v4l2m2m @ 0x146f700] Failed to set minimum video quantizer scale
Output #0, null, to 'pipe:':
  Metadata:
encoder : Lavf57.71.100
Stream #0:0: Video: h264 (h264_v4l2m2m), yuv420p, 1280x720 [SAR 1:1 DAR 
16:9], q=2-31, 200 kb/s, 25 fps, 25 tbn, 25 tbc
Metadata:
  encoder : Lavc57.89.100 h264_v4l2m2m
[h264_v4l2m2m @ 0x146f700] output  POLLERR
[h264_v4l2m2m @ 0x146f700] VIDIOC_STREAMON failed on capture context
Video encoding failed

Decoder iws working OK with gstreamer, but fails to allocate memory with ffmpeg 
(unrelated).

Is there missing patches to make encoder work, or some specific parameters  ?

Thanks,
Neil

-- 
Neil Armstrong
Embedded Linux Software Engineer
BayLibre - At the Heart of Embedded Linux
www.baylibre.com


Re: [PATCH] MAINTAINERS: add entry for meson ao cec driver

2017-08-08 Thread Neil Armstrong
Le 08/08/2017 16:18, Hans Verkuil a écrit :
> Add entry to the MAINTAINERS file for the meson ao cec driver.
> 
> Signed-off-by: Hans Verkuil <hans.verk...@cisco.com>
> ---
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 9826a918d37a..ed568e1ac856 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -8671,6 +8671,16 @@ F: drivers/leds/leds-menf21bmc.c
>  F:   drivers/hwmon/menf21bmc_hwmon.c
>  F:   Documentation/hwmon/menf21bmc
> 
> +MESON AO CEC DRIVER FOR AMLOGIC SOCS
> +M:   Neil Armstrong <narmstr...@baylibre.com>
> +L:   linux-me...@lists.freedesktop.org
> +L:   linux-amlo...@lists.infradead.org
> +W:   http://linux-meson.com/
> +S:   Supported
> +F:   drivers/media/platform/meson/ao-cec.c
> +F:   Documentation/devicetree/bindings/media/meson-ao-cec.txt
> +T:   git git://linuxtv.org/media_tree.git
> +
>  METAG ARCHITECTURE
>  M:   James Hogan <james.ho...@imgtec.com>
>  L:   linux-me...@vger.kernel.org
> 

Hi Hans,

Thanks !

Acked-by: Neil Armstrong <narmstr...@baylibre.com>


Re: [PATCH v3 0/2] media: Add Amlogic Meson AO CEC Controller support

2017-07-28 Thread Neil Armstrong
On 07/28/2017 02:37 PM, Hans Verkuil wrote:
> On 07/28/2017 02:35 PM, Hans Verkuil wrote:
>> Hi Neil,
>>
>> On 07/27/2017 05:20 PM, Neil Armstrong wrote:
>>> The Amlogic SoC embeds a standalone CEC controller, this patch adds a driver
>>> for such controller.
>>> The controller does not need HPD to be active, and could support up to max
>>> 5 logical addresses, but only 1 is handled since the Suspend firmware can
>>> make use of this unique logical address to wake up the device.
>>>
>>> The Suspend firmware configuration will be added in an other patchset.
>>
>> Note that to get the right module dependencies you will also need to add
>> this line:
>>
>>  select CEC_CORE if CEC_NOTIFIER
>>
>> to DRM_MESON_DW_HDMI in drivers/gpu/drm/meson/Kconfig.
>>
>> This ensures that if DRM_MESON_DW_HDMI is 'y' but VIDEO_MESON_AO_CEC is 'm'
>> the CEC_CORE config is set to 'y'.
>>
>> Obviously this is a patch for dri-devel.
> 
> I was too quick sending this: I expect this line to appear in DRM_DW_HDMI,
> not DRM_MESON_DW_HDMI. Sorry about the noise.

Indeed, I will respin russell's notifier patch with this.

Thanks,
Neil

> 
>   Hans
> 
>>
>> Regards,
>>
>>  Hans
>>
>>>
>>> Changes since v2 at [2] :
>>>  - change meson_ao_cec_read/write prototype to simplify error handling
>>>
>>> Changes since v1 at [1] :
>>>  - add timeout to wait busy, with error return
>>>  - handle busy error in all read/write operations
>>>  - add CEC_CAP_PASSTHROUGH
>>>  - add bindings ack
>>>
>>> [1] 
>>> https://lkml.kernel.org/r/1499336870-24118-1-git-send-email-narmstr...@baylibre.com
>>> [2] 
>>> https://lkml.kernel.org/r/1499673696-21372-1-git-send-email-narmstr...@baylibre.com
>>>
>>> Neil Armstrong (2):
>>>   platform: Add Amlogic Meson AO CEC Controller driver
>>>   dt-bindings: media: Add Amlogic Meson AO-CEC bindings
>>>
>>>  .../devicetree/bindings/media/meson-ao-cec.txt |  28 +
>>>  drivers/media/platform/Kconfig |  11 +
>>>  drivers/media/platform/Makefile|   2 +
>>>  drivers/media/platform/meson/Makefile  |   1 +
>>>  drivers/media/platform/meson/ao-cec.c  | 744 
>>> +
>>>  5 files changed, 786 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/media/meson-ao-cec.txt
>>>  create mode 100644 drivers/media/platform/meson/Makefile
>>>  create mode 100644 drivers/media/platform/meson/ao-cec.c
>>>
>>
> 



[PATCH v3 2/2] dt-bindings: media: Add Amlogic Meson AO-CEC bindings

2017-07-27 Thread Neil Armstrong
The Amlogic SoCs embeds a standalone CEC Controller, this patch adds this
device bindings.

Acked-by: Rob Herring <r...@kernel.org>
Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 .../devicetree/bindings/media/meson-ao-cec.txt | 28 ++
 1 file changed, 28 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/meson-ao-cec.txt

diff --git a/Documentation/devicetree/bindings/media/meson-ao-cec.txt 
b/Documentation/devicetree/bindings/media/meson-ao-cec.txt
new file mode 100644
index 000..8671bdb
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/meson-ao-cec.txt
@@ -0,0 +1,28 @@
+* Amlogic Meson AO-CEC driver
+
+The Amlogic Meson AO-CEC module is present is Amlogic SoCs and its purpose is
+to handle communication between HDMI connected devices over the CEC bus.
+
+Required properties:
+  - compatible : value should be following
+   "amlogic,meson-gx-ao-cec"
+
+  - reg : Physical base address of the IP registers and length of memory
+ mapped region.
+
+  - interrupts : AO-CEC interrupt number to the CPU.
+  - clocks : from common clock binding: handle to AO-CEC clock.
+  - clock-names : from common clock binding: must contain "core",
+ corresponding to entry in the clocks property.
+  - hdmi-phandle: phandle to the HDMI controller
+
+Example:
+
+cec_AO: cec@100 {
+   compatible = "amlogic,meson-gx-ao-cec";
+   reg = <0x0 0x00100 0x0 0x14>;
+   interrupts = ;
+   clocks = <_AO CLKID_AO_CEC_32K>;
+   clock-names = "core";
+   hdmi-phandle = <_tx>;
+};
-- 
1.9.1



[PATCH v3 0/2] media: Add Amlogic Meson AO CEC Controller support

2017-07-27 Thread Neil Armstrong
The Amlogic SoC embeds a standalone CEC controller, this patch adds a driver
for such controller.
The controller does not need HPD to be active, and could support up to max
5 logical addresses, but only 1 is handled since the Suspend firmware can
make use of this unique logical address to wake up the device.

The Suspend firmware configuration will be added in an other patchset.

Changes since v2 at [2] :
 - change meson_ao_cec_read/write prototype to simplify error handling

Changes since v1 at [1] :
 - add timeout to wait busy, with error return
 - handle busy error in all read/write operations
 - add CEC_CAP_PASSTHROUGH
 - add bindings ack

[1] 
https://lkml.kernel.org/r/1499336870-24118-1-git-send-email-narmstr...@baylibre.com
[2] 
https://lkml.kernel.org/r/1499673696-21372-1-git-send-email-narmstr...@baylibre.com

Neil Armstrong (2):
  platform: Add Amlogic Meson AO CEC Controller driver
  dt-bindings: media: Add Amlogic Meson AO-CEC bindings

 .../devicetree/bindings/media/meson-ao-cec.txt |  28 +
 drivers/media/platform/Kconfig |  11 +
 drivers/media/platform/Makefile|   2 +
 drivers/media/platform/meson/Makefile  |   1 +
 drivers/media/platform/meson/ao-cec.c  | 744 +
 5 files changed, 786 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/meson-ao-cec.txt
 create mode 100644 drivers/media/platform/meson/Makefile
 create mode 100644 drivers/media/platform/meson/ao-cec.c

-- 
1.9.1



[PATCH v3 1/2] platform: Add Amlogic Meson AO CEC Controller driver

2017-07-27 Thread Neil Armstrong
The Amlogic SoC embeds a standalone CEC controller, this patch adds a driver
for such controller.
The controller does not need HPD to be active, and could support up to max
5 logical addresses, but only 1 is handled since the Suspend firmware can
make use of this unique logical address to wake up the device.

The Suspend firmware configuration will be added in an other patchset.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/media/platform/Kconfig|  11 +
 drivers/media/platform/Makefile   |   2 +
 drivers/media/platform/meson/Makefile |   1 +
 drivers/media/platform/meson/ao-cec.c | 744 ++
 4 files changed, 758 insertions(+)
 create mode 100644 drivers/media/platform/meson/Makefile
 create mode 100644 drivers/media/platform/meson/ao-cec.c

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 1313cd5..1e67381 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -536,6 +536,17 @@ menuconfig CEC_PLATFORM_DRIVERS
 
 if CEC_PLATFORM_DRIVERS
 
+config VIDEO_MESON_AO_CEC
+   tristate "Amlogic Meson AO CEC driver"
+   depends on ARCH_MESON || COMPILE_TEST
+   select CEC_CORE
+   select CEC_NOTIFIER
+   ---help---
+ This is a driver for Amlogic Meson SoCs AO CEC interface. It uses the
+ generic CEC framework interface.
+ CEC bus is present in the HDMI connector and enables communication
+ between compatible devices.
+
 config VIDEO_SAMSUNG_S5P_CEC
tristate "Samsung S5P CEC driver"
depends on PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 9beadc7..a52d7b6 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -86,3 +86,5 @@ obj-$(CONFIG_VIDEO_MEDIATEK_MDP)  += mtk-mdp/
 obj-$(CONFIG_VIDEO_MEDIATEK_JPEG)  += mtk-jpeg/
 
 obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/
+
+obj-y  += meson/
diff --git a/drivers/media/platform/meson/Makefile 
b/drivers/media/platform/meson/Makefile
new file mode 100644
index 000..597beb8
--- /dev/null
+++ b/drivers/media/platform/meson/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VIDEO_MESON_AO_CEC)   += ao-cec.o
diff --git a/drivers/media/platform/meson/ao-cec.c 
b/drivers/media/platform/meson/ao-cec.c
new file mode 100644
index 000..5c3607c
--- /dev/null
+++ b/drivers/media/platform/meson/ao-cec.c
@@ -0,0 +1,744 @@
+/*
+ * Driver for Amlogic Meson AO CEC Controller
+ *
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved
+ * Copyright (C) 2017 BayLibre, SAS
+ * Author: Neil Armstrong <narmstr...@baylibre.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* CEC Registers */
+
+/*
+ * [2:1] cntl_clk
+ *  - 0 = Disable clk (Power-off mode)
+ *  - 1 = Enable gated clock (Normal mode)
+ *  - 2 = Enable free-run clk (Debug mode)
+ */
+#define CEC_GEN_CNTL_REG   0x00
+
+#define CEC_GEN_CNTL_RESET BIT(0)
+#define CEC_GEN_CNTL_CLK_DISABLE   0
+#define CEC_GEN_CNTL_CLK_ENABLE1
+#define CEC_GEN_CNTL_CLK_ENABLE_DBG2
+#define CEC_GEN_CNTL_CLK_CTRL_MASK GENMASK(2, 1)
+
+/*
+ * [7:0] cec_reg_addr
+ * [15:8] cec_reg_wrdata
+ * [16] cec_reg_wr
+ *  - 0 = Read
+ *  - 1 = Write
+ * [23] bus free
+ * [31:24] cec_reg_rddata
+ */
+#define CEC_RW_REG 0x04
+
+#define CEC_RW_ADDRGENMASK(7, 0)
+#define CEC_RW_WR_DATA GENMASK(15, 8)
+#define CEC_RW_WRITE_ENBIT(16)
+#define CEC_RW_BUS_BUSYBIT(23)
+#define CEC_RW_RD_DATA GENMASK(31, 24)
+
+/*
+ * [1] tx intr
+ * [2] rx intr
+ */
+#define CEC_INTR_MASKN_REG 0x08
+#define CEC_INTR_CLR_REG   0x0c
+#define CEC_INTR_STAT_REG  0x10
+
+#define CEC_INTR_TXBIT(1)
+#define CEC_INTR_RXBIT(2)
+
+/* CEC Commands */
+
+#define CEC_TX_MSG_0_HEADER0x00
+#define CEC_TX_MSG_1_OPCODE0x01
+#define CEC_TX_MSG_2_OP1   0x02
+#define CEC_TX_MSG_3_OP2   0x03
+#define CEC_TX_MSG_4_OP3   0x04
+#define CEC_TX_MSG_5_OP4   0x05
+#define CEC_TX_MSG_6_OP5   0x06
+#define CEC_TX_MSG_7_OP6   0x07
+#define CEC_TX_MSG_8_OP7   0x08
+#define CEC_TX_MSG_9_OP8   0x09
+#define CEC_TX_MSG_A_OP9   0x0A
+#define CEC_TX_MSG_B_OP10  0x0B
+#define CEC_TX_MSG_C_OP11  0x0C
+#define CEC_TX_MSG_D_OP12  0x0D
+#define CEC_TX_MSG_E_OP13  0x0E
+#define CEC_TX_MSG_F_OP14  0x0F
+#define CEC_TX_MSG_LENGTH  0x10
+#define CEC

Re: [PATCH v2 1/2] platform: Add Amlogic Meson AO CEC Controller driver

2017-07-27 Thread Neil Armstrong
On 07/27/2017 04:43 PM, Neil Armstrong wrote:
> On 07/25/2017 03:45 PM, Hans Verkuil wrote:
>> On 07/25/17 14:34, Neil Armstrong wrote:
>>> Hi Hans,
>>
>>>>> +static int meson_ao_cec_probe(struct platform_device *pdev)
>>>>> +{
>>>>> + struct meson_ao_cec_device *ao_cec;
>>>>> + struct platform_device *hdmi_dev;
>>>>> + struct device_node *np;
>>>>> + struct resource *res;
>>>>> + int ret, irq;
>>>>> +
>>>>> + np = of_parse_phandle(pdev->dev.of_node, "hdmi-phandle", 0);
>>>>> + if (!np) {
>>>>> + dev_err(>dev, "Failed to find hdmi node\n");
>>>>> + return -ENODEV;
>>>>> + }
>>>>> +
>>>>> + hdmi_dev = of_find_device_by_node(np);
>>>>> + if (hdmi_dev == NULL)
>>>>> + return -EPROBE_DEFER;
>>>>> +
>>>>> + ao_cec = devm_kzalloc(>dev, sizeof(*ao_cec), GFP_KERNEL);
>>>>> + if (!ao_cec)
>>>>> + return -ENOMEM;
>>>>> +
>>>>> + spin_lock_init(_cec->cec_reg_lock);
>>>>> +
>>>>> + ao_cec->notify = cec_notifier_get(_dev->dev);
>>>>> + if (!ao_cec->notify)
>>>>> + return -ENOMEM;
>>>>> +
>>>>> + ao_cec->adap = cec_allocate_adapter(_ao_cec_ops, ao_cec,
>>>>> + "meson_ao_cec",
>>>>> + CEC_CAP_LOG_ADDRS |
>>>>> + CEC_CAP_TRANSMIT |
>>>>> + CEC_CAP_RC |
>>>>> + CEC_CAP_PASSTHROUGH,
>>>>> + 1); /* Use 1 for now */
>>>>
>>>> I recommend that you add support for 2 logical addresses. More isn't 
>>>> allowed
>>>> by the CEC 2.0 spec anyway (no such restriction for CEC 1.4, but more than
>>>> two really isn't needed).
>>>
>>> I know, but in the "communication" register with the suspend/poweroff 
>>> firmware
>>> that  handles the wake up, only a single logical address is supported...
>>>
>>> What should I do in this case ? Which logical adress should I pass to the 
>>> firmware when implementing ir ?
>>
>> Ah, OK. Interesting.
>>
>> From cec-adap.c:
>>
>> if (log_addrs->num_log_addrs == 2) {
>> if (!(type_mask & ((1 << 
>> CEC_LOG_ADDR_TYPE_AUDIOSYSTEM) |
>>(1 << CEC_LOG_ADDR_TYPE_TV {
>> dprintk(1, "two LAs is only allowed for 
>> audiosystem and TV\n");
>> return -EINVAL;
>> }
>> if (!(type_mask & ((1 << CEC_LOG_ADDR_TYPE_PLAYBACK) 
>> |
>>(1 << 
>> CEC_LOG_ADDR_TYPE_RECORD {
>> dprintk(1, "an audiosystem/TV can only be 
>> combined with record or playback\n");
>> return -EINVAL;
>> }
>> }
>>
>> So you would store the TV or AUDIOSYSTEM logical address in the firmware, 
>> since those
>> describe the system best.
>>
>> I.e. it is a TV/Audiosystem with recording/playback capabilities.
>>
>> The problem is that for CEC 1.4 no such restriction is imposed (the test 
>> above is
>> specific to CEC 2.0). But I think it makes sense to just check if 
>> TV/Audiosystem
>> is selected and pick that as the LA to store in the firmware, and otherwise 
>> just
>> pick the first LA (log_addr[0]).
> 
> 
> Ok I'll add support for dual LA, and I'll do this LA selection when I'll add 
> firmware support.

Sorry, but having more than 1 LA makes the CEC controller very unstable, I'll 
need more info from amlogic to activate multiple LAs.

Neil

> 
> Thanks,
> Neil
> 
> 
>> Regards,
>>
>>  Hans
>>
> 



Re: [PATCH v2 1/2] platform: Add Amlogic Meson AO CEC Controller driver

2017-07-27 Thread Neil Armstrong
On 07/25/2017 03:45 PM, Hans Verkuil wrote:
> On 07/25/17 14:34, Neil Armstrong wrote:
>> Hi Hans,
> 
>>>> +static int meson_ao_cec_probe(struct platform_device *pdev)
>>>> +{
>>>> +  struct meson_ao_cec_device *ao_cec;
>>>> +  struct platform_device *hdmi_dev;
>>>> +  struct device_node *np;
>>>> +  struct resource *res;
>>>> +  int ret, irq;
>>>> +
>>>> +  np = of_parse_phandle(pdev->dev.of_node, "hdmi-phandle", 0);
>>>> +  if (!np) {
>>>> +  dev_err(>dev, "Failed to find hdmi node\n");
>>>> +  return -ENODEV;
>>>> +  }
>>>> +
>>>> +  hdmi_dev = of_find_device_by_node(np);
>>>> +  if (hdmi_dev == NULL)
>>>> +  return -EPROBE_DEFER;
>>>> +
>>>> +  ao_cec = devm_kzalloc(>dev, sizeof(*ao_cec), GFP_KERNEL);
>>>> +  if (!ao_cec)
>>>> +  return -ENOMEM;
>>>> +
>>>> +  spin_lock_init(_cec->cec_reg_lock);
>>>> +
>>>> +  ao_cec->notify = cec_notifier_get(_dev->dev);
>>>> +  if (!ao_cec->notify)
>>>> +  return -ENOMEM;
>>>> +
>>>> +  ao_cec->adap = cec_allocate_adapter(_ao_cec_ops, ao_cec,
>>>> +  "meson_ao_cec",
>>>> +  CEC_CAP_LOG_ADDRS |
>>>> +  CEC_CAP_TRANSMIT |
>>>> +  CEC_CAP_RC |
>>>> +  CEC_CAP_PASSTHROUGH,
>>>> +  1); /* Use 1 for now */
>>>
>>> I recommend that you add support for 2 logical addresses. More isn't allowed
>>> by the CEC 2.0 spec anyway (no such restriction for CEC 1.4, but more than
>>> two really isn't needed).
>>
>> I know, but in the "communication" register with the suspend/poweroff 
>> firmware
>> that  handles the wake up, only a single logical address is supported...
>>
>> What should I do in this case ? Which logical adress should I pass to the 
>> firmware when implementing ir ?
> 
> Ah, OK. Interesting.
> 
> From cec-adap.c:
> 
> if (log_addrs->num_log_addrs == 2) {
> if (!(type_mask & ((1 << 
> CEC_LOG_ADDR_TYPE_AUDIOSYSTEM) |
>(1 << CEC_LOG_ADDR_TYPE_TV {
> dprintk(1, "two LAs is only allowed for 
> audiosystem and TV\n");
> return -EINVAL;
> }
> if (!(type_mask & ((1 << CEC_LOG_ADDR_TYPE_PLAYBACK) |
>(1 << CEC_LOG_ADDR_TYPE_RECORD 
> {
> dprintk(1, "an audiosystem/TV can only be 
> combined with record or playback\n");
> return -EINVAL;
> }
> }
> 
> So you would store the TV or AUDIOSYSTEM logical address in the firmware, 
> since those
> describe the system best.
> 
> I.e. it is a TV/Audiosystem with recording/playback capabilities.
> 
> The problem is that for CEC 1.4 no such restriction is imposed (the test 
> above is
> specific to CEC 2.0). But I think it makes sense to just check if 
> TV/Audiosystem
> is selected and pick that as the LA to store in the firmware, and otherwise 
> just
> pick the first LA (log_addr[0]).


Ok I'll add support for dual LA, and I'll do this LA selection when I'll add 
firmware support.

Thanks,
Neil


> Regards,
> 
>   Hans
> 



Re: [PATCH v2 1/2] platform: Add Amlogic Meson AO CEC Controller driver

2017-07-25 Thread Neil Armstrong
Hi Hans,

On 07/17/2017 10:01 AM, Hans Verkuil wrote:
> On 10/07/17 10:01, Neil Armstrong wrote:
>> The Amlogic SoC embeds a standalone CEC controller, this patch adds a driver
>> for such controller.
>> The controller does not need HPD to be active, and could support up to max
>> 5 logical addresses, but only 1 is handled since the Suspend firmware can
>> make use of this unique logical address to wake up the device.
>>
>> The Suspend firmware configuration will be added in an other patchset.
>>
>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
>> ---
>>  drivers/media/platform/Kconfig|  11 +
>>  drivers/media/platform/Makefile   |   2 +
>>  drivers/media/platform/meson/Makefile |   1 +
>>  drivers/media/platform/meson/ao-cec.c | 781 
>> ++
>>  4 files changed, 795 insertions(+)
>>  create mode 100644 drivers/media/platform/meson/Makefile
>>  create mode 100644 drivers/media/platform/meson/ao-cec.c
>>
>> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
>> index 1313cd5..1e67381 100644
>> --- a/drivers/media/platform/Kconfig
>> +++ b/drivers/media/platform/Kconfig
>> @@ -536,6 +536,17 @@ menuconfig CEC_PLATFORM_DRIVERS
>>  
>>  if CEC_PLATFORM_DRIVERS
>>  
>> +config VIDEO_MESON_AO_CEC
>> +tristate "Amlogic Meson AO CEC driver"
>> +depends on ARCH_MESON || COMPILE_TEST
>> +select CEC_CORE
>> +select CEC_NOTIFIER
>> +---help---
>> +  This is a driver for Amlogic Meson SoCs AO CEC interface. It uses the
>> +  generic CEC framework interface.
>> +  CEC bus is present in the HDMI connector and enables communication
>> +  between compatible devices.
>> +
>>  config VIDEO_SAMSUNG_S5P_CEC
>> tristate "Samsung S5P CEC driver"
>> depends on PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST
>> diff --git a/drivers/media/platform/Makefile 
>> b/drivers/media/platform/Makefile
>> index 9beadc7..a52d7b6 100644
>> --- a/drivers/media/platform/Makefile
>> +++ b/drivers/media/platform/Makefile
>> @@ -86,3 +86,5 @@ obj-$(CONFIG_VIDEO_MEDIATEK_MDP)   += mtk-mdp/
>>  obj-$(CONFIG_VIDEO_MEDIATEK_JPEG)   += mtk-jpeg/
>>  
>>  obj-$(CONFIG_VIDEO_QCOM_VENUS)  += qcom/venus/
>> +
>> +obj-y   += meson/
>> diff --git a/drivers/media/platform/meson/Makefile 
>> b/drivers/media/platform/meson/Makefile
>> new file mode 100644
>> index 000..597beb8
>> --- /dev/null
>> +++ b/drivers/media/platform/meson/Makefile
>> @@ -0,0 +1 @@
>> +obj-$(CONFIG_VIDEO_MESON_AO_CEC)+= ao-cec.o
>> diff --git a/drivers/media/platform/meson/ao-cec.c 
>> b/drivers/media/platform/meson/ao-cec.c
>> new file mode 100644
>> index 000..cdc1f61
>> --- /dev/null
>> +++ b/drivers/media/platform/meson/ao-cec.c
>> @@ -0,0 +1,781 @@
>> +/*
>> + * Driver for Amlogic Meson AO CEC Controller
>> + *
>> + * Copyright (C) 2015 Amlogic, Inc. All rights reserved
>> + * Copyright (C) 2017 BayLibre, SAS
>> + * Author: Neil Armstrong <narmstr...@baylibre.com>
>> + *
>> + * SPDX-License-Identifier: GPL-2.0+
>> + */
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +/* CEC Registers */
>> +
>> +/*
>> + * [2:1] cntl_clk
>> + *  - 0 = Disable clk (Power-off mode)
>> + *  - 1 = Enable gated clock (Normal mode)
>> + *  - 2 = Enable free-run clk (Debug mode)
>> + */
>> +#define CEC_GEN_CNTL_REG0x00
>> +
>> +#define CEC_GEN_CNTL_RESET  BIT(0)
>> +#define CEC_GEN_CNTL_CLK_DISABLE0
>> +#define CEC_GEN_CNTL_CLK_ENABLE 1
>> +#define CEC_GEN_CNTL_CLK_ENABLE_DBG 2
>> +#define CEC_GEN_CNTL_CLK_CTRL_MASK  GENMASK(2, 1)
>> +
>> +/*
>> + * [7:0] cec_reg_addr
>> + * [15:8] cec_reg_wrdata
>> + * [16] cec_reg_wr
>> + *  - 0 = Read
>> + *  - 1 = Write
>> + * [23] bus free
>> + * [31:24] cec_reg_rddata
>> + */
>> +#define CEC_RW_REG  0x04
>> +
>> +#define CEC_RW_ADDR GENMASK(7, 0)
>> +#define CEC_RW_WR_DATA  GENMASK(15, 8)
>> +#define CEC_RW_WRITE_EN BIT(16)
>> +#defi

[PATCH v2 0/2] media: Add Amlogic Meson AO CEC Controller support

2017-07-10 Thread Neil Armstrong
The Amlogic SoC embeds a standalone CEC controller, this patch adds a driver
for such controller.
The controller does not need HPD to be active, and could support up to max
5 logical addresses, but only 1 is handled since the Suspend firmware can
make use of this unique logical address to wake up the device.

The Suspend firmware configuration will be added in an other patchset.

Changes since v1 at [1] :
 - add timeout to wait busy, with error return
 - handle busy error in all read/write operations
 - add CEC_CAP_PASSTHROUGH
 - add bindings ack

[1] 
https://lkml.kernel.org/r/1499336870-24118-1-git-send-email-narmstr...@baylibre.com

Neil Armstrong (2):
  platform: Add Amlogic Meson AO CEC Controller driver
  dt-bindings: media: Add Amlogic Meson AO-CEC bindings

 .../devicetree/bindings/media/meson-ao-cec.txt |  28 +
 drivers/media/platform/Kconfig |  11 +
 drivers/media/platform/Makefile|   2 +
 drivers/media/platform/meson/Makefile  |   1 +
 drivers/media/platform/meson/ao-cec.c  | 781 +
 5 files changed, 823 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/meson-ao-cec.txt
 create mode 100644 drivers/media/platform/meson/Makefile
 create mode 100644 drivers/media/platform/meson/ao-cec.c

-- 
1.9.1



[PATCH v2 1/2] platform: Add Amlogic Meson AO CEC Controller driver

2017-07-10 Thread Neil Armstrong
The Amlogic SoC embeds a standalone CEC controller, this patch adds a driver
for such controller.
The controller does not need HPD to be active, and could support up to max
5 logical addresses, but only 1 is handled since the Suspend firmware can
make use of this unique logical address to wake up the device.

The Suspend firmware configuration will be added in an other patchset.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/media/platform/Kconfig|  11 +
 drivers/media/platform/Makefile   |   2 +
 drivers/media/platform/meson/Makefile |   1 +
 drivers/media/platform/meson/ao-cec.c | 781 ++
 4 files changed, 795 insertions(+)
 create mode 100644 drivers/media/platform/meson/Makefile
 create mode 100644 drivers/media/platform/meson/ao-cec.c

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 1313cd5..1e67381 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -536,6 +536,17 @@ menuconfig CEC_PLATFORM_DRIVERS
 
 if CEC_PLATFORM_DRIVERS
 
+config VIDEO_MESON_AO_CEC
+   tristate "Amlogic Meson AO CEC driver"
+   depends on ARCH_MESON || COMPILE_TEST
+   select CEC_CORE
+   select CEC_NOTIFIER
+   ---help---
+ This is a driver for Amlogic Meson SoCs AO CEC interface. It uses the
+ generic CEC framework interface.
+ CEC bus is present in the HDMI connector and enables communication
+ between compatible devices.
+
 config VIDEO_SAMSUNG_S5P_CEC
tristate "Samsung S5P CEC driver"
depends on PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 9beadc7..a52d7b6 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -86,3 +86,5 @@ obj-$(CONFIG_VIDEO_MEDIATEK_MDP)  += mtk-mdp/
 obj-$(CONFIG_VIDEO_MEDIATEK_JPEG)  += mtk-jpeg/
 
 obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/
+
+obj-y  += meson/
diff --git a/drivers/media/platform/meson/Makefile 
b/drivers/media/platform/meson/Makefile
new file mode 100644
index 000..597beb8
--- /dev/null
+++ b/drivers/media/platform/meson/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VIDEO_MESON_AO_CEC)   += ao-cec.o
diff --git a/drivers/media/platform/meson/ao-cec.c 
b/drivers/media/platform/meson/ao-cec.c
new file mode 100644
index 000..cdc1f61
--- /dev/null
+++ b/drivers/media/platform/meson/ao-cec.c
@@ -0,0 +1,781 @@
+/*
+ * Driver for Amlogic Meson AO CEC Controller
+ *
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved
+ * Copyright (C) 2017 BayLibre, SAS
+ * Author: Neil Armstrong <narmstr...@baylibre.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* CEC Registers */
+
+/*
+ * [2:1] cntl_clk
+ *  - 0 = Disable clk (Power-off mode)
+ *  - 1 = Enable gated clock (Normal mode)
+ *  - 2 = Enable free-run clk (Debug mode)
+ */
+#define CEC_GEN_CNTL_REG   0x00
+
+#define CEC_GEN_CNTL_RESET BIT(0)
+#define CEC_GEN_CNTL_CLK_DISABLE   0
+#define CEC_GEN_CNTL_CLK_ENABLE1
+#define CEC_GEN_CNTL_CLK_ENABLE_DBG2
+#define CEC_GEN_CNTL_CLK_CTRL_MASK GENMASK(2, 1)
+
+/*
+ * [7:0] cec_reg_addr
+ * [15:8] cec_reg_wrdata
+ * [16] cec_reg_wr
+ *  - 0 = Read
+ *  - 1 = Write
+ * [23] bus free
+ * [31:24] cec_reg_rddata
+ */
+#define CEC_RW_REG 0x04
+
+#define CEC_RW_ADDRGENMASK(7, 0)
+#define CEC_RW_WR_DATA GENMASK(15, 8)
+#define CEC_RW_WRITE_ENBIT(16)
+#define CEC_RW_BUS_BUSYBIT(23)
+#define CEC_RW_RD_DATA GENMASK(31, 24)
+
+/*
+ * [1] tx intr
+ * [2] rx intr
+ */
+#define CEC_INTR_MASKN_REG 0x08
+#define CEC_INTR_CLR_REG   0x0c
+#define CEC_INTR_STAT_REG  0x10
+
+#define CEC_INTR_TXBIT(1)
+#define CEC_INTR_RXBIT(2)
+
+/* CEC Commands */
+
+#define CEC_TX_MSG_0_HEADER0x00
+#define CEC_TX_MSG_1_OPCODE0x01
+#define CEC_TX_MSG_2_OP1   0x02
+#define CEC_TX_MSG_3_OP2   0x03
+#define CEC_TX_MSG_4_OP3   0x04
+#define CEC_TX_MSG_5_OP4   0x05
+#define CEC_TX_MSG_6_OP5   0x06
+#define CEC_TX_MSG_7_OP6   0x07
+#define CEC_TX_MSG_8_OP7   0x08
+#define CEC_TX_MSG_9_OP8   0x09
+#define CEC_TX_MSG_A_OP9   0x0A
+#define CEC_TX_MSG_B_OP10  0x0B
+#define CEC_TX_MSG_C_OP11  0x0C
+#define CEC_TX_MSG_D_OP12  0x0D
+#define CEC_TX_MSG_E_OP13  0x0E
+#define CEC_TX_MSG_F_OP14  0x0F
+#define CEC_TX_MSG_LENGTH  0x10
+#define CEC

[PATCH v2 2/2] dt-bindings: media: Add Amlogic Meson AO-CEC bindings

2017-07-10 Thread Neil Armstrong
The Amlogic SoCs embeds a standalone CEC Controller, this patch adds this
device bindings.

Acked-by: Rob Herring <r...@kernel.org>
Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 .../devicetree/bindings/media/meson-ao-cec.txt | 28 ++
 1 file changed, 28 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/meson-ao-cec.txt

diff --git a/Documentation/devicetree/bindings/media/meson-ao-cec.txt 
b/Documentation/devicetree/bindings/media/meson-ao-cec.txt
new file mode 100644
index 000..8671bdb
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/meson-ao-cec.txt
@@ -0,0 +1,28 @@
+* Amlogic Meson AO-CEC driver
+
+The Amlogic Meson AO-CEC module is present is Amlogic SoCs and its purpose is
+to handle communication between HDMI connected devices over the CEC bus.
+
+Required properties:
+  - compatible : value should be following
+   "amlogic,meson-gx-ao-cec"
+
+  - reg : Physical base address of the IP registers and length of memory
+ mapped region.
+
+  - interrupts : AO-CEC interrupt number to the CPU.
+  - clocks : from common clock binding: handle to AO-CEC clock.
+  - clock-names : from common clock binding: must contain "core",
+ corresponding to entry in the clocks property.
+  - hdmi-phandle: phandle to the HDMI controller
+
+Example:
+
+cec_AO: cec@100 {
+   compatible = "amlogic,meson-gx-ao-cec";
+   reg = <0x0 0x00100 0x0 0x14>;
+   interrupts = ;
+   clocks = <_AO CLKID_AO_CEC_32K>;
+   clock-names = "core";
+   hdmi-phandle = <_tx>;
+};
-- 
1.9.1



Re: [PATCH 1/2] platform: Add Amlogic Meson AO CEC Controller driver

2017-07-06 Thread Neil Armstrong
On 07/06/2017 12:55 PM, Hans Verkuil wrote:
> On 07/06/17 12:27, Neil Armstrong wrote:
>> The Amlogic SoC embeds a standalone CEC controller, this patch adds a driver
>> for such controller.
>> The controller does not need HPD to be active, and could support up to max
>> 5 logical addresses, but only 1 is handled since the Suspend firmware can
>> make use of this unique logical address to wake up the device.
>>
>> The Suspend firmware configuration will be added in an other patchset.
>>
>> Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
>> ---
>>  drivers/media/platform/Kconfig|  11 +
>>  drivers/media/platform/Makefile   |   2 +
>>  drivers/media/platform/meson/Makefile |   1 +
>>  drivers/media/platform/meson/ao-cec.c | 653 
>> ++
>>  4 files changed, 667 insertions(+)
>>  create mode 100644 drivers/media/platform/meson/Makefile
>>  create mode 100644 drivers/media/platform/meson/ao-cec.c
>>
>> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
>> index 1313cd5..1e67381 100644
>> --- a/drivers/media/platform/Kconfig
>> +++ b/drivers/media/platform/Kconfig
>> @@ -536,6 +536,17 @@ menuconfig CEC_PLATFORM_DRIVERS
>>  
>>  if CEC_PLATFORM_DRIVERS
>>  
>> +config VIDEO_MESON_AO_CEC
>> +tristate "Amlogic Meson AO CEC driver"
>> +depends on ARCH_MESON || COMPILE_TEST
>> +select CEC_CORE
>> +select CEC_NOTIFIER
>> +---help---
>> +  This is a driver for Amlogic Meson SoCs AO CEC interface. It uses the
>> +  generic CEC framework interface.
>> +  CEC bus is present in the HDMI connector and enables communication
>> +  between compatible devices.
>> +
>>  config VIDEO_SAMSUNG_S5P_CEC
>> tristate "Samsung S5P CEC driver"
>> depends on PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST
>> diff --git a/drivers/media/platform/Makefile 
>> b/drivers/media/platform/Makefile
>> index 9beadc7..a52d7b6 100644
>> --- a/drivers/media/platform/Makefile
>> +++ b/drivers/media/platform/Makefile
>> @@ -86,3 +86,5 @@ obj-$(CONFIG_VIDEO_MEDIATEK_MDP)   += mtk-mdp/
>>  obj-$(CONFIG_VIDEO_MEDIATEK_JPEG)   += mtk-jpeg/
>>  
>>  obj-$(CONFIG_VIDEO_QCOM_VENUS)  += qcom/venus/
>> +
>> +obj-y   += meson/
>> diff --git a/drivers/media/platform/meson/Makefile 
>> b/drivers/media/platform/meson/Makefile
>> new file mode 100644
>> index 000..597beb8
>> --- /dev/null
>> +++ b/drivers/media/platform/meson/Makefile
>> @@ -0,0 +1 @@
>> +obj-$(CONFIG_VIDEO_MESON_AO_CEC)+= ao-cec.o
>> diff --git a/drivers/media/platform/meson/ao-cec.c 
>> b/drivers/media/platform/meson/ao-cec.c
>> new file mode 100644
>> index 000..26d7c3e8
>> --- /dev/null
>> +++ b/drivers/media/platform/meson/ao-cec.c
>> @@ -0,0 +1,653 @@
>> +/*
>> + * Driver for Amlogic Meson AO CEC Controller
>> + *
>> + * Copyright (C) 2015 Amlogic, Inc. All rights reserved
>> + * Copyright (C) 2017 BayLibre, SAS
>> + * Author: Neil Armstrong <narmstr...@baylibre.com>
>> + *
>> + * SPDX-License-Identifier: GPL-2.0+
>> + */
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +/* CEC Registers */
>> +
>> +/*
>> + * [2:1] cntl_clk
>> + *  - 0 = Disable clk (Power-off mode)
>> + *  - 1 = Enable gated clock (Normal mode)
>> + *  - 2 = Enable free-run clk (Debug mode)
>> + */
>> +#define CEC_GEN_CNTL_REG0x00
>> +
>> +#define CEC_GEN_CNTL_RESET  BIT(0)
>> +#define CEC_GEN_CNTL_CLK_DISABLE0
>> +#define CEC_GEN_CNTL_CLK_ENABLE 1
>> +#define CEC_GEN_CNTL_CLK_ENABLE_DBG 2
>> +#define CEC_GEN_CNTL_CLK_CTRL_MASK  GENMASK(2, 1)
>> +
>> +/*
>> + * [7:0] cec_reg_addr
>> + * [15:8] cec_reg_wrdata
>> + * [16] cec_reg_wr
>> + *  - 0 = Read
>> + *  - 1 = Write
>> + * [23] bus free
>> + * [31:24] cec_reg_rddata
>> + */
>> +#define CEC_RW_REG  0x04
>> +
>> +#define CEC_RW_ADDR GENMASK(7, 0)
>> +#define CEC_RW_WR_DATA  GENMASK(15, 8)
>> +#define CEC_RW_WRITE_EN BIT(16)
>> +#define CEC_RW_BUS_BU

[PATCH 2/2] dt-bindings: media: Add Amlogic Meson AO-CEC bindings

2017-07-06 Thread Neil Armstrong
The Amlogic SoCs embeds a standalone CEC Controller, this patch adds this
device bindings.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 .../devicetree/bindings/media/meson-ao-cec.txt | 28 ++
 1 file changed, 28 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/meson-ao-cec.txt

diff --git a/Documentation/devicetree/bindings/media/meson-ao-cec.txt 
b/Documentation/devicetree/bindings/media/meson-ao-cec.txt
new file mode 100644
index 000..8671bdb
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/meson-ao-cec.txt
@@ -0,0 +1,28 @@
+* Amlogic Meson AO-CEC driver
+
+The Amlogic Meson AO-CEC module is present is Amlogic SoCs and its purpose is
+to handle communication between HDMI connected devices over the CEC bus.
+
+Required properties:
+  - compatible : value should be following
+   "amlogic,meson-gx-ao-cec"
+
+  - reg : Physical base address of the IP registers and length of memory
+ mapped region.
+
+  - interrupts : AO-CEC interrupt number to the CPU.
+  - clocks : from common clock binding: handle to AO-CEC clock.
+  - clock-names : from common clock binding: must contain "core",
+ corresponding to entry in the clocks property.
+  - hdmi-phandle: phandle to the HDMI controller
+
+Example:
+
+cec_AO: cec@100 {
+   compatible = "amlogic,meson-gx-ao-cec";
+   reg = <0x0 0x00100 0x0 0x14>;
+   interrupts = ;
+   clocks = <_AO CLKID_AO_CEC_32K>;
+   clock-names = "core";
+   hdmi-phandle = <_tx>;
+};
-- 
1.9.1



[PATCH 0/2] media: Add Amlogic Meson AO CEC Controller support

2017-07-06 Thread Neil Armstrong
The Amlogic SoC embeds a standalone CEC controller, this patch adds a driver
for such controller.
The controller does not need HPD to be active, and could support up to max
5 logical addresses, but only 1 is handled since the Suspend firmware can
make use of this unique logical address to wake up the device.

The Suspend firmware configuration will be added in an other patchset.

Neil Armstrong (2):
  platform: Add Amlogic Meson AO CEC Controller driver
  dt-bindings: media: Add Amlogic Meson AO-CEC bindings

 .../devicetree/bindings/media/meson-ao-cec.txt |  28 +
 drivers/media/platform/Kconfig |  11 +
 drivers/media/platform/Makefile|   2 +
 drivers/media/platform/meson/Makefile  |   1 +
 drivers/media/platform/meson/ao-cec.c  | 653 +
 5 files changed, 695 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/meson-ao-cec.txt
 create mode 100644 drivers/media/platform/meson/Makefile
 create mode 100644 drivers/media/platform/meson/ao-cec.c

-- 
1.9.1



[PATCH 1/2] platform: Add Amlogic Meson AO CEC Controller driver

2017-07-06 Thread Neil Armstrong
The Amlogic SoC embeds a standalone CEC controller, this patch adds a driver
for such controller.
The controller does not need HPD to be active, and could support up to max
5 logical addresses, but only 1 is handled since the Suspend firmware can
make use of this unique logical address to wake up the device.

The Suspend firmware configuration will be added in an other patchset.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/media/platform/Kconfig|  11 +
 drivers/media/platform/Makefile   |   2 +
 drivers/media/platform/meson/Makefile |   1 +
 drivers/media/platform/meson/ao-cec.c | 653 ++
 4 files changed, 667 insertions(+)
 create mode 100644 drivers/media/platform/meson/Makefile
 create mode 100644 drivers/media/platform/meson/ao-cec.c

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 1313cd5..1e67381 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -536,6 +536,17 @@ menuconfig CEC_PLATFORM_DRIVERS
 
 if CEC_PLATFORM_DRIVERS
 
+config VIDEO_MESON_AO_CEC
+   tristate "Amlogic Meson AO CEC driver"
+   depends on ARCH_MESON || COMPILE_TEST
+   select CEC_CORE
+   select CEC_NOTIFIER
+   ---help---
+ This is a driver for Amlogic Meson SoCs AO CEC interface. It uses the
+ generic CEC framework interface.
+ CEC bus is present in the HDMI connector and enables communication
+ between compatible devices.
+
 config VIDEO_SAMSUNG_S5P_CEC
tristate "Samsung S5P CEC driver"
depends on PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 9beadc7..a52d7b6 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -86,3 +86,5 @@ obj-$(CONFIG_VIDEO_MEDIATEK_MDP)  += mtk-mdp/
 obj-$(CONFIG_VIDEO_MEDIATEK_JPEG)  += mtk-jpeg/
 
 obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/
+
+obj-y  += meson/
diff --git a/drivers/media/platform/meson/Makefile 
b/drivers/media/platform/meson/Makefile
new file mode 100644
index 000..597beb8
--- /dev/null
+++ b/drivers/media/platform/meson/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VIDEO_MESON_AO_CEC)   += ao-cec.o
diff --git a/drivers/media/platform/meson/ao-cec.c 
b/drivers/media/platform/meson/ao-cec.c
new file mode 100644
index 000..26d7c3e8
--- /dev/null
+++ b/drivers/media/platform/meson/ao-cec.c
@@ -0,0 +1,653 @@
+/*
+ * Driver for Amlogic Meson AO CEC Controller
+ *
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved
+ * Copyright (C) 2017 BayLibre, SAS
+ * Author: Neil Armstrong <narmstr...@baylibre.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* CEC Registers */
+
+/*
+ * [2:1] cntl_clk
+ *  - 0 = Disable clk (Power-off mode)
+ *  - 1 = Enable gated clock (Normal mode)
+ *  - 2 = Enable free-run clk (Debug mode)
+ */
+#define CEC_GEN_CNTL_REG   0x00
+
+#define CEC_GEN_CNTL_RESET BIT(0)
+#define CEC_GEN_CNTL_CLK_DISABLE   0
+#define CEC_GEN_CNTL_CLK_ENABLE1
+#define CEC_GEN_CNTL_CLK_ENABLE_DBG2
+#define CEC_GEN_CNTL_CLK_CTRL_MASK GENMASK(2, 1)
+
+/*
+ * [7:0] cec_reg_addr
+ * [15:8] cec_reg_wrdata
+ * [16] cec_reg_wr
+ *  - 0 = Read
+ *  - 1 = Write
+ * [23] bus free
+ * [31:24] cec_reg_rddata
+ */
+#define CEC_RW_REG 0x04
+
+#define CEC_RW_ADDRGENMASK(7, 0)
+#define CEC_RW_WR_DATA GENMASK(15, 8)
+#define CEC_RW_WRITE_ENBIT(16)
+#define CEC_RW_BUS_BUSYBIT(23)
+#define CEC_RW_RD_DATA GENMASK(31, 24)
+
+/*
+ * [1] tx intr
+ * [2] rx intr
+ */
+#define CEC_INTR_MASKN_REG 0x08
+#define CEC_INTR_CLR_REG   0x0c
+#define CEC_INTR_STAT_REG  0x10
+
+#define CEC_INTR_TXBIT(1)
+#define CEC_INTR_RXBIT(2)
+
+/* CEC Commands */
+
+#define CEC_TX_MSG_0_HEADER0x00
+#define CEC_TX_MSG_1_OPCODE0x01
+#define CEC_TX_MSG_2_OP1   0x02
+#define CEC_TX_MSG_3_OP2   0x03
+#define CEC_TX_MSG_4_OP3   0x04
+#define CEC_TX_MSG_5_OP4   0x05
+#define CEC_TX_MSG_6_OP5   0x06
+#define CEC_TX_MSG_7_OP6   0x07
+#define CEC_TX_MSG_8_OP7   0x08
+#define CEC_TX_MSG_9_OP8   0x09
+#define CEC_TX_MSG_A_OP9   0x0A
+#define CEC_TX_MSG_B_OP10  0x0B
+#define CEC_TX_MSG_C_OP11  0x0C
+#define CEC_TX_MSG_D_OP12  0x0D
+#define CEC_TX_MSG_E_OP13  0x0E
+#define CEC_TX_MSG_F_OP14  0x0F
+#define CEC_TX_MSG_LENGTH  0x10
+#define CEC

Re: [ANN] HDMI CEC Status Update

2017-05-30 Thread Neil Armstrong
Hi Hans,

On 05/30/2017 08:53 AM, Hans Verkuil wrote:
> For those who are interested in HDMI CEC support I made a little status
> document that I intend to keep up to date:
> 
> https://hverkuil.home.xs4all.nl/cec-status.txt
> 
> My goal is to get CEC supported for any mainlined HDMI driver where the 
> hardware
> supports CEC.
> 
> If anyone is working on a CEC driver that I don't know already about, just 
> drop
> me an email so I can update the status.
> 
> I also started maintaining a list of DisplayPort to HDMI adapters that support
> CEC. If you have one that works and is not on the list, then please let me 
> know.
> Seeing /dev/cecX is not enough, some adapters do not connect the CEC pin, so 
> they
> won't be able to detect any other CEC devices. See the test instructions in 
> the
> cec-status.txt file on how to make sure the adapter has a working CEC pin. I
> plan to do some more testing this week, so hopefully the list will expand.
> 
> Thanks!
> 
> Hans

Following our discussion on IRC,
I'm working on a CEC driver for the standalone Amlogic CEC Controller that is 
able
to wake up the device from Suspend or Power Off mode by passing infos to the FW.

I initially planned to use the DW-HDMI CEC controller but I recently found out 
that
on the Amlogic Meson GX SoCs, the CEC line can be pinmuxed to either an Amlogic 
custom
controller or either to a Synopsys IP.

But it's connected to the Synopsys HDMI-RX controller... so my plan to use 
Russell's code
is now dead.

Anyway, I'll still need to have the CEC notifier suport for DW-HDMI, so I made 
a rebase/cleanup
of Russell's driver on 4.12-rc3 :
https://github.com/superna/linux/commits/amlogic/v4.12/rmk-dw-hdmi-cec
The rebase is aligned on dw-hdmi-i2s to use the bridge read/write ops.

Neil


[PATCH] media: rc: meson-ir: store raw event without processing

2017-04-25 Thread Neil Armstrong
From: Jonas Karlman <jo...@kwiboo.se>

This patch fixes meson-it driver by storing event without processing
to avoid losing key pressed events when system is loaded and events
are occurring too fast.

This issue was reported at [1]

[1] https://github.com/LibreELEC/linux-amlogic/pull/42

Signed-off-by: Jonas Karlman <jo...@kwiboo.se>
Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/media/rc/meson-ir.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c
index 5576dbd..42ae2ec 100644
--- a/drivers/media/rc/meson-ir.c
+++ b/drivers/media/rc/meson-ir.c
@@ -97,7 +97,7 @@ static irqreturn_t meson_ir_irq(int irqno, void *dev_id)
 
rawir.pulse = !!(readl(ir->reg + IR_DEC_STATUS) & STATUS_IR_DEC_IN);
 
-   ir_raw_event_store_with_filter(ir->rc, );
+   ir_raw_event_store(ir->rc, );
ir_raw_event_handle(ir->rc);
 
spin_unlock(>lock);
-- 
1.9.1



[PATCH] media: rc: meson-ir: switch config to NEC decoding on shutdown

2017-04-25 Thread Neil Armstrong
From: Alex Deryskyba <a...@codesnake.com>

On the Amlogic SoCs, the bootloader firmware can handle the IR hardware in
order to Wake up or Power back the system when in suspend on shutdown mode.

This patch switches the hardware configuration in a state usable by the
firmware to permit powering the system back.

Some vendor bootloader firmware were modified to switch to this configuration
but it may not be the case for all available products.

This patch was originally posted at [1].

[1] https://github.com/LibreELEC/linux-amlogic/pull/27

Signed-off-by: Alex Deryskyba <a...@codesnake.com>
Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/media/rc/meson-ir.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c
index 42ae2ec..0632f6a 100644
--- a/drivers/media/rc/meson-ir.c
+++ b/drivers/media/rc/meson-ir.c
@@ -211,6 +211,32 @@ static int meson_ir_remove(struct platform_device *pdev)
return 0;
 }
 
+static void meson_ir_shutdown(struct platform_device *pdev)
+{
+   struct device *dev = >dev;
+   struct device_node *node = dev->of_node;
+   struct meson_ir *ir = platform_get_drvdata(pdev);
+   unsigned long flags;
+
+   spin_lock_irqsave(>lock, flags);
+
+   /*
+* Set operation mode to NEC/hardware decoding to give
+* bootloader a chance to power the system back on
+*/
+   if (of_device_is_compatible(node, "amlogic,meson6-ir"))
+   meson_ir_set_mask(ir, IR_DEC_REG1, REG1_MODE_MASK,
+   DECODE_MODE_NEC << REG1_MODE_SHIFT);
+   else
+   meson_ir_set_mask(ir, IR_DEC_REG2, REG2_MODE_MASK,
+   DECODE_MODE_NEC << REG2_MODE_SHIFT);
+
+   /* Set rate to default value */
+   meson_ir_set_mask(ir, IR_DEC_REG0, REG0_RATE_MASK, 0x13);
+
+   spin_unlock_irqrestore(>lock, flags);
+}
+
 static const struct of_device_id meson_ir_match[] = {
{ .compatible = "amlogic,meson6-ir" },
{ .compatible = "amlogic,meson8b-ir" },
@@ -222,6 +248,7 @@ static int meson_ir_remove(struct platform_device *pdev)
 static struct platform_driver meson_ir_driver = {
.probe  = meson_ir_probe,
.remove = meson_ir_remove,
+   .shutdown   = meson_ir_shutdown,
.driver = {
.name   = DRIVER_NAME,
.of_match_table = meson_ir_match,
-- 
1.9.1



[PATCH] ARM64: defconfig: enable IR core, decoders and Meson IR device

2017-04-25 Thread Neil Armstrong
This patch enables the MEDIA Infrared RC Decoders and Meson Infrared
decoder for ARM64 defconfig.
These drivers are selected as modules by default.

Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 arch/arm64/configs/defconfig | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c021aefa..59c400f 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -321,6 +321,11 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
 CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
 CONFIG_MEDIA_CONTROLLER=y
+CONFIG_MEDIA_RC_SUPPORT=y
+CONFIG_RC_CORE=y
+CONFIG_RC_DEVICES=y
+CONFIG_RC_DECODERS=y
+CONFIG_IR_MESON=m
 CONFIG_VIDEO_V4L2_SUBDEV_API=y
 # CONFIG_DVB_NET is not set
 CONFIG_V4L_MEM2MEM_DRIVERS=y
-- 
1.9.1



Re: [PATCH 1/5] media: rc: meson-ir: remove irq from struct meson_ir

2017-04-11 Thread Neil Armstrong
On 04/11/2017 07:53 AM, Heiner Kallweit wrote:
> The irq number is used in the probe function only, therefore just use
> a local variable.
> 
> Signed-off-by: Heiner Kallweit 
> ---
>  drivers/media/rc/meson-ir.c | 11 +--
>  1 file changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c
> index 5576dbd6..a4128d7c 100644
> --- a/drivers/media/rc/meson-ir.c
> +++ b/drivers/media/rc/meson-ir.c
> @@ -68,7 +68,6 @@
>  struct meson_ir {
>   void __iomem*reg;
>   struct rc_dev   *rc;
> - int irq;
>   spinlock_t  lock;
>  };
>  
> @@ -112,7 +111,7 @@ static int meson_ir_probe(struct platform_device *pdev)
>   struct resource *res;
>   const char *map_name;
>   struct meson_ir *ir;
> - int ret;
> + int irq, ret;
>  
>   ir = devm_kzalloc(dev, sizeof(struct meson_ir), GFP_KERNEL);
>   if (!ir)
> @@ -125,10 +124,10 @@ static int meson_ir_probe(struct platform_device *pdev)
>   return PTR_ERR(ir->reg);
>   }
>  
> - ir->irq = platform_get_irq(pdev, 0);
> - if (ir->irq < 0) {
> + irq = platform_get_irq(pdev, 0);
> + if (irq < 0) {
>   dev_err(dev, "no irq resource\n");
> - return ir->irq;
> + return irq;
>   }
>  
>   ir->rc = rc_allocate_device(RC_DRIVER_IR_RAW);
> @@ -158,7 +157,7 @@ static int meson_ir_probe(struct platform_device *pdev)
>   goto out_free;
>   }
>  
> - ret = devm_request_irq(dev, ir->irq, meson_ir_irq, 0, "ir-meson", ir);
> + ret = devm_request_irq(dev, irq, meson_ir_irq, 0, "ir-meson", ir);
>   if (ret) {
>   dev_err(dev, "failed to request irq\n");
>   goto out_unreg;
> 

Hi Heiner,

I'm not really convinced this is useful, if somehow for future enhancements we 
need the IRQ
number, this will need to be reverted...

Neil


Re: [PATCH 3/5] media: rc: meson-ir: switch to managed rc device allocation / registration

2017-04-11 Thread Neil Armstrong
On 04/11/2017 08:02 AM, Heiner Kallweit wrote:
> Switch to the managed versions of rc_allocate_device/rc_register_device,
> thus simplifying the code.
> 
> Signed-off-by: Heiner Kallweit <hkallwe...@gmail.com>
> ---
>  drivers/media/rc/meson-ir.c | 18 --
>  1 file changed, 4 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c
> index a52036c5..d56ef27e 100644
> --- a/drivers/media/rc/meson-ir.c
> +++ b/drivers/media/rc/meson-ir.c
> @@ -128,7 +128,7 @@ static int meson_ir_probe(struct platform_device *pdev)
>   return irq;
>   }
>  
> - ir->rc = rc_allocate_device(RC_DRIVER_IR_RAW);
> + ir->rc = devm_rc_allocate_device(dev, RC_DRIVER_IR_RAW);
>   if (!ir->rc) {
>   dev_err(dev, "failed to allocate rc device\n");
>   return -ENOMEM;
> @@ -140,7 +140,6 @@ static int meson_ir_probe(struct platform_device *pdev)
>   ir->rc->input_id.bustype = BUS_HOST;
>   map_name = of_get_property(node, "linux,rc-map-name", NULL);
>   ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY;
> - ir->rc->dev.parent = dev;
>   ir->rc->allowed_protocols = RC_BIT_ALL_IR_DECODER;
>   ir->rc->rx_resolution = US_TO_NS(MESON_TRATE);
>   ir->rc->timeout = MS_TO_NS(200);
> @@ -149,16 +148,16 @@ static int meson_ir_probe(struct platform_device *pdev)
>   spin_lock_init(>lock);
>   platform_set_drvdata(pdev, ir);
>  
> - ret = rc_register_device(ir->rc);
> + ret = devm_rc_register_device(dev, ir->rc);
>   if (ret) {
>   dev_err(dev, "failed to register rc device\n");
> - goto out_free;
> + return ret;
>   }
>  
>   ret = devm_request_irq(dev, irq, meson_ir_irq, 0, "ir-meson", ir);
>   if (ret) {
>   dev_err(dev, "failed to request irq\n");
> - goto out_unreg;
> + return ret;
>   }
>  
>   /* Reset the decoder */
> @@ -184,13 +183,6 @@ static int meson_ir_probe(struct platform_device *pdev)
>   dev_info(dev, "receiver initialized\n");
>  
>   return 0;
> -out_unreg:
> - rc_unregister_device(ir->rc);
> - ir->rc = NULL;
> -out_free:
> - rc_free_device(ir->rc);
> -
> - return ret;
>  }
>  
>  static int meson_ir_remove(struct platform_device *pdev)
> @@ -203,8 +195,6 @@ static int meson_ir_remove(struct platform_device *pdev)
>   meson_ir_set_mask(ir, IR_DEC_REG1, REG1_ENABLE, 0);
>   spin_unlock_irqrestore(>lock, flags);
>  
> - rc_unregister_device(ir->rc);
> -
>   return 0;
>  }
>  
> 

Reviewed-by: Neil Armstrong <narmstr...@baylibre.com>


Re: [PATCH 4/5] media: rc: meson-ir: use readl_relaxed in the interrupt handler

2017-04-11 Thread Neil Armstrong
On 04/11/2017 08:05 AM, Heiner Kallweit wrote:
> We don't need the memory barriers here and an interrupt handler should
> be as fast as possible. Therefore switch to readl_relaxed.
> 
> Signed-off-by: Heiner Kallweit <hkallwe...@gmail.com>
> ---
>  drivers/media/rc/meson-ir.c | 7 ---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c
> index d56ef27e..246da2db 100644
> --- a/drivers/media/rc/meson-ir.c
> +++ b/drivers/media/rc/meson-ir.c
> @@ -83,16 +83,17 @@ static void meson_ir_set_mask(struct meson_ir *ir, 
> unsigned int reg,
>  static irqreturn_t meson_ir_irq(int irqno, void *dev_id)
>  {
>   struct meson_ir *ir = dev_id;
> - u32 duration;
> + u32 duration, status;
>   DEFINE_IR_RAW_EVENT(rawir);
>  
>   spin_lock(>lock);
>  
> - duration = readl(ir->reg + IR_DEC_REG1);
> + duration = readl_relaxed(ir->reg + IR_DEC_REG1);
>   duration = FIELD_GET(REG1_TIME_IV_MASK, duration);
>   rawir.duration = US_TO_NS(duration * MESON_TRATE);
>  
> - rawir.pulse = !!(readl(ir->reg + IR_DEC_STATUS) & STATUS_IR_DEC_IN);
> + status = readl_relaxed(ir->reg + IR_DEC_STATUS);
> + rawir.pulse = !!(status & STATUS_IR_DEC_IN);
>  
>   ir_raw_event_store_with_filter(ir->rc, );
>   ir_raw_event_handle(ir->rc);
> 

Reviewed-by: Neil Armstrong <narmstr...@baylibre.com>


Re: [PATCH v6.1 0/4] drm: bridge: dw-hdmi: Add support for Custom PHYs

2017-04-04 Thread Neil Armstrong
On 04/04/2017 02:31 PM, Neil Armstrong wrote:
> The Amlogic GX SoCs implements a Synopsys DesignWare HDMI TX Controller
> in combination with a very custom PHY.
> 
> Thanks to Laurent Pinchart's changes, the HW report the following :
>  Detected HDMI TX controller v2.01a with HDCP (meson_dw_hdmi_phy)
> 
> The following differs from common PHY integration as managed in the current
> driver :
>  - Amlogic PHY is not configured through the internal I2C link
>  - Amlogic PHY do not use the ENTMDS, SVSRET, PDDQ, ... signals from the 
> controller
>  - Amlogic PHY do not export HPD ands RxSense signals to the controller
> 
> And finally, concerning the controller integration :
>  - the Controller registers are not flat memory-mapped, and uses an
> addr+read/write register pair to write all registers.
>  - Inputs only YUV444 pixel data
> 
> Most of these uses case are implemented in Laurent Pinchart v5.1 patchset 
> merged
> in drm-misc-next branch.
> 
> This is why the following patchset implements :
>  - Configure the Input format from the plat_data
>  - Add PHY callback to handle HPD and RxSense out of the dw-hdmi driver
> 
> To implement the input format handling, the Synopsys HDMIT TX Controller input
> V4L bus formats are used and missing formats + documentation are added.
> 
> This patchset makes the Amlogic GX SoCs HDMI output successfully work, and is
> also tested on the RK3288 ACT8846 EVB Board.
> 
> Changes since v6 at [8] :
>  - Dropped already merged media patches in 
> topic/synopsys-media-formats-2017-04-03 tag
>  - Reword the patch "Switch to V4L bus format and encodings" commit message
>  - Fix typo in patch "Switch to V4L bus format and encodings"
>  - Add Laurent Pinchart reviewed/acked-by's
>  - Rebased on drm-misc-next at 9c4ad466d1dd
> 
> Changes since v5.1 at [7] :
>  - Rework of the 48bit tables in V4L bus formats documentation
>  - Add Archit reviewed-by's
> 
> Changes since v5 at [6] :
>  - Small addition in V4L YUV bus formats documentation
> 
> Changes since v4 at [5] :
>  - Rebased on drm-misc-next at bd283d2f66c2
>  - Fix 4:2:0 bus formats naming
>  - Renamed function fd_registered to i2c_init in dw-hdmi.c
> 
> Changes since v3 at [4] :
>  - Fix 4:2:0 bus formats naming
>  - Add separate 36bit and 48bit tables for bus formats documentation
>  - Added 4:2:0 bus config in hdmi_video_sample
>  - Moved dw_hdmi documentation in a "bridge" subdir
>  - Rebase on drm-misc-next at 62c58af32c93
> 
> Changes since v2 at [3] :
>  - Rebase on laurent patch "Extract PHY interrupt setup to a function"
>  - Reduce phy operations
>  - Switch the V4L bus formats and encodings instead of custom enum
> 
> Changes since v1 at [2] :
>  - Drop patches submitted by laurent
> 
> Changes since RFC at [1] :
>  - Regmap fixup for 4bytes register access, tested on RK3288 SoC
>  - Move phy callbacks to phy_ops and move Synopsys PHY calls into default ops
>  - Move HDMI link data into shared header
>  - Move Pixel Encoding enum to shared header
> 
> [1] 
> http://lkml.kernel.org/r/1484656294-6140-1-git-send-email-narmstr...@baylibre.com
> [2] 
> http://lkml.kernel.org/r/1485774318-21916-1-git-send-email-narmstr...@baylibre.com
> [3] 
> http://lkml.kernel.org/r/1488468572-31971-1-git-send-email-narmstr...@baylibre.com
> [4] 
> http://lkml.kernel.org/r/1488904944-14285-1-git-send-email-narmstr...@baylibre.com
> [5] 
> http://lkml.kernel.org/r/1490109161-20529-1-git-send-email-narmstr...@baylibre.com
> [6] 
> http://lkml.kernel.org/r/1490864675-17336-1-git-send-email-narmstr...@baylibre.com
> [7] 
> http://lkml.kernel.org/r/1490970319-24981-1-git-send-email-narmstr...@baylibre.com
> [8] 
> http://lkml.kernel.org/r/1491230558-10804-1-git-send-email-narmstr...@baylibre.com
> 
> Laurent Pinchart (1):
>   drm: bridge: dw-hdmi: Extract PHY interrupt setup to a function
> 
> Neil Armstrong (3):
>   drm: bridge: dw-hdmi: Switch to V4L bus format and encodings
>   drm: bridge: dw-hdmi: Add Documentation on supported input formats
>   drm: bridge: dw-hdmi: Move HPD handling to PHY operations
> 
>  Documentation/gpu/bridge/dw-hdmi.rst  |  15 +
>  Documentation/gpu/index.rst   |   1 +
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 470 
> --
>  include/drm/bridge/dw_hdmi.h  |  68 +
>  4 files changed, 398 insertions(+), 156 deletions(-)
>  create mode 100644 Documentation/gpu/bridge/dw-hdmi.rst
> 

Applied to drm-misc-next

Thanks Daniel, Sean,
Neil


[PATCH v6.1 1/4] drm: bridge: dw-hdmi: Extract PHY interrupt setup to a function

2017-04-04 Thread Neil Armstrong
From: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>

In preparation for adding PHY operations to handle RX SENSE and HPD,
group all the PHY interrupt setup code in a single location and extract
it to a separate function.

Signed-off-by: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
Reviewed-by: Jose Abreu <joab...@synopsys.com>
[narmstrong: renamed dw_hdmi_fb_registered to dw_hdmi_setup_i2c]
Reviewed-by: Archit Taneja <arch...@codeaurora.org>
Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 51 ++-
 1 file changed, 23 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 32f02e9..ff1fae3 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1558,8 +1558,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct 
drm_display_mode *mode)
return 0;
 }
 
-/* Wait until we are registered to enable interrupts */
-static int dw_hdmi_fb_registered(struct dw_hdmi *hdmi)
+static void dw_hdmi_setup_i2c(struct dw_hdmi *hdmi)
 {
hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
HDMI_PHY_I2CM_INT_ADDR);
@@ -1567,15 +1566,6 @@ static int dw_hdmi_fb_registered(struct dw_hdmi *hdmi)
hdmi_writeb(hdmi, HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL |
HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL,
HDMI_PHY_I2CM_CTLINT_ADDR);
-
-   /* enable cable hot plug irq */
-   hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0);
-
-   /* Clear Hotplug interrupts */
-   hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE,
-   HDMI_IH_PHY_STAT0);
-
-   return 0;
 }
 
 static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
@@ -1693,6 +1683,26 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi)
hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0);
 }
 
+static void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi)
+{
+   /*
+* Configure the PHY RX SENSE and HPD interrupts polarities and clear
+* any pending interrupt.
+*/
+   hdmi_writeb(hdmi, HDMI_PHY_HPD | HDMI_PHY_RX_SENSE, HDMI_PHY_POL0);
+   hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE,
+   HDMI_IH_PHY_STAT0);
+
+   /* Enable cable hot plug irq. */
+   hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0);
+
+   /* Clear and unmute interrupts. */
+   hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE,
+   HDMI_IH_PHY_STAT0);
+   hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE),
+   HDMI_IH_MUTE_PHY_STAT0);
+}
+
 static enum drm_connector_status
 dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 {
@@ -2204,29 +2214,14 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
hdmi->ddc = NULL;
}
 
-   /*
-* Configure registers related to HDMI interrupt
-* generation before registering IRQ.
-*/
-   hdmi_writeb(hdmi, HDMI_PHY_HPD | HDMI_PHY_RX_SENSE, HDMI_PHY_POL0);
-
-   /* Clear Hotplug interrupts */
-   hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE,
-   HDMI_IH_PHY_STAT0);
-
hdmi->bridge.driver_private = hdmi;
hdmi->bridge.funcs = _hdmi_bridge_funcs;
 #ifdef CONFIG_OF
hdmi->bridge.of_node = pdev->dev.of_node;
 #endif
 
-   ret = dw_hdmi_fb_registered(hdmi);
-   if (ret)
-   goto err_iahb;
-
-   /* Unmute interrupts */
-   hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE),
-   HDMI_IH_MUTE_PHY_STAT0);
+   dw_hdmi_setup_i2c(hdmi);
+   dw_hdmi_phy_setup_hpd(hdmi);
 
memset(, 0, sizeof(pdevinfo));
pdevinfo.parent = dev;
-- 
1.9.1



[PATCH v6.1 0/4] drm: bridge: dw-hdmi: Add support for Custom PHYs

2017-04-04 Thread Neil Armstrong
The Amlogic GX SoCs implements a Synopsys DesignWare HDMI TX Controller
in combination with a very custom PHY.

Thanks to Laurent Pinchart's changes, the HW report the following :
 Detected HDMI TX controller v2.01a with HDCP (meson_dw_hdmi_phy)

The following differs from common PHY integration as managed in the current
driver :
 - Amlogic PHY is not configured through the internal I2C link
 - Amlogic PHY do not use the ENTMDS, SVSRET, PDDQ, ... signals from the 
controller
 - Amlogic PHY do not export HPD ands RxSense signals to the controller

And finally, concerning the controller integration :
 - the Controller registers are not flat memory-mapped, and uses an
addr+read/write register pair to write all registers.
 - Inputs only YUV444 pixel data

Most of these uses case are implemented in Laurent Pinchart v5.1 patchset merged
in drm-misc-next branch.

This is why the following patchset implements :
 - Configure the Input format from the plat_data
 - Add PHY callback to handle HPD and RxSense out of the dw-hdmi driver

To implement the input format handling, the Synopsys HDMIT TX Controller input
V4L bus formats are used and missing formats + documentation are added.

This patchset makes the Amlogic GX SoCs HDMI output successfully work, and is
also tested on the RK3288 ACT8846 EVB Board.

Changes since v6 at [8] :
 - Dropped already merged media patches in 
topic/synopsys-media-formats-2017-04-03 tag
 - Reword the patch "Switch to V4L bus format and encodings" commit message
 - Fix typo in patch "Switch to V4L bus format and encodings"
 - Add Laurent Pinchart reviewed/acked-by's
 - Rebased on drm-misc-next at 9c4ad466d1dd

Changes since v5.1 at [7] :
 - Rework of the 48bit tables in V4L bus formats documentation
 - Add Archit reviewed-by's

Changes since v5 at [6] :
 - Small addition in V4L YUV bus formats documentation

Changes since v4 at [5] :
 - Rebased on drm-misc-next at bd283d2f66c2
 - Fix 4:2:0 bus formats naming
 - Renamed function fd_registered to i2c_init in dw-hdmi.c

Changes since v3 at [4] :
 - Fix 4:2:0 bus formats naming
 - Add separate 36bit and 48bit tables for bus formats documentation
 - Added 4:2:0 bus config in hdmi_video_sample
 - Moved dw_hdmi documentation in a "bridge" subdir
 - Rebase on drm-misc-next at 62c58af32c93

Changes since v2 at [3] :
 - Rebase on laurent patch "Extract PHY interrupt setup to a function"
 - Reduce phy operations
 - Switch the V4L bus formats and encodings instead of custom enum

Changes since v1 at [2] :
 - Drop patches submitted by laurent

Changes since RFC at [1] :
 - Regmap fixup for 4bytes register access, tested on RK3288 SoC
 - Move phy callbacks to phy_ops and move Synopsys PHY calls into default ops
 - Move HDMI link data into shared header
 - Move Pixel Encoding enum to shared header

[1] 
http://lkml.kernel.org/r/1484656294-6140-1-git-send-email-narmstr...@baylibre.com
[2] 
http://lkml.kernel.org/r/1485774318-21916-1-git-send-email-narmstr...@baylibre.com
[3] 
http://lkml.kernel.org/r/1488468572-31971-1-git-send-email-narmstr...@baylibre.com
[4] 
http://lkml.kernel.org/r/1488904944-14285-1-git-send-email-narmstr...@baylibre.com
[5] 
http://lkml.kernel.org/r/1490109161-20529-1-git-send-email-narmstr...@baylibre.com
[6] 
http://lkml.kernel.org/r/1490864675-17336-1-git-send-email-narmstr...@baylibre.com
[7] 
http://lkml.kernel.org/r/1490970319-24981-1-git-send-email-narmstr...@baylibre.com
[8] 
http://lkml.kernel.org/r/1491230558-10804-1-git-send-email-narmstr...@baylibre.com

Laurent Pinchart (1):
  drm: bridge: dw-hdmi: Extract PHY interrupt setup to a function

Neil Armstrong (3):
  drm: bridge: dw-hdmi: Switch to V4L bus format and encodings
  drm: bridge: dw-hdmi: Add Documentation on supported input formats
  drm: bridge: dw-hdmi: Move HPD handling to PHY operations

 Documentation/gpu/bridge/dw-hdmi.rst  |  15 +
 Documentation/gpu/index.rst   |   1 +
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 470 --
 include/drm/bridge/dw_hdmi.h  |  68 +
 4 files changed, 398 insertions(+), 156 deletions(-)
 create mode 100644 Documentation/gpu/bridge/dw-hdmi.rst

-- 
1.9.1



[PATCH v6.1 2/4] drm: bridge: dw-hdmi: Switch to V4L bus format and encodings

2017-04-04 Thread Neil Armstrong
Switch code to use the newly introduced V4L bus formats IDs instead of custom
defines. Also use the V4L encoding defines.

Some display pipelines can only provide non-RBG input pixels to the HDMI TX
Controller, this patch takes the pixel format from the plat_data if provided.

Reviewed-by: Jose Abreu <joab...@synopsys.com>
Reviewed-by: Archit Taneja <arch...@codeaurora.org>
Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
Signed-off-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 326 +-
 include/drm/bridge/dw_hdmi.h  |  63 ++
 2 files changed, 294 insertions(+), 95 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index ff1fae3..16d5fff3 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -30,18 +30,15 @@
 #include 
 #include 
 
+#include 
+#include 
+
 #include "dw-hdmi.h"
 #include "dw-hdmi-audio.h"
 
 #define DDC_SEGMENT_ADDR   0x30
 #define HDMI_EDID_LEN  512
 
-#define RGB0
-#define YCBCR444   1
-#define YCBCR422_16BITS2
-#define YCBCR422_8BITS 3
-#define XVYCC444   4
-
 enum hdmi_datamap {
RGB444_8B = 0x01,
RGB444_10B = 0x03,
@@ -95,10 +92,10 @@ struct hdmi_vmode {
 };
 
 struct hdmi_data_info {
-   unsigned int enc_in_format;
-   unsigned int enc_out_format;
-   unsigned int enc_color_depth;
-   unsigned int colorimetry;
+   unsigned int enc_in_bus_format;
+   unsigned int enc_out_bus_format;
+   unsigned int enc_in_encoding;
+   unsigned int enc_out_encoding;
unsigned int pix_repet_factor;
unsigned int hdcp_enable;
struct hdmi_vmode video_mode;
@@ -567,6 +564,92 @@ void dw_hdmi_audio_disable(struct dw_hdmi *hdmi)
 }
 EXPORT_SYMBOL_GPL(dw_hdmi_audio_disable);
 
+static bool hdmi_bus_fmt_is_rgb(unsigned int bus_format)
+{
+   switch (bus_format) {
+   case MEDIA_BUS_FMT_RGB888_1X24:
+   case MEDIA_BUS_FMT_RGB101010_1X30:
+   case MEDIA_BUS_FMT_RGB121212_1X36:
+   case MEDIA_BUS_FMT_RGB161616_1X48:
+   return true;
+
+   default:
+   return false;
+   }
+}
+
+static bool hdmi_bus_fmt_is_yuv444(unsigned int bus_format)
+{
+   switch (bus_format) {
+   case MEDIA_BUS_FMT_YUV8_1X24:
+   case MEDIA_BUS_FMT_YUV10_1X30:
+   case MEDIA_BUS_FMT_YUV12_1X36:
+   case MEDIA_BUS_FMT_YUV16_1X48:
+   return true;
+
+   default:
+   return false;
+   }
+}
+
+static bool hdmi_bus_fmt_is_yuv422(unsigned int bus_format)
+{
+   switch (bus_format) {
+   case MEDIA_BUS_FMT_UYVY8_1X16:
+   case MEDIA_BUS_FMT_UYVY10_1X20:
+   case MEDIA_BUS_FMT_UYVY12_1X24:
+   return true;
+
+   default:
+   return false;
+   }
+}
+
+static bool hdmi_bus_fmt_is_yuv420(unsigned int bus_format)
+{
+   switch (bus_format) {
+   case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
+   case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
+   case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
+   case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
+   return true;
+
+   default:
+   return false;
+   }
+}
+
+static int hdmi_bus_fmt_color_depth(unsigned int bus_format)
+{
+   switch (bus_format) {
+   case MEDIA_BUS_FMT_RGB888_1X24:
+   case MEDIA_BUS_FMT_YUV8_1X24:
+   case MEDIA_BUS_FMT_UYVY8_1X16:
+   case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
+   return 8;
+
+   case MEDIA_BUS_FMT_RGB101010_1X30:
+   case MEDIA_BUS_FMT_YUV10_1X30:
+   case MEDIA_BUS_FMT_UYVY10_1X20:
+   case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
+   return 10;
+
+   case MEDIA_BUS_FMT_RGB121212_1X36:
+   case MEDIA_BUS_FMT_YUV12_1X36:
+   case MEDIA_BUS_FMT_UYVY12_1X24:
+   case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
+   return 12;
+
+   case MEDIA_BUS_FMT_RGB161616_1X48:
+   case MEDIA_BUS_FMT_YUV16_1X48:
+   case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
+   return 16;
+
+   default:
+   return 0;
+   }
+}
+
 /*
  * this submodule is responsible for the video data synchronization.
  * for example, for RGB 4:4:4 input, the data map is defined as
@@ -579,37 +662,49 @@ static void hdmi_video_sample(struct dw_hdmi *hdmi)
int color_format = 0;
u8 val;
 
-   if (hdmi->hdmi_data.enc_in_format == RGB) {
-   if (hdmi->hdmi_data.enc_color_depth == 8)
-   color_format = 0x01;
-   else if (hdmi->hdmi_data.enc_color_depth == 10)
-   color_format = 0x03;
-   else if (hdmi->hdmi_data.enc_color_depth == 12)
-   color_format = 0x05;
-   else if (hdmi->hdmi_data.enc_color_depth == 16)
- 

  1   2   >