// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * DRM driver for Pervasive Displays RePaper branded e-ink panels
 *
 * Copyright 2013-2017 Pervasive Displays, Inc.
 * Copyright 2017 Noralf Trønnes
 *
 * The driver supports:
 * Material Film: Aurora Mb (V231)
 * Driver IC: G2 (eTC)
 *
 * The controller code was taken from the userspace driver:
 * https://github.com/repaper/gratis
 */

#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/property.h>
#include <linux/sched/clock.h>
#include <linux/spi/spi.h>
#include <linux/thermal.h>

#include <drm/drm_atomic_helper.h>
#include <drm/drm_connector.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_format_helper.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_managed.h>
#include <drm/drm_modes.h>
#include <drm/drm_rect.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_simple_kms_helper.h>

#define REPAPER_RID_G2_COG_ID	0x12

enum repaper_model {
	/* 0 is reserved to avoid clashing with NULL */
	E1144CS021 = 1,
	E1190CS021,
	E2200CS021,
	E2271CS021,
};

enum repaper_stage {         /* Image pixel -> Display pixel */
	REPAPER_COMPENSATE,  /* B -> W, W -> B (Current Image) */
	REPAPER_WHITE,       /* B -> N, W -> W (Current Image) */
	REPAPER_INVERSE,     /* B -> N, W -> B (New Image) */
	REPAPER_NORMAL       /* B -> B, W -> W (New Image) */
};

enum repaper_epd_border_byte {
	REPAPER_BORDER_BYTE_NONE,
	REPAPER_BORDER_BYTE_ZERO,
	REPAPER_BORDER_BYTE_SET,
};

struct repaper_epd {
	struct drm_device drm;
	struct drm_simple_display_pipe pipe;
	const struct drm_display_mode *mode;
	struct drm_connector connector;
	struct spi_device *spi;

	struct gpio_desc *panel_on;
	struct gpio_desc *border;
	struct gpio_desc *discharge;
	struct gpio_desc *reset;
	struct gpio_desc *busy;

	struct thermal_zone_device *thermal;

	unsigned int height;
	unsigned int width;
	unsigned int bytes_per_scan;
	const u8 *channel_select;
	unsigned int stage_time;
	unsigned int factored_stage_time;
	bool middle_scan;
	bool pre_border_byte;
	enum repaper_epd_border_byte border_byte;

	u8 *line_buffer;
	void *current_frame;

	bool cleared;
	bool partial;
};

static inline struct repaper_epd *drm_to_epd(struct drm_device *drm)
{
	return container_of(drm, struct repaper_epd, drm);
}

static int repaper_spi_transfer(struct spi_device *spi, u8 header,
				const void *tx, void *rx, size_t len)
{
	void *txbuf = NULL, *rxbuf = NULL;
	struct spi_transfer tr[2] = {};
	u8 *headerbuf;
	int ret;

	headerbuf = kmalloc(1, GFP_KERNEL);
	if (!headerbuf)
		return -ENOMEM;

	headerbuf[0] = header;
	tr[0].tx_buf = headerbuf;
	tr[0].len = 1;

	/* Stack allocated tx? */
	if (tx && len <= 32) {
		txbuf = kmemdup(tx, len, GFP_KERNEL);
		if (!txbuf) {
			ret = -ENOMEM;
			goto out_free;
		}
	}

	if (rx) {
		rxbuf = kmalloc(len, GFP_KERNEL);
		if (!rxbuf) {
			ret = -ENOMEM;
			goto out_free;
		}
	}

	tr[1].tx_buf = txbuf ? txbuf : tx;
	tr[1].rx_buf = rxbuf;
	tr[1].len = len;

	ndelay(80);
	ret = spi_sync_transfer(spi, tr, 2);
	if (rx && !ret)
		memcpy(rx, rxbuf, len);

out_free:
	kfree(headerbuf);
	kfree(txbuf);
	kfree(rxbuf);

	return ret;
}

static int repaper_write_buf(struct spi_device *spi, u8 reg,
			     const u8 *buf, size_t len)
{
	int ret;

	ret = repaper_spi_transfer(spi, 0x70, &reg, NULL, 1);
	if (ret)
		return ret;

	return repaper_spi_transfer(spi, 0x72, buf, NULL, len);
}

static int repaper_write_val(struct spi_device *spi, u8 reg, u8 val)
{
	return repaper_write_buf(spi, reg, &val, 1);
}

static int repaper_read_val(struct spi_device *spi, u8 reg)
{
	int ret;
	u8 val;

	ret = repaper_spi_transfer(spi, 0x70, &reg, NULL, 1);
	if (ret)
		return ret;

	ret = repaper_spi_transfer(spi, 0x73, NULL, &val, 1);

	return ret ? ret : val;
}

