diff --git a/drivers/video/display/display-core.c b/drivers/video/display/display-core.c
index 55a7399..12fb882 100644
--- a/drivers/video/display/display-core.c
+++ b/drivers/video/display/display-core.c
@@ -99,6 +99,14 @@ int display_entity_get_modes(struct display_entity *entity,
}
EXPORT_SYMBOL_GPL(display_entity_get_modes);
+int display_entity_set_mode(struct display_entity *entity,
+ const struct videomode *mode)
+{
+ if (!entity->opt_ctrl.hdmi || !entity->ops.ctrl->set_mode)
+ return 0;
+ return entity->ops.ctrl->set_mode(entity, mode);
+}
+EXPORT_SYMBOL_GPL(display_entity_set_mode);
/**
* display_entity_get_size - Get display entity physical size
* @entity: The display entity@@ -140,6 +148,37 @@ int display_entity_get_params(struct display_entity *entity,
}
EXPORT_SYMBOL_GPL(display_entity_get_params);
+int display_entity_subscribe_event(struct display_entity *entity,
+ struct display_event_subscriber *subscriber)
+{
+ if (!entity || !subscriber || !subscriber->notify)
+ return -EINVAL;
+
+ mutex_lock(&entity->entity_mutex);
+ list_add_tail(&subscriber->list, &entity->list_subscribers);
+ mutex_unlock(&entity->entity_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(display_entity_subscribe_event);
+
+int display_entity_notify_event_subscriber(struct display_entity *entity,
+ enum display_entity_event_type type, unsigned int value)
+{
+ struct display_event_subscriber *subscriber;
+
+ if (!entity || type < 0)
+ return -EINVAL;
+
+ mutex_lock(&entity->entity_mutex);
+ list_for_each_entry(subscriber, &entity->list_subscribers, list) {
+ subscriber->notify(entity, type, value, subscriber->context);
+ }
+ mutex_unlock(&entity->entity_mutex);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(display_entity_notify_event_subscriber);
+
/* -----------------------------------------------------------------------------
* Video operations
*/@@ -312,6 +351,9 @@ int __must_check __display_entity_register(struct display_entity *entity,
kref_init(&entity->ref);
entity->owner = owner;
entity->state = DISPLAY_ENTITY_STATE_OFF;
+ entity->list_subscribers.next = &entity->list_subscribers;
+ entity->list_subscribers.prev = &entity->list_subscribers;
+ mutex_init(&entity->entity_mutex);
mutex_lock(&display_entity_mutex);
list_add(&entity->list, &display_entity_list);
@@ -357,6 +399,49 @@ void display_entity_unregister(struct display_entity *entity)
}
EXPORT_SYMBOL_GPL(display_entity_unregister);
+/* -----------------------------------------------------------------------------
+ * Display Entity Hdmi ops
+ */
+
+int display_entity_hdmi_get_edid(struct display_entity *entity,
+ struct display_entity_edid *edid)
+{
+ if (!entity->opt_ctrl.hdmi || !entity->opt_ctrl.hdmi->get_edid)
+ return 0;
+
+ return entity->opt_ctrl.hdmi->get_edid(entity, edid);
+}
+EXPORT_SYMBOL_GPL(display_entity_hdmi_get_edid);
+
+int display_entity_hdmi_check_mode(struct display_entity *entity,
+ const struct videomode *mode)
+{
+ if (!entity->opt_ctrl.hdmi || !entity->opt_ctrl.hdmi->check_mode)
+ return 0;
+
+ return entity->opt_ctrl.hdmi->check_mode(entity, mode);
+}
+EXPORT_SYMBOL_GPL(display_entity_hdmi_check_mode);
+
+int display_entity_hdmi_init_audio(struct display_entity *entity,
+ const struct display_entity_audio_params *params)
+{
+ if (!entity->opt_ctrl.hdmi || !entity->opt_ctrl.hdmi->init_audio)
+ return 0;
+
+ return entity->opt_ctrl.hdmi->init_audio(entity, params);
+}
+EXPORT_SYMBOL_GPL(display_entity_hdmi_init_audio);
+
+int display_entity_hdmi_set_audiostate(struct display_entity *entity,
+ enum display_entity_audiostate state)
+{
+ if (!entity->opt_ctrl.hdmi || !entity->opt_ctrl.hdmi->set_audiostate)
+ return 0;
+
+ return entity->opt_ctrl.hdmi->set_audiostate(entity, state);
+}
+EXPORT_SYMBOL_GPL(display_entity_hdmi_set_audiostate);
MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
MODULE_DESCRIPTION("Display Core");
MODULE_LICENSE("GPL");diff --git a/include/video/display.h b/include/video/display.h
index 817f4ae..eae373f 100644
--- a/include/video/display.h
+++ b/include/video/display.h
@@ -66,22 +66,64 @@ enum display_entity_stream_state {
DISPLAY_ENTITY_STREAM_CONTINUOUS,
};
+enum display_entity_event_type {
+ DISPLAY_ENTITY_HDMI_HOTPLUG,
+};
+
enum display_entity_interface_type {
DISPLAY_ENTITY_INTERFACE_DPI,
+ DISPLAY_ENTITY_INTERFACE_HDMI,
+};
+
+enum display_entity_audio_interface {
+ DISPLAY_ENTITY_AUDIO_I2S,
+ DISPLAY_ENTITY_AUDIO_SPDIF,
+};
+
+enum display_entity_audiostate {
+ DISPLAY_ENTITY_AUDIOSTATE_OFF,
+ DISPLAY_ENTITY_AUDIOSTATE_ON,
};
struct display_entity_interface_params {
enum display_entity_interface_type type;
};
+struct display_event_subscriber {
+ struct list_head list;
+ void(*notify)(struct display_entity *ent,
+ enum display_entity_event_type type,
+ unsigned int value, void *context);
+ void *context;
+};
+
+struct display_entity_edid {
+ u8 *edid;
+ int len;
+};
+
+struct display_entity_audio_params {
+ enum display_entity_audio_interface type;
+ int channels;
+ int sf;
+ int bits_per_sample;
+};
+
struct display_entity_control_ops {
int (*set_state)(struct display_entity *ent,
enum display_entity_state state);
+
int (*update)(struct display_entity *ent);
+
int (*get_modes)(struct display_entity *ent,
const struct videomode **modes);
+
+ int (*set_mode)(struct display_entity *entity,
+ const struct videomode *modes);
+
int (*get_params)(struct display_entity *ent,
struct display_entity_interface_params *params);
+
int (*get_size)(struct display_entity *ent,
unsigned int *width, unsigned int *height);
};@@ -91,8 +133,29 @@ struct display_entity_video_ops {
enum display_entity_stream_state state);
};
+struct display_entity_hdmi_control_ops {
+
+ int (*get_edid)(struct display_entity *ent,
+ struct display_entity_edid *edid);
+
+ int (*check_mode)(struct display_entity *entity,
+ const struct videomode *modes);
+
+ int (*init_audio)(struct display_entity *entity,
+ const struct display_entity_audio_params *params);
+
+ int (*set_audiostate)(struct display_entity *entity,
+ enum display_entity_audiostate state);
+};
+
+struct display_entity_hdmi_video_ops {
+ int (*get_edid)(struct display_entity *ent,
+ enum display_entity_stream_state state);
+};
+
struct display_entity {
struct list_head list;
+ struct list_head list_subscribers;
struct device *dev;
struct module *owner;
struct kref ref;@@ -104,26 +167,51 @@ struct display_entity {
const struct display_entity_video_ops *video;
} ops;
+ union {
+ const struct display_entity_hdmi_control_ops *hdmi;
+ } opt_ctrl;
+
+ union {
+ const struct display_entity_hdmi_video_ops *hdmi;
+ } opt_video;
+
void(*release)(struct display_entity *ent);
enum display_entity_state state;
+ struct mutex entity_mutex;
+ void *private;
};
+/* generic display entity ops */
+
int display_entity_set_state(struct display_entity *entity,
enum display_entity_state state);
+
int display_entity_update(struct display_entity *entity);
+
int display_entity_get_modes(struct display_entity *entity,
const struct videomode **modes);
+
+int display_entity_set_mode(struct display_entity *entity,
+ const struct videomode *modes);
+
int display_entity_get_params(struct display_entity *entity,
- struct display_entity_interface_params *params);
+ struct display_entity_interface_params *params);
+
int display_entity_get_size(struct display_entity *entity,
- unsigned int *width, unsigned int *height);
+ unsigned int *width, unsigned int *height);
int display_entity_set_stream(struct display_entity *entity,
enum display_entity_stream_state state);
+int display_entity_subscribe_event(struct display_entity *entity,
+ struct display_event_subscriber *subscriber);
+
+int display_entity_notify_event_subscriber(struct display_entity *entity,
+ enum display_entity_event_type type, unsigned int value);
+
static inline void display_entity_connect(struct display_entity *source,
- struct display_entity *sink)
+ struct display_entity *sink)
{
sink->source = source;
}@@ -147,4 +235,21 @@ void display_entity_unregister_notifier(struct display_entity_notifier *notifier
#define display_entity_register(display_entity) \
__display_entity_register(display_entity, THIS_MODULE)
+/* hdmi ops */
+
+int display_entity_hdmi_get_edid(struct display_entity *entity,
+ struct display_entity_edid *edid);
+
+int display_entity_hdmi_check_mode(struct display_entity *entity,
+ const struct videomode *modes);
+
+int display_entity_hdmi_get_hpdstate(struct display_entity *entity,
+ unsigned int *hpd_state);
+
+int display_entity_hdmi_init_audio(struct display_entity *entity,
+ const struct display_entity_audio_params *params);
+
+int display_entity_hdmi_set_audiostate(struct display_entity *entity,
+ enum display_entity_audiostate state);
+
#endif /* __DISPLAY_H__ */
--
1.8.0