diff options
Diffstat (limited to 'drivers/video/s3c2410fb.c')
-rw-r--r-- | drivers/video/s3c2410fb.c | 357 |
1 files changed, 172 insertions, 185 deletions
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index 8a4c6470d799..f10310178e3e 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c | |||
@@ -31,8 +31,8 @@ | |||
31 | * - add pixel clock divisor control | 31 | * - add pixel clock divisor control |
32 | * | 32 | * |
33 | * 2004-11-11: Arnaud Patard <arnaud.patard@rtp-net.org> | 33 | * 2004-11-11: Arnaud Patard <arnaud.patard@rtp-net.org> |
34 | * - Removed the use of currcon as it no more exist | 34 | * - Removed the use of currcon as it no more exist |
35 | * - Added LCD power sysfs interface | 35 | * - Added LCD power sysfs interface |
36 | * | 36 | * |
37 | * 2004-11-03: Ben Dooks <ben-linux@fluff.org> | 37 | * 2004-11-03: Ben Dooks <ben-linux@fluff.org> |
38 | * - minor cleanups | 38 | * - minor cleanups |
@@ -49,12 +49,12 @@ | |||
49 | * - Suppress command line options | 49 | * - Suppress command line options |
50 | * | 50 | * |
51 | * 2004-09-15: Arnaud Patard <arnaud.patard@rtp-net.org> | 51 | * 2004-09-15: Arnaud Patard <arnaud.patard@rtp-net.org> |
52 | * - code cleanup | 52 | * - code cleanup |
53 | * | 53 | * |
54 | * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org> | 54 | * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org> |
55 | * - Renamed from h1940fb.c to s3c2410fb.c | 55 | * - Renamed from h1940fb.c to s3c2410fb.c |
56 | * - Add support for different devices | 56 | * - Add support for different devices |
57 | * - Backlight support | 57 | * - Backlight support |
58 | * | 58 | * |
59 | * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at> | 59 | * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at> |
60 | * - added clock (de-)allocation code | 60 | * - added clock (de-)allocation code |
@@ -102,14 +102,13 @@ | |||
102 | 102 | ||
103 | #include "s3c2410fb.h" | 103 | #include "s3c2410fb.h" |
104 | 104 | ||
105 | |||
106 | static struct s3c2410fb_mach_info *mach_info; | 105 | static struct s3c2410fb_mach_info *mach_info; |
107 | 106 | ||
108 | /* Debugging stuff */ | 107 | /* Debugging stuff */ |
109 | #ifdef CONFIG_FB_S3C2410_DEBUG | 108 | #ifdef CONFIG_FB_S3C2410_DEBUG |
110 | static int debug = 1; | 109 | static int debug = 1; |
111 | #else | 110 | #else |
112 | static int debug = 0; | 111 | static int debug = 0; |
113 | #endif | 112 | #endif |
114 | 113 | ||
115 | #define dprintk(msg...) if (debug) { printk(KERN_DEBUG "s3c2410fb: " msg); } | 114 | #define dprintk(msg...) if (debug) { printk(KERN_DEBUG "s3c2410fb: " msg); } |
@@ -119,19 +118,20 @@ static int debug = 0; | |||
119 | /* s3c2410fb_set_lcdaddr | 118 | /* s3c2410fb_set_lcdaddr |
120 | * | 119 | * |
121 | * initialise lcd controller address pointers | 120 | * initialise lcd controller address pointers |
122 | */ | 121 | */ |
123 | |||
124 | static void s3c2410fb_set_lcdaddr(struct s3c2410fb_info *fbi) | 122 | static void s3c2410fb_set_lcdaddr(struct s3c2410fb_info *fbi) |
125 | { | 123 | { |
126 | struct fb_var_screeninfo *var = &fbi->fb->var; | 124 | struct fb_var_screeninfo *var = &fbi->fb->var; |
127 | unsigned long saddr1, saddr2, saddr3; | 125 | unsigned long saddr1, saddr2, saddr3; |
126 | int line_length = var->xres * var->bits_per_pixel; | ||
128 | 127 | ||
129 | saddr1 = fbi->fb->fix.smem_start >> 1; | 128 | saddr1 = fbi->fb->fix.smem_start >> 1; |
130 | saddr2 = fbi->fb->fix.smem_start; | 129 | saddr2 = fbi->fb->fix.smem_start; |
131 | saddr2 += (var->xres * var->yres * var->bits_per_pixel)/8; | 130 | saddr2 += (line_length * var->yres) / 8; |
132 | saddr2>>= 1; | 131 | saddr2 >>= 1; |
133 | 132 | ||
134 | saddr3 = S3C2410_OFFSIZE(0) | S3C2410_PAGEWIDTH((var->xres * var->bits_per_pixel / 16) & 0x3ff); | 133 | saddr3 = S3C2410_OFFSIZE(0) | |
134 | S3C2410_PAGEWIDTH((line_length / 16) & 0x3ff); | ||
135 | 135 | ||
136 | dprintk("LCDSADDR1 = 0x%08lx\n", saddr1); | 136 | dprintk("LCDSADDR1 = 0x%08lx\n", saddr1); |
137 | dprintk("LCDSADDR2 = 0x%08lx\n", saddr2); | 137 | dprintk("LCDSADDR2 = 0x%08lx\n", saddr2); |
@@ -145,8 +145,7 @@ static void s3c2410fb_set_lcdaddr(struct s3c2410fb_info *fbi) | |||
145 | /* s3c2410fb_calc_pixclk() | 145 | /* s3c2410fb_calc_pixclk() |
146 | * | 146 | * |
147 | * calculate divisor for clk->pixclk | 147 | * calculate divisor for clk->pixclk |
148 | */ | 148 | */ |
149 | |||
150 | static unsigned int s3c2410fb_calc_pixclk(struct s3c2410fb_info *fbi, | 149 | static unsigned int s3c2410fb_calc_pixclk(struct s3c2410fb_info *fbi, |
151 | unsigned long pixclk) | 150 | unsigned long pixclk) |
152 | { | 151 | { |
@@ -159,8 +158,8 @@ static unsigned int s3c2410fb_calc_pixclk(struct s3c2410fb_info *fbi, | |||
159 | */ | 158 | */ |
160 | 159 | ||
161 | div = (unsigned long long)clk * pixclk; | 160 | div = (unsigned long long)clk * pixclk; |
162 | do_div(div,1000000UL); | 161 | do_div(div, 1000000UL); |
163 | do_div(div,1000000UL); | 162 | do_div(div, 1000000UL); |
164 | 163 | ||
165 | dprintk("pixclk %ld, divisor is %ld\n", pixclk, (long)div); | 164 | dprintk("pixclk %ld, divisor is %ld\n", pixclk, (long)div); |
166 | return div; | 165 | return div; |
@@ -198,93 +197,84 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var, | |||
198 | else if (var->bits_per_pixel < fbi->mach_info->bpp.min) | 197 | else if (var->bits_per_pixel < fbi->mach_info->bpp.min) |
199 | var->bits_per_pixel = fbi->mach_info->bpp.min; | 198 | var->bits_per_pixel = fbi->mach_info->bpp.min; |
200 | 199 | ||
200 | var->transp.offset = 0; | ||
201 | var->transp.length = 0; | ||
201 | /* set r/g/b positions */ | 202 | /* set r/g/b positions */ |
202 | switch (var->bits_per_pixel) { | 203 | switch (var->bits_per_pixel) { |
203 | case 1: | 204 | case 1: |
204 | case 2: | 205 | case 2: |
205 | case 4: | 206 | case 4: |
206 | var->red.offset = 0; | 207 | var->red.offset = 0; |
207 | var->red.length = var->bits_per_pixel; | 208 | var->red.length = var->bits_per_pixel; |
208 | var->green = var->red; | 209 | var->green = var->red; |
209 | var->blue = var->red; | 210 | var->blue = var->red; |
210 | var->transp.offset = 0; | 211 | break; |
211 | var->transp.length = 0; | 212 | case 8: |
212 | break; | 213 | if (fbi->mach_info->type != S3C2410_LCDCON1_TFT) { |
213 | case 8: | 214 | /* 8 bpp 332 */ |
214 | if ( fbi->mach_info->type != S3C2410_LCDCON1_TFT ) { | 215 | var->red.length = 3; |
215 | /* 8 bpp 332 */ | 216 | var->red.offset = 5; |
216 | var->red.length = 3; | 217 | var->green.length = 3; |
217 | var->red.offset = 5; | 218 | var->green.offset = 2; |
218 | var->green.length = 3; | 219 | var->blue.length = 2; |
219 | var->green.offset = 2; | ||
220 | var->blue.length = 2; | ||
221 | var->blue.offset = 0; | ||
222 | var->transp.length = 0; | ||
223 | } else { | ||
224 | var->red.offset = 0; | ||
225 | var->red.length = var->bits_per_pixel; | ||
226 | var->green = var->red; | ||
227 | var->blue = var->red; | ||
228 | var->transp.offset = 0; | ||
229 | var->transp.length = 0; | ||
230 | } | ||
231 | break; | ||
232 | case 12: | ||
233 | /* 12 bpp 444 */ | ||
234 | var->red.length = 4; | ||
235 | var->red.offset = 8; | ||
236 | var->green.length = 4; | ||
237 | var->green.offset = 4; | ||
238 | var->blue.length = 4; | ||
239 | var->blue.offset = 0; | 220 | var->blue.offset = 0; |
240 | var->transp.length = 0; | 221 | } else { |
241 | break; | 222 | var->red.offset = 0; |
242 | |||
243 | default: | ||
244 | case 16: | ||
245 | if (fbi->regs.lcdcon5 & S3C2410_LCDCON5_FRM565 ) { | ||
246 | /* 16 bpp, 565 format */ | ||
247 | var->red.offset = 11; | ||
248 | var->green.offset = 5; | ||
249 | var->blue.offset = 0; | ||
250 | var->red.length = 5; | ||
251 | var->green.length = 6; | ||
252 | var->blue.length = 5; | ||
253 | var->transp.length = 0; | ||
254 | } else { | ||
255 | /* 16 bpp, 5551 format */ | ||
256 | var->red.offset = 11; | ||
257 | var->green.offset = 6; | ||
258 | var->blue.offset = 1; | ||
259 | var->red.length = 5; | ||
260 | var->green.length = 5; | ||
261 | var->blue.length = 5; | ||
262 | var->transp.length = 0; | ||
263 | } | ||
264 | break; | ||
265 | case 24: | ||
266 | /* 24 bpp 888 */ | ||
267 | var->red.length = 8; | 223 | var->red.length = 8; |
268 | var->red.offset = 16; | 224 | var->green = var->red; |
269 | var->green.length = 8; | 225 | var->blue = var->red; |
270 | var->green.offset = 8; | 226 | } |
271 | var->blue.length = 8; | 227 | break; |
228 | case 12: | ||
229 | /* 12 bpp 444 */ | ||
230 | var->red.length = 4; | ||
231 | var->red.offset = 8; | ||
232 | var->green.length = 4; | ||
233 | var->green.offset = 4; | ||
234 | var->blue.length = 4; | ||
235 | var->blue.offset = 0; | ||
236 | break; | ||
237 | |||
238 | default: | ||
239 | case 16: | ||
240 | if (fbi->regs.lcdcon5 & S3C2410_LCDCON5_FRM565) { | ||
241 | /* 16 bpp, 565 format */ | ||
242 | var->red.offset = 11; | ||
243 | var->green.offset = 5; | ||
272 | var->blue.offset = 0; | 244 | var->blue.offset = 0; |
273 | var->transp.length = 0; | 245 | var->red.length = 5; |
274 | break; | 246 | var->green.length = 6; |
247 | var->blue.length = 5; | ||
248 | } else { | ||
249 | /* 16 bpp, 5551 format */ | ||
250 | var->red.offset = 11; | ||
251 | var->green.offset = 6; | ||
252 | var->blue.offset = 1; | ||
253 | var->red.length = 5; | ||
254 | var->green.length = 5; | ||
255 | var->blue.length = 5; | ||
256 | } | ||
257 | break; | ||
258 | case 24: | ||
259 | /* 24 bpp 888 */ | ||
260 | var->red.length = 8; | ||
261 | var->red.offset = 16; | ||
262 | var->green.length = 8; | ||
263 | var->green.offset = 8; | ||
264 | var->blue.length = 8; | ||
265 | var->blue.offset = 0; | ||
266 | break; | ||
275 | 267 | ||
276 | 268 | ||
277 | } | 269 | } |
278 | return 0; | 270 | return 0; |
279 | } | 271 | } |
280 | 272 | ||
281 | |||
282 | /* s3c2410fb_activate_var | 273 | /* s3c2410fb_activate_var |
283 | * | 274 | * |
284 | * activate (set) the controller from the given framebuffer | 275 | * activate (set) the controller from the given framebuffer |
285 | * information | 276 | * information |
286 | */ | 277 | */ |
287 | |||
288 | static void s3c2410fb_activate_var(struct s3c2410fb_info *fbi, | 278 | static void s3c2410fb_activate_var(struct s3c2410fb_info *fbi, |
289 | struct fb_var_screeninfo *var) | 279 | struct fb_var_screeninfo *var) |
290 | { | 280 | { |
@@ -319,7 +309,8 @@ static void s3c2410fb_activate_var(struct s3c2410fb_info *fbi, | |||
319 | 309 | ||
320 | default: | 310 | default: |
321 | /* invalid pixel depth */ | 311 | /* invalid pixel depth */ |
322 | dev_err(fbi->dev, "invalid bpp %d\n", var->bits_per_pixel); | 312 | dev_err(fbi->dev, "invalid bpp %d\n", |
313 | var->bits_per_pixel); | ||
323 | } | 314 | } |
324 | else | 315 | else |
325 | switch (var->bits_per_pixel) { | 316 | switch (var->bits_per_pixel) { |
@@ -341,19 +332,18 @@ static void s3c2410fb_activate_var(struct s3c2410fb_info *fbi, | |||
341 | 332 | ||
342 | default: | 333 | default: |
343 | /* invalid pixel depth */ | 334 | /* invalid pixel depth */ |
344 | dev_err(fbi->dev, "invalid bpp %d\n", var->bits_per_pixel); | 335 | dev_err(fbi->dev, "invalid bpp %d\n", |
336 | var->bits_per_pixel); | ||
345 | } | 337 | } |
346 | 338 | ||
347 | /* check to see if we need to update sync/borders */ | 339 | /* check to see if we need to update sync/borders */ |
348 | 340 | ||
349 | if (!fbi->mach_info->fixed_syncs) { | 341 | if (!fbi->mach_info->fixed_syncs) { |
350 | dprintk("setting vert: up=%d, low=%d, sync=%d\n", | 342 | dprintk("setting vert: up=%d, low=%d, sync=%d\n", |
351 | var->upper_margin, var->lower_margin, | 343 | var->upper_margin, var->lower_margin, var->vsync_len); |
352 | var->vsync_len); | ||
353 | 344 | ||
354 | dprintk("setting horz: lft=%d, rt=%d, sync=%d\n", | 345 | dprintk("setting horz: lft=%d, rt=%d, sync=%d\n", |
355 | var->left_margin, var->right_margin, | 346 | var->left_margin, var->right_margin, var->hsync_len); |
356 | var->hsync_len); | ||
357 | 347 | ||
358 | fbi->regs.lcdcon2 = | 348 | fbi->regs.lcdcon2 = |
359 | S3C2410_LCDCON2_VBPD(var->upper_margin - 1) | | 349 | S3C2410_LCDCON2_VBPD(var->upper_margin - 1) | |
@@ -373,27 +363,24 @@ static void s3c2410fb_activate_var(struct s3c2410fb_info *fbi, | |||
373 | fbi->regs.lcdcon2 &= ~S3C2410_LCDCON2_LINEVAL(0x3ff); | 363 | fbi->regs.lcdcon2 &= ~S3C2410_LCDCON2_LINEVAL(0x3ff); |
374 | fbi->regs.lcdcon2 |= S3C2410_LCDCON2_LINEVAL(var->yres - 1); | 364 | fbi->regs.lcdcon2 |= S3C2410_LCDCON2_LINEVAL(var->yres - 1); |
375 | 365 | ||
376 | switch(fbi->mach_info->type) { | 366 | switch (fbi->mach_info->type) { |
377 | case S3C2410_LCDCON1_DSCAN4: | 367 | case S3C2410_LCDCON1_DSCAN4: |
378 | case S3C2410_LCDCON1_STN8: | 368 | case S3C2410_LCDCON1_STN8: |
379 | hs = var->xres / 8; | 369 | hs = var->xres / 8; |
380 | break; | 370 | break; |
381 | case S3C2410_LCDCON1_STN4: | 371 | case S3C2410_LCDCON1_STN4: |
382 | hs = var->xres / 4; | 372 | hs = var->xres / 4; |
383 | break; | 373 | break; |
384 | default: | 374 | default: |
385 | case S3C2410_LCDCON1_TFT: | 375 | case S3C2410_LCDCON1_TFT: |
386 | hs = var->xres; | 376 | hs = var->xres; |
387 | break; | 377 | break; |
388 | |||
389 | } | 378 | } |
390 | 379 | ||
391 | /* Special cases : STN color displays */ | 380 | /* Special cases : STN color displays */ |
392 | if ( ((fbi->regs.lcdcon1 & S3C2410_LCDCON1_MODEMASK) == S3C2410_LCDCON1_STN8BPP) \ | 381 | if (((fbi->regs.lcdcon1 & S3C2410_LCDCON1_MODEMASK) == S3C2410_LCDCON1_STN8BPP) || |
393 | || ((fbi->regs.lcdcon1 & S3C2410_LCDCON1_MODEMASK) == S3C2410_LCDCON1_STN12BPP) ) { | 382 | ((fbi->regs.lcdcon1 & S3C2410_LCDCON1_MODEMASK) == S3C2410_LCDCON1_STN12BPP)) |
394 | hs = hs * 3; | 383 | hs = hs * 3; |
395 | } | ||
396 | |||
397 | 384 | ||
398 | fbi->regs.lcdcon3 &= ~S3C2410_LCDCON3_HOZVAL(0x7ff); | 385 | fbi->regs.lcdcon3 &= ~S3C2410_LCDCON3_HOZVAL(0x7ff); |
399 | fbi->regs.lcdcon3 |= S3C2410_LCDCON3_HOZVAL(hs - 1); | 386 | fbi->regs.lcdcon3 |= S3C2410_LCDCON3_HOZVAL(hs - 1); |
@@ -402,11 +389,10 @@ static void s3c2410fb_activate_var(struct s3c2410fb_info *fbi, | |||
402 | int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock); | 389 | int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock); |
403 | 390 | ||
404 | if (fbi->mach_info->type == S3C2410_LCDCON1_TFT) { | 391 | if (fbi->mach_info->type == S3C2410_LCDCON1_TFT) { |
405 | clkdiv = (clkdiv / 2) -1; | 392 | clkdiv = (clkdiv / 2) - 1; |
406 | if (clkdiv < 0) | 393 | if (clkdiv < 0) |
407 | clkdiv = 0; | 394 | clkdiv = 0; |
408 | } | 395 | } else { |
409 | else { | ||
410 | clkdiv = (clkdiv / 2); | 396 | clkdiv = (clkdiv / 2); |
411 | if (clkdiv < 2) | 397 | if (clkdiv < 2) |
412 | clkdiv = 2; | 398 | clkdiv = 2; |
@@ -437,9 +423,8 @@ static void s3c2410fb_activate_var(struct s3c2410fb_info *fbi, | |||
437 | writel(fbi->regs.lcdcon1, S3C2410_LCDCON1); | 423 | writel(fbi->regs.lcdcon1, S3C2410_LCDCON1); |
438 | } | 424 | } |
439 | 425 | ||
440 | |||
441 | /* | 426 | /* |
442 | * s3c2410fb_set_par - Optional function. Alters the hardware state. | 427 | * s3c2410fb_set_par - Alters the hardware state. |
443 | * @info: frame buffer structure that represents a single frame buffer | 428 | * @info: frame buffer structure that represents a single frame buffer |
444 | * | 429 | * |
445 | */ | 430 | */ |
@@ -448,20 +433,19 @@ static int s3c2410fb_set_par(struct fb_info *info) | |||
448 | struct s3c2410fb_info *fbi = info->par; | 433 | struct s3c2410fb_info *fbi = info->par; |
449 | struct fb_var_screeninfo *var = &info->var; | 434 | struct fb_var_screeninfo *var = &info->var; |
450 | 435 | ||
451 | switch (var->bits_per_pixel) | 436 | switch (var->bits_per_pixel) { |
452 | { | 437 | case 16: |
453 | case 16: | 438 | info->fix.visual = FB_VISUAL_TRUECOLOR; |
454 | fbi->fb->fix.visual = FB_VISUAL_TRUECOLOR; | 439 | break; |
455 | break; | 440 | case 1: |
456 | case 1: | 441 | info->fix.visual = FB_VISUAL_MONO01; |
457 | fbi->fb->fix.visual = FB_VISUAL_MONO01; | 442 | break; |
458 | break; | 443 | default: |
459 | default: | 444 | info->fix.visual = FB_VISUAL_PSEUDOCOLOR; |
460 | fbi->fb->fix.visual = FB_VISUAL_PSEUDOCOLOR; | 445 | break; |
461 | break; | ||
462 | } | 446 | } |
463 | 447 | ||
464 | fbi->fb->fix.line_length = (var->width*var->bits_per_pixel)/8; | 448 | info->fix.line_length = (var->width * var->bits_per_pixel) / 8; |
465 | 449 | ||
466 | /* activate this new configuration */ | 450 | /* activate this new configuration */ |
467 | 451 | ||
@@ -493,7 +477,8 @@ static void schedule_palette_update(struct s3c2410fb_info *fbi, | |||
493 | } | 477 | } |
494 | 478 | ||
495 | /* from pxafb.c */ | 479 | /* from pxafb.c */ |
496 | static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf) | 480 | static inline unsigned int chan_to_field(unsigned int chan, |
481 | struct fb_bitfield *bf) | ||
497 | { | 482 | { |
498 | chan &= 0xffff; | 483 | chan &= 0xffff; |
499 | chan >>= 16 - bf->length; | 484 | chan >>= 16 - bf->length; |
@@ -507,18 +492,19 @@ static int s3c2410fb_setcolreg(unsigned regno, | |||
507 | struct s3c2410fb_info *fbi = info->par; | 492 | struct s3c2410fb_info *fbi = info->par; |
508 | unsigned int val; | 493 | unsigned int val; |
509 | 494 | ||
510 | /* dprintk("setcol: regno=%d, rgb=%d,%d,%d\n", regno, red, green, blue); */ | 495 | /* dprintk("setcol: regno=%d, rgb=%d,%d,%d\n", |
496 | regno, red, green, blue); */ | ||
511 | 497 | ||
512 | switch (fbi->fb->fix.visual) { | 498 | switch (info->fix.visual) { |
513 | case FB_VISUAL_TRUECOLOR: | 499 | case FB_VISUAL_TRUECOLOR: |
514 | /* true-colour, use pseuo-palette */ | 500 | /* true-colour, use pseudo-palette */ |
515 | 501 | ||
516 | if (regno < 16) { | 502 | if (regno < 16) { |
517 | u32 *pal = fbi->fb->pseudo_palette; | 503 | u32 *pal = info->pseudo_palette; |
518 | 504 | ||
519 | val = chan_to_field(red, &fbi->fb->var.red); | 505 | val = chan_to_field(red, &info->var.red); |
520 | val |= chan_to_field(green, &fbi->fb->var.green); | 506 | val |= chan_to_field(green, &info->var.green); |
521 | val |= chan_to_field(blue, &fbi->fb->var.blue); | 507 | val |= chan_to_field(blue, &info->var.blue); |
522 | 508 | ||
523 | pal[regno] = val; | 509 | pal[regno] = val; |
524 | } | 510 | } |
@@ -539,14 +525,13 @@ static int s3c2410fb_setcolreg(unsigned regno, | |||
539 | break; | 525 | break; |
540 | 526 | ||
541 | default: | 527 | default: |
542 | return 1; /* unknown type */ | 528 | return 1; /* unknown type */ |
543 | } | 529 | } |
544 | 530 | ||
545 | return 0; | 531 | return 0; |
546 | } | 532 | } |
547 | 533 | ||
548 | 534 | /* | |
549 | /** | ||
550 | * s3c2410fb_blank | 535 | * s3c2410fb_blank |
551 | * @blank_mode: the blank mode we want. | 536 | * @blank_mode: the blank mode we want. |
552 | * @info: frame buffer structure that represents a single frame buffer | 537 | * @info: frame buffer structure that represents a single frame buffer |
@@ -579,12 +564,14 @@ static int s3c2410fb_blank(int blank_mode, struct fb_info *info) | |||
579 | return 0; | 564 | return 0; |
580 | } | 565 | } |
581 | 566 | ||
582 | static int s3c2410fb_debug_show(struct device *dev, struct device_attribute *attr, char *buf) | 567 | static int s3c2410fb_debug_show(struct device *dev, |
568 | struct device_attribute *attr, char *buf) | ||
583 | { | 569 | { |
584 | return snprintf(buf, PAGE_SIZE, "%s\n", debug ? "on" : "off"); | 570 | return snprintf(buf, PAGE_SIZE, "%s\n", debug ? "on" : "off"); |
585 | } | 571 | } |
586 | static int s3c2410fb_debug_store(struct device *dev, struct device_attribute *attr, | 572 | static int s3c2410fb_debug_store(struct device *dev, |
587 | const char *buf, size_t len) | 573 | struct device_attribute *attr, |
574 | const char *buf, size_t len) | ||
588 | { | 575 | { |
589 | if (mach_info == NULL) | 576 | if (mach_info == NULL) |
590 | return -EINVAL; | 577 | return -EINVAL; |
@@ -607,10 +594,7 @@ static int s3c2410fb_debug_store(struct device *dev, struct device_attribute *at | |||
607 | return len; | 594 | return len; |
608 | } | 595 | } |
609 | 596 | ||
610 | 597 | static DEVICE_ATTR(debug, 0666, s3c2410fb_debug_show, s3c2410fb_debug_store); | |
611 | static DEVICE_ATTR(debug, 0666, | ||
612 | s3c2410fb_debug_show, | ||
613 | s3c2410fb_debug_store); | ||
614 | 598 | ||
615 | static struct fb_ops s3c2410fb_ops = { | 599 | static struct fb_ops s3c2410fb_ops = { |
616 | .owner = THIS_MODULE, | 600 | .owner = THIS_MODULE, |
@@ -623,7 +607,6 @@ static struct fb_ops s3c2410fb_ops = { | |||
623 | .fb_imageblit = cfb_imageblit, | 607 | .fb_imageblit = cfb_imageblit, |
624 | }; | 608 | }; |
625 | 609 | ||
626 | |||
627 | /* | 610 | /* |
628 | * s3c2410fb_map_video_memory(): | 611 | * s3c2410fb_map_video_memory(): |
629 | * Allocates the DRAM memory for the frame buffer. This buffer is | 612 | * Allocates the DRAM memory for the frame buffer. This buffer is |
@@ -661,7 +644,8 @@ static int __init s3c2410fb_map_video_memory(struct s3c2410fb_info *fbi) | |||
661 | 644 | ||
662 | static inline void s3c2410fb_unmap_video_memory(struct s3c2410fb_info *fbi) | 645 | static inline void s3c2410fb_unmap_video_memory(struct s3c2410fb_info *fbi) |
663 | { | 646 | { |
664 | dma_free_writecombine(fbi->dev,fbi->map_size,fbi->map_cpu, fbi->map_dma); | 647 | dma_free_writecombine(fbi->dev, fbi->map_size, fbi->map_cpu, |
648 | fbi->map_dma); | ||
665 | } | 649 | } |
666 | 650 | ||
667 | static inline void modify_gpio(void __iomem *reg, | 651 | static inline void modify_gpio(void __iomem *reg, |
@@ -673,11 +657,9 @@ static inline void modify_gpio(void __iomem *reg, | |||
673 | writel(tmp | set, reg); | 657 | writel(tmp | set, reg); |
674 | } | 658 | } |
675 | 659 | ||
676 | |||
677 | /* | 660 | /* |
678 | * s3c2410fb_init_registers - Initialise all LCD-related registers | 661 | * s3c2410fb_init_registers - Initialise all LCD-related registers |
679 | */ | 662 | */ |
680 | |||
681 | static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi) | 663 | static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi) |
682 | { | 664 | { |
683 | unsigned long flags; | 665 | unsigned long flags; |
@@ -702,7 +684,7 @@ static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi) | |||
702 | writel(fbi->regs.lcdcon4, regs + S3C2410_LCDCON4); | 684 | writel(fbi->regs.lcdcon4, regs + S3C2410_LCDCON4); |
703 | writel(fbi->regs.lcdcon5, regs + S3C2410_LCDCON5); | 685 | writel(fbi->regs.lcdcon5, regs + S3C2410_LCDCON5); |
704 | 686 | ||
705 | s3c2410fb_set_lcdaddr(fbi); | 687 | s3c2410fb_set_lcdaddr(fbi); |
706 | 688 | ||
707 | dprintk("LPCSEL = 0x%08lx\n", mach_info->lpcsel); | 689 | dprintk("LPCSEL = 0x%08lx\n", mach_info->lpcsel); |
708 | writel(mach_info->lpcsel, regs + S3C2410_LPCSEL); | 690 | writel(mach_info->lpcsel, regs + S3C2410_LPCSEL); |
@@ -721,13 +703,13 @@ static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi) | |||
721 | static void s3c2410fb_write_palette(struct s3c2410fb_info *fbi) | 703 | static void s3c2410fb_write_palette(struct s3c2410fb_info *fbi) |
722 | { | 704 | { |
723 | unsigned int i; | 705 | unsigned int i; |
724 | unsigned long ent; | ||
725 | void __iomem *regs = fbi->io; | 706 | void __iomem *regs = fbi->io; |
726 | 707 | ||
727 | fbi->palette_ready = 0; | 708 | fbi->palette_ready = 0; |
728 | 709 | ||
729 | for (i = 0; i < 256; i++) { | 710 | for (i = 0; i < 256; i++) { |
730 | if ((ent = fbi->palette_buffer[i]) == PALETTE_BUFF_CLEAR) | 711 | unsigned long ent = fbi->palette_buffer[i]; |
712 | if (ent == PALETTE_BUFF_CLEAR) | ||
731 | continue; | 713 | continue; |
732 | 714 | ||
733 | writel(ent, regs + S3C2410_TFTPAL(i)); | 715 | writel(ent, regs + S3C2410_TFTPAL(i)); |
@@ -761,12 +743,12 @@ static irqreturn_t s3c2410fb_irq(int irq, void *dev_id) | |||
761 | return IRQ_HANDLED; | 743 | return IRQ_HANDLED; |
762 | } | 744 | } |
763 | 745 | ||
764 | static char driver_name[]="s3c2410fb"; | 746 | static char driver_name[] = "s3c2410fb"; |
765 | 747 | ||
766 | static int __init s3c2410fb_probe(struct platform_device *pdev) | 748 | static int __init s3c2410fb_probe(struct platform_device *pdev) |
767 | { | 749 | { |
768 | struct s3c2410fb_info *info; | 750 | struct s3c2410fb_info *info; |
769 | struct fb_info *fbinfo; | 751 | struct fb_info *fbinfo; |
770 | struct s3c2410fb_hw *mregs; | 752 | struct s3c2410fb_hw *mregs; |
771 | struct resource *res; | 753 | struct resource *res; |
772 | int ret; | 754 | int ret; |
@@ -777,7 +759,8 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) | |||
777 | 759 | ||
778 | mach_info = pdev->dev.platform_data; | 760 | mach_info = pdev->dev.platform_data; |
779 | if (mach_info == NULL) { | 761 | if (mach_info == NULL) { |
780 | dev_err(&pdev->dev,"no platform data for lcd, cannot attach\n"); | 762 | dev_err(&pdev->dev, |
763 | "no platform data for lcd, cannot attach\n"); | ||
781 | return -EINVAL; | 764 | return -EINVAL; |
782 | } | 765 | } |
783 | 766 | ||
@@ -790,9 +773,8 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) | |||
790 | } | 773 | } |
791 | 774 | ||
792 | fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), &pdev->dev); | 775 | fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), &pdev->dev); |
793 | if (!fbinfo) { | 776 | if (!fbinfo) |
794 | return -ENOMEM; | 777 | return -ENOMEM; |
795 | } | ||
796 | 778 | ||
797 | info = fbinfo->par; | 779 | info = fbinfo->par; |
798 | info->fb = fbinfo; | 780 | info->fb = fbinfo; |
@@ -800,12 +782,12 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) | |||
800 | 782 | ||
801 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 783 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
802 | if (res == NULL) { | 784 | if (res == NULL) { |
803 | dev_err(&pdev->dev, "failed to get memory registersn"); | 785 | dev_err(&pdev->dev, "failed to get memory registers\n"); |
804 | ret = -ENXIO; | 786 | ret = -ENXIO; |
805 | goto dealloc_fb; | 787 | goto dealloc_fb; |
806 | } | 788 | } |
807 | 789 | ||
808 | size = (res->end - res->start)+1; | 790 | size = (res->end - res->start) + 1; |
809 | info->mem = request_mem_region(res->start, size, pdev->name); | 791 | info->mem = request_mem_region(res->start, size, pdev->name); |
810 | if (info->mem == NULL) { | 792 | if (info->mem == NULL) { |
811 | dev_err(&pdev->dev, "failed to get memory region\n"); | 793 | dev_err(&pdev->dev, "failed to get memory region\n"); |
@@ -859,13 +841,19 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) | |||
859 | fbinfo->var.yres_virtual = mach_info->yres.defval; | 841 | fbinfo->var.yres_virtual = mach_info->yres.defval; |
860 | fbinfo->var.bits_per_pixel = mach_info->bpp.defval; | 842 | fbinfo->var.bits_per_pixel = mach_info->bpp.defval; |
861 | 843 | ||
862 | fbinfo->var.upper_margin = S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) + 1; | 844 | fbinfo->var.upper_margin = |
863 | fbinfo->var.lower_margin = S3C2410_LCDCON2_GET_VFPD(mregs->lcdcon2) + 1; | 845 | S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) + 1; |
864 | fbinfo->var.vsync_len = S3C2410_LCDCON2_GET_VSPW(mregs->lcdcon2) + 1; | 846 | fbinfo->var.lower_margin = |
847 | S3C2410_LCDCON2_GET_VFPD(mregs->lcdcon2) + 1; | ||
848 | fbinfo->var.vsync_len = | ||
849 | S3C2410_LCDCON2_GET_VSPW(mregs->lcdcon2) + 1; | ||
865 | 850 | ||
866 | fbinfo->var.left_margin = S3C2410_LCDCON3_GET_HFPD(mregs->lcdcon3) + 1; | 851 | fbinfo->var.left_margin = |
867 | fbinfo->var.right_margin = S3C2410_LCDCON3_GET_HBPD(mregs->lcdcon3) + 1; | 852 | S3C2410_LCDCON3_GET_HFPD(mregs->lcdcon3) + 1; |
868 | fbinfo->var.hsync_len = S3C2410_LCDCON4_GET_HSPW(mregs->lcdcon4) + 1; | 853 | fbinfo->var.right_margin = |
854 | S3C2410_LCDCON3_GET_HBPD(mregs->lcdcon3) + 1; | ||
855 | fbinfo->var.hsync_len = | ||
856 | S3C2410_LCDCON4_GET_HSPW(mregs->lcdcon4) + 1; | ||
869 | 857 | ||
870 | fbinfo->var.red.offset = 11; | 858 | fbinfo->var.red.offset = 11; |
871 | fbinfo->var.green.offset = 5; | 859 | fbinfo->var.green.offset = 5; |
@@ -875,7 +863,7 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) | |||
875 | fbinfo->var.green.length = 6; | 863 | fbinfo->var.green.length = 6; |
876 | fbinfo->var.blue.length = 5; | 864 | fbinfo->var.blue.length = 5; |
877 | fbinfo->var.transp.length = 0; | 865 | fbinfo->var.transp.length = 0; |
878 | fbinfo->fix.smem_len = mach_info->xres.max * | 866 | fbinfo->fix.smem_len = mach_info->xres.max * |
879 | mach_info->yres.max * | 867 | mach_info->yres.max * |
880 | mach_info->bpp.max / 8; | 868 | mach_info->bpp.max / 8; |
881 | 869 | ||
@@ -904,20 +892,21 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) | |||
904 | /* Initialize video memory */ | 892 | /* Initialize video memory */ |
905 | ret = s3c2410fb_map_video_memory(info); | 893 | ret = s3c2410fb_map_video_memory(info); |
906 | if (ret) { | 894 | if (ret) { |
907 | printk( KERN_ERR "Failed to allocate video RAM: %d\n", ret); | 895 | printk(KERN_ERR "Failed to allocate video RAM: %d\n", ret); |
908 | ret = -ENOMEM; | 896 | ret = -ENOMEM; |
909 | goto release_clock; | 897 | goto release_clock; |
910 | } | 898 | } |
911 | 899 | ||
912 | dprintk("got video memory\n"); | 900 | dprintk("got video memory\n"); |
913 | 901 | ||
914 | ret = s3c2410fb_init_registers(info); | 902 | s3c2410fb_init_registers(info); |
915 | 903 | ||
916 | ret = s3c2410fb_check_var(&fbinfo->var, fbinfo); | 904 | s3c2410fb_check_var(&fbinfo->var, fbinfo); |
917 | 905 | ||
918 | ret = register_framebuffer(fbinfo); | 906 | ret = register_framebuffer(fbinfo); |
919 | if (ret < 0) { | 907 | if (ret < 0) { |
920 | printk(KERN_ERR "Failed to register framebuffer device: %d\n", ret); | 908 | printk(KERN_ERR "Failed to register framebuffer device: %d\n", |
909 | ret); | ||
921 | goto free_video_memory; | 910 | goto free_video_memory; |
922 | } | 911 | } |
923 | 912 | ||
@@ -935,7 +924,7 @@ release_clock: | |||
935 | clk_disable(info->clk); | 924 | clk_disable(info->clk); |
936 | clk_put(info->clk); | 925 | clk_put(info->clk); |
937 | release_irq: | 926 | release_irq: |
938 | free_irq(irq,info); | 927 | free_irq(irq, info); |
939 | release_regs: | 928 | release_regs: |
940 | iounmap(info->io); | 929 | iounmap(info->io); |
941 | release_mem: | 930 | release_mem: |
@@ -949,8 +938,7 @@ dealloc_fb: | |||
949 | /* s3c2410fb_stop_lcd | 938 | /* s3c2410fb_stop_lcd |
950 | * | 939 | * |
951 | * shutdown the lcd controller | 940 | * shutdown the lcd controller |
952 | */ | 941 | */ |
953 | |||
954 | static void s3c2410fb_stop_lcd(struct s3c2410fb_info *fbi) | 942 | static void s3c2410fb_stop_lcd(struct s3c2410fb_info *fbi) |
955 | { | 943 | { |
956 | unsigned long flags; | 944 | unsigned long flags; |
@@ -968,7 +956,7 @@ static void s3c2410fb_stop_lcd(struct s3c2410fb_info *fbi) | |||
968 | */ | 956 | */ |
969 | static int s3c2410fb_remove(struct platform_device *pdev) | 957 | static int s3c2410fb_remove(struct platform_device *pdev) |
970 | { | 958 | { |
971 | struct fb_info *fbinfo = platform_get_drvdata(pdev); | 959 | struct fb_info *fbinfo = platform_get_drvdata(pdev); |
972 | struct s3c2410fb_info *info = fbinfo->par; | 960 | struct s3c2410fb_info *info = fbinfo->par; |
973 | int irq; | 961 | int irq; |
974 | 962 | ||
@@ -977,14 +965,14 @@ static int s3c2410fb_remove(struct platform_device *pdev) | |||
977 | 965 | ||
978 | s3c2410fb_unmap_video_memory(info); | 966 | s3c2410fb_unmap_video_memory(info); |
979 | 967 | ||
980 | if (info->clk) { | 968 | if (info->clk) { |
981 | clk_disable(info->clk); | 969 | clk_disable(info->clk); |
982 | clk_put(info->clk); | 970 | clk_put(info->clk); |
983 | info->clk = NULL; | 971 | info->clk = NULL; |
984 | } | 972 | } |
985 | 973 | ||
986 | irq = platform_get_irq(pdev, 0); | 974 | irq = platform_get_irq(pdev, 0); |
987 | free_irq(irq,info); | 975 | free_irq(irq, info); |
988 | 976 | ||
989 | release_resource(info->mem); | 977 | release_resource(info->mem); |
990 | kfree(info->mem); | 978 | kfree(info->mem); |
@@ -997,7 +985,6 @@ static int s3c2410fb_remove(struct platform_device *pdev) | |||
997 | #ifdef CONFIG_PM | 985 | #ifdef CONFIG_PM |
998 | 986 | ||
999 | /* suspend and resume support for the lcd controller */ | 987 | /* suspend and resume support for the lcd controller */ |
1000 | |||
1001 | static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state) | 988 | static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state) |
1002 | { | 989 | { |
1003 | struct fb_info *fbinfo = platform_get_drvdata(dev); | 990 | struct fb_info *fbinfo = platform_get_drvdata(dev); |
@@ -1054,10 +1041,10 @@ static void __exit s3c2410fb_cleanup(void) | |||
1054 | platform_driver_unregister(&s3c2410fb_driver); | 1041 | platform_driver_unregister(&s3c2410fb_driver); |
1055 | } | 1042 | } |
1056 | 1043 | ||
1057 | |||
1058 | module_init(s3c2410fb_init); | 1044 | module_init(s3c2410fb_init); |
1059 | module_exit(s3c2410fb_cleanup); | 1045 | module_exit(s3c2410fb_cleanup); |
1060 | 1046 | ||
1061 | MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, Ben Dooks <ben-linux@fluff.org>"); | 1047 | MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, " |
1048 | "Ben Dooks <ben-linux@fluff.org>"); | ||
1062 | MODULE_DESCRIPTION("Framebuffer driver for the s3c2410"); | 1049 | MODULE_DESCRIPTION("Framebuffer driver for the s3c2410"); |
1063 | MODULE_LICENSE("GPL"); | 1050 | MODULE_LICENSE("GPL"); |