static int repaper_read_id(struct spi_device *spi)
{
	int ret;
	u8 id;

	ret = repaper_spi_transfer(spi, 0x71, NULL, &id, 1);

	return ret ? ret : id;
}

static void repaper_spi_mosi_low(struct spi_device *spi)
{
	const u8 buf[1] = { 0 };

	spi_write(spi, buf, 1);
}

/* pixels on display are numbered from 1 so even is actually bits 1,3,5,... */
static void repaper_even_pixels(struct repaper_epd *epd, u8 **pp,
				const u8 *data, u8 fixed_value, const u8 *mask,
				enum repaper_stage stage)
{
	unsigned int b;

	for (b = 0; b < (epd->width / 8); b++) {
		if (data) {
			u8 pixels = data[b] & 0xaa;
			u8 pixel_mask = 0xff;
			u8 p1, p2, p3, p4;

			if (mask) {
				pixel_mask = (mask[b] ^ pixels) & 0xaa;
				pixel_mask |= pixel_mask >> 1;
			}

			switch (stage) {
			case REPAPER_COMPENSATE: /* B -> W, W -> B (Current) */
				pixels = 0xaa | ((pixels ^ 0xaa) >> 1);
				break;
			case REPAPER_WHITE:      /* B -> N, W -> W (Current) */
				pixels = 0x55 + ((pixels ^ 0xaa) >> 1);
				break;
			case REPAPER_INVERSE:    /* B -> N, W -> B (New) */
				pixels = 0x55 | (pixels ^ 0xaa);
				break;
			case REPAPER_NORMAL:     /* B -> B, W -> W (New) */
				pixels = 0xaa | (pixels >> 1);
				break;
			}

			pixels = (pixels & pixel_mask) | (~pixel_mask & 0x55);
			p1 = (pixels >> 6) & 0x03;
			p2 = (pixels >> 4) & 0x03;
			p3 = (pixels >> 2) & 0x03;
			p4 = (pixels >> 0) & 0x03;
			pixels = (p1 << 0) | (p2 << 2) | (p3 << 4) | (p4 << 6);
			*(*pp)++ = pixels;
		} else {
			*(*pp)++ = fixed_value;
		}
	}
}

/* pixels on display are numbered from 1 so odd is actually bits 0,2,4,... */
static void repaper_odd_pixels(struct repaper_epd *epd, u8 **pp,
			       const u8 *data, u8 fixed_value, const u8 *mask,
			       enum repaper_stage stage)
{
	unsigned int b;

	for (b = epd->width / 8; b > 0; b--) {
		if (data) {
			u8 pixels = data[b - 1] & 0x55;
			u8 pixel_mask = 0xff;

			if (mask) {
				pixel_mask = (mask[b - 1] ^ pixels) & 0x55;
				pixel_mask |= pixel_mask << 1;
			}

			switch (stage) {
			case REPAPER_COMPENSATE: /* B -> W, W -> B (Current) */
				pixels = 0xaa | (pixels ^ 0x55);
				break;
			case REPAPER_WHITE:      /* B -> N, W -> W (Current) */
				pixels = 0x55 + (pixels ^ 0x55);
				break;
			case REPAPER_INVERSE:    /* B -> N, W -> B (New) */
				pixels = 0x55 | ((pixels ^ 0x55) << 1);
				break;
			case REPAPER_NORMAL:     /* B -> B, W -> W (New) */
				pixels = 0xaa | pixels;
				break;
			}

			pixels = (pixels & pixel_mask) | (~pixel_mask & 0x55);
			*(*pp)++ = pixels;
		} else {
			*(*pp)++ = fixed_value;
		}
	}
}

/* interleave bits: (byte)76543210 -> (16 bit).7.6.5.4.3.2.1 */
static inline u16 repaper_interleave_bits(u16 value)
{
	value = (value | (value << 4)) & 0x0f0f;
	value = (value | (value << 2)) & 0x3333;
	value = (value | (value << 1)) & 0x5555;

	return value;
}

/* pixels on display are numbered from 1 */
static void repaper_all_pixels(struct repaper_epd *epd, u8 **pp,
			       const u8 *data, u8 fixed_value, const u8 *mask,
			       enum repaper_stage stage)
{
	unsigned int b;

