1 #include "matroxfb_g450.h"
2 #include "matroxfb_misc.h"
3 #include "matroxfb_DAC1064.h"
4 #include <linux/matroxfb.h>
5 #include <asm/uaccess.h>
7 static int matroxfb_g450_get_reg(WPMINFO
int reg
) {
11 val
= matroxfb_DAC_in(PMINFO reg
);
12 matroxfb_DAC_unlock();
16 static int matroxfb_g450_set_reg(WPMINFO
int reg
, int val
) {
18 matroxfb_DAC_out(PMINFO reg
, val
);
19 matroxfb_DAC_unlock();
23 static const struct matrox_pll_features maven_pll
= {
31 static void DAC1064_calcclock(unsigned int freq
, unsigned int fmax
,
32 unsigned int* in
, unsigned int* feed
, unsigned int* post
) {
36 fvco
= matroxfb_PLL_calcclock(&maven_pll
, freq
, fmax
, in
, feed
, &p
);
37 /* 0 => 100 ... 275 MHz
46 As you can see, never choose frequency > 621 MHz, there is unavailable gap...
47 Just to be sure, currently driver uses 110 ... 500 MHz range.
51 else if (fvco
<= 350000)
53 else if (fvco
<= 460000)
55 else if (fvco
<= 550000)
57 else if (fvco
<= 590000)
65 static inline int matroxfb_g450_compute_timming(struct matroxfb_g450_info
* m2info
,
66 struct my_timming
* mt
,
67 struct mavenregs
* m
) {
70 DAC1064_calcclock(mt
->pixclock
, 500000, &a
, &b
, &c
);
74 printk(KERN_DEBUG
"PLL: %02X %02X %02X\n", a
, b
, c
);
78 static inline int matroxfb_g450_program_timming(struct matroxfb_g450_info
* m2info
, const struct mavenregs
* m
) {
79 MINFO_FROM(m2info
->primary_dev
);
81 matroxfb_g450_set_reg(PMINFO M1064_XPIXPLL2M
, m
->regs
[0x81]);
82 matroxfb_g450_set_reg(PMINFO M1064_XPIXPLL2N
, m
->regs
[0x80]);
83 matroxfb_g450_set_reg(PMINFO M1064_XPIXPLL2P
, m
->regs
[0x82]);
87 /******************************************************/
89 static int matroxfb_g450_compute(void* md
, struct my_timming
* mt
, struct matrox_hw_state
* mr
) {
90 return matroxfb_g450_compute_timming(md
, mt
, &mr
->maven
);
93 static int matroxfb_g450_program(void* md
, const struct matrox_hw_state
* mr
) {
94 return matroxfb_g450_program_timming(md
, &mr
->maven
);
97 static int matroxfb_g450_start(void* md
) {
101 static void matroxfb_g450_incuse(void* md
) {
105 static void matroxfb_g450_decuse(void* md
) {
109 static int matroxfb_g450_set_mode(void* md
, u_int32_t arg
) {
110 if (arg
== MATROXFB_OUTPUT_MODE_MONITOR
) {
116 static int matroxfb_g450_get_mode(void* md
, u_int32_t
* arg
) {
117 *arg
= MATROXFB_OUTPUT_MODE_MONITOR
;
121 static struct matrox_altout matroxfb_g450_altout
= {
122 matroxfb_g450_compute
,
123 matroxfb_g450_program
,
125 matroxfb_g450_incuse
,
126 matroxfb_g450_decuse
,
127 matroxfb_g450_set_mode
,
128 matroxfb_g450_get_mode
131 static int matroxfb_g450_connect(struct matroxfb_g450_info
* m2info
) {
132 MINFO_FROM(m2info
->primary_dev
);
134 down_write(&ACCESS_FBINFO(altout
.lock
));
135 ACCESS_FBINFO(altout
.device
) = m2info
;
136 ACCESS_FBINFO(altout
.output
) = &matroxfb_g450_altout
;
137 up_write(&ACCESS_FBINFO(altout
.lock
));
138 ACCESS_FBINFO(output
.all
) |= MATROXFB_OUTPUT_CONN_SECONDARY
;
142 static void matroxfb_g450_shutdown(struct matroxfb_g450_info
* m2info
) {
143 MINFO_FROM(m2info
->primary_dev
);
146 ACCESS_FBINFO(output
.all
) &= ~MATROXFB_OUTPUT_CONN_SECONDARY
;
147 ACCESS_FBINFO(output
.ph
) &= ~MATROXFB_OUTPUT_CONN_SECONDARY
;
148 ACCESS_FBINFO(output
.sh
) &= ~MATROXFB_OUTPUT_CONN_SECONDARY
;
149 down_write(&ACCESS_FBINFO(altout
.lock
));
150 ACCESS_FBINFO(altout
.device
) = NULL
;
151 ACCESS_FBINFO(altout
.output
) = NULL
;
152 up_write(&ACCESS_FBINFO(altout
.lock
));
153 m2info
->primary_dev
= NULL
;
157 /* we do not have __setup() yet */
158 static void* matroxfb_g450_probe(struct matrox_fb_info
* minfo
) {
159 struct matroxfb_g450_info
* m2info
;
161 /* hardware is not G450 incapable... */
162 if (!ACCESS_FBINFO(devflags
.g450dac
))
164 m2info
= (struct matroxfb_g450_info
*)kmalloc(sizeof(*m2info
), GFP_KERNEL
);
166 printk(KERN_ERR
"matroxfb_g450: Not enough memory for G450 DAC control structs\n");
169 memset(m2info
, 0, sizeof(*m2info
));
170 m2info
->primary_dev
= MINFO
;
171 if (matroxfb_g450_connect(m2info
)) {
173 printk(KERN_ERR
"matroxfb_g450: G450 DAC failed to initialize\n");
179 static void matroxfb_g450_remove(struct matrox_fb_info
* minfo
, void* g450
) {
180 matroxfb_g450_shutdown(g450
);
184 static struct matroxfb_driver g450
= {
185 name
: "Matrox G450 output #2",
186 probe
: matroxfb_g450_probe
,
187 remove
: matroxfb_g450_remove
};
189 static int matroxfb_g450_init(void) {
190 matroxfb_register_driver(&g450
);
194 static void matroxfb_g450_exit(void) {
195 matroxfb_unregister_driver(&g450
);
198 MODULE_AUTHOR("(c) 2000 Petr Vandrovec <vandrove@vc.cvut.cz>");
199 MODULE_DESCRIPTION("Matrox G450 secondary output driver");
200 module_init(matroxfb_g450_init
);
201 module_exit(matroxfb_g450_exit
);