~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/video/pnx4008/pnxrgbfb.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * drivers/video/pnx4008/pnxrgbfb.c
 
3
 *
 
4
 * PNX4008's framebuffer support
 
5
 *
 
6
 * Author: Grigory Tolstolytkin <gtolstolytkin@ru.mvista.com>
 
7
 * Based on Philips Semiconductors's code
 
8
 *
 
9
 * Copyrght (c) 2005 MontaVista Software, Inc.
 
10
 * Copyright (c) 2005 Philips Semiconductors
 
11
 * This file is licensed under the terms of the GNU General Public License
 
12
 * version 2. This program is licensed "as is" without any warranty of any
 
13
 * kind, whether express or implied.
 
14
 */
 
15
 
 
16
#include <linux/module.h>
 
17
#include <linux/kernel.h>
 
18
#include <linux/errno.h>
 
19
#include <linux/string.h>
 
20
#include <linux/mm.h>
 
21
#include <linux/vmalloc.h>
 
22
#include <linux/delay.h>
 
23
#include <linux/interrupt.h>
 
24
#include <linux/fb.h>
 
25
#include <linux/init.h>
 
26
#include <linux/platform_device.h>
 
27
 
 
28
#include "sdum.h"
 
29
#include "fbcommon.h"
 
30
 
 
31
static u32 colreg[16];
 
32
 
 
33
static struct fb_var_screeninfo rgbfb_var __initdata = {
 
34
        .xres = LCD_X_RES,
 
35
        .yres = LCD_Y_RES,
 
36
        .xres_virtual = LCD_X_RES,
 
37
        .yres_virtual = LCD_Y_RES,
 
38
        .bits_per_pixel = 32,
 
39
        .red.offset = 16,
 
40
        .red.length = 8,
 
41
        .green.offset = 8,
 
42
        .green.length = 8,
 
43
        .blue.offset = 0,
 
44
        .blue.length = 8,
 
45
        .left_margin = 0,
 
46
        .right_margin = 0,
 
47
        .upper_margin = 0,
 
48
        .lower_margin = 0,
 
49
        .vmode = FB_VMODE_NONINTERLACED,
 
50
};
 
51
static struct fb_fix_screeninfo rgbfb_fix __initdata = {
 
52
        .id = "RGBFB",
 
53
        .line_length = LCD_X_RES * LCD_BBP,
 
54
        .type = FB_TYPE_PACKED_PIXELS,
 
55
        .visual = FB_VISUAL_TRUECOLOR,
 
56
        .xpanstep = 0,
 
57
        .ypanstep = 0,
 
58
        .ywrapstep = 0,
 
59
        .accel = FB_ACCEL_NONE,
 
60
};
 
61
 
 
62
static int channel_owned;
 
63
 
 
64
static int no_cursor(struct fb_info *info, struct fb_cursor *cursor)
 
65
{
 
66
        return 0;
 
67
}
 
68
 
 
69
static int rgbfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 
70
                           u_int transp, struct fb_info *info)
 
71
{
 
72
        if (regno > 15)
 
73
                return 1;
 
74
 
 
75
        colreg[regno] = ((red & 0xff00) << 8) | (green & 0xff00) |
 
76
            ((blue & 0xff00) >> 8);
 
77
        return 0;
 
78
}
 
79
 
 
80
static int rgbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
81
{
 
82
        return pnx4008_sdum_mmap(info, vma, NULL);
 
83
}
 
84
 
 
85
static struct fb_ops rgbfb_ops = {
 
86
        .fb_mmap = rgbfb_mmap,
 
87
        .fb_setcolreg = rgbfb_setcolreg,
 
88
        .fb_fillrect = cfb_fillrect,
 
89
        .fb_copyarea = cfb_copyarea,
 
90
        .fb_imageblit = cfb_imageblit,
 
91
};
 
92
 
 
93
static int rgbfb_remove(struct platform_device *pdev)
 
94
{
 
95
        struct fb_info *info = platform_get_drvdata(pdev);
 
96
 
 
97
        if (info) {
 
98
                unregister_framebuffer(info);
 
99
                fb_dealloc_cmap(&info->cmap);
 
100
                framebuffer_release(info);
 
101
                platform_set_drvdata(pdev, NULL);
 
102
        }
 
103
 
 
104
        pnx4008_free_dum_channel(channel_owned, pdev->id);
 
105
        pnx4008_set_dum_exit_notification(pdev->id);
 
106
 
 
107
        return 0;
 
108
}
 
