9 #include <linux/hdreg.h>
16 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
18 * scan framebuffer devices
20 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
31 static fb_info_t
*fb_get_info(hd_data_t
*hd_data
);
33 void hd_scan_fb(hd_data_t
*hd_data
)
38 unsigned imac_dev
, imac_vend
;
40 monitor_info_t
*mi
= NULL
;
42 if(!hd_probe_feature(hd_data
, pr_fb
)) return;
44 hd_data
->module
= mod_fb
;
47 remove_hd_entries(hd_data
);
49 PROGRESS(1, 0, "read info");
51 fb
= fb_get_info(hd_data
);
54 imac_dev
= MAKE_ID(TAG_EISA
, 0x9d03);
55 imac_vend
= name2eisa_id("APP");
57 for(hd
= hd_data
->hd
; hd
; hd
= hd
->next
) {
58 if(hd
->base_class
.id
== bc_monitor
) break;
61 if(hd
&& hd
->device
.id
== imac_dev
&& hd
->vendor
.id
== imac_vend
) {
63 remove_tagged_hd_entries(hd_data
);
68 /* add monitor entry based on fb data if we have no other info */
70 hd
= add_hd_entry(hd_data
, __LINE__
, 0);
71 hd
->base_class
.id
= bc_monitor
;
73 hd
->vendor
.id
= imac_vend
;
74 hd
->device
.id
= imac_dev
;
77 hd
->vendor
.name
= new_str("Generic");
78 hd
->device
.name
= new_str("Monitor");
81 res
= add_res_entry(&hd
->res
, new_mem(sizeof *res
));
82 res
->monitor
.type
= res_monitor
;
83 res
->monitor
.width
= fb
->width
;
84 res
->monitor
.height
= fb
->height
;
85 res
->monitor
.vfreq
= fb
->v_freq
+ 0.5;
88 mi
= new_mem(sizeof *mi
);
89 hd
->detail
= new_mem(sizeof *hd
->detail
);
90 hd
->detail
->type
= hd_detail_monitor
;
91 hd
->detail
->monitor
.data
= mi
;
95 mi
->max_vsync
= fb
->v_freq
* 1.11 + 0.9;
96 mi
->max_hsync
= fb
->h_freq
/ 1000.0 + 1.9;
97 if(mi
->max_vsync
<= mi
->min_vsync
) mi
->max_vsync
= mi
->min_vsync
+ 10;
98 if(mi
->max_hsync
<= mi
->min_hsync
) mi
->max_hsync
= mi
->min_hsync
+ 5;
100 mi
->max_vsync
= ((mi
->max_vsync
+ 9) / 10) * 10;
106 fb_info_t
*fb_get_info(hd_data_t
*hd_data
)
109 struct fb_var_screeninfo fbv_info
;
110 static fb_info_t fb_info
;
111 fb_info_t
*fb
= NULL
;
114 fd
= open(DEV_FB
, O_RDONLY
);
115 if(fd
< 0) fd
= open(DEV_FB0
, O_RDONLY
);
116 if(fd
< 0) return fb
;
118 if(!ioctl(fd
, FBIOGET_VSCREENINFO
, &fbv_info
)) {
119 h
= fbv_info
.left_margin
+ fbv_info
.xres
+ fbv_info
.right_margin
+ fbv_info
.hsync_len
;
120 v
= fbv_info
.upper_margin
+ fbv_info
.yres
+ fbv_info
.lower_margin
+ fbv_info
.vsync_len
;
121 if(fbv_info
.pixclock
&& h
&& v
) {
122 fb_info
.width
= fbv_info
.xres
;
123 fb_info
.height
= fbv_info
.yres
;
124 fb_info
.pix_clock
= 1e12
/ fbv_info
.pixclock
;
125 fb_info
.h_freq
= fb_info
.pix_clock
/ h
;
126 fb_info
.v_freq
= fb_info
.h_freq
/ v
;
128 ADD2LOG("fb: size %d x %d\n", fb_info
.width
, fb_info
.height
);
129 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
);