18623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko/*
28623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko * Toppoly TD028TTEC1 panel support
38623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko *
48623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko * Copyright (C) 2008 Nokia Corporation
58623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
68623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko *
78623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko * Neo 1973 code (jbt6k74.c):
88623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko * Copyright (C) 2006-2007 by OpenMoko, Inc.
98623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko * Author: Harald Welte <laforge@openmoko.org>
108623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko *
118623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko * Ported and adapted from Neo 1973 U-Boot by:
128623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko * H. Nikolaus Schaller <hns@goldelico.com>
138623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko *
148623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko * This program is free software; you can redistribute it and/or modify it
158623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko * under the terms of the GNU General Public License version 2 as published by
168623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko * the Free Software Foundation.
178623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko *
188623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko * This program is distributed in the hope that it will be useful, but WITHOUT
198623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
208623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
218623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko * more details.
228623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko *
238623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko * You should have received a copy of the GNU General Public License along with
248623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko * this program.  If not, see <http://www.gnu.org/licenses/>.
258623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko */
268623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
278623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko#include <linux/module.h>
288623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko#include <linux/delay.h>
298623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko#include <linux/spi/spi.h>
308623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko#include <linux/gpio.h>
318623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko#include <video/omapdss.h>
328623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko#include <video/omap-panel-data.h>
338623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
348623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskostruct panel_drv_data {
358623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct omap_dss_device dssdev;
368623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct omap_dss_device *in;
378623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
388623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	int data_lines;
398623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
408623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct omap_video_timings videomode;
418623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
428623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct spi_device *spi_dev;
438623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko};
448623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
458623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskostatic struct omap_video_timings td028ttec1_panel_timings = {
468623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.x_res		= 480,
478623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.y_res		= 640,
48d8d789416aa71253c6532c9adc7469cb947031f6Tomi Valkeinen	.pixelclock	= 22153000,
498623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.hfp		= 24,
508623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.hsw		= 8,
518623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.hbp		= 8,
528623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.vfp		= 4,
538623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.vsw		= 2,
548623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.vbp		= 2,
558623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
568623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.vsync_level	= OMAPDSS_SIG_ACTIVE_LOW,
578623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.hsync_level	= OMAPDSS_SIG_ACTIVE_LOW,
588623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
598623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.data_pclk_edge	= OMAPDSS_DRIVE_SIG_FALLING_EDGE,
608623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.de_level	= OMAPDSS_SIG_ACTIVE_HIGH,
618623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.sync_pclk_edge	= OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
628623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko};
638623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
648623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko#define JBT_COMMAND	0x000
658623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko#define JBT_DATA	0x100
668623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
678623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskostatic int jbt_ret_write_0(struct panel_drv_data *ddata, u8 reg)
688623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko{
698623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	int rc;
708623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	u16 tx_buf = JBT_COMMAND | reg;
718623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
728623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	rc = spi_write(ddata->spi_dev, (u8 *)&tx_buf,
738623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko			1*sizeof(u16));
748623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	if (rc != 0)
758623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		dev_err(&ddata->spi_dev->dev,
768623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko			"jbt_ret_write_0 spi_write ret %d\n", rc);
778623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
788623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	return rc;
798623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko}
808623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
818623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskostatic int jbt_reg_write_1(struct panel_drv_data *ddata, u8 reg, u8 data)
828623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko{
838623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	int rc;
848623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	u16 tx_buf[2];
858623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
868623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	tx_buf[0] = JBT_COMMAND | reg;
878623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	tx_buf[1] = JBT_DATA | data;
888623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	rc = spi_write(ddata->spi_dev, (u8 *)tx_buf,
898623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko			2*sizeof(u16));
908623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	if (rc != 0)
918623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		dev_err(&ddata->spi_dev->dev,
928623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko			"jbt_reg_write_1 spi_write ret %d\n", rc);
938623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
948623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	return rc;
958623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko}
968623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
978623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskostatic int jbt_reg_write_2(struct panel_drv_data *ddata, u8 reg, u16 data)
988623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko{
998623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	int rc;
1008623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	u16 tx_buf[3];
1018623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1028623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	tx_buf[0] = JBT_COMMAND | reg;
1038623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	tx_buf[1] = JBT_DATA | (data >> 8);
1048623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	tx_buf[2] = JBT_DATA | (data & 0xff);
1058623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1068623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	rc = spi_write(ddata->spi_dev, (u8 *)tx_buf,
1078623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko			3*sizeof(u16));
1088623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1098623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	if (rc != 0)
1108623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		dev_err(&ddata->spi_dev->dev,
1118623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko			"jbt_reg_write_2 spi_write ret %d\n", rc);
1128623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1138623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	return rc;
1148623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko}
1158623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1168623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskoenum jbt_register {
1178623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_SLEEP_IN		= 0x10,
1188623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_SLEEP_OUT		= 0x11,
1198623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1208623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_DISPLAY_OFF		= 0x28,
1218623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_DISPLAY_ON		= 0x29,
1228623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1238623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_RGB_FORMAT		= 0x3a,
1248623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_QUAD_RATE		= 0x3b,
1258623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1268623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_POWER_ON_OFF		= 0xb0,
1278623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_BOOSTER_OP		= 0xb1,
1288623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_BOOSTER_MODE		= 0xb2,
1298623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_BOOSTER_FREQ		= 0xb3,
1308623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_OPAMP_SYSCLK		= 0xb4,
1318623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_VSC_VOLTAGE		= 0xb5,
1328623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_VCOM_VOLTAGE		= 0xb6,
1338623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_EXT_DISPL		= 0xb7,
1348623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_OUTPUT_CONTROL		= 0xb8,
1358623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_DCCLK_DCEV		= 0xb9,
1368623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_DISPLAY_MODE1		= 0xba,
1378623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_DISPLAY_MODE2		= 0xbb,
1388623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_DISPLAY_MODE		= 0xbc,
1398623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_ASW_SLEW		= 0xbd,
1408623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_DUMMY_DISPLAY		= 0xbe,
1418623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_DRIVE_SYSTEM		= 0xbf,
1428623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1438623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_SLEEP_OUT_FR_A		= 0xc0,
1448623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_SLEEP_OUT_FR_B		= 0xc1,
1458623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_SLEEP_OUT_FR_C		= 0xc2,
1468623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_SLEEP_IN_LCCNT_D	= 0xc3,
1478623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_SLEEP_IN_LCCNT_E	= 0xc4,
1488623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_SLEEP_IN_LCCNT_F	= 0xc5,
1498623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_SLEEP_IN_LCCNT_G	= 0xc6,
1508623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1518623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_GAMMA1_FINE_1		= 0xc7,
1528623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_GAMMA1_FINE_2		= 0xc8,
1538623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_GAMMA1_INCLINATION	= 0xc9,
1548623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_GAMMA1_BLUE_OFFSET	= 0xca,
1558623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1568623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_BLANK_CONTROL		= 0xcf,
1578623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_BLANK_TH_TV		= 0xd0,
1588623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_CKV_ON_OFF		= 0xd1,
1598623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_CKV_1_2			= 0xd2,
1608623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_OEV_TIMING		= 0xd3,
1618623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_ASW_TIMING_1		= 0xd4,
1628623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_ASW_TIMING_2		= 0xd5,
1638623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1648623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_HCLOCK_VGA		= 0xec,
1658623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	JBT_REG_HCLOCK_QVGA		= 0xed,
1668623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko};
1678623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1688623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
1698623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1708623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskostatic int td028ttec1_panel_connect(struct omap_dss_device *dssdev)
1718623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko{
1728623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct panel_drv_data *ddata = to_panel_data(dssdev);
1738623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct omap_dss_device *in = ddata->in;
1748623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	int r;
1758623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1768623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	if (omapdss_device_is_connected(dssdev))
1778623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		return 0;
1788623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1798623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r = in->ops.dpi->connect(in, dssdev);
1808623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	if (r)
1818623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		return r;
1828623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1838623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	return 0;
1848623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko}
1858623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1868623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskostatic void td028ttec1_panel_disconnect(struct omap_dss_device *dssdev)
1878623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko{
1888623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct panel_drv_data *ddata = to_panel_data(dssdev);
1898623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct omap_dss_device *in = ddata->in;
1908623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1918623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	if (!omapdss_device_is_connected(dssdev))
1928623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		return;
1938623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1948623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	in->ops.dpi->disconnect(in, dssdev);
1958623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko}
1968623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
1978623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskostatic int td028ttec1_panel_enable(struct omap_dss_device *dssdev)
1988623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko{
1998623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct panel_drv_data *ddata = to_panel_data(dssdev);
2008623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct omap_dss_device *in = ddata->in;
2018623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	int r;
2028623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2038623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	if (!omapdss_device_is_connected(dssdev))
2048623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		return -ENODEV;
2058623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2068623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	if (omapdss_device_is_enabled(dssdev))
2078623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		return 0;
2088623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2091f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko	if (ddata->data_lines)
2101f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko		in->ops.dpi->set_data_lines(in, ddata->data_lines);
2118623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	in->ops.dpi->set_timings(in, &ddata->videomode);
2128623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2138623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r = in->ops.dpi->enable(in);
2148623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	if (r)
2158623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		return r;
2168623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2178623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	dev_dbg(dssdev->dev, "td028ttec1_panel_enable() - state %d\n",
2188623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		dssdev->state);
2198623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2208623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	/* three times command zero */
2218623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_ret_write_0(ddata, 0x00);
2228623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	usleep_range(1000, 2000);
2238623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_ret_write_0(ddata, 0x00);
2248623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	usleep_range(1000, 2000);
2258623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_ret_write_0(ddata, 0x00);
2268623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	usleep_range(1000, 2000);
2278623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2288623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	if (r) {
2298623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		dev_warn(dssdev->dev, "transfer error\n");
2308623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		goto transfer_err;
2318623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	}
2328623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2338623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	/* deep standby out */
2348623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_POWER_ON_OFF, 0x17);
2358623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2368623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	/* RGB I/F on, RAM write off, QVGA through, SIGCON enable */
2378623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_DISPLAY_MODE, 0x80);
2388623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2398623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	/* Quad mode off */
2408623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_QUAD_RATE, 0x00);
2418623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2428623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	/* AVDD on, XVDD on */
2438623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_POWER_ON_OFF, 0x16);
2448623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2458623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	/* Output control */
2468623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_2(ddata, JBT_REG_OUTPUT_CONTROL, 0xfff9);
2478623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2488623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	/* Sleep mode off */
2498623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_ret_write_0(ddata, JBT_REG_SLEEP_OUT);
2508623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2518623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	/* at this point we have like 50% grey */
2528623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2538623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	/* initialize register set */
2548623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_DISPLAY_MODE1, 0x01);
2558623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_DISPLAY_MODE2, 0x00);
2568623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_RGB_FORMAT, 0x60);
2578623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_DRIVE_SYSTEM, 0x10);
2588623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_BOOSTER_OP, 0x56);
2598623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_BOOSTER_MODE, 0x33);
2608623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_BOOSTER_FREQ, 0x11);
2618623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_BOOSTER_FREQ, 0x11);
2628623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_OPAMP_SYSCLK, 0x02);
2638623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_VSC_VOLTAGE, 0x2b);
2648623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_VCOM_VOLTAGE, 0x40);
2658623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_EXT_DISPL, 0x03);
2668623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_DCCLK_DCEV, 0x04);
2678623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	/*
2688623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	 * default of 0x02 in JBT_REG_ASW_SLEW responsible for 72Hz requirement
2698623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	 * to avoid red / blue flicker
2708623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	 */
2718623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_ASW_SLEW, 0x04);
2728623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_DUMMY_DISPLAY, 0x00);
2738623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2748623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_SLEEP_OUT_FR_A, 0x11);
2758623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_SLEEP_OUT_FR_B, 0x11);
2768623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_SLEEP_OUT_FR_C, 0x11);
2778623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_2(ddata, JBT_REG_SLEEP_IN_LCCNT_D, 0x2040);
2788623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_2(ddata, JBT_REG_SLEEP_IN_LCCNT_E, 0x60c0);
2798623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_2(ddata, JBT_REG_SLEEP_IN_LCCNT_F, 0x1020);
2808623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_2(ddata, JBT_REG_SLEEP_IN_LCCNT_G, 0x60c0);
2818623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2828623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_2(ddata, JBT_REG_GAMMA1_FINE_1, 0x5533);
2838623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_GAMMA1_FINE_2, 0x00);
2848623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_GAMMA1_INCLINATION, 0x00);
2858623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_GAMMA1_BLUE_OFFSET, 0x00);
2868623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2878623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_2(ddata, JBT_REG_HCLOCK_VGA, 0x1f0);
2888623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_BLANK_CONTROL, 0x02);
2898623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_2(ddata, JBT_REG_BLANK_TH_TV, 0x0804);
2908623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2918623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_CKV_ON_OFF, 0x01);
2928623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_2(ddata, JBT_REG_CKV_1_2, 0x0000);
2938623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2948623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_2(ddata, JBT_REG_OEV_TIMING, 0x0d0e);
2958623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_2(ddata, JBT_REG_ASW_TIMING_1, 0x11a4);
2968623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_reg_write_1(ddata, JBT_REG_ASW_TIMING_2, 0x0e);
2978623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
2988623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r |= jbt_ret_write_0(ddata, JBT_REG_DISPLAY_ON);
2998623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3008623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
3018623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3028623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskotransfer_err:
3038623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3048623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	return r ? -EIO : 0;
3058623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko}
3068623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3078623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskostatic void td028ttec1_panel_disable(struct omap_dss_device *dssdev)
3088623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko{
3098623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct panel_drv_data *ddata = to_panel_data(dssdev);
3108623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct omap_dss_device *in = ddata->in;
3118623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3128623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	if (!omapdss_device_is_enabled(dssdev))
3138623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		return;
3148623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3158623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	dev_dbg(dssdev->dev, "td028ttec1_panel_disable()\n");
3168623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3178623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	jbt_ret_write_0(ddata, JBT_REG_DISPLAY_OFF);
3188623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	jbt_reg_write_2(ddata, JBT_REG_OUTPUT_CONTROL, 0x8002);
3198623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	jbt_ret_write_0(ddata, JBT_REG_SLEEP_IN);
3208623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	jbt_reg_write_1(ddata, JBT_REG_POWER_ON_OFF, 0x00);
3218623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3228623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	in->ops.dpi->disable(in);
3238623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3248623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
3258623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko}
3268623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3278623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskostatic void td028ttec1_panel_set_timings(struct omap_dss_device *dssdev,
3288623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		struct omap_video_timings *timings)
3298623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko{
3308623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct panel_drv_data *ddata = to_panel_data(dssdev);
3318623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct omap_dss_device *in = ddata->in;
3328623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3338623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	ddata->videomode = *timings;
3348623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	dssdev->panel.timings = *timings;
3358623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3368623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	in->ops.dpi->set_timings(in, timings);
3378623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko}
3388623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3398623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskostatic void td028ttec1_panel_get_timings(struct omap_dss_device *dssdev,
3408623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		struct omap_video_timings *timings)
3418623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko{
3428623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct panel_drv_data *ddata = to_panel_data(dssdev);
3438623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3448623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	*timings = ddata->videomode;
3458623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko}
3468623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3478623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskostatic int td028ttec1_panel_check_timings(struct omap_dss_device *dssdev,
3488623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		struct omap_video_timings *timings)
3498623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko{
3508623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct panel_drv_data *ddata = to_panel_data(dssdev);
3518623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct omap_dss_device *in = ddata->in;
3528623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3538623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	return in->ops.dpi->check_timings(in, timings);
3548623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko}
3558623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3568623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskostatic struct omap_dss_driver td028ttec1_ops = {
3578623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.connect	= td028ttec1_panel_connect,
3588623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.disconnect	= td028ttec1_panel_disconnect,
3598623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3608623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.enable		= td028ttec1_panel_enable,
3618623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.disable	= td028ttec1_panel_disable,
3628623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3638623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.set_timings	= td028ttec1_panel_set_timings,
3648623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.get_timings	= td028ttec1_panel_get_timings,
3658623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.check_timings	= td028ttec1_panel_check_timings,
3668623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko};
3678623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3688623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskostatic int td028ttec1_panel_probe_pdata(struct spi_device *spi)
3698623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko{
3708623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	const struct panel_tpo_td028ttec1_platform_data *pdata;
3718623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
3728623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct omap_dss_device *dssdev, *in;
3738623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3748623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	pdata = dev_get_platdata(&spi->dev);
3758623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3768623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	in = omap_dss_find_output(pdata->source);
3778623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	if (in == NULL) {
3788623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		dev_err(&spi->dev, "failed to find video source '%s'\n",
3798623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko				pdata->source);
3808623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		return -EPROBE_DEFER;
3818623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	}
3828623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3838623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	ddata->in = in;
3848623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3858623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	ddata->data_lines = pdata->data_lines;
3868623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3878623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	dssdev = &ddata->dssdev;
3888623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	dssdev->name = pdata->name;
3898623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3908623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	return 0;
3918623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko}
3928623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
3931f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Beliskostatic int td028ttec1_probe_of(struct spi_device *spi)
3941f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko{
3951f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko	struct device_node *node = spi->dev.of_node;
3961f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
3971f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko	struct omap_dss_device *in;
3981f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko
3991f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko	in = omapdss_of_find_source_for_first_ep(node);
4001f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko	if (IS_ERR(in)) {
4011f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko		dev_err(&spi->dev, "failed to find video source\n");
4021f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko		return PTR_ERR(in);
4031f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko	}
4041f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko
4051f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko	ddata->in = in;
4061f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko
4071f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko	return 0;
4081f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko}
4091f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko
4108623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskostatic int td028ttec1_panel_probe(struct spi_device *spi)
4118623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko{
4128623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct panel_drv_data *ddata;
4138623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct omap_dss_device *dssdev;
4148623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	int r;
4158623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4168623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	dev_dbg(&spi->dev, "%s\n", __func__);
4178623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4188623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	spi->bits_per_word = 9;
4198623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	spi->mode = SPI_MODE_3;
4208623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4218623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r = spi_setup(spi);
4228623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	if (r < 0) {
4238623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		dev_err(&spi->dev, "spi_setup failed: %d\n", r);
4248623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		return r;
4258623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	}
4268623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4278623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL);
4288623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	if (ddata == NULL)
4298623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		return -ENOMEM;
4308623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4318623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	dev_set_drvdata(&spi->dev, ddata);
4328623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4338623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	ddata->spi_dev = spi;
4348623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4358623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	if (dev_get_platdata(&spi->dev)) {
4368623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		r = td028ttec1_panel_probe_pdata(spi);
4378623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		if (r)
4388623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko			return r;
4391f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko	} else if (spi->dev.of_node) {
4401f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko		r = td028ttec1_probe_of(spi);
4411f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko		if (r)
4421f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko			return r;
4438623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	} else {
4448623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		return -ENODEV;
4458623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	}
4468623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4478623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	ddata->videomode = td028ttec1_panel_timings;
4488623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4498623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	dssdev = &ddata->dssdev;
4508623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	dssdev->dev = &spi->dev;
4518623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	dssdev->driver = &td028ttec1_ops;
4528623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	dssdev->type = OMAP_DISPLAY_TYPE_DPI;
4538623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	dssdev->owner = THIS_MODULE;
4548623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	dssdev->panel.timings = ddata->videomode;
4558623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	dssdev->phy.dpi.data_lines = ddata->data_lines;
4568623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4578623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	r = omapdss_register_display(dssdev);
4588623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	if (r) {
4598623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		dev_err(&spi->dev, "Failed to register panel\n");
4608623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		goto err_reg;
4618623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	}
4628623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4638623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	return 0;
4648623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4658623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskoerr_reg:
4668623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	omap_dss_put_device(ddata->in);
4678623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	return r;
4688623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko}
4698623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4708623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskostatic int td028ttec1_panel_remove(struct spi_device *spi)
4718623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko{
4728623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
4738623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct omap_dss_device *dssdev = &ddata->dssdev;
4748623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	struct omap_dss_device *in = ddata->in;
4758623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4768623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	dev_dbg(&ddata->spi_dev->dev, "%s\n", __func__);
4778623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4788623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	omapdss_unregister_display(dssdev);
4798623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4808623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	td028ttec1_panel_disable(dssdev);
4818623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	td028ttec1_panel_disconnect(dssdev);
4828623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4838623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	omap_dss_put_device(in);
4848623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4858623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	return 0;
4868623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko}
4878623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4881f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Beliskostatic const struct of_device_id td028ttec1_of_match[] = {
4891f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko	{ .compatible = "omapdss,toppoly,td028ttec1", },
4901f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko	{},
4911f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko};
4921f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko
4931f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek BeliskoMODULE_DEVICE_TABLE(of, td028ttec1_of_match);
4941f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko
4958623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskostatic struct spi_driver td028ttec1_spi_driver = {
4968623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.probe		= td028ttec1_panel_probe,
4978623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.remove		= td028ttec1_panel_remove,
4988623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
4998623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	.driver         = {
5008623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		.name   = "panel-tpo-td028ttec1",
5018623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko		.owner  = THIS_MODULE,
5021f32450911dfa243b8ff79cef62d2ddaeeb3e033Marek Belisko		.of_match_table = td028ttec1_of_match,
503422ccbd57170d18cfd9d4c0cdbdd4603929fc51bTomi Valkeinen		.suppress_bind_attrs = true,
5048623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko	},
5058623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko};
5068623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
5078623ec220b9c9d873ef82d41c9adbac7eec53174Marek Beliskomodule_spi_driver(td028ttec1_spi_driver);
5088623ec220b9c9d873ef82d41c9adbac7eec53174Marek Belisko
509c84d95058a41445f8d8e6c23965f97a8445df978Marek BeliskoMODULE_ALIAS("spi:toppoly,td028ttec1");
5108623ec220b9c9d873ef82d41c9adbac7eec53174Marek BeliskoMODULE_AUTHOR("H. Nikolaus Schaller <hns@goldelico.com>");
5118623ec220b9c9d873ef82d41c9adbac7eec53174Marek BeliskoMODULE_DESCRIPTION("Toppoly TD028TTEC1 panel driver");
5128623ec220b9c9d873ef82d41c9adbac7eec53174Marek BeliskoMODULE_LICENSE("GPL");
513