diff options
| author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2003-07-17 19:44:45 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2003-07-17 19:44:45 -0700 |
| commit | 4d33d4eb3bf10be402ce8e021fd098356bf42584 (patch) | |
| tree | 7239a68b7e148341fefcf32ed883f1008ac86d5d | |
| parent | d949155d52d922706843bb6559315a8a8f5b874e (diff) | |
[PATCH] forward port 2.4 Zoom video support
Also apply the right fix to the yenta hang problem
| -rw-r--r-- | drivers/pcmcia/ricoh.h | 33 | ||||
| -rw-r--r-- | drivers/pcmcia/ti113x.h | 90 | ||||
| -rw-r--r-- | drivers/pcmcia/yenta_socket.c | 2 | ||||
| -rw-r--r-- | include/pcmcia/ss.h | 5 |
4 files changed, 125 insertions, 5 deletions
diff --git a/drivers/pcmcia/ricoh.h b/drivers/pcmcia/ricoh.h index dcfcbd4328b3..9f9c688d20eb 100644 --- a/drivers/pcmcia/ricoh.h +++ b/drivers/pcmcia/ricoh.h @@ -116,6 +116,8 @@ #define RL5C4XX_CMD_SHIFT 4 #define RL5C4XX_HOLD_MASK 0x1c00 #define RL5C4XX_HOLD_SHIFT 10 +#define RL5C4XX_MISC_CONTROL 0x2F /* 8 bit */ +#define RL5C4XX_ZV_ENABLE 0x08 #ifdef __YENTA_H @@ -125,10 +127,41 @@ #define rl_mem(socket) ((socket)->private[3]) #define rl_config(socket) ((socket)->private[4]) +static void ricoh_zoom_video(struct pcmcia_socket *sock, int onoff) +{ + u8 reg; + struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); + + reg = config_readb(socket, RL5C4XX_MISC_CONTROL); + if (onoff) + /* Zoom zoom, we will all go together, zoom zoom, zoom zoom */ + reg |= RL5C4XX_ZV_ENABLE; + else + reg &= ~RL5C4XX_ZV_ENABLE; + + config_writeb(socket, RL5C4XX_MISC_CONTROL, reg); +} + +static void ricoh_set_zv(struct pcmcia_socket *sock) +{ + struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); + if(socket->dev->vendor == PCI_VENDOR_ID_RICOH) + { + switch(socket->dev->device) + { + /* There may be more .. */ + case PCI_DEVICE_ID_RICOH_RL5C478: + sock->zoom_video = ricoh_zoom_video; + break; + } + } +} + static int ricoh_init(struct pcmcia_socket *sock) { struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); yenta_init(sock); + ricoh_set_zv(sock); config_writew(socket, RL5C4XX_MISC, rl_misc(socket)); config_writew(socket, RL5C4XX_16BIT_CTL, rl_ctl(socket)); diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index 2cdb46d4eb3c..4a0099518a76 100644 --- a/drivers/pcmcia/ti113x.h +++ b/drivers/pcmcia/ti113x.h @@ -148,14 +148,96 @@ static int ti_intctl(struct yenta_socket *socket) return 0; } +/* + * Zoom video control for TI122x/113x chips + */ + +static void ti_zoom_video(struct pcmcia_socket *sock, int onoff) +{ + u8 reg; + struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); + + /* If we don't have a Zoom Video switch this is harmless, + we just tristate the unused (ZV) lines */ + reg = config_readb(socket, TI113X_CARD_CONTROL); + if (onoff) + /* Zoom zoom, we will all go together, zoom zoom, zoom zoom */ + reg |= TI113X_CCR_ZVENABLE; + else + reg &= ~TI113X_CCR_ZVENABLE; + config_writeb(socket, TI113X_CARD_CONTROL, reg); +} + +/* + * The 145x series can also use this. They have an additional + * ZV autodetect mode we don't use but don't actually need. + * FIXME: manual says its in func0 and func1 but disagrees with + * itself about this - do we need to force func0, if so we need + * to know a lot more about socket pairings in pcmcia_socket than + * we do now.. uggh. + */ + +static void ti1250_zoom_video(struct pcmcia_socket *sock, int onoff) +{ + struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); + int shift = 0; + u8 reg; + + ti_zoom_video(sock, onoff); + + reg = config_readb(socket, 0x84); + reg |= (1<<7); /* ZV bus enable */ + + if(PCI_FUNC(socket->dev->devfn)==1) + shift = 1; + + if(onoff) + { + reg &= ~(1<<6); /* Clear select bit */ + reg |= shift<<6; /* Favour our socket */ + reg |= 1<<shift; /* Socket zoom video on */ + } + else + { + reg &= ~(1<<6); /* Clear select bit */ + reg |= (1^shift)<<6; /* Favour other socket */ + reg &= ~(1<<shift); /* Socket zoon video off */ + } + + config_writeb(socket, 0x84, reg); +} + +static void ti_set_zv(struct pcmcia_socket *sock) +{ + struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); + if(socket->dev->vendor == PCI_VENDOR_ID_TI) + { + switch(socket->dev->device) + { + /* There may be more .. */ + case PCI_DEVICE_ID_TI_1220: + case PCI_DEVICE_ID_TI_1221: + case PCI_DEVICE_ID_TI_1225: + sock->zoom_video = ti_zoom_video; + break; + case PCI_DEVICE_ID_TI_1250: + case PCI_DEVICE_ID_TI_1251A: + case PCI_DEVICE_ID_TI_1251B: + case PCI_DEVICE_ID_TI_1450: + sock->zoom_video = ti1250_zoom_video; + } + } +} static int ti_init(struct pcmcia_socket *sock) { struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); yenta_init(sock); + ti_set_zv(sock); ti_intctl(socket); return 0; } + /* * Generic TI init - TI has an extension for the * INTCTL register that sets the PCI CSC interrupt. @@ -176,9 +258,6 @@ static int ti_override(struct yenta_socket *socket) if (new != reg) exca_writeb(socket, I365_INTCTL, new); -#if 0 - /* THIS CAUSES HANGS! Disabled for now, do not know why */ - /* * If ISA interrupts don't work, then fall back to routing card * interrupts to the PCI interrupt of the socket. @@ -190,7 +269,7 @@ static int ti_override(struct yenta_socket *socket) u8 irqmux, devctl; devctl = config_readb(socket, TI113X_DEVICE_CONTROL); - if (devctl & TI113X_DCR_IMODE_MASK != TI12XX_DCR_IMODE_ALL_SERIAL) { + if ((devctl & TI113X_DCR_IMODE_MASK) != TI12XX_DCR_IMODE_ALL_SERIAL) { printk (KERN_INFO "ti113x: Routing card interrupts to PCI\n"); devctl &= ~TI113X_DCR_IMODE_MASK; @@ -203,7 +282,6 @@ static int ti_override(struct yenta_socket *socket) config_writeb(socket, TI113X_DEVICE_CONTROL, devctl); } } -#endif socket->socket.ops->init = ti_init; return 0; @@ -220,6 +298,7 @@ static int ti113x_init(struct pcmcia_socket *sock) { struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); yenta_init(sock); + ti_set_zv(sock); config_writel(socket, TI113X_SYSTEM_CONTROL, ti_sysctl(socket)); config_writeb(socket, TI113X_CARD_CONTROL, ti_cardctl(socket)); @@ -248,6 +327,7 @@ static int ti1250_init(struct pcmcia_socket *sock) struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); yenta_init(sock); ti113x_init(sock); + ti_set_zv(sock); ti_irqmux(socket) = config_readl(socket, TI122X_IRQMUX); ti_irqmux(socket) = (ti_irqmux(socket) & ~0x0f) | 0x02; /* route INTA */ if (!(ti_sysctl(socket) & TI122X_SCR_INTRTIE)) diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 707cb7297fc5..5056a66e3ff1 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -297,6 +297,8 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state) } exca_writeb(socket, I365_CSCINT, reg); exca_readb(socket, I365_CSC); + if(sock->zoom_video) + sock->zoom_video(sock, state->flags & SS_ZVCARD); } config_writew(socket, CB_BRIDGE_CONTROL, bridge); /* Socket event mask: get card insert/remove events.. */ diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h index 24cb380be518..08169885af48 100644 --- a/include/pcmcia/ss.h +++ b/include/pcmcia/ss.h @@ -51,6 +51,7 @@ #define SS_3VCARD 0x1000 #define SS_XVCARD 0x2000 #define SS_PENDING 0x4000 +#define SS_ZVCARD 0x8000 /* InquireSocket capabilities */ #define SS_CAP_PAGE_REGS 0x0001 @@ -209,6 +210,10 @@ struct pcmcia_socket { /* socket operations */ struct pccard_operations * ops; + /* Zoom video behaviour is so chip specific its not worth adding + this to _ops */ + void (*zoom_video)(struct pcmcia_socket *, int); + /* state thread */ struct semaphore skt_sem; /* protects socket h/w state */ |
