2 * newport_con.c: Abscon for newport hardware
4 * (C) 1998 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
5 * (C) 1999 Ulf Carlsson (ulfc@thepuffingruop.com)
7 * This driver is based on sgicons.c and cons_newport.
9 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
10 * Copyright (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx)
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/errno.h>
15 #include <linux/tty.h>
17 #include <linux/selection.h>
18 #include <linux/console.h>
19 #include <linux/vt_kern.h>
21 #include <linux/module.h>
22 #include <linux/slab.h>
25 #include <asm/uaccess.h>
26 #include <asm/system.h>
28 #include <asm/pgtable.h>
29 #include <video/newport.h>
31 #include <linux/linux_logo.h>
32 #include <linux/font.h>
35 extern struct font_desc font_vga_8x16
;
36 extern unsigned long sgi_gfxaddr
;
38 #define FONT_DATA ((unsigned char *)font_vga_8x16.data)
40 /* borrowed from fbcon.c */
41 #define REFCOUNT(fd) (((int *)(fd))[-1])
42 #define FNTSIZE(fd) (((int *)(fd))[-2])
43 #define FNTCHARCNT(fd) (((int *)(fd))[-3])
44 #define FONT_EXTRA_WORDS 3
46 static unsigned char *font_data
[MAX_NR_CONSOLES
];
48 static struct newport_regs
*npregs
;
50 static int logo_active
;
52 static int xcurs_correction
= 29;
53 static int newport_xsize
;
54 static int newport_ysize
;
56 static int newport_set_def_font(int unit
, struct console_font
*op
);
58 #define BMASK(c) (c << 24)
60 #define RENDER(regs, cp) do { \
61 (regs)->go.zpattern = BMASK((cp)[0x0]); (regs)->go.zpattern = BMASK((cp)[0x1]); \
62 (regs)->go.zpattern = BMASK((cp)[0x2]); (regs)->go.zpattern = BMASK((cp)[0x3]); \
63 (regs)->go.zpattern = BMASK((cp)[0x4]); (regs)->go.zpattern = BMASK((cp)[0x5]); \
64 (regs)->go.zpattern = BMASK((cp)[0x6]); (regs)->go.zpattern = BMASK((cp)[0x7]); \
65 (regs)->go.zpattern = BMASK((cp)[0x8]); (regs)->go.zpattern = BMASK((cp)[0x9]); \
66 (regs)->go.zpattern = BMASK((cp)[0xa]); (regs)->go.zpattern = BMASK((cp)[0xb]); \
67 (regs)->go.zpattern = BMASK((cp)[0xc]); (regs)->go.zpattern = BMASK((cp)[0xd]); \
68 (regs)->go.zpattern = BMASK((cp)[0xe]); (regs)->go.zpattern = BMASK((cp)[0xf]); \
71 #define TESTVAL 0xdeadbeef
72 #define XSTI_TO_FXSTART(val) (((val) & 0xffff) << 11)
74 static inline void newport_render_background(int xstart
, int ystart
,
75 int xend
, int yend
, int ci
)
78 npregs
->set
.wrmask
= 0xffffffff;
79 npregs
->set
.drawmode0
= (NPORT_DMODE0_DRAW
| NPORT_DMODE0_BLOCK
|
80 NPORT_DMODE0_DOSETUP
| NPORT_DMODE0_STOPX
81 | NPORT_DMODE0_STOPY
);
82 npregs
->set
.colori
= ci
;
83 npregs
->set
.xystarti
=
84 (xstart
<< 16) | ((ystart
+ topscan
) & 0x3ff);
86 ((xend
+ 7) << 16) | ((yend
+ topscan
+ 15) & 0x3ff);
89 static inline void newport_init_cmap(void)
93 for (i
= 0; i
< 16; i
++) {
94 newport_bfwait(npregs
);
95 newport_cmap_setaddr(npregs
, color_table
[i
]);
96 newport_cmap_setrgb(npregs
,
98 default_grn
[i
], default_blu
[i
]);
102 static void newport_show_logo(void)
104 #ifdef CONFIG_LOGO_SGI_CLUT224
105 const struct linux_logo
*logo
= fb_find_logo(8);
106 const unsigned char *clut
= logo
->clut
;
107 const unsigned char *data
= logo
->data
;
110 for (i
= 0; i
< logo
->clutsize
; i
++) {
111 newport_bfwait(npregs
);
112 newport_cmap_setaddr(npregs
, i
+ 0x20);
113 newport_cmap_setrgb(npregs
, clut
[0], clut
[1], clut
[2]);
117 newport_wait(npregs
);
118 npregs
->set
.drawmode0
= (NPORT_DMODE0_DRAW
| NPORT_DMODE0_BLOCK
|
121 npregs
->set
.xystarti
= ((newport_xsize
- logo
->width
) << 16) | (0);
122 npregs
->set
.xyendi
= ((newport_xsize
- 1) << 16);
123 newport_wait(npregs
);
125 for (i
= 0; i
< logo
->width
*logo
->height
; i
++)
126 npregs
->go
.hostrw0
= *data
++ << 24;
127 #endif /* CONFIG_LOGO_SGI_CLUT224 */
130 static inline void newport_clear_screen(int xstart
, int ystart
, int xend
,
136 newport_wait(npregs
);
137 npregs
->set
.wrmask
= 0xffffffff;
138 npregs
->set
.drawmode0
= (NPORT_DMODE0_DRAW
| NPORT_DMODE0_BLOCK
|
139 NPORT_DMODE0_DOSETUP
| NPORT_DMODE0_STOPX
140 | NPORT_DMODE0_STOPY
);
141 npregs
->set
.colori
= ci
;
142 npregs
->set
.xystarti
= (xstart
<< 16) | ystart
;
143 npregs
->go
.xyendi
= (xend
<< 16) | yend
;
146 static inline void newport_clear_lines(int ystart
, int yend
, int ci
)
148 ystart
= ((ystart
<< 4) + topscan
) & 0x3ff;
149 yend
= ((yend
<< 4) + topscan
+ 15) & 0x3ff;
150 newport_clear_screen(0, ystart
, 1280 + 63, yend
, ci
);
153 void newport_reset(void)
158 newport_wait(npregs
);
159 treg
= newport_vc2_get(npregs
, VC2_IREG_CONTROL
);
160 newport_vc2_set(npregs
, VC2_IREG_CONTROL
,
161 (treg
| VC2_CTRL_EVIDEO
));
163 treg
= newport_vc2_get(npregs
, VC2_IREG_CENTRY
);
164 newport_vc2_set(npregs
, VC2_IREG_RADDR
, treg
);
165 npregs
->set
.dcbmode
= (NPORT_DMODE_AVC2
| VC2_REGADDR_RAM
|
166 NPORT_DMODE_W2
| VC2_PROTOCOL
);
167 for (i
= 0; i
< 128; i
++) {
168 newport_bfwait(npregs
);
169 if (i
== 92 || i
== 94)
170 npregs
->set
.dcbdata0
.byshort
.s1
= 0xff00;
172 npregs
->set
.dcbdata0
.byshort
.s1
= 0x0000;
177 /* turn off popup plane */
178 npregs
->set
.dcbmode
= (DCB_XMAP0
| R_DCB_XMAP9_PROTOCOL
|
179 XM9_CRS_CONFIG
| NPORT_DMODE_W1
);
180 npregs
->set
.dcbdata0
.bybytes
.b3
&= ~XM9_PUPMODE
;
181 npregs
->set
.dcbmode
= (DCB_XMAP1
| R_DCB_XMAP9_PROTOCOL
|
182 XM9_CRS_CONFIG
| NPORT_DMODE_W1
);
183 npregs
->set
.dcbdata0
.bybytes
.b3
&= ~XM9_PUPMODE
;
186 npregs
->cset
.topscan
= 0x3ff;
187 npregs
->cset
.xywin
= (4096 << 16) | 4096;
189 /* Clear the screen. */
190 newport_clear_screen(0, 0, 1280 + 63, 1024, 0);
194 * calculate the actual screen size by reading
195 * the video timing out of the VC2
197 void newport_get_screensize(void)
200 unsigned short ventry
, treg
;
201 unsigned short linetable
[128]; /* should be enough */
203 ventry
= newport_vc2_get(npregs
, VC2_IREG_VENTRY
);
204 newport_vc2_set(npregs
, VC2_IREG_RADDR
, ventry
);
205 npregs
->set
.dcbmode
= (NPORT_DMODE_AVC2
| VC2_REGADDR_RAM
|
206 NPORT_DMODE_W2
| VC2_PROTOCOL
);
207 for (i
= 0; i
< 128; i
++) {
208 newport_bfwait(npregs
);
209 linetable
[i
] = npregs
->set
.dcbdata0
.byshort
.s1
;
212 newport_xsize
= newport_ysize
= 0;
213 for (i
= 0; linetable
[i
+ 1] && (i
< sizeof(linetable
)); i
+= 2) {
215 newport_vc2_set(npregs
, VC2_IREG_RADDR
, linetable
[i
]);
216 npregs
->set
.dcbmode
= (NPORT_DMODE_AVC2
| VC2_REGADDR_RAM
|
217 NPORT_DMODE_W2
| VC2_PROTOCOL
);
219 newport_bfwait(npregs
);
220 treg
= npregs
->set
.dcbdata0
.byshort
.s1
;
222 cols
+= (treg
>> 7) & 0xfe;
223 if ((treg
& 0x80) == 0) {
224 newport_bfwait(npregs
);
225 treg
= npregs
->set
.dcbdata0
.byshort
.s1
;
227 } while ((treg
& 0x8000) == 0);
229 if (cols
> newport_xsize
)
230 newport_xsize
= cols
;
231 newport_ysize
+= linetable
[i
+ 1];
234 printk("NG1: Screensize %dx%d\n", newport_xsize
, newport_ysize
);
237 static void newport_get_revisions(void)
240 unsigned int board_rev
;
241 unsigned int rex3_rev
;
242 unsigned int vc2_rev
;
243 unsigned int cmap_rev
;
244 unsigned int xmap9_rev
;
245 unsigned int bt445_rev
;
246 unsigned int bitplanes
;
248 rex3_rev
= npregs
->cset
.status
& NPORT_STAT_VERS
;
250 npregs
->set
.dcbmode
= (DCB_CMAP0
| NCMAP_PROTOCOL
|
251 NCMAP_REGADDR_RREG
| NPORT_DMODE_W1
);
252 tmp
= npregs
->set
.dcbdata0
.bybytes
.b3
;
254 board_rev
= (tmp
>> 4) & 7;
255 bitplanes
= ((board_rev
> 1) && (tmp
& 0x80)) ? 8 : 24;
257 npregs
->set
.dcbmode
= (DCB_CMAP1
| NCMAP_PROTOCOL
|
258 NCMAP_REGADDR_RREG
| NPORT_DMODE_W1
);
259 tmp
= npregs
->set
.dcbdata0
.bybytes
.b3
;
260 if ((tmp
& 7) < cmap_rev
)
261 cmap_rev
= (tmp
& 7);
263 vc2_rev
= (newport_vc2_get(npregs
, VC2_IREG_CONFIG
) >> 5) & 7;
265 npregs
->set
.dcbmode
= (DCB_XMAP0
| R_DCB_XMAP9_PROTOCOL
|
266 XM9_CRS_REVISION
| NPORT_DMODE_W1
);
267 xmap9_rev
= npregs
->set
.dcbdata0
.bybytes
.b3
& 7;
269 npregs
->set
.dcbmode
= (DCB_BT445
| BT445_PROTOCOL
|
270 BT445_CSR_ADDR_REG
| NPORT_DMODE_W1
);
271 npregs
->set
.dcbdata0
.bybytes
.b3
= BT445_REVISION_REG
;
272 npregs
->set
.dcbmode
= (DCB_BT445
| BT445_PROTOCOL
|
273 BT445_CSR_REVISION
| NPORT_DMODE_W1
);
274 bt445_rev
= (npregs
->set
.dcbdata0
.bybytes
.b3
>> 4) - 0x0a;
276 #define L(a) (char)('A'+(a))
278 ("NG1: Revision %d, %d bitplanes, REX3 revision %c, VC2 revision %c, xmap9 revision %c, cmap revision %c, bt445 revision %c\n",
279 board_rev
, bitplanes
, L(rex3_rev
), L(vc2_rev
), L(xmap9_rev
),
280 L(cmap_rev
? (cmap_rev
+ 1) : 0), L(bt445_rev
));
283 if (board_rev
== 3) /* I don't know all affected revisions */
284 xcurs_correction
= 21;
287 /* Can't be __init, take_over_console may call it later */
288 static const char *newport_startup(void)
294 npregs
= (struct newport_regs
*) /* ioremap cannot fail */
295 ioremap(sgi_gfxaddr
, sizeof(struct newport_regs
));
296 npregs
->cset
.config
= NPORT_CFG_GD0
;
298 if (newport_wait(npregs
))
301 npregs
->set
.xstarti
= TESTVAL
;
302 if (npregs
->set
._xstart
.word
!= XSTI_TO_FXSTART(TESTVAL
))
305 for (i
= 0; i
< MAX_NR_CONSOLES
; i
++)
306 font_data
[i
] = FONT_DATA
;
309 newport_get_revisions();
310 newport_get_screensize();
312 return "SGI Newport";
315 iounmap((void *)npregs
);
319 static void newport_init(struct vc_data
*vc
, int init
)
321 vc
->vc_cols
= newport_xsize
/ 8;
322 vc
->vc_rows
= newport_ysize
/ 16;
323 vc
->vc_can_do_color
= 1;
326 static void newport_deinit(struct vc_data
*c
)
330 /* free memory used by user font */
331 for (i
= 0; i
< MAX_NR_CONSOLES
; i
++)
332 newport_set_def_font(i
, NULL
);
335 static void newport_clear(struct vc_data
*vc
, int sy
, int sx
, int height
,
338 int xend
= ((sx
+ width
) << 3) - 1;
339 int ystart
= ((sy
<< 4) + topscan
) & 0x3ff;
340 int yend
= (((sy
+ height
) << 4) + topscan
- 1) & 0x3ff;
346 newport_clear_screen(sx
<< 3, ystart
, xend
, yend
,
347 (vc
->vc_color
& 0xf0) >> 4);
349 newport_clear_screen(sx
<< 3, ystart
, xend
, 1023,
350 (vc
->vc_color
& 0xf0) >> 4);
351 newport_clear_screen(sx
<< 3, 0, xend
, yend
,
352 (vc
->vc_color
& 0xf0) >> 4);
356 static void newport_putc(struct vc_data
*vc
, int charattr
, int ypos
,
361 p
= &font_data
[vc
->vc_num
][(charattr
& 0xff) << 4];
362 charattr
= (charattr
>> 8) & 0xff;
366 newport_render_background(xpos
, ypos
, xpos
, ypos
,
367 (charattr
& 0xf0) >> 4);
369 /* Set the color and drawing mode. */
370 newport_wait(npregs
);
371 npregs
->set
.colori
= charattr
& 0xf;
372 npregs
->set
.drawmode0
= (NPORT_DMODE0_DRAW
| NPORT_DMODE0_BLOCK
|
373 NPORT_DMODE0_STOPX
| NPORT_DMODE0_ZPENAB
|
376 /* Set coordinates for bitmap operation. */
377 npregs
->set
.xystarti
= (xpos
<< 16) | ((ypos
+ topscan
) & 0x3ff);
378 npregs
->set
.xyendi
= ((xpos
+ 7) << 16);
379 newport_wait(npregs
);
381 /* Go, baby, go... */
385 static void newport_putcs(struct vc_data
*vc
, const unsigned short *s
,
386 int count
, int ypos
, int xpos
)
392 charattr
= (scr_readw(s
) >> 8) & 0xff;
398 /* Clear the area behing the string */
399 newport_render_background(xpos
, ypos
,
400 xpos
+ ((count
- 1) << 3), ypos
,
401 (charattr
& 0xf0) >> 4);
403 newport_wait(npregs
);
405 /* Set the color and drawing mode. */
406 npregs
->set
.colori
= charattr
& 0xf;
407 npregs
->set
.drawmode0
= (NPORT_DMODE0_DRAW
| NPORT_DMODE0_BLOCK
|
408 NPORT_DMODE0_STOPX
| NPORT_DMODE0_ZPENAB
|
411 for (i
= 0; i
< count
; i
++, xpos
+= 8) {
412 p
= &font_data
[vc
->vc_num
][(scr_readw(s
++) & 0xff) << 4];
414 newport_wait(npregs
);
416 /* Set coordinates for bitmap operation. */
417 npregs
->set
.xystarti
=
418 (xpos
<< 16) | ((ypos
+ topscan
) & 0x3ff);
419 npregs
->set
.xyendi
= ((xpos
+ 7) << 16);
421 /* Go, baby, go... */
426 static void newport_cursor(struct vc_data
*vc
, int mode
)
433 treg
= newport_vc2_get(npregs
, VC2_IREG_CONTROL
);
434 newport_vc2_set(npregs
, VC2_IREG_CONTROL
,
435 (treg
& ~(VC2_CTRL_ECDISP
)));
440 treg
= newport_vc2_get(npregs
, VC2_IREG_CONTROL
);
441 newport_vc2_set(npregs
, VC2_IREG_CONTROL
,
442 (treg
| VC2_CTRL_ECDISP
));
443 xcurs
= (vc
->vc_pos
- vc
->vc_visible_origin
) / 2;
444 ycurs
= ((xcurs
/ vc
->vc_cols
) << 4) + 31;
445 xcurs
= ((xcurs
% vc
->vc_cols
) << 3) + xcurs_correction
;
446 newport_vc2_set(npregs
, VC2_IREG_CURSX
, xcurs
);
447 newport_vc2_set(npregs
, VC2_IREG_CURSY
, ycurs
);
451 static int newport_switch(struct vc_data
*vc
)
453 static int logo_drawn
= 0;
456 npregs
->cset
.topscan
= 0x3ff;
467 static int newport_blank(struct vc_data
*c
, int blank
, int mode_switch
)
472 /* unblank console */
473 treg
= newport_vc2_get(npregs
, VC2_IREG_CONTROL
);
474 newport_vc2_set(npregs
, VC2_IREG_CONTROL
,
475 (treg
| VC2_CTRL_EDISP
));
478 treg
= newport_vc2_get(npregs
, VC2_IREG_CONTROL
);
479 newport_vc2_set(npregs
, VC2_IREG_CONTROL
,
480 (treg
& ~(VC2_CTRL_EDISP
)));
485 static int newport_set_font(int unit
, struct console_font
*op
)
489 int size
= h
* op
->charcount
;
491 unsigned char *new_data
, *data
= op
->data
, *p
;
493 /* ladis: when I grow up, there will be a day... and more sizes will
494 * be supported ;-) */
495 if ((w
!= 8) || (h
!= 16)
496 || (op
->charcount
!= 256 && op
->charcount
!= 512))
499 if (!(new_data
= kmalloc(FONT_EXTRA_WORDS
* sizeof(int) + size
,
500 GFP_USER
))) return -ENOMEM
;
502 new_data
+= FONT_EXTRA_WORDS
* sizeof(int);
503 FNTSIZE(new_data
) = size
;
504 FNTCHARCNT(new_data
) = op
->charcount
;
505 REFCOUNT(new_data
) = 0; /* usage counter */
508 for (i
= 0; i
< op
->charcount
; i
++) {
514 /* check if font is already used by other console */
515 for (i
= 0; i
< MAX_NR_CONSOLES
; i
++) {
516 if (font_data
[i
] != FONT_DATA
517 && FNTSIZE(font_data
[i
]) == size
518 && !memcmp(font_data
[i
], new_data
, size
)) {
519 kfree(new_data
- FONT_EXTRA_WORDS
* sizeof(int));
520 /* current font is the same as the new one */
523 new_data
= font_data
[i
];
527 /* old font is user font */
528 if (font_data
[unit
] != FONT_DATA
) {
529 if (--REFCOUNT(font_data
[unit
]) == 0)
530 kfree(font_data
[unit
] -
531 FONT_EXTRA_WORDS
* sizeof(int));
533 REFCOUNT(new_data
)++;
534 font_data
[unit
] = new_data
;
539 static int newport_set_def_font(int unit
, struct console_font
*op
)
541 if (font_data
[unit
] != FONT_DATA
) {
542 if (--REFCOUNT(font_data
[unit
]) == 0)
543 kfree(font_data
[unit
] -
544 FONT_EXTRA_WORDS
* sizeof(int));
545 font_data
[unit
] = FONT_DATA
;
551 static int newport_font_default(struct vc_data
*vc
, struct console_font
*op
, char *name
)
553 return newport_set_def_font(vc
->vc_num
, op
);
556 static int newport_font_set(struct vc_data
*vc
, struct console_font
*font
, unsigned flags
)
558 return newport_set_font(vc
->vc_num
, font
);
561 static int newport_set_palette(struct vc_data
*vc
, unsigned char *table
)
566 static int newport_scrolldelta(struct vc_data
*vc
, int lines
)
568 /* there is (nearly) no off-screen memory, so we can't scroll back */
572 static int newport_scroll(struct vc_data
*vc
, int t
, int b
, int dir
,
576 unsigned short *s
, *d
;
577 unsigned short chattr
;
579 logo_active
= 0; /* it's time to disable the logo now.. */
581 if (t
== 0 && b
== vc
->vc_rows
) {
583 topscan
= (topscan
+ (lines
<< 4)) & 0x3ff;
584 newport_clear_lines(vc
->vc_rows
- lines
,
586 (vc
->vc_color
& 0xf0) >> 4);
588 topscan
= (topscan
+ (-lines
<< 4)) & 0x3ff;
589 newport_clear_lines(0, lines
- 1,
590 (vc
->vc_color
& 0xf0) >> 4);
592 npregs
->cset
.topscan
= (topscan
- 1) & 0x3ff;
596 count
= (b
- t
- lines
) * vc
->vc_cols
;
600 s
= (unsigned short *) (vc
->vc_origin
+
601 vc
->vc_size_row
* (t
+ lines
));
602 d
= (unsigned short *) (vc
->vc_origin
+
603 vc
->vc_size_row
* t
);
605 chattr
= scr_readw(s
++);
606 if (chattr
!= scr_readw(d
)) {
607 newport_putc(vc
, chattr
, y
, x
);
608 scr_writew(chattr
, d
);
611 if (++x
== vc
->vc_cols
) {
616 d
= (unsigned short *) (vc
->vc_origin
+
617 vc
->vc_size_row
* (b
- lines
));
620 for (count
= 0; count
< (lines
* vc
->vc_cols
); count
++) {
621 if (scr_readw(d
) != vc
->vc_video_erase_char
) {
622 newport_putc(vc
, vc
->vc_video_erase_char
,
624 scr_writew(vc
->vc_video_erase_char
, d
);
627 if (++x
== vc
->vc_cols
) {
635 s
= (unsigned short *) (vc
->vc_origin
+
636 vc
->vc_size_row
* (b
- lines
) - 2);
637 d
= (unsigned short *) (vc
->vc_origin
+
638 vc
->vc_size_row
* b
- 2);
640 chattr
= scr_readw(s
--);
641 if (chattr
!= scr_readw(d
)) {
642 newport_putc(vc
, chattr
, y
, x
);
643 scr_writew(chattr
, d
);
651 d
= (unsigned short *) (vc
->vc_origin
+
652 vc
->vc_size_row
* t
);
655 for (count
= 0; count
< (lines
* vc
->vc_cols
); count
++) {
656 if (scr_readw(d
) != vc
->vc_video_erase_char
) {
657 newport_putc(vc
, vc
->vc_video_erase_char
,
659 scr_writew(vc
->vc_video_erase_char
, d
);
662 if (++x
== vc
->vc_cols
) {
671 static void newport_bmove(struct vc_data
*vc
, int sy
, int sx
, int dy
,
672 int dx
, int h
, int w
)
674 short xs
, ys
, xe
, ye
, xoffs
, yoffs
, tmp
;
677 xe
= ((sx
+ w
) << 3) - 1;
679 * as bmove is only used to move stuff around in the same line
680 * (h == 1), we don't care about wrap arounds caused by topscan != 0
682 ys
= ((sy
<< 4) + topscan
) & 0x3ff;
683 ye
= (((sy
+ h
) << 4) - 1 + topscan
) & 0x3ff;
684 xoffs
= (dx
- sx
) << 3;
685 yoffs
= (dy
- sy
) << 4;
687 /* move to the right, exchange starting points */
692 newport_wait(npregs
);
693 npregs
->set
.drawmode0
= (NPORT_DMODE0_S2S
| NPORT_DMODE0_BLOCK
|
694 NPORT_DMODE0_DOSETUP
| NPORT_DMODE0_STOPX
695 | NPORT_DMODE0_STOPY
);
696 npregs
->set
.xystarti
= (xs
<< 16) | ys
;
697 npregs
->set
.xyendi
= (xe
<< 16) | ye
;
698 npregs
->go
.xymove
= (xoffs
<< 16) | yoffs
;
701 static int newport_dummy(struct vc_data
*c
)
706 #define DUMMY (void *) newport_dummy
708 const struct consw newport_con
= {
709 .owner
= THIS_MODULE
,
710 .con_startup
= newport_startup
,
711 .con_init
= newport_init
,
712 .con_deinit
= newport_deinit
,
713 .con_clear
= newport_clear
,
714 .con_putc
= newport_putc
,
715 .con_putcs
= newport_putcs
,
716 .con_cursor
= newport_cursor
,
717 .con_scroll
= newport_scroll
,
718 .con_bmove
= newport_bmove
,
719 .con_switch
= newport_switch
,
720 .con_blank
= newport_blank
,
721 .con_font_set
= newport_font_set
,
722 .con_font_default
= newport_font_default
,
723 .con_set_palette
= newport_set_palette
,
724 .con_scrolldelta
= newport_scrolldelta
,
725 .con_set_origin
= DUMMY
,
726 .con_save_screen
= DUMMY
730 static int __init
newport_console_init(void)
732 return take_over_console(&newport_con
, 0, MAX_NR_CONSOLES
- 1, 1);
735 static void __exit
newport_console_exit(void)
737 give_up_console(&newport_con
);
738 iounmap((void *)npregs
);
741 module_init(newport_console_init
);
742 module_exit(newport_console_exit
);
745 MODULE_LICENSE("GPL");