/*
 * Copyright (C) 2012 Russell King
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_encoder_slave.h>
#include "armada_output.h"
#include "armada_drm.h"

struct armada_connector {
	struct drm_connector conn;
	const struct armada_output_type *type;
};

#define drm_to_armada_conn(c) container_of(c, struct armada_connector, conn)

struct drm_encoder *armada_drm_connector_encoder(struct drm_connector *conn)
{
	struct drm_encoder *enc = conn->encoder;

	return enc ? enc : drm_encoder_find(conn->dev, conn->encoder_ids[0]);
}

static enum drm_connector_status armada_drm_connector_detect(
	struct drm_connector *conn, bool force)
{
	struct armada_connector *dconn = drm_to_armada_conn(conn);
	enum drm_connector_status status = connector_status_disconnected;

	if (dconn->type->detect) {
		status = dconn->type->detect(conn, force);
	} else {
		struct drm_encoder *enc = armada_drm_connector_encoder(conn);

		if (enc)
			status = encoder_helper_funcs(enc)->detect(enc, conn);
	}

	return status;
}

static void armada_drm_connector_destroy(struct drm_connector *conn)
{
	struct armada_connector *dconn = drm_to_armada_conn(conn);

	drm_connector_unregister(conn);
	drm_connector_cleanup(conn);
	kfree(dconn);
}

static int armada_drm_connector_set_property(struct drm_connector *conn,
	struct drm_property *property, uint64_t value)
{
	struct armada_connector *dconn = drm_to_armada_conn(conn);

	if (!dconn->type->set_property)
		return -EINVAL;

	return dconn->type->set_property(conn, property, value);
}

static const struct drm_connector_funcs armada_drm_conn_funcs = {
	.dpms		= drm_helper_connector_dpms,
	.fill_modes	= drm_helper_probe_single_connector_modes,
	.detect		= armada_drm_connector_detect,
	.destroy	= armada_drm_connector_destroy,
	.set_property	= armada_drm_connector_set_property,
};

/* Shouldn't this be a generic helper function? */
int armada_drm_slave_encoder_mode_valid(struct drm_connector *conn,
	struct drm_display_mode *mode)
{
	struct drm_encoder *encoder = armada_drm_connector_encoder(conn);
	int valid = MODE_BAD;

	if (encoder) {
		struct drm_encoder_slave *slave = to_encoder_slave(encoder);

		valid = slave->slave_funcs->mode_valid(encoder, mode);
	}
	return valid;
}

int armada_drm_slave_encoder_set_property(struct drm_connector *conn,
	struct drm_property *property, uint64_t value)
{
	struct drm_encoder *encoder = armada_drm_connector_encoder(conn);
	int rc = -EINVAL;

	if (encoder) {
		struct drm_encoder_slave *slave = to_encoder_slave(encoder);

		rc = slave->slave_funcs->set_property(encoder, conn, property,
						      value);
	}
	return rc;
}

int armada_output_create(struct drm_device *dev,
	const struct armada_output_type *type, const void *data)
{
	struct armada_connector *dconn;
	int ret;

	dconn = kzalloc(sizeof(*dconn), GFP_KERNEL);
	if (!dconn)
		return -ENOMEM;

	dconn->type = type;

	ret = drm_connector_init(dev, &dconn->conn, &armada_drm_conn_funcs,
				 type->connector_type);
	if (ret) {
		DRM_ERROR("unable to init connector\n");
		goto err_destroy_dconn;
	}

	ret = type->create(&dconn->conn, data);
	if (ret)
		goto err_conn;

	ret = drm_connector_register(&dconn->conn);
	if (ret)
		goto err_sysfs;

	return 0;

 err_sysfs:
	if (dconn->conn.encoder)
		dconn->conn.encoder->funcs->destroy(dconn->conn.encoder);
 err_conn:
	drm_connector_cleanup(&dconn->conn);
 err_destroy_dconn:
	kfree(dconn);
	return ret;
}