109
 
 
110
static int __devinit rgbfb_probe(struct platform_device *pdev)
 
111
{
 
112
        struct fb_info *info;
 
113
        struct dumchannel_uf chan_uf;
 
114
        int ret;
 
115
        char *option;
 
116
 
 
117
        info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev);
 
118
        if (!info) {
 
119
                ret = -ENOMEM;
 
120
                goto err;
 
121
        }
 
122
 
 
123
        pnx4008_get_fb_addresses(FB_TYPE_RGB, (void **)&info->screen_base,
 
124
                                 (dma_addr_t *) &rgbfb_fix.smem_start,
 
125
                                 &rgbfb_fix.smem_len);
 
126
 
 
127
        if ((ret = pnx4008_alloc_dum_channel(pdev->id)) < 0)
 
128
                goto err0;
 
129
        else {
 
130
                channel_owned = ret;
 
131
                chan_uf.channelnr = channel_owned;
 
132
                chan_uf.dirty = (u32 *) NULL;
 
133
                chan_uf.source = (u32 *) rgbfb_fix.smem_start;
 
134
                chan_uf.x_offset = 0;
 
135
                chan_uf.y_offset = 0;
 
136
                chan_uf.width = LCD_X_RES;
 
137
                chan_uf.height = LCD_Y_RES;
 
138
 
 
139
                if ((ret = pnx4008_put_dum_channel_uf(chan_uf, pdev->id))< 0)
 
140
                        goto err1;
 
141
 
 
142
                if ((ret =
 
143
                     pnx4008_set_dum_channel_sync(channel_owned, CONF_SYNC_ON,
 
144
                                                  pdev->id)) < 0)
 
145
                        goto err1;
 
146
 
 
147
                if ((ret =
 
148
                     pnx4008_set_dum_channel_dirty_detect(channel_owned,
 
149
                                                         CONF_DIRTYDETECTION_ON,
 
150
                                                         pdev->id)) < 0)
 
151
                        goto err1;
 
152
        }
 
153
 
 
154
        if (!fb_get_options("pnxrgbfb", &option) && option &&
 
155
                        !strcmp(option, "nocursor"))
 
156
                rgbfb_ops.fb_cursor = no_cursor;
 
157
 
 
158
        info->node = -1;
 
159
        info->flags = FBINFO_FLAG_DEFAULT;
 
160
        info->fbops = &rgbfb_ops;
 
161
        info->fix = rgbfb_fix;
 
162
        info->var = rgbfb_var;
 
163
        info->screen_size = rgbfb_fix.smem_len;
 
164
        info->pseudo_palette = info->par;
 
165
        info->par = NULL;
 
166
 
 
167
        ret = fb_alloc_cmap(&info->cmap, 256, 0);
 
168
        if (ret < 0)
 
169
                goto err1;
 
170
 
 
171
        ret = register_framebuffer(info);
 
172
        if (ret < 0)
 
173
                goto err2;
 
174
        platform_set_drvdata(pdev, info);
 
175
 
 
176
        return 0;
 
177
 
 
178
err2:
 
179
        fb_dealloc_cmap(&info->cmap);
 
180
err1:
 
181
        pnx4008_free_dum_channel(channel_owned, pdev->id);
 
182
err0:
 
183
        framebuffer_release(info);
 
184
err:
 
185
        return ret;
 
186
}
 
187
 
 
188
static struct platform_driver rgbfb_driver = {
 
189
        .driver = {
 
190
                .name = "pnx4008-rgbfb",
 
191
        },
 
192
        .probe = rgbfb_probe,
 
193
        .remove = rgbfb_remove,
 
194
};
 
195
 
 
196
static int __init rgbfb_init(void)
 
197
{
 
198
        return platform_driver_register(&rgbfb_driver);
 
199
}
 
200
 
 
201
static void __exit rgbfb_exit(void)
 
202
{
 
203
        platform_driver_unregister(&rgbfb_driver);
 
204
}
 
205
 
 
206
module_init(rgbfb_init);
 
207
module_exit(rgbfb_exit);
 
208
 
 
209
MODULE_LICENSE("GPL");