/*
 * Copyright © 2016 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Author: Deepak M <m.deepak at intel.com>
 */

#include "intel_drv.h"
#include "intel_dsi.h"
#include "i915_drv.h"
#include <video/mipi_display.h>
#include <drm/drm_mipi_dsi.h>

#define CONTROL_DISPLAY_BCTRL		(1 << 5)
#define CONTROL_DISPLAY_DD		(1 << 3)
#define CONTROL_DISPLAY_BL		(1 << 2)

#define POWER_SAVE_OFF			(0 << 0)
#define POWER_SAVE_LOW			(1 << 0)
#define POWER_SAVE_MEDIUM		(2 << 0)
#define POWER_SAVE_HIGH			(3 << 0)
#define POWER_SAVE_OUTDOOR_MODE		(4 << 0)

#define PANEL_PWM_MAX_VALUE		0xFF

static u32 dcs_get_backlight(struct intel_connector *connector)
{
	struct intel_encoder *encoder = connector->encoder;
	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
	struct mipi_dsi_device *dsi_device;
	u8 data = 0;
	enum port port;

	/* FIXME: Need to take care of 16 bit brightness level */
	for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) {
		dsi_device = intel_dsi->dsi_hosts[port]->device;
		mipi_dsi_dcs_read(dsi_device, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
				  &data, sizeof(data));
		break;
	}

	return data;
}

static void dcs_set_backlight(const struct drm_connector_state *conn_state, u32 level)
{
	struct intel_dsi *intel_dsi = enc_to_intel_dsi(conn_state->best_encoder);
	struct mipi_dsi_device *dsi_device;
	u8 data = level;
	enum port port;

	/* FIXME: Need to take care of 16 bit brightness level */
	for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) {
		dsi_device = intel_dsi->dsi_hosts[port]->device;
		mipi_dsi_dcs_write(dsi_device, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
				   &data, sizeof(data));
	}
}

static void dcs_disable_backlight(const struct drm_connector_state *conn_state)
{
	struct intel_dsi *intel_dsi = enc_to_intel_dsi(conn_state->best_encoder);
	struct mipi_dsi_device *dsi_device;
	enum port port;

	dcs_set_backlight(conn_state, 0);

	for_each_dsi_port(port, intel_dsi->dcs_cabc_ports) {
		u8 cabc = POWER_SAVE_OFF;

		dsi_device = intel_dsi->dsi_hosts[port]->device;
		mipi_dsi_dcs_write(dsi_device, MIPI_DCS_WRITE_POWER_SAVE,
				   &cabc, sizeof(cabc));
	}

	for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) {
		u8 ctrl = 0;

		dsi_device = intel_dsi->dsi_hosts[port]->device;

		mipi_dsi_dcs_read(dsi_device, MIPI_DCS_GET_CONTROL_DISPLAY,
				  &ctrl, sizeof(ctrl));

		ctrl &= ~CONTROL_DISPLAY_BL;
		ctrl &= ~CONTROL_DISPLAY_DD;
		ctrl &= ~CONTROL_DISPLAY_BCTRL;

		mipi_dsi_dcs_write(dsi_device, MIPI_DCS_WRITE_CONTROL_DISPLAY,
				   &ctrl, sizeof(ctrl));
	}
}

static void dcs_enable_backlight(const struct intel_crtc_state *crtc_state,
				 const struct drm_connector_state *conn_state)
{
	struct intel_dsi *intel_dsi = enc_to_intel_dsi(conn_state->best_encoder);
	struct intel_panel *panel = &to_intel_connector(conn_state->connector)->panel;
	struct mipi_dsi_device *dsi_device;
	enum port port;

	for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) {
		u8 ctrl = 0;

		dsi_device = intel_dsi->dsi_hosts[port]->device;

		mipi_dsi_dcs_read(dsi_device, MIPI_DCS_GET_CONTROL_DISPLAY,
				  &ctrl, sizeof(ctrl));

		ctrl |= CONTROL_DISPLAY_BL;
		ctrl |= CONTROL_DISPLAY_DD;
		ctrl |= CONTROL_DISPLAY_BCTRL;

		mipi_dsi_dcs_write(dsi_device, MIPI_DCS_WRITE_CONTROL_DISPLAY,
				   &ctrl, sizeof(ctrl));
	}

	for_each_dsi_port(port, intel_dsi->dcs_cabc_ports) {
		u8 cabc = POWER_SAVE_MEDIUM;

		dsi_device = intel_dsi->dsi_hosts[port]->device;
		mipi_dsi_dcs_write(dsi_device, MIPI_DCS_WRITE_POWER_SAVE,
				   &cabc, sizeof(cabc));
	}

	dcs_set_backlight(conn_state, panel->backlight.level);
}

static int dcs_setup_backlight(struct intel_connector *connector,
			       enum pipe unused)
{
	struct intel_panel *panel = &connector->panel;

	panel->backlight.max = PANEL_PWM_MAX_VALUE;
	panel->backlight.level = PANEL_PWM_MAX_VALUE;

	return 0;
}

int intel_dsi_dcs_init_backlight_funcs(struct intel_connector *intel_connector)
{
	struct drm_device *dev = intel_connector->base.dev;
	struct drm_i915_private *dev_priv = to_i915(dev);
	struct intel_encoder *encoder = intel_connector->encoder;
	struct intel_panel *panel = &intel_connector->panel;

	if (dev_priv->vbt.backlight.type != INTEL_BACKLIGHT_DSI_DCS)
		return -ENODEV;

	if (WARN_ON(encoder->type != INTEL_OUTPUT_DSI))
		return -EINVAL;

	panel->backlight.setup = dcs_setup_backlight;
	panel->backlight.enable = dcs_enable_backlight;
	panel->backlight.disable = dcs_disable_backlight;
	panel->backlight.set = dcs_set_backlight;
	panel->backlight.get = dcs_get_backlight;

	return 0;
}
