Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: MIT
  2
  3#include <drm/drm_atomic_state_helper.h>
  4#include <drm/drm_edid.h>
  5#include <drm/drm_modeset_helper_vtables.h>
  6#include <drm/drm_print.h>
  7#include <drm/drm_probe_helper.h>
  8
  9#include "ast_ddc.h"
 10#include "ast_drv.h"
 11
 12/*
 13 * Encoder
 14 */
 15
 16static const struct drm_encoder_funcs ast_vga_encoder_funcs = {
 17	.destroy = drm_encoder_cleanup,
 18};
 19
 20/*
 21 * Connector
 22 */
 23
 24static int ast_vga_connector_helper_get_modes(struct drm_connector *connector)
 25{
 26	struct ast_connector *ast_connector = to_ast_connector(connector);
 27	int count;
 28
 29	if (ast_connector->physical_status == connector_status_connected) {
 30		count = drm_connector_helper_get_modes(connector);
 31	} else {
 32		drm_edid_connector_update(connector, NULL);
 33
 34		/*
 35		 * There's no EDID data without a connected monitor. Set BMC-
 36		 * compatible modes in this case. The XGA default resolution
 37		 * should work well for all BMCs.
 38		 */
 39		count = drm_add_modes_noedid(connector, 4096, 4096);
 40		if (count)
 41			drm_set_preferred_mode(connector, 1024, 768);
 42	}
 43
 44	return count;
 45}
 46
 47static int ast_vga_connector_helper_detect_ctx(struct drm_connector *connector,
 48					       struct drm_modeset_acquire_ctx *ctx,
 49					       bool force)
 50{
 51	struct ast_connector *ast_connector = to_ast_connector(connector);
 52	enum drm_connector_status status;
 53
 54	status = drm_connector_helper_detect_from_ddc(connector, ctx, force);
 55
 56	if (status != ast_connector->physical_status)
 57		++connector->epoch_counter;
 58	ast_connector->physical_status = status;
 59
 60	return connector_status_connected;
 61}
 62
 63static const struct drm_connector_helper_funcs ast_vga_connector_helper_funcs = {
 64	.get_modes = ast_vga_connector_helper_get_modes,
 65	.detect_ctx = ast_vga_connector_helper_detect_ctx,
 66};
 67
 68static const struct drm_connector_funcs ast_vga_connector_funcs = {
 69	.reset = drm_atomic_helper_connector_reset,
 70	.fill_modes = drm_helper_probe_single_connector_modes,
 71	.destroy = drm_connector_cleanup,
 72	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 73	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 74};
 75
 76/*
 77 * Output
 78 */
 79
 80int ast_vga_output_init(struct ast_device *ast)
 81{
 82	struct drm_device *dev = &ast->base;
 83	struct drm_crtc *crtc = &ast->crtc;
 84	struct i2c_adapter *ddc;
 85	struct drm_encoder *encoder;
 86	struct ast_connector *ast_connector;
 87	struct drm_connector *connector;
 88	int ret;
 89
 90	/* DDC */
 91
 92	ddc = ast_ddc_create(ast);
 93	if (IS_ERR(ddc))
 94		return PTR_ERR(ddc);
 95
 96	/* encoder */
 97
 98	encoder = &ast->output.vga.encoder;
 99	ret = drm_encoder_init(dev, encoder, &ast_vga_encoder_funcs,
100			       DRM_MODE_ENCODER_DAC, NULL);
101	if (ret)
102		return ret;
103	encoder->possible_crtcs = drm_crtc_mask(crtc);
104
105	/* connector */
106
107	ast_connector = &ast->output.vga.connector;
108	connector = &ast_connector->base;
109	ret = drm_connector_init_with_ddc(dev, connector, &ast_vga_connector_funcs,
110					  DRM_MODE_CONNECTOR_VGA, ddc);
111	if (ret)
112		return ret;
113	drm_connector_helper_add(connector, &ast_vga_connector_helper_funcs);
114
115	connector->interlace_allowed = 0;
116	connector->doublescan_allowed = 0;
117	connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
118
119	ast_connector->physical_status = connector->status;
120
121	ret = drm_connector_attach_encoder(connector, encoder);
122	if (ret)
123		return ret;
124
125	return 0;
126}