Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f4f6bda0 authored by Mike Rapoport's avatar Mike Rapoport Committed by Richard Purdie
Browse files

backlight: add support for Toppoly TDO35S series to tdo24m lcd driver

parent c835ee7f
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -52,11 +52,11 @@ config LCD_ILI9320
	  then say y to include a power driver for it.

config LCD_TDO24M
	tristate "Toppoly TDO24M LCD Panels support"
	tristate "Toppoly TDO24M  and TDO35S LCD Panels support"
	depends on LCD_CLASS_DEVICE && SPI_MASTER
	default n
	help
	  If you have a Toppoly TDO24M series LCD panel, say y here to
	  If you have a Toppoly TDO24M/TDO35S series LCD panel, say y here to
	  include the support for it.

config LCD_VGG2432A4
+86 −8
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/spi/spi.h>
#include <linux/spi/tdo24m.h>
#include <linux/fb.h>
#include <linux/lcd.h>

@@ -31,6 +32,9 @@ struct tdo24m {
	struct spi_transfer	xfer;
	uint8_t			*buf;

	int (*adj_mode)(struct tdo24m *lcd, int mode);
	int color_invert;

	int			power;
	int			mode;
};
@@ -66,7 +70,7 @@ static uint32_t lcd_panel_off[] = {
	CMD_NULL,
};

