merge of '178eac00dc5aa8338d42e8e203633bec7817bbf6'
[vuplus_openembedded] / packages / linux / linux-rp-2.6.24 / tosa / 0067-modeswitching.patch
1 From aded2e51a7a2113dae6431c858df1d95fb312851 Mon Sep 17 00:00:00 2001
2 From: Dmitry Baryshkov <dbaryshkov@gmail.com>
3 Date: Wed, 13 Feb 2008 19:34:08 +0300
4 Subject: [PATCH] modeswitching
5
6 Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
7 ---
8  arch/arm/mach-pxa/tosa.c          |   33 +++++++++++++++++++++++++++++++-
9  drivers/mfd/tc6393xb.c            |    2 +-
10  drivers/video/backlight/tosa_bl.c |   38 +++++++++++++++++++++++++++++++++---
11  drivers/video/tmiofb.c            |    8 +++---
12  include/asm-arm/arch-pxa/tosa.h   |    2 +
13  include/linux/mfd/tc6393xb.h      |    2 +-
14  include/linux/mfd/tmio.h          |    2 +-
15  7 files changed, 75 insertions(+), 12 deletions(-)
16
17 diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
18 index 94c9915..6631de2 100644
19 --- a/arch/arm/mach-pxa/tosa.c
20 +++ b/arch/arm/mach-pxa/tosa.c
21 @@ -455,9 +455,40 @@ static struct fb_videomode tosa_tc6393xb_lcd_mode[] = {
22         }
23  };
24  
25 +static DEFINE_SPINLOCK(tosa_lcd_mode_lock);
26 +
27 +static const struct fb_videomode *tosa_lcd_mode = &tosa_tc6393xb_lcd_mode[0];
28 +
29 +static int tosa_lcd_set_mode(struct platform_device *fb_dev,
30 +                                       const struct fb_videomode *mode)
31 +{
32 +       int rc;
33 +       unsigned long flags;
34 +
35 +       spin_lock_irqsave(&tosa_lcd_mode_lock, flags);
36 +       rc = tc6393xb_lcd_mode(fb_dev, mode);
37 +       if (!rc)
38 +               tosa_lcd_mode = mode;
39 +       spin_unlock_irqrestore(&tosa_lcd_mode_lock, flags);
40 +
41 +       return rc;
42 +}
43 +
44 +const struct fb_videomode *tosa_lcd_get_mode(void)
45 +{
46 +       unsigned long flags;
47 +       const struct fb_videomode *mode;
48 +
49 +       spin_lock_irqsave(&tosa_lcd_mode_lock, flags);
50 +       mode = tosa_lcd_mode;
51 +       spin_unlock_irqrestore(&tosa_lcd_mode_lock, flags);
52 +
53 +       return mode;
54 +}
55 +
56  static struct tmio_fb_data tosa_tc6393xb_fb_config = {
57         .lcd_set_power  = tc6393xb_lcd_set_power,
58 -       .lcd_mode       = tc6393xb_lcd_mode,
59 +       .lcd_mode       = tosa_lcd_set_mode,
60         .num_modes      = ARRAY_SIZE(tosa_tc6393xb_lcd_mode),
61         .modes          = &tosa_tc6393xb_lcd_mode[0],
62  };
63 diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
64 index 9001687..21190f3 100644
65 --- a/drivers/mfd/tc6393xb.c
66 +++ b/drivers/mfd/tc6393xb.c
67 @@ -196,7 +196,7 @@ int tc6393xb_lcd_set_power(struct platform_device *fb, bool on)
68  EXPORT_SYMBOL(tc6393xb_lcd_set_power);
69  
70  int tc6393xb_lcd_mode(struct platform_device *fb_dev,
71 -                                       struct fb_videomode *mode) {
72 +                                       const struct fb_videomode *mode) {
73         struct tc6393xb                 *tc6393xb =
74                 platform_get_drvdata(to_platform_device(fb_dev->dev.parent));
75         struct tc6393xb_scr __iomem     *scr    = tc6393xb->scr;
76 diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c
77 index 9ef0bfb..45fc6ae 100644
78 --- a/drivers/video/backlight/tosa_bl.c
79 +++ b/drivers/video/backlight/tosa_bl.c
80 @@ -48,6 +48,9 @@ struct tosa_bl_data {
81         struct ssp_dev          nssp_dev;
82         struct ssp_state        nssp_state;
83  
84 +       /* listen for mode changes */
85 +       struct notifier_block   fb_notif;
86 +
87         struct backlight_device *bl_dev;
88  };
89  
90 @@ -103,14 +106,19 @@ static void tosa_lcd_tg_init(struct tosa_bl_data *data)
91         pxa_nssp_output(data, TG_GPOSR,0x02);           /* GPOS0=powercontrol, GPOS1=GPIO, GPOS2=TCTL */
92  }
93  
94 -static void tosa_lcd_tg_on(struct tosa_bl_data *data/*, const struct fb_videomode *mode*/)
95 +static void tosa_lcd_tg_on(struct tosa_bl_data *data)
96  {
97 -       const int value = TG_REG0_COLOR | TG_REG0_UD | TG_REG0_LR;
98 +       const struct fb_videomode *mode = tosa_lcd_get_mode();
99 +
100 +       int value = TG_REG0_COLOR | TG_REG0_UD | TG_REG0_LR;
101 +
102 +       if (mode->yres == 640)
103 +               value |= TG_REG0_VQV;
104  
105         tosa_lcd_tg_init(data);
106  
107 -       dev_dbg(&data->bl_dev->dev, "tosa_lcd_on\n");
108 -       pxa_nssp_output(data, TG_PNLCTL, value | (/*mode->yres == 320 ? 0 : */ TG_REG0_VQV));
109 +       dev_dbg(&data->bl_dev->dev, "tosa_lcd_on: %04x (%d)\n", value, mode->yres);
110 +       pxa_nssp_output(data, TG_PNLCTL, value);
111  
112         /* TG LCD pannel power up */
113         pxa_nssp_output(data, TG_PINICTL,0x4);
114 @@ -173,6 +181,20 @@ static struct backlight_ops tosa_bl_ops = {
115         .update_status          = tosa_bl_update_status,
116  };
117  
118 +static int fb_notifier_callback(struct notifier_block *self,
119 +                               unsigned long event, void *_data)
120 +{
121 +       struct tosa_bl_data *bl_data =
122 +               container_of(self, struct tosa_bl_data, fb_notif);
123 +
124 +       if (event != FB_EVENT_MODE_CHANGE && event != FB_EVENT_MODE_CHANGE_ALL)
125 +               return 0;
126 +
127 +       tosa_bl_update_status(bl_data->bl_dev);
128 +
129 +       return 0;
130 +}
131 +
132  static int tosa_bl_detect_client(struct i2c_adapter *adapter, int address,
133                          int kind)
134  {
135 @@ -238,9 +260,15 @@ static int tosa_bl_detect_client(struct i2c_adapter *adapter, int address,
136         data->bl_dev->props.power = FB_BLANK_UNBLANK;
137         backlight_update_status(data->bl_dev);
138  
139 +       data->fb_notif.notifier_call = fb_notifier_callback;
140 +       err = fb_register_client(&data->fb_notif);
141 +       if (err)
142 +               goto err_fb_register;
143  
144         return 0;
145  
146 +err_fb_register:
147 +       backlight_device_unregister(data->bl_dev);
148  err_bl_register:
149         tosa_set_backlight(data, 0);
150         tosa_lcd_tg_off(data);
151 @@ -265,6 +293,8 @@ static int tosa_bl_detach_client(struct i2c_client *client)
152         int err = 0;
153         struct tosa_bl_data *data = i2c_get_clientdata(client);
154  
155 +       fb_unregister_client(&data->fb_notif);
156 +
157         backlight_device_unregister(data->bl_dev);
158  
159         tosa_set_backlight(data, 0);
160 diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
161 index 958ee8a..cc75df9 100644
162 --- a/drivers/video/tmiofb.c
163 +++ b/drivers/video/tmiofb.c
164 @@ -618,17 +618,17 @@ static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
165  
166  static int tmiofb_set_par(struct fb_info *info)
167  {
168 -/*     struct fb_var_screeninfo        *var    = &info->var;
169 +       struct fb_var_screeninfo        *var    = &info->var;
170         struct fb_videomode             *mode;
171  
172         mode = tmiofb_find_mode(info, var);
173         if (!mode)
174                 return -EINVAL;
175  
176 -       if (info->mode == mode)
177 -               return 0;
178 +/*     if (info->mode == mode)
179 +               return 0;*/
180  
181 -       info->mode              = mode; */
182 +       info->mode              = mode;
183         info->fix.line_length   = info->mode->xres * 2;
184  
185         tmiofb_hw_mode(to_platform_device(info->device));
186 diff --git a/include/asm-arm/arch-pxa/tosa.h b/include/asm-arm/arch-pxa/tosa.h
187 index 410fa9a..624c636 100644
188 --- a/include/asm-arm/arch-pxa/tosa.h
189 +++ b/include/asm-arm/arch-pxa/tosa.h
190 @@ -230,4 +230,6 @@ extern struct platform_device tosascoop_device;
191  #define TOSA_KEY_MAIL          KEY_MAIL
192  #endif
193  
194 +const struct fb_videomode *tosa_lcd_get_mode(void);
195 +
196  #endif /* _ASM_ARCH_TOSA_H_ */
197 diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h
198 index 97c4c7c..8ab9e91 100644
199 --- a/include/linux/mfd/tc6393xb.h
200 +++ b/include/linux/mfd/tc6393xb.h
201 @@ -53,7 +53,7 @@ struct tc6393xb_platform_data {
202  
203  extern int tc6393xb_lcd_set_power(struct platform_device *fb_dev, bool on);
204  extern int tc6393xb_lcd_mode(struct platform_device *fb_dev,
205 -                                       struct fb_videomode *mode);
206 +                                       const struct fb_videomode *mode);
207  
208  /*
209   * Relative to irq_base
210 diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
211 index b6d4aac..fe7ff2d 100644
212 --- a/include/linux/mfd/tmio.h
213 +++ b/include/linux/mfd/tmio.h
214 @@ -19,7 +19,7 @@ struct tmio_fb_data {
215         int                     (*lcd_set_power)(struct platform_device *fb_dev,
216                                                                 bool on);
217         int                     (*lcd_mode)(struct platform_device *fb_dev,
218 -                                               struct fb_videomode *mode);
219 +                                       const struct fb_videomode *mode);
220         int                     num_modes;
221         struct fb_videomode     *modes;
222  };
223 -- 
224 1.5.4.1
225