	for (b = epd->width / 8; b > 0; b--) {
		if (data) {
			u16 pixels = repaper_interleave_bits(data[b - 1]);
			u16 pixel_mask = 0xffff;

			if (mask) {
				pixel_mask = repaper_interleave_bits(mask[b - 1]);

				pixel_mask = (pixel_mask ^ pixels) & 0x5555;
				pixel_mask |= pixel_mask << 1;
			}

			switch (stage) {
			case REPAPER_COMPENSATE: /* B -> W, W -> B (Current) */
				pixels = 0xaaaa | (pixels ^ 0x5555);
				break;
			case REPAPER_WHITE:      /* B -> N, W -> W (Current) */
				pixels = 0x5555 + (pixels ^ 0x5555);
				break;
			case REPAPER_INVERSE:    /* B -> N, W -> B (New) */
				pixels = 0x5555 | ((pixels ^ 0x5555) << 1);
				break;
			case REPAPER_NORMAL:     /* B -> B, W -> W (New) */
				pixels = 0xaaaa | pixels;
				break;
			}

			pixels = (pixels & pixel_mask) | (~pixel_mask & 0x5555);
			*(*pp)++ = pixels >> 8;
			*(*pp)++ = pixels;
		} else {
			*(*pp)++ = fixed_value;
			*(*pp)++ = fixed_value;
		}
	}
}

/* output one line of scan and data bytes to the display */
static void repaper_one_line(struct repaper_epd *epd, unsigned int line,
			     const u8 *data, u8 fixed_value, const u8 *mask,
			     enum repaper_stage stage)
{
	u8 *p = epd->line_buffer;
	unsigned int b;

	repaper_spi_mosi_low(epd->spi);

	if (epd->pre_border_byte)
		*p++ = 0x00;

	if (epd->middle_scan) {
		/* data bytes */
		repaper_odd_pixels(epd, &p, data, fixed_value, mask, stage);

		/* scan line */
		for (b = epd->bytes_per_scan; b > 0; b--) {
			if (line / 4 == b - 1)
				*p++ = 0x03 << (2 * (line & 0x03));
			else
				*p++ = 0x00;
		}

		/* data bytes */
		repaper_even_pixels(epd, &p, data, fixed_value, mask, stage);
	} else {
		/*
		 * even scan line, but as lines on display are numbered from 1,
		 * line: 1,3,5,...
		 */
		for (b = 0; b < epd->bytes_per_scan; b++) {
			if (0 != (line & 0x01) && line / 8 == b)
				*p++ = 0xc0 >> (line & 0x06);
			else
				*p++ = 0x00;
		}

		/* data bytes */
		repaper_all_pixels(epd, &p, data, fixed_value, mask, stage);

		/*
		 * odd scan line, but as lines on display are numbered from 1,
		 * line: 0,2,4,6,...
		 */
		for (b = epd->bytes_per_scan; b > 0; b--) {
			if (0 == (line & 0x01) && line / 8 == b - 1)
				*p++ = 0x03 << (line & 0x06);
			else
				*p++ = 0x00;
		}
	}

	switch (epd->border_byte) {
	case REPAPER_BORDER_BYTE_NONE:
		break;

	case REPAPER_BORDER_BYTE_ZERO:
		*p++ = 0x00;
		break;

	case REPAPER_BORDER_BYTE_SET:
		switch (stage) {
		case REPAPER_COMPENSATE:
		case REPAPER_WHITE:
		case REPAPER_INVERSE:
			*p++ = 0x00;
			break;
		case REPAPER_NORMAL:
			*p++ = 0xaa;
			break;
		}
		break;
	}

	repaper_write_buf(epd->spi, 0x0a, epd->line_buffer,
			  p - epd->line_buffer);

	/* Output data to panel */
	repaper_write_val(epd->spi, 0x02, 0x07);

	repaper_spi_mosi_low(epd->spi);
}

static void repaper_frame_fixed(struct repaper_epd *epd, u8 fixed_value,
				enum repaper_stage stage)
{
	unsigned int line;

	for (line = 0; line < epd->height; line++)
		repaper_one_line(epd, line, NULL, fixed_value, NULL, stage);
}

static void repaper_frame_data(struct repaper_epd *epd, const u8 *image,
			       const u8 *mask, enum repaper_stage stage)
{
	unsigned int line;

	if (!mask) {
		for (line = 0; line < epd->height; line++) {
			repaper_one_line(epd, line,
					 &image[line * (epd->width / 8)],
					 0, NULL, stage);
		}
	} else {
		for (line = 0; line < epd->height; line++) {
			size_t n = line * epd->width / 8;

			repaper_one_line(epd, line, &image[n], 0, &mask[n],
					 stage);
		}
	}
}

static void repaper_frame_fixed_repeat(struct repaper_epd *epd, u8 fixed_value,
				       enum repaper_stage stage)
{
	u64 start = local_clock();
	u64 end = start + (epd->factored_stage_time * 1000 * 1000);

	do {
		repaper_frame_fixed(epd, fixed_value, stage);
	} while (local_clock() < end);
}