static uint32_t lcd_vga_pass_through[] = {
static uint32_t lcd_vga_pass_through_tdo24m[] = {
	CMD1(0xB0, 0x16),
	CMD1(0xBC, 0x80),
	CMD1(0xE1, 0x00),
@@ -75,7 +79,7 @@ static uint32_t lcd_vga_pass_through[] = {
	CMD_NULL,
};

static uint32_t lcd_qvga_pass_through[] = {
static uint32_t lcd_qvga_pass_through_tdo24m[] = {
	CMD1(0xB0, 0x16),
	CMD1(0xBC, 0x81),
	CMD1(0xE1, 0x00),
@@ -84,7 +88,7 @@ static uint32_t lcd_qvga_pass_through[] = {
	CMD_NULL,
};

static uint32_t lcd_vga_transfer[] = {
static uint32_t lcd_vga_transfer_tdo24m[] = {
	CMD1(0xcf, 0x02), 	/* Blanking period control (1) */
	CMD2(0xd0, 0x08, 0x04),	/* Blanking period control (2) */
	CMD1(0xd1, 0x01),	/* CKV timing control on/off */
@@ -110,6 +114,35 @@ static uint32_t lcd_qvga_transfer[] = {
	CMD_NULL,
};

static uint32_t lcd_vga_pass_through_tdo35s[] = {
	CMD1(0xB0, 0x16),
	CMD1(0xBC, 0x80),
	CMD1(0xE1, 0x00),
	CMD1(0x3B, 0x00),
	CMD_NULL,
};

static uint32_t lcd_qvga_pass_through_tdo35s[] = {
	CMD1(0xB0, 0x16),
	CMD1(0xBC, 0x81),
	CMD1(0xE1, 0x00),
	CMD1(0x3B, 0x22),
	CMD_NULL,
};

static uint32_t lcd_vga_transfer_tdo35s[] = {
	CMD1(0xcf, 0x02), 	/* Blanking period control (1) */
	CMD2(0xd0, 0x08, 0x04),	/* Blanking period control (2) */
	CMD1(0xd1, 0x01),	/* CKV timing control on/off */
	CMD2(0xd2, 0x00, 0x1e),	/* CKV 1,2 timing control */
	CMD2(0xd3, 0x14, 0x28),	/* OEV timing control */
	CMD2(0xd4, 0x28, 0x64),	/* ASW timing control (1) */
	CMD1(0xd5, 0x28),	/* ASW timing control (2) */
	CMD0(0x21),		/* Invert for normally black display */
	CMD0(0x29),		/* Display on */
	CMD_NULL,
};

static uint32_t lcd_panel_config[] = {
	CMD2(0xb8, 0xff, 0xf9),	/* Output control */
	CMD0(0x11),		/* sleep out */
@@ -148,6 +181,8 @@ static int tdo24m_writes(struct tdo24m *lcd, uint32_t *array)
	int nparams, err = 0;

	for (; *p != CMD_NULL; p++) {
		if (!lcd->color_invert && *p == CMD0(0x21))
			continue;

		nparams = (*p >> 30) & 0x3;

@@ -184,12 +219,33 @@ static int tdo24m_adj_mode(struct tdo24m *lcd, int mode)
{
	switch (mode) {
	case MODE_VGA:
		tdo24m_writes(lcd, lcd_vga_pass_through);
		tdo24m_writes(lcd, lcd_vga_pass_through_tdo24m);
		tdo24m_writes(lcd, lcd_panel_config);
		tdo24m_writes(lcd, lcd_vga_transfer);
		tdo24m_writes(lcd, lcd_vga_transfer_tdo24m);
		break;
	case MODE_QVGA:
		tdo24m_writes(lcd, lcd_qvga_pass_through);
		tdo24m_writes(lcd, lcd_qvga_pass_through_tdo24m);
		tdo24m_writes(lcd, lcd_panel_config);
		tdo24m_writes(lcd, lcd_qvga_transfer);
		break;
	default:
		return -EINVAL;
	}

	lcd->mode = mode;
	return 0;
}

static int tdo35s_adj_mode(struct tdo24m *lcd, int mode)
{
	switch (mode) {
	case MODE_VGA:
		tdo24m_writes(lcd, lcd_vga_pass_through_tdo35s);
		tdo24m_writes(lcd, lcd_panel_config);
		tdo24m_writes(lcd, lcd_vga_transfer_tdo35s);
		break;
	case MODE_QVGA:
		tdo24m_writes(lcd, lcd_qvga_pass_through_tdo35s);
		tdo24m_writes(lcd, lcd_panel_config);
		tdo24m_writes(lcd, lcd_qvga_transfer);
		break;
@@ -213,7 +269,7 @@ static int tdo24m_power_on(struct tdo24m *lcd)
	if (err)
		goto out;

	err = tdo24m_adj_mode(lcd, lcd->mode);
	err = lcd->adj_mode(lcd, lcd->mode);
out:
	return err;
}
@@ -262,7 +318,7 @@ static int tdo24m_set_mode(struct lcd_device *ld, struct fb_videomode *m)
	if (lcd->mode == mode)
		return 0;

	return tdo24m_adj_mode(lcd, mode);
	return lcd->adj_mode(lcd, mode);
}

static struct lcd_ops tdo24m_ops = {
@@ -276,8 +332,16 @@ static int __devinit tdo24m_probe(struct spi_device *spi)
	struct tdo24m *lcd;
	struct spi_message *m;
	struct spi_transfer *x;
	struct tdo24m_platform_data *pdata;
	enum tdo24m_model model;
	int err;

	pdata = spi->dev.platform_data;
	if (pdata)
		model = pdata->model;
	else
		model = TDO24M;

	spi->bits_per_word = 8;
	spi->mode = SPI_MODE_3;
	err = spi_setup(spi);
@@ -306,6 +370,20 @@ static int __devinit tdo24m_probe(struct spi_device *spi)
	x->tx_buf = &lcd->buf[0];
	spi_message_add_tail(x, m);

	switch (model) {
	case TDO24M:
		lcd->color_invert = 1;
		lcd->adj_mode = tdo24m_adj_mode;
		break;
	case TDO35S:
		lcd->adj_mode = tdo35s_adj_mode;
		lcd->color_invert = 0;
		break;
	default:
		dev_err(&spi->dev, "Unsupported model");
		goto out_free;
	}

	lcd->lcd_dev = lcd_device_register("tdo24m", &spi->dev,
					lcd, &tdo24m_ops);
	if (IS_ERR(lcd->lcd_dev)) {
+13 −0
Original line number Diff line number Diff line
#ifndef __TDO24M_H__
#define __TDO24M_H__

enum tdo24m_model {
	TDO24M,
	TDO35S,
};

struct tdo24m_platform_data {
	enum tdo24m_model model;
};

#endif /* __TDO24M_H__ */