PageRenderTime 35ms CodeModel.GetById 18ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/video/omap2/dss/sdi.c

https://bitbucket.org/wisechild/galaxy-nexus
C | 182 lines | 121 code | 42 blank | 19 comment | 13 complexity | 7686ada22d617e878415bb97ca80c45d MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1/*
  2 * linux/drivers/video/omap2/dss/sdi.c
  3 *
  4 * Copyright (C) 2009 Nokia Corporation
  5 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
  6 *
  7 * This program is free software; you can redistribute it and/or modify it
  8 * under the terms of the GNU General Public License version 2 as published by
  9 * the Free Software Foundation.
 10 *
 11 * This program is distributed in the hope that it will be useful, but WITHOUT
 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 14 * more details.
 15 *
 16 * You should have received a copy of the GNU General Public License along with
 17 * this program.  If not, see <http://www.gnu.org/licenses/>.
 18 */
 19
 20#define DSS_SUBSYS_NAME "SDI"
 21
 22#include <linux/kernel.h>
 23#include <linux/delay.h>
 24#include <linux/err.h>
 25#include <linux/regulator/consumer.h>
 26
 27#include <video/omapdss.h>
 28#include "dss.h"
 29
 30static struct {
 31	bool update_enabled;
 32	struct regulator *vdds_sdi_reg;
 33} sdi;
 34
 35static void sdi_basic_init(struct omap_dss_device *dssdev)
 36
 37{
 38	dispc_set_parallel_interface_mode(dssdev->manager->id,
 39			OMAP_DSS_PARALLELMODE_BYPASS);
 40
 41	dispc_set_lcd_display_type(dssdev->manager->id,
 42			OMAP_DSS_LCD_DISPLAY_TFT);
 43
 44	dispc_set_tft_data_lines(dssdev->manager->id, 24);
 45	dispc_lcd_enable_signal_polarity(1);
 46}
 47
 48int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
 49{
 50	struct omap_video_timings *t = &dssdev->panel.timings;
 51	struct dss_clock_info dss_cinfo;
 52	struct dispc_clock_info dispc_cinfo;
 53	u16 lck_div, pck_div;
 54	unsigned long fck;
 55	unsigned long pck;
 56	int r;
 57
 58	r = omap_dss_start_device(dssdev);
 59	if (r) {
 60		DSSERR("failed to start device\n");
 61		goto err_start_dev;
 62	}
 63
 64	r = regulator_enable(sdi.vdds_sdi_reg);
 65	if (r)
 66		goto err_reg_enable;
 67
 68	r = dss_runtime_get();
 69	if (r)
 70		goto err_get_dss;
 71
 72	r = dispc_runtime_get();
 73	if (r)
 74		goto err_get_dispc;
 75
 76	sdi_basic_init(dssdev);
 77
 78	/* 15.5.9.1.2 */
 79	dssdev->panel.config |= OMAP_DSS_LCD_RF | OMAP_DSS_LCD_ONOFF;
 80
 81	dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
 82			dssdev->panel.acbi, dssdev->panel.acb);
 83
 84	r = dss_calc_clock_div(1, t->pixel_clock * 1000,
 85			&dss_cinfo, &dispc_cinfo);
 86	if (r)
 87		goto err_calc_clock_div;
 88
 89	fck = dss_cinfo.fck;
 90	lck_div = dispc_cinfo.lck_div;
 91	pck_div = dispc_cinfo.pck_div;
 92
 93	pck = fck / lck_div / pck_div / 1000;
 94
 95	if (pck != t->pixel_clock) {
 96		DSSWARN("Could not find exact pixel clock. Requested %d kHz, "
 97				"got %lu kHz\n",
 98				t->pixel_clock, pck);
 99
100		t->pixel_clock = pck;
101	}
102
103
104	dispc_set_lcd_timings(dssdev->manager->id, t);
105
106	r = dss_set_clock_div(&dss_cinfo);
107	if (r)
108		goto err_set_dss_clock_div;
109
110	r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
111	if (r)
112		goto err_set_dispc_clock_div;
113
114	dss_sdi_init(dssdev->phy.sdi.datapairs);
115	r = dss_sdi_enable();
116	if (r)
117		goto err_sdi_enable;
118	mdelay(2);
119
120	dssdev->manager->enable(dssdev->manager);
121
122	return 0;
123
124err_sdi_enable:
125err_set_dispc_clock_div:
126err_set_dss_clock_div:
127err_calc_clock_div:
128	dispc_runtime_put();
129err_get_dispc:
130	dss_runtime_put();
131err_get_dss:
132	regulator_disable(sdi.vdds_sdi_reg);
133err_reg_enable:
134	omap_dss_stop_device(dssdev);
135err_start_dev:
136	return r;
137}
138EXPORT_SYMBOL(omapdss_sdi_display_enable);
139
140void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
141{
142	dssdev->manager->disable(dssdev->manager);
143
144	dss_sdi_disable();
145
146	dispc_runtime_put();
147	dss_runtime_put();
148
149	regulator_disable(sdi.vdds_sdi_reg);
150
151	omap_dss_stop_device(dssdev);
152}
153EXPORT_SYMBOL(omapdss_sdi_display_disable);
154
155int sdi_init_display(struct omap_dss_device *dssdev)
156{
157	DSSDBG("SDI init\n");
158
159	if (sdi.vdds_sdi_reg == NULL) {
160		struct regulator *vdds_sdi;
161
162		vdds_sdi = dss_get_vdds_sdi();
163
164		if (IS_ERR(vdds_sdi)) {
165			DSSERR("can't get VDDS_SDI regulator\n");
166			return PTR_ERR(vdds_sdi);
167		}
168
169		sdi.vdds_sdi_reg = vdds_sdi;
170	}
171
172	return 0;
173}
174
175int sdi_init(void)
176{
177	return 0;
178}
179
180void sdi_exit(void)
181{
182}