1 /* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 #include <linux/delay.h>
19 #ifdef CONFIG_ARCH_MSM7X30
20 #include <linux/mfd/pmic8058.h>
22 #include <mach/gpio.h>
25 static int lcdc_sharp_panel_off(struct platform_device *pdev);
31 static unsigned char bit_shift[8] = { (1 << 7), /* MSB */
41 struct sharp_state_type {
42 boolean disp_initialized;
44 boolean disp_powered_up;
47 struct sharp_spi_data {
52 static struct sharp_spi_data init_sequence[] = {
111 static struct sharp_state_type sharp_state = { 0 };
112 static struct msm_panel_common_pdata *lcdc_sharp_pdata;
114 static void sharp_spi_write_byte(u8 val)
118 /* Clock should be Low before entering */
119 for (i = 0; i < 8; i++) {
120 /* #1: Drive the Data (High or Low) */
121 if (val & bit_shift[i])
122 gpio_set_value(spi_mosi, 1);
124 gpio_set_value(spi_mosi, 0);
126 /* #2: Drive the Clk High and then Low */
127 gpio_set_value(spi_sclk, 1);
128 gpio_set_value(spi_sclk, 0);
132 static void serigo(u8 reg, u8 data)
134 /* Enable the Chip Select - low */
135 gpio_set_value(spi_cs, 0);
138 /* Transmit register address first, then data */
139 sharp_spi_write_byte(reg);
141 /* Idle state of MOSI is Low */
142 gpio_set_value(spi_mosi, 0);
144 sharp_spi_write_byte(data);
146 gpio_set_value(spi_mosi, 0);
147 gpio_set_value(spi_cs, 1);
150 static void sharp_spi_init(void)
152 spi_sclk = *(lcdc_sharp_pdata->gpio_num);
153 spi_cs = *(lcdc_sharp_pdata->gpio_num + 1);
154 spi_mosi = *(lcdc_sharp_pdata->gpio_num + 2);
155 spi_miso = *(lcdc_sharp_pdata->gpio_num + 3);
157 /* Set the output so that we don't disturb the slave device */
158 gpio_set_value(spi_sclk, 0);
159 gpio_set_value(spi_mosi, 0);
161 /* Set the Chip Select deasserted (active low) */
162 gpio_set_value(spi_cs, 1);
165 static void sharp_disp_powerup(void)
167 if (!sharp_state.disp_powered_up && !sharp_state.display_on)
168 sharp_state.disp_powered_up = TRUE;
171 static void sharp_disp_on(void)
175 if (sharp_state.disp_powered_up && !sharp_state.display_on) {
176 for (i = 0; i < ARRAY_SIZE(init_sequence); i++) {
177 serigo(init_sequence[i].addr,
178 init_sequence[i].data);
186 sharp_state.display_on = TRUE;
190 static int lcdc_sharp_panel_on(struct platform_device *pdev)
192 if (!sharp_state.disp_initialized) {
193 lcdc_sharp_pdata->panel_config_gpio(1);
195 sharp_disp_powerup();
197 sharp_state.disp_initialized = TRUE;
202 static int lcdc_sharp_panel_off(struct platform_device *pdev)
204 if (sharp_state.disp_powered_up && sharp_state.display_on) {
211 sharp_state.display_on = FALSE;
212 sharp_state.disp_initialized = FALSE;
217 static int __init sharp_probe(struct platform_device *pdev)
220 lcdc_sharp_pdata = pdev->dev.platform_data;
223 msm_fb_add_device(pdev);
227 static struct platform_driver this_driver = {
228 .probe = sharp_probe,
230 .name = "lcdc_sharp_wvga",
234 static struct msm_fb_panel_data sharp_panel_data = {
235 .on = lcdc_sharp_panel_on,
236 .off = lcdc_sharp_panel_off,
239 static struct platform_device this_device = {
240 .name = "lcdc_sharp_wvga",
243 .platform_data = &sharp_panel_data,
247 static int __init lcdc_sharp_panel_init(void)
250 struct msm_panel_info *pinfo;
252 #ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
253 if (msm_fb_detect_client("lcdc_sharp_wvga_pt"))
257 ret = platform_driver_register(&this_driver);
261 pinfo = &sharp_panel_data.panel_info;
264 pinfo->type = LCDC_PANEL;
265 pinfo->pdest = DISPLAY_1;
266 pinfo->wait_cycle = 0;
269 pinfo->clk_rate = 24500000;
273 pinfo->lcdc.h_back_porch = 20;
274 pinfo->lcdc.h_front_porch = 10;
275 pinfo->lcdc.h_pulse_width = 10;
276 pinfo->lcdc.v_back_porch = 2;
277 pinfo->lcdc.v_front_porch = 2;
278 pinfo->lcdc.v_pulse_width = 2;
279 pinfo->lcdc.border_clr = 0;
280 pinfo->lcdc.underflow_clr = 0xff;
281 pinfo->lcdc.hsync_skew = 0;
283 ret = platform_device_register(&this_device);
285 platform_driver_unregister(&this_driver);
290 module_init(lcdc_sharp_panel_init);