9
#include <linux/hdreg.h>
17
* @defgroup Framebuffer Framebuffer devices
18
* @ingroup libhdDEVint
19
* @brief Scan framebuffer devices
32
static fb_info_t *fb_get_info(hd_data_t *hd_data);
34
void hd_scan_fb(hd_data_t *hd_data)
39
unsigned imac_dev, imac_vend;
41
monitor_info_t *mi = NULL;
43
if(!hd_probe_feature(hd_data, pr_fb)) return;
45
hd_data->module = mod_fb;
48
remove_hd_entries(hd_data);
50
PROGRESS(1, 0, "read info");
52
fb = fb_get_info(hd_data);
55
imac_dev = MAKE_ID(TAG_EISA, 0x9d03);
56
imac_vend = name2eisa_id("APP");
58
for(hd = hd_data->hd; hd; hd = hd->next) {
59
if(hd->base_class.id == bc_monitor) break;
62
if(hd && hd->device.id == imac_dev && hd->vendor.id == imac_vend) {
64
remove_tagged_hd_entries(hd_data);
69
/* add monitor entry based on fb data if we have no other info */
71
hd = add_hd_entry(hd_data, __LINE__, 0);
72
hd->base_class.id = bc_monitor;
74
hd->vendor.id = imac_vend;
75
hd->device.id = imac_dev;
78
hd->vendor.name = new_str("Generic");
79
hd->device.name = new_str("Monitor");
82
res = add_res_entry(&hd->res, new_mem(sizeof *res));
83
res->monitor.type = res_monitor;
84
res->monitor.width = fb->width;
85
res->monitor.height = fb->height;
86
res->monitor.vfreq = fb->v_freq + 0.5;
89
mi = new_mem(sizeof *mi);
90
hd->detail = new_mem(sizeof *hd->detail);
91
hd->detail->type = hd_detail_monitor;
92
hd->detail->monitor.data = mi;
96
mi->max_vsync = fb->v_freq * 1.11 + 0.9;
97
mi->max_hsync = fb->h_freq / 1000.0 + 1.9;
98
if(mi->max_vsync <= mi->min_vsync) mi->max_vsync = mi->min_vsync + 10;
99
if(mi->max_hsync <= mi->min_hsync) mi->max_hsync = mi->min_hsync + 5;
101
mi->max_vsync = ((mi->max_vsync + 9) / 10) * 10;
107
fb_info_t *fb_get_info(hd_data_t *hd_data)
110
struct fb_var_screeninfo fbv_info;
111
static fb_info_t fb_info;
112
fb_info_t *fb = NULL;
115
fd = open(DEV_FB, O_RDONLY);
116
if(fd < 0) fd = open(DEV_FB0, O_RDONLY);
117
if(fd < 0) return fb;
119
if(!ioctl(fd, FBIOGET_VSCREENINFO, &fbv_info)) {
120
h = fbv_info.left_margin + fbv_info.xres + fbv_info.right_margin + fbv_info.hsync_len;
121
v = fbv_info.upper_margin + fbv_info.yres + fbv_info.lower_margin + fbv_info.vsync_len;
122
if(fbv_info.pixclock && h && v) {
123
fb_info.width = fbv_info.xres;
124
fb_info.height = fbv_info.yres;
125
fb_info.pix_clock = 1e12 / fbv_info.pixclock;
126
fb_info.h_freq = fb_info.pix_clock / h;
127
fb_info.v_freq = fb_info.h_freq / v;
129
ADD2LOG("fb: size %d x %d\n", fb_info.width, fb_info.height);
130
ADD2LOG("fb: timing %.2f MHz, %.2f kHz, %.2f Hz\n", fb_info.pix_clock * 1e-6, fb_info.h_freq * 1e-3, fb_info.v_freq);