static void repaper_frame_data_repeat(struct repaper_epd *epd, const u8 *image,
				      const u8 *mask, enum repaper_stage stage)
{
	u64 start = local_clock();
	u64 end = start + (epd->factored_stage_time * 1000 * 1000);

	do {
		repaper_frame_data(epd, image, mask, stage);
	} while (local_clock() < end);
}

static void repaper_get_temperature(struct repaper_epd *epd)
{
	int ret, temperature = 0;
	unsigned int factor10x;

	if (!epd->thermal)
		return;

	ret = thermal_zone_get_temp(epd->thermal, &temperature);
	if (ret) {
		DRM_DEV_ERROR(&epd->spi->dev, "Failed to get temperature (%d)\n", ret);
		return;
	}

	temperature /= 1000;

	if (temperature <= -10)
		factor10x = 170;
	else if (temperature <= -5)
		factor10x = 120;
	else if (temperature <= 5)
		factor10x = 80;
	else if (temperature <= 10)
		factor10x = 40;
	else if (temperature <= 15)
		factor10x = 30;
	else if (temperature <= 20)
		factor10x = 20;
	else if (temperature <= 40)
		factor10x = 10;
	else
		factor10x = 7;

	epd->factored_stage_time = epd->stage_time * factor10x / 10;
}

static int repaper_fb_dirty(struct drm_framebuffer *fb)
{
	struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
	struct repaper_epd *epd = drm_to_epd(fb->dev);
	struct drm_rect clip;
	int idx, ret = 0;
	u8 *buf = NULL;

	if (!drm_dev_enter(fb->dev, &idx))
		return -ENODEV;

	/* repaper can't do partial updates */
	clip.x1 = 0;
	clip.x2 = fb->width;
	clip.y1 = 0;
	clip.y2 = fb->height;

	repaper_get_temperature(epd);

	DRM_DEBUG("Flushing [FB:%d] st=%ums\n", fb->base.id,
		  epd->factored_stage_time);

	buf = kmalloc_array(fb->width, fb->height, GFP_KERNEL);
	if (!buf) {
		ret = -ENOMEM;
		goto out_exit;
	}

	ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
	if (ret)
		goto out_free;

	drm_fb_xrgb8888_to_mono(buf, 0, cma_obj->vaddr, fb, &clip);

	drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);

	if (epd->partial) {
		repaper_frame_data_repeat(epd, buf, epd->current_frame,
					  REPAPER_NORMAL);
	} else if (epd->cleared) {
		repaper_frame_data_repeat(epd, epd->current_frame, NULL,
					  REPAPER_COMPENSATE);
		repaper_frame_data_repeat(epd, epd->current_frame, NULL,
					  REPAPER_WHITE);
		repaper_frame_data_repeat(epd, buf, NULL, REPAPER_INVERSE);
		repaper_frame_data_repeat(epd, buf, NULL, REPAPER_NORMAL);

		epd->partial = true;
	} else {
		/* Clear display (anything -> white) */
		repaper_frame_fixed_repeat(epd, 0xff, REPAPER_COMPENSATE);
		repaper_frame_fixed_repeat(epd, 0xff, REPAPER_WHITE);
		repaper_frame_fixed_repeat(epd, 0xaa, REPAPER_INVERSE);
		repaper_frame_fixed_repeat(epd, 0xaa, REPAPER_NORMAL);

		/* Assuming a clear (white) screen output an image */
		repaper_frame_fixed_repeat(epd, 0xaa, REPAPER_COMPENSATE);
		repaper_frame_fixed_repeat(epd, 0xaa, REPAPER_WHITE);
		repaper_frame_data_repeat(epd, buf, NULL, REPAPER_INVERSE);
		repaper_frame_data_repeat(epd, buf, NULL, REPAPER_NORMAL);

		epd->cleared = true;
		epd->partial = true;
	}

	memcpy(epd->current_frame, buf, fb->width * fb->height / 8);

	/*
	 * An extra frame write is needed if pixels are set in the bottom line,
	 * or else grey lines rises up from the pixels
	 */
	if (epd->pre_border_byte) {
		unsigned int x;

		for (x = 0; x < (fb->width / 8); x++)
			if (buf[x + (fb->width * (fb->height - 1) / 8)]) {
				repaper_frame_data_repeat(epd, buf,
							  epd->current_frame,
							  REPAPER_NORMAL);
				break;
			}
	}

out_free:
	kfree(buf);
out_exit:
	drm_dev_exit(idx);

	return ret;
}

