GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / msm / mddi.c
blob132eb1adff16b7b28b40a5c8ba11f1b3e1f59426
1 /* Copyright (c) 2008-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
15 * 02110-1301, USA.
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/sched.h>
21 #include <linux/time.h>
22 #include <linux/init.h>
23 #include <linux/interrupt.h>
24 #include <linux/spinlock.h>
25 #include <linux/delay.h>
26 #include <mach/hardware.h>
27 #include <asm/io.h>
29 #include <asm/system.h>
30 #include <asm/mach-types.h>
31 #include <linux/semaphore.h>
32 #include <linux/uaccess.h>
33 #include <linux/clk.h>
34 #include <linux/platform_device.h>
36 #include "msm_fb.h"
37 #include "mddihosti.h"
38 #include "mddihost.h"
39 #include <mach/gpio.h>
40 #include <mach/clk.h>
42 static int mddi_probe(struct platform_device *pdev);
43 static int mddi_remove(struct platform_device *pdev);
45 static int mddi_off(struct platform_device *pdev);
46 static int mddi_on(struct platform_device *pdev);
48 static int mddi_suspend(struct platform_device *pdev, pm_message_t state);
49 static int mddi_resume(struct platform_device *pdev);
51 #ifdef CONFIG_HAS_EARLYSUSPEND
52 static void mddi_early_suspend(struct early_suspend *h);
53 static void mddi_early_resume(struct early_suspend *h);
54 #endif
56 static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
57 static int pdev_list_cnt;
58 static struct clk *mddi_clk;
59 static struct clk *mddi_pclk;
60 static struct mddi_platform_data *mddi_pdata;
62 static struct platform_driver mddi_driver = {
63 .probe = mddi_probe,
64 .remove = mddi_remove,
65 #ifndef CONFIG_HAS_EARLYSUSPEND
66 #ifdef CONFIG_PM
67 .suspend = mddi_suspend,
68 .resume = mddi_resume,
69 #endif
70 #endif
71 .suspend_late = NULL,
72 .resume_early = NULL,
73 .shutdown = NULL,
74 .driver = {
75 .name = "mddi",
79 extern int int_mddi_pri_flag;
81 static int mddi_off(struct platform_device *pdev)
83 int ret = 0;
85 ret = panel_next_off(pdev);
87 if (mddi_pdata && mddi_pdata->mddi_power_save)
88 mddi_pdata->mddi_power_save(0);
90 return ret;
93 static int mddi_on(struct platform_device *pdev)
95 int ret = 0;
96 u32 clk_rate;
97 struct msm_fb_data_type *mfd;
99 mfd = platform_get_drvdata(pdev);
101 if (mddi_pdata && mddi_pdata->mddi_power_save)
102 mddi_pdata->mddi_power_save(1);
104 clk_rate = mfd->fbi->var.pixclock;
105 clk_rate = min(clk_rate, mfd->panel_info.clk_max);
107 if (mddi_pdata &&
108 mddi_pdata->mddi_sel_clk &&
109 mddi_pdata->mddi_sel_clk(&clk_rate))
110 printk(KERN_ERR
111 "%s: can't select mddi io clk targate rate = %d\n",
112 __func__, clk_rate);
114 if (clk_set_min_rate(mddi_clk, clk_rate) < 0)
115 printk(KERN_ERR "%s: clk_set_min_rate failed\n",
116 __func__);
118 ret = panel_next_on(pdev);
120 return ret;
123 static int mddi_resource_initialized;
125 static int mddi_probe(struct platform_device *pdev)
127 struct msm_fb_data_type *mfd;
128 struct platform_device *mdp_dev = NULL;
129 struct msm_fb_panel_data *pdata = NULL;
130 int rc;
131 resource_size_t size ;
132 u32 clk_rate;
134 if ((pdev->id == 0) && (pdev->num_resources >= 0)) {
135 mddi_pdata = pdev->dev.platform_data;
137 size = resource_size(&pdev->resource[0]);
138 msm_pmdh_base = ioremap(pdev->resource[0].start, size);
140 MSM_FB_INFO("primary mddi base phy_addr = 0x%x virt = 0x%x\n",
141 pdev->resource[0].start, (int) msm_pmdh_base);
143 if (unlikely(!msm_pmdh_base))
144 return -ENOMEM;
146 if (mddi_pdata && mddi_pdata->mddi_power_save)
147 mddi_pdata->mddi_power_save(1);
149 mddi_resource_initialized = 1;
150 return 0;
153 if (!mddi_resource_initialized)
154 return -EPERM;
156 mfd = platform_get_drvdata(pdev);
158 if (!mfd)
159 return -ENODEV;
161 if (mfd->key != MFD_KEY)
162 return -EINVAL;
164 if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
165 return -ENOMEM;
167 mdp_dev = platform_device_alloc("mdp", pdev->id);
168 if (!mdp_dev)
169 return -ENOMEM;
172 * link to the latest pdev
174 mfd->pdev = mdp_dev;
175 mfd->dest = DISPLAY_LCD;
178 * alloc panel device data
180 if (platform_device_add_data
181 (mdp_dev, pdev->dev.platform_data,
182 sizeof(struct msm_fb_panel_data))) {
183 printk(KERN_ERR "mddi_probe: platform_device_add_data failed!\n");
184 platform_device_put(mdp_dev);
185 return -ENOMEM;
188 * data chain
190 pdata = mdp_dev->dev.platform_data;
191 pdata->on = mddi_on;
192 pdata->off = mddi_off;
193 pdata->next = pdev;
196 * get/set panel specific fb info
198 mfd->panel_info = pdata->panel_info;
199 mfd->fb_imgType = MDP_RGB_565;
201 clk_rate = mfd->panel_info.clk_max;
202 if (mddi_pdata &&
203 mddi_pdata->mddi_sel_clk &&
204 mddi_pdata->mddi_sel_clk(&clk_rate))
205 printk(KERN_ERR
206 "%s: can't select mddi io clk targate rate = %d\n",
207 __func__, clk_rate);
209 if (clk_set_max_rate(mddi_clk, clk_rate) < 0)
210 printk(KERN_ERR "%s: clk_set_max_rate failed\n", __func__);
211 mfd->panel_info.clk_rate = mfd->panel_info.clk_min;
214 * set driver data
216 platform_set_drvdata(mdp_dev, mfd);
219 * register in mdp driver
221 rc = platform_device_add(mdp_dev);
222 if (rc)
223 goto mddi_probe_err;
225 pdev_list[pdev_list_cnt++] = pdev;
227 #ifdef CONFIG_HAS_EARLYSUSPEND
228 mfd->mddi_early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
229 mfd->mddi_early_suspend.suspend = mddi_early_suspend;
230 mfd->mddi_early_suspend.resume = mddi_early_resume;
231 register_early_suspend(&mfd->mddi_early_suspend);
232 #endif
234 return 0;
236 mddi_probe_err:
237 platform_device_put(mdp_dev);
238 return rc;
241 static int mddi_pad_ctrl;
242 static int mddi_power_locked;
243 static int mddi_is_in_suspend;
245 void mddi_disable(int lock)
247 mddi_host_type host_idx = MDDI_HOST_PRIM;
249 if (mddi_power_locked)
250 return;
252 if (lock)
253 mddi_power_locked = 1;
255 if (mddi_host_timer.function)
256 del_timer_sync(&mddi_host_timer);
258 mddi_pad_ctrl = mddi_host_reg_in(PAD_CTL);
259 mddi_host_reg_out(PAD_CTL, 0x0);
261 if (clk_set_min_rate(mddi_clk, 0) < 0)
262 printk(KERN_ERR "%s: clk_set_min_rate failed\n", __func__);
264 clk_disable(mddi_clk);
265 if (mddi_pclk)
266 clk_disable(mddi_pclk);
267 disable_irq(INT_MDDI_PRI);
269 if (mddi_pdata && mddi_pdata->mddi_power_save)
270 mddi_pdata->mddi_power_save(0);
273 static int mddi_suspend(struct platform_device *pdev, pm_message_t state)
275 if (mddi_is_in_suspend)
276 return 0;
278 mddi_is_in_suspend = 1;
279 mddi_disable(0);
280 return 0;
283 static int mddi_resume(struct platform_device *pdev)
285 mddi_host_type host_idx = MDDI_HOST_PRIM;
287 if (!mddi_is_in_suspend)
288 return 0;
290 mddi_is_in_suspend = 0;
292 if (mddi_power_locked)
293 return 0;
295 enable_irq(INT_MDDI_PRI);
296 clk_enable(mddi_clk);
297 if (mddi_pclk)
298 clk_enable(mddi_pclk);
299 mddi_host_reg_out(PAD_CTL, mddi_pad_ctrl);
301 if (mddi_host_timer.function)
302 mddi_host_timer_service(0);
304 return 0;
307 #ifdef CONFIG_HAS_EARLYSUSPEND
308 static void mddi_early_suspend(struct early_suspend *h)
310 pm_message_t state;
311 struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
312 mddi_early_suspend);
314 state.event = PM_EVENT_SUSPEND;
315 mddi_suspend(mfd->pdev, state);
318 static void mddi_early_resume(struct early_suspend *h)
320 struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
321 mddi_early_suspend);
322 mddi_resume(mfd->pdev);
324 #endif
326 static int mddi_remove(struct platform_device *pdev)
328 if (mddi_host_timer.function)
329 del_timer_sync(&mddi_host_timer);
331 iounmap(msm_pmdh_base);
333 return 0;
336 static int mddi_register_driver(void)
338 return platform_driver_register(&mddi_driver);
341 static int __init mddi_driver_init(void)
343 int ret;
345 mddi_clk = clk_get(NULL, "mddi_clk");
346 if (IS_ERR(mddi_clk)) {
347 printk(KERN_ERR "can't find mddi_clk \n");
348 return PTR_ERR(mddi_clk);
350 clk_enable(mddi_clk);
352 mddi_pclk = clk_get(NULL, "mddi_pclk");
353 if (IS_ERR(mddi_pclk))
354 mddi_pclk = NULL;
355 else
356 clk_enable(mddi_pclk);
358 ret = mddi_register_driver();
359 if (ret) {
360 clk_disable(mddi_clk);
361 clk_put(mddi_clk);
362 if (mddi_pclk) {
363 clk_disable(mddi_pclk);
364 clk_put(mddi_pclk);
366 printk(KERN_ERR "mddi_register_driver() failed!\n");
367 return ret;
370 mddi_init();
372 return ret;
375 module_init(mddi_driver_init);