From: <he...@us...> - 2004-06-23 17:34:35
|
Update of /cvsroot/gc-linux/linux/arch/ppc/platforms In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20759 Modified Files: gc-dvdcover.c Log Message: Added code to stop DVD motor on init to save DVD life. Otherwise, cosmetic changes. Index: gc-dvdcover.c =================================================================== RCS file: /cvsroot/gc-linux/linux/arch/ppc/platforms/gc-dvdcover.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- gc-dvdcover.c 16 Jun 2004 15:32:36 -0000 1.4 +++ gc-dvdcover.c 23 Jun 2004 17:34:24 -0000 1.5 @@ -1,7 +1,8 @@ /* ------------------------------------------------------------------------- */ -/* gc-dvdcover.c GameCube DVD Cover Close Message Driver */ +/* gc-dvdcover.c GameCube DVD Cover Close Message Driver */ /* ------------------------------------------------------------------------- */ /* Copyright (C) 2004 Stefan Esser + Copyright (C) 2004 Albert Herranz This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ------------------------------------------------------------------------- */ -/* - * Albert Herranz - * GAMECUBE - * - Fixed bug that caused kernel to "loop" in gc_dvdcover_handler - * sometimes during kernel init. - */ #include <linux/init.h> #include <linux/kernel.h> @@ -33,51 +28,80 @@ #define DVD_IRQ 2 -#define GAMECUBE_DICVR 0xcc006004 /* DI Cover Register */ -#define GC_DI_DISR 0xcc006000 /* DI Status Register */ -#define GC_DI_DISR_BRKINT (1<<6) -#define GC_DI_DISR_BRKINTMASK (1<<5) -#define GC_DI_DISR_TCINT (1<<4) -#define GC_DI_DISR_TCINTMASK (1<<3) -#define GC_DI_DISR_DEINT (1<<2) -#define GC_DI_DISR_DEINTMASK (1<<1) -#define GC_DI_DISR_BRK (1<<0) +#define DI_DISR 0xcc006000 /* DI Status Register */ +#define DI_DISR_BRKINT (1<<6) +#define DI_DISR_BRKINTMASK (1<<5) +#define DI_DISR_TCINT (1<<4) +#define DI_DISR_TCINTMASK (1<<3) +#define DI_DISR_DEINT (1<<2) +#define DI_DISR_DEINTMASK (1<<1) +#define DI_DISR_BRK (1<<0) +#define DI_DICVR 0xcc006004 /* DI Cover Register */ +#define DI_DICVR_CVRINT (1<<2) +#define DI_DICVR_CVRINTMASK (1<<1) +#define DI_DICVR_CVR (1<<0) -static irqreturn_t gc_dvdcover_handler(int this_irq, void *dev_id, struct pt_regs *regs) { +#define DI_DICMDBUF0 0xcc006008 /* DI Command Buffer 0 */ - unsigned long reason = readl(GAMECUBE_DICVR); +#define DI_DICR 0xcc00601c /* DI Control Register */ +#define DI_DICR_RW (1<<2) +#define DI_DICR_DMA (1<<1) +#define DI_DICR_TSTART (1<<0) + +#define DI_CMD_STOP (0xE3) + +/** + * + */ +static irqreturn_t gc_dvdcover_handler(int this_irq, void *dev_id, + struct pt_regs *regs) +{ + unsigned long reason = readl(DI_DICVR); + + /* handle only DVD cover interrupts here */ + if (reason & DI_DICVR_CVRINT) { + writel(reason | DI_DICVR_CVRINT, DI_DICVR); + printk(KERN_INFO "gc_dvdcover: DVD cover was %s.\n", + (reason & DI_DICVR_CVR) ? "opened" : "closed"); - // really a DVD cover interrupt? - if (reason & 4) { - writel(reason | 4, GAMECUBE_DICVR); - printk(KERN_INFO "gc_dvdcover: DVD cover was closed\n"); return IRQ_HANDLED; } return IRQ_NONE; } +/** + * + */ static int gc_dvdcover_init(void) { unsigned long outval; int err; - + /* clear pending DI interrupts and mask new ones */ /* this prevents an annoying bug while we lack a complete DVD driver */ - outval = GC_DI_DISR_BRKINT | GC_DI_DISR_TCINT | GC_DI_DISR_DEINT; - outval &= ~(GC_DI_DISR_BRKINTMASK | GC_DI_DISR_TCINTMASK | - GC_DI_DISR_DEINTMASK); - writel(outval, GC_DI_DISR); + outval = DI_DISR_BRKINT | DI_DISR_TCINT | DI_DISR_DEINT; + outval &= ~(DI_DISR_BRKINTMASK | DI_DISR_TCINTMASK | DI_DISR_DEINTMASK); + writel(outval, DI_DISR); - err = request_irq(DVD_IRQ, gc_dvdcover_handler, 0, "GameCube DVD Cover", 0); + /* stop DVD motor */ + writel(DI_CMD_STOP << 24, DI_DICMDBUF0); + writel(DI_DICR_TSTART, DI_DICR); + + err = + request_irq(DVD_IRQ, gc_dvdcover_handler, 0, "GameCube DVD Cover", + 0); if (err) return err; - writel(readl(GAMECUBE_DICVR) | 2, GAMECUBE_DICVR); + writel(readl(DI_DICVR) | DI_DICVR_CVRINTMASK, DI_DICVR); return 0; } +/** + * + */ static void gc_dvdcover_exit(void) { free_irq(DVD_IRQ, 0); @@ -89,3 +113,4 @@ module_init(gc_dvdcover_init); module_exit(gc_dvdcover_exit); + |