static void power_off(struct repaper_epd *epd)
{
	/* Turn off power and all signals */
	gpiod_set_value_cansleep(epd->reset, 0);
	gpiod_set_value_cansleep(epd->panel_on, 0);
	if (epd->border)
		gpiod_set_value_cansleep(epd->border, 0);

	/* Ensure SPI MOSI and CLOCK are Low before CS Low */
	repaper_spi_mosi_low(epd->spi);

	/* Discharge pulse */
	gpiod_set_value_cansleep(epd->discharge, 1);
	msleep(150);
	gpiod_set_value_cansleep(epd->discharge, 0);
}

static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
				struct drm_crtc_state *crtc_state,
				struct drm_plane_state *plane_state)
{
	struct repaper_epd *epd = drm_to_epd(pipe->crtc.dev);
	struct spi_device *spi = epd->spi;
	struct device *dev = &spi->dev;
	bool dc_ok = false;
	int i, ret, idx;

	if (!drm_dev_enter(pipe->crtc.dev, &idx))
		return;

	DRM_DEBUG_DRIVER("\n");

	/* Power up sequence */
	gpiod_set_value_cansleep(epd->reset, 0);
	gpiod_set_value_cansleep(epd->panel_on, 0);
	gpiod_set_value_cansleep(epd->discharge, 0);
	if (epd->border)
		gpiod_set_value_cansleep(epd->border, 0);
	repaper_spi_mosi_low(spi);
	usleep_range(5000, 10000);

	gpiod_set_value_cansleep(epd->panel_on, 1);
	/*
	 * This delay comes from the repaper.org userspace driver, it's not
	 * mentioned in the datasheet.
	 */
	usleep_range(10000, 15000);
	gpiod_set_value_cansleep(epd->reset, 1);
	if (epd->border)
		gpiod_set_value_cansleep(epd->border, 1);
	usleep_range(5000, 10000);
	gpiod_set_value_cansleep(epd->reset, 0);
	usleep_range(5000, 10000);
	gpiod_set_value_cansleep(epd->reset, 1);
	usleep_range(5000, 10000);

	/* Wait for COG to become ready */
	for (i = 100; i > 0; i--) {
		if (!gpiod_get_value_cansleep(epd->busy))
			break;

		usleep_range(10, 100);
	}

	if (!i) {
		DRM_DEV_ERROR(dev, "timeout waiting for panel to become ready.\n");
		power_off(epd);
		goto out_exit;
	}

	repaper_read_id(spi);
	ret = repaper_read_id(spi);
	if (ret != REPAPER_RID_G2_COG_ID) {
		if (ret < 0)
			dev_err(dev, "failed to read chip (%d)\n", ret);
		else
			dev_err(dev, "wrong COG ID 0x%02x\n", ret);
		power_off(epd);
		goto out_exit;
	}

	/* Disable OE */
	repaper_write_val(spi, 0x02, 0x40);

	ret = repaper_read_val(spi, 0x0f);
	if (ret < 0 || !(ret & 0x80)) {
		if (ret < 0)
			DRM_DEV_ERROR(dev, "failed to read chip (%d)\n", ret);
		else
			DRM_DEV_ERROR(dev, "panel is reported broken\n");
		power_off(epd);
		goto out_exit;
	}

	/* Power saving mode */
	repaper_write_val(spi, 0x0b, 0x02);
	/* Channel select */
	repaper_write_buf(spi, 0x01, epd->channel_select, 8);
	/* High power mode osc */
	repaper_write_val(spi, 0x07, 0xd1);
	/* Power setting */
	repaper_write_val(spi, 0x08, 0x02);
	/* Vcom level */
	repaper_write_val(spi, 0x09, 0xc2);
	/* Power setting */
	repaper_write_val(spi, 0x04, 0x03);
	/* Driver latch on */
	repaper_write_val(spi, 0x03, 0x01);
	/* Driver latch off */
	repaper_write_val(spi, 0x03, 0x00);
	usleep_range(5000, 10000);

	/* Start chargepump */
	for (i = 0; i < 4; ++i) {
		/* Charge pump positive voltage on - VGH/VDL on */
		repaper_write_val(spi, 0x05, 0x01);
		msleep(240);

		/* Charge pump negative voltage on - VGL/VDL on */
		repaper_write_val(spi, 0x05, 0x03);
		msleep(40);

		/* Charge pump Vcom on - Vcom driver on */
		repaper_write_val(spi, 0x05, 0x0f);
		msleep(40);

		/* check DC/DC */
		ret = repaper_read_val(spi, 0x0f);
		if (ret < 0) {
			DRM_DEV_ERROR(dev, "failed to read chip (%d)\n", ret);
			power_off(epd);
			goto out_exit;
		}

		if (ret & 0x40) {
			dc_ok = true;
			break;
		}
	}

	if (!dc_ok) {
		DRM_DEV_ERROR(dev, "dc/dc failed\n");
		power_off(epd);
		goto out_exit;
	}

