summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/bridge/lontium-lt9611.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/bridge/lontium-lt9611.c')
-rw-r--r--drivers/gpu/drm/bridge/lontium-lt9611.c143
1 files changed, 81 insertions, 62 deletions
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
index a2d032ee4744..0628d8e737ab 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -843,84 +843,96 @@ lt9611_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
#define LT9611_INFOFRAME_AUDIO 0x02
#define LT9611_INFOFRAME_AVI 0x08
#define LT9611_INFOFRAME_SPD 0x10
-#define LT9611_INFOFRAME_VENDOR 0x20
+#define LT9611_INFOFRAME_HDMI 0x20
-static int lt9611_hdmi_clear_infoframe(struct drm_bridge *bridge,
- enum hdmi_infoframe_type type)
+static int lt9611_hdmi_clear_audio_infoframe(struct drm_bridge *bridge)
{
struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
- unsigned int mask;
- switch (type) {
- case HDMI_INFOFRAME_TYPE_AUDIO:
- mask = LT9611_INFOFRAME_AUDIO;
- break;
+ regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AUDIO, 0);
- case HDMI_INFOFRAME_TYPE_AVI:
- mask = LT9611_INFOFRAME_AVI;
- break;
+ return 0;
+}
- case HDMI_INFOFRAME_TYPE_SPD:
- mask = LT9611_INFOFRAME_SPD;
- break;
+static int lt9611_hdmi_clear_avi_infoframe(struct drm_bridge *bridge)
+{
+ struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
- case HDMI_INFOFRAME_TYPE_VENDOR:
- mask = LT9611_INFOFRAME_VENDOR;
- break;
+ regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AVI, 0);
- default:
- drm_dbg_driver(lt9611->bridge.dev, "Unsupported HDMI InfoFrame %x\n", type);
- mask = 0;
- break;
- }
+ return 0;
+}
+
+static int lt9611_hdmi_clear_spd_infoframe(struct drm_bridge *bridge)
+{
+ struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
- if (mask)
- regmap_update_bits(lt9611->regmap, 0x843d, mask, 0);
+ regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_SPD, 0);
return 0;
}
-static int lt9611_hdmi_write_infoframe(struct drm_bridge *bridge,
- enum hdmi_infoframe_type type,
- const u8 *buffer, size_t len)
+static int lt9611_hdmi_clear_hdmi_infoframe(struct drm_bridge *bridge)
+{
+ struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+
+ regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_HDMI, 0);
+
+ return 0;
+}
+
+static int lt9611_hdmi_write_audio_infoframe(struct drm_bridge *bridge,
+ const u8 *buffer, size_t len)
{
struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
- unsigned int mask, addr;
int i;
- switch (type) {
- case HDMI_INFOFRAME_TYPE_AUDIO:
- mask = LT9611_INFOFRAME_AUDIO;
- addr = 0x84b2;
- break;
-
- case HDMI_INFOFRAME_TYPE_AVI:
- mask = LT9611_INFOFRAME_AVI;
- addr = 0x8440;
- break;
-
- case HDMI_INFOFRAME_TYPE_SPD:
- mask = LT9611_INFOFRAME_SPD;
- addr = 0x8493;
- break;
-
- case HDMI_INFOFRAME_TYPE_VENDOR:
- mask = LT9611_INFOFRAME_VENDOR;
- addr = 0x8474;
- break;
-
- default:
- drm_dbg_driver(lt9611->bridge.dev, "Unsupported HDMI InfoFrame %x\n", type);
- mask = 0;
- break;
- }
+ for (i = 0; i < len; i++)
+ regmap_write(lt9611->regmap, 0x84b2 + i, buffer[i]);
- if (mask) {
- for (i = 0; i < len; i++)
- regmap_write(lt9611->regmap, addr + i, buffer[i]);
+ regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AUDIO, LT9611_INFOFRAME_AUDIO);
- regmap_update_bits(lt9611->regmap, 0x843d, mask, mask);
- }
+ return 0;
+}
+
+static int lt9611_hdmi_write_avi_infoframe(struct drm_bridge *bridge,
+ const u8 *buffer, size_t len)
+{
+ struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+ int i;
+
+ for (i = 0; i < len; i++)
+ regmap_write(lt9611->regmap, 0x8440 + i, buffer[i]);
+
+ regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AVI, LT9611_INFOFRAME_AVI);
+
+ return 0;
+}
+
+static int lt9611_hdmi_write_spd_infoframe(struct drm_bridge *bridge,
+ const u8 *buffer, size_t len)
+{
+ struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+ int i;
+
+ for (i = 0; i < len; i++)
+ regmap_write(lt9611->regmap, 0x8493 + i, buffer[i]);
+
+ regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_SPD, LT9611_INFOFRAME_SPD);
+
+ return 0;
+}
+
+static int lt9611_hdmi_write_hdmi_infoframe(struct drm_bridge *bridge,
+ const u8 *buffer, size_t len)
+{
+ struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+ int i;
+
+ for (i = 0; i < len; i++)
+ regmap_write(lt9611->regmap, 0x8474 + i, buffer[i]);
+
+ regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_HDMI, LT9611_INFOFRAME_HDMI);
return 0;
}
@@ -1003,8 +1015,14 @@ static const struct drm_bridge_funcs lt9611_bridge_funcs = {
.atomic_get_input_bus_fmts = lt9611_atomic_get_input_bus_fmts,
.hdmi_tmds_char_rate_valid = lt9611_hdmi_tmds_char_rate_valid,
- .hdmi_write_infoframe = lt9611_hdmi_write_infoframe,
- .hdmi_clear_infoframe = lt9611_hdmi_clear_infoframe,
+ .hdmi_write_audio_infoframe = lt9611_hdmi_write_audio_infoframe,
+ .hdmi_clear_audio_infoframe = lt9611_hdmi_clear_audio_infoframe,
+ .hdmi_write_avi_infoframe = lt9611_hdmi_write_avi_infoframe,
+ .hdmi_clear_avi_infoframe = lt9611_hdmi_clear_avi_infoframe,
+ .hdmi_write_spd_infoframe = lt9611_hdmi_write_spd_infoframe,
+ .hdmi_clear_spd_infoframe = lt9611_hdmi_clear_spd_infoframe,
+ .hdmi_write_hdmi_infoframe = lt9611_hdmi_write_hdmi_infoframe,
+ .hdmi_clear_hdmi_infoframe = lt9611_hdmi_clear_hdmi_infoframe,
.hdmi_audio_startup = lt9611_hdmi_audio_startup,
.hdmi_audio_prepare = lt9611_hdmi_audio_prepare,
@@ -1132,7 +1150,8 @@ static int lt9611_probe(struct i2c_client *client)
lt9611->bridge.of_node = client->dev.of_node;
lt9611->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
DRM_BRIDGE_OP_HPD | DRM_BRIDGE_OP_MODES |
- DRM_BRIDGE_OP_HDMI | DRM_BRIDGE_OP_HDMI_AUDIO;
+ DRM_BRIDGE_OP_HDMI | DRM_BRIDGE_OP_HDMI_AUDIO |
+ DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME;
lt9611->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
lt9611->bridge.vendor = "Lontium";
lt9611->bridge.product = "LT9611";