	/*
	 * Output enable to disable
	 * The userspace driver sets this to 0x04, but the datasheet says 0x06
	 */
	repaper_write_val(spi, 0x02, 0x04);

	epd->partial = false;
out_exit:
	drm_dev_exit(idx);
}

static void repaper_pipe_disable(struct drm_simple_display_pipe *pipe)
{
	struct repaper_epd *epd = drm_to_epd(pipe->crtc.dev);
	struct spi_device *spi = epd->spi;
	unsigned int line;

	/*
	 * This callback is not protected by drm_dev_enter/exit since we want to
	 * turn off the display on regular driver unload. It's highly unlikely
	 * that the underlying SPI controller is gone should this be called after
	 * unplug.
	 */

	DRM_DEBUG_DRIVER("\n");

	/* Nothing frame */
	for (line = 0; line < epd->height; line++)
		repaper_one_line(epd, 0x7fffu, NULL, 0x00, NULL,
				 REPAPER_COMPENSATE);

	/* 2.7" */
	if (epd->border) {
		/* Dummy line */
		repaper_one_line(epd, 0x7fffu, NULL, 0x00, NULL,
				 REPAPER_COMPENSATE);
		msleep(25);
		gpiod_set_value_cansleep(epd->border, 0);
		msleep(200);
		gpiod_set_value_cansleep(epd->border, 1);
	} else {
		/* Border dummy line */
		repaper_one_line(epd, 0x7fffu, NULL, 0x00, NULL,
				 REPAPER_NORMAL);
		msleep(200);
	}

	/* not described in datasheet */
	repaper_write_val(spi, 0x0b, 0x00);
	/* Latch reset turn on */
	repaper_write_val(spi, 0x03, 0x01);
	/* Power off charge pump Vcom */
	repaper_write_val(spi, 0x05, 0x03);
	/* Power off charge pump neg voltage */
	repaper_write_val(spi, 0x05, 0x01);
	msleep(120);
	/* Discharge internal */
	repaper_write_val(spi, 0x04, 0x80);
	/* turn off all charge pumps */
	repaper_write_val(spi, 0x05, 0x00);
	/* Turn off osc */
	repaper_write_val(spi, 0x07, 0x01);
	msleep(50);

	power_off(epd);
}

static void repaper_pipe_update(struct drm_simple_display_pipe *pipe,
				struct drm_plane_state *old_state)
{
	struct drm_plane_state *state = pipe->plane.state;
	struct drm_rect rect;

	if (!pipe->crtc.state->active)
		return;

	if (drm_atomic_helper_damage_merged(old_state, state, &rect))
		repaper_fb_dirty(state->fb);
}

static const struct drm_simple_display_pipe_funcs repaper_pipe_funcs = {
	.enable = repaper_pipe_enable,
	.disable = repaper_pipe_disable,
	.update = repaper_pipe_update,
};

static int repaper_connector_get_modes(struct drm_connector *connector)
{
	struct repaper_epd *epd = drm_to_epd(connector->dev);
	struct drm_display_mode *mode;

	mode = drm_mode_duplicate(connector->dev, epd->mode);
	if (!mode) {
		DRM_ERROR("Failed to duplicate mode\n");
		return 0;
	}

	drm_mode_set_name(mode);
	mode->type |= DRM_MODE_TYPE_PREFERRED;
	drm_mode_probed_add(connector, mode);

	connector->display_info.width_mm = mode->width_mm;
	connector->display_info.height_mm = mode->height_mm;

	return 1;
}

static const struct drm_connector_helper_funcs repaper_connector_hfuncs = {
	.get_modes = repaper_connector_get_modes,
};

static const struct drm_connector_funcs repaper_connector_funcs = {
	.reset = drm_atomic_helper_connector_reset,
	.fill_modes = drm_helper_probe_single_connector_modes,
	.destroy = drm_connector_cleanup,
	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};

static const struct drm_mode_config_funcs repaper_mode_config_funcs = {
	.fb_create = drm_gem_fb_create_with_dirty,
	.atomic_check = drm_atomic_helper_check,
	.atomic_commit = drm_atomic_helper_commit,
};

static const uint32_t repaper_formats[] = {
	DRM_FORMAT_XRGB8888,
};

static const struct drm_display_mode repaper_e1144cs021_mode = {
	DRM_SIMPLE_MODE(128, 96, 29, 22),
};

static const u8 repaper_e1144cs021_cs[] = { 0x00, 0x00, 0x00, 0x00,
					    0x00, 0x0f, 0xff, 0x00 };

static const struct drm_display_mode repaper_e1190cs021_mode = {
	DRM_SIMPLE_MODE(144, 128, 36, 32),
};

static const u8 repaper_e1190cs021_cs[] = { 0x00, 0x00, 0x00, 0x03,
					    0xfc, 0x00, 0x00, 0xff };

static const struct drm_display_mode repaper_e2200cs021_mode = {
	DRM_SIMPLE_MODE(200, 96, 46, 22),
};

static const u8 repaper_e2200cs021_cs[] = { 0x00, 0x00, 0x00, 0x00,
					    0x01, 0xff, 0xe0, 0x00 };

static const struct drm_display_mode repaper_e2271cs021_mode = {
	DRM_SIMPLE_MODE(264, 176, 57, 38),
};

static const u8 repaper_e2271cs021_cs[] = { 0x00, 0x00, 0x00, 0x7f,
					    0xff, 0xfe, 0x00, 0x00 };

DEFINE_DRM_GEM_CMA_FOPS(repaper_fops);

static const struct drm_driver repaper_driver = {
	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
	.fops			= &repaper_fops,
	DRM_GEM_CMA_DRIVER_OPS_VMAP,
	.name			= "repaper",
	.desc			= "Pervasive Displays RePaper e-ink panels",
	.date			= "20170405",
	.major			= 1,
	.minor			= 0,
};

static const struct of_device_id repaper_of_match[] = {
	{ .compatible = "pervasive,e1144cs021", .data = (void *)E1144CS021 },
	{ .compatible = "pervasive,e1190cs021", .data = (void *)E1190CS021 },
	{ .compatible = "pervasive,e2200cs021", .data = (void *)E2200CS021 },
	{ .compatible = "pervasive,e2271cs021", .data = (void *)E2271CS021 },
	{},
};
MODULE_DEVICE_TABLE(of, repaper_of_match);

static const struct spi_device_id repaper_id[] = {
	{ "e1144cs021", E1144CS021 },
	{ "e1190cs021", E1190CS021 },
	{ "e2200cs021", E2200CS021 },
	{ "e2271cs021", E2271CS021 },
	{ },
};
MODULE_DEVICE_TABLE(spi, repaper_id);

static int repaper_probe(struct spi_device *spi)
{
	const struct drm_display_mode *mode;
	const struct spi_device_id *spi_id;
	struct device *dev = &spi->dev;
	enum repaper_model model;
	const char *thermal_zone;
	struct repaper_epd *epd;
	size_t line_buffer_size;
	struct drm_device *drm;
	const void *match;
	int ret;

	match = device_get_match_data(dev);
	if (match) {
		model = (enum repaper_model)match;
	} else {
		spi_id = spi_get_device_id(spi);
		model = (enum repaper_model)spi_id->driver_data;
	}

	/* The SPI device is used to allocate dma memory */
	if (!dev->coherent_dma_mask) {
		ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
		if (ret) {
			dev_warn(dev, "Failed to set dma mask %d\n", ret);
			return ret;
		}
	}

	epd = devm_drm_dev_alloc(dev, &repaper_driver,
				 struct repaper_epd, drm);
	if (IS_ERR(epd))
		return PTR_ERR(epd);

	drm = &epd->drm;

	ret = drmm_mode_config_init(drm);
	if (ret)
		return ret;
	drm->mode_config.funcs = &repaper_mode_config_funcs;

	epd->spi = spi;

	epd->panel_on = devm_gpiod_get(dev, "panel-on", GPIOD_OUT_LOW);
	if (IS_ERR(epd->panel_on)) {
		ret = PTR_ERR(epd->panel_on);
		if (ret != -EPROBE_DEFER)
			DRM_DEV_ERROR(dev, "Failed to get gpio 'panel-on'\n");
		return ret;
	}

	epd->discharge = devm_gpiod_get(dev, "discharge", GPIOD_OUT_LOW);
	if (IS_ERR(epd->discharge)) {
		ret = PTR_ERR(epd->discharge);
		if (ret != -EPROBE_DEFER)
			DRM_DEV_ERROR(dev, "Failed to get gpio 'discharge'\n");
		return ret;
	}

	epd->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
	if (IS_ERR(epd->reset)) {
		ret = PTR_ERR(epd->reset);
		if (ret != -EPROBE_DEFER)
			DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n");
		return ret;
	}

	epd->busy = devm_gpiod_get(dev, "busy", GPIOD_IN);
	if (IS_ERR(epd->busy)) {
		ret = PTR_ERR(epd->busy);
		if (ret != -EPROBE_DEFER)
			DRM_DEV_ERROR(dev, "Failed to get gpio 'busy'\n");
		return ret;
	}

	if (!device_property_read_string(dev, "pervasive,thermal-zone",
					 &thermal_zone)) {
		epd->thermal = thermal_zone_get_zone_by_name(thermal_zone);
		if (IS_ERR(epd->thermal)) {
			DRM_DEV_ERROR(dev, "Failed to get thermal zone: %s\n", thermal_zone);
			return PTR_ERR(epd->thermal);
		}
	}

	switch (model) {
	case E1144CS021:
		mode = &repaper_e1144cs021_mode;
		epd->channel_select = repaper_e1144cs021_cs;
		epd->stage_time = 480;
		epd->bytes_per_scan = 96 / 4;
		epd->middle_scan = true; /* data-scan-data */
		epd->pre_border_byte = false;
		epd->border_byte = REPAPER_BORDER_BYTE_ZERO;
		break;

	case E1190CS021:
		mode = &repaper_e1190cs021_mode;
		epd->channel_select = repaper_e1190cs021_cs;
		epd->stage_time = 480;
		epd->bytes_per_scan = 128 / 4 / 2;
		epd->middle_scan = false; /* scan-data-scan */
		epd->pre_border_byte = false;
		epd->border_byte = REPAPER_BORDER_BYTE_SET;
		break;

	case E2200CS021:
		mode = &repaper_e2200cs021_mode;
		epd->channel_select = repaper_e2200cs021_cs;
		epd->stage_time = 480;
		epd->bytes_per_scan = 96 / 4;
		epd->middle_scan = true; /* data-scan-data */
		epd->pre_border_byte = true;
		epd->border_byte = REPAPER_BORDER_BYTE_NONE;
		break;

	case E2271CS021:
		epd->border = devm_gpiod_get(dev, "border", GPIOD_OUT_LOW);
		if (IS_ERR(epd->border)) {
			ret = PTR_ERR(epd->border);
			if (ret != -EPROBE_DEFER)
				DRM_DEV_ERROR(dev, "Failed to get gpio 'border'\n");
			return ret;
		}

		mode = &repaper_e2271cs021_mode;
		epd->channel_select = repaper_e2271cs021_cs;
		epd->stage_time = 630;
		epd->bytes_per_scan = 176 / 4;
		epd->middle_scan = true; /* data-scan-data */
		epd->pre_border_byte = true;
		epd->border_byte = REPAPER_BORDER_BYTE_NONE;
		break;

	default:
		return -ENODEV;
	}

	epd->mode = mode;
	epd->width = mode->hdisplay;
	epd->height = mode->vdisplay;
	epd->factored_stage_time = epd->stage_time;

	line_buffer_size = 2 * epd->width / 8 + epd->bytes_per_scan + 2;
	epd->line_buffer = devm_kzalloc(dev, line_buffer_size, GFP_KERNEL);
	if (!epd->line_buffer)
		return -ENOMEM;

	epd->current_frame = devm_kzalloc(dev, epd->width * epd->height / 8,
					  GFP_KERNEL);
	if (!epd->current_frame)
		return -ENOMEM;

	drm->mode_config.min_width = mode->hdisplay;
	drm->mode_config.max_width = mode->hdisplay;
	drm->mode_config.min_height = mode->vdisplay;
	drm->mode_config.max_height = mode->vdisplay;

	drm_connector_helper_add(&epd->connector, &repaper_connector_hfuncs);
	ret = drm_connector_init(drm, &epd->connector, &repaper_connector_funcs,
				 DRM_MODE_CONNECTOR_SPI);
	if (ret)
		return ret;

	ret = drm_simple_display_pipe_init(drm, &epd->pipe, &repaper_pipe_funcs,
					   repaper_formats, ARRAY_SIZE(repaper_formats),
					   NULL, &epd->connector);
	if (ret)
		return ret;

	drm_mode_config_reset(drm);

	ret = drm_dev_register(drm, 0);
	if (ret)
		return ret;

	spi_set_drvdata(spi, drm);

	DRM_DEBUG_DRIVER("SPI speed: %uMHz\n", spi->max_speed_hz / 1000000);

	drm_fbdev_generic_setup(drm, 0);

	return 0;
}

static void repaper_remove(struct spi_device *spi)
{
	struct drm_device *drm = spi_get_drvdata(spi);

	drm_dev_unplug(drm);
	drm_atomic_helper_shutdown(drm);
}

static void repaper_shutdown(struct spi_device *spi)
{
	drm_atomic_helper_shutdown(spi_get_drvdata(spi));
}

static struct spi_driver repaper_spi_driver = {
	.driver = {
		.name = "repaper",
		.of_match_table = repaper_of_match,
	},
	.id_table = repaper_id,
	.probe = repaper_probe,
	.remove = repaper_remove,
	.shutdown = repaper_shutdown,
};
module_spi_driver(repaper_spi_driver);

MODULE_DESCRIPTION("Pervasive Displays RePaper DRM driver");
MODULE_AUTHOR("Noralf Trønnes");
MODULE_LICENSE("GPL");
