Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Oct 1997 13:23:39 -0600 (MDT)
From:      Nate Williams <nate@mt.sri.com>
To:        mobile@freebsd.org
Cc:        handy@sag.space.lockheed.com
Subject:   Patches from -current for -stable I'd like to commit after testing
Message-ID:  <199710211923.NAA07091@rocky.mt.sri.com>

next in thread | raw e-mail | index | archive | help
I'd like to bring in most of the recent changes to 2.2, not that 2.2.5
is out the door.  (I didn't want to break things for the release, and
didn't have time to test them enough for the release.)

These changes provide very little additions to the default behavior
(mostly fixes), but do add some additional functionality via sysctl's
(machdep.pccard.pcic_resume_reset & machdep.pccard.apm_pccard_resume) if
you enable them.

Here are the changes in log message style
--------------------- cut here ---------------------
MFC: Bring in all the 'safe' changes from current
- Speaker audio & low power mode on certain Cirrus Logic chips.
- Update chip ID comments.
- PCIC_RESUME_RESET & APM_PCCARD_RESUME sysctls.
- make getb() and putb() member functions of struct pcic_slot.
- Allocate the 'PCIC' interrupt from the last available (higher #) IRQ
  instead of the first available, like Win95 does.
- Don't start at IRQ 0 in build-freelist, but instead start at IRQ 1.
- Don't apply 5V when we want 3.3V.  Kludge around the case where the PCIC
  refuses to use 5V because it knows better than us.
- Make MOD_* macros almost consistent.
--------------------- cut here ---------------------

If I get get some yay/nay responses from this as to whether or not they
work fine, I'll commit them.  Unfortunately, I'm only able to test them
in -current right now since my 2.2 disk is apparently dead. :(

Note, I already committed changes to the aic6360 driver to both -current
and -stable hat 'sort of' allows my external CD to work.  They're not
really robust, but it's better than nothing for now.



Nate
-----------
===================================================================
RCS file: /home/CVS/src/sys/pccard/i82365.h,v
retrieving revision 1.5
diff -c -r1.5 i82365.h
*** i82365.h	1996/06/14 11:01:56	1.5
--- i82365.h	1997/10/21 19:12:30
***************
*** 38,51 ****
  #define	PCIC_VLSI	2		/* VLSI chip */
  #define	PCIC_PD672X	3		/* Cirrus logic 627x */
  #define	PCIC_PD6710	4		/* Cirrus logic 6710 */
! #define	PCIC_CL6729	5
! #define	PCIC_VG468	6
! #define	PCIC_VG469	7
  #define	PCIC_RF5C396	8		/* Ricoh RF5C396 */
  #define	PCIC_IBM_KING	9		/* IBM KING PCMCIA Controller */
! #ifdef	PC98
! #define	PCIC_PC98	10
! #endif
  /*
   *	Address of the controllers. Each controller can manage
   *	two PCMCIA slots. Up to 8 slots are supported in total.
--- 38,51 ----
  #define	PCIC_VLSI	2		/* VLSI chip */
  #define	PCIC_PD672X	3		/* Cirrus logic 627x */
  #define	PCIC_PD6710	4		/* Cirrus logic 6710 */
! #define	PCIC_CL6729	5		/* Cirrus logic 6729 */
! #define	PCIC_VG468	6		/* Vadem 468 */
! #define	PCIC_VG469	7		/* Vadem 469 */
  #define	PCIC_RF5C396	8		/* Ricoh RF5C396 */
  #define	PCIC_IBM_KING	9		/* IBM KING PCMCIA Controller */
! #define	PCIC_PC98	10		/* NEC PC98 PCMCIA Controller */
! #define	PCIC_TI1130	11		/* TI PCI1130 CardBus */
! 
  /*
   *	Address of the controllers. Each controller can manage
   *	two PCMCIA slots. Up to 8 slots are supported in total.
***************
*** 57,66 ****
   *	identify the port number, and the lower 6 bits
   *	select one of the 64 possible data registers.
   */
! #define PCIC_INDEX_0	0x3E0	/* index reg, chips 0 and 1 */
! #define PCIC_DATA_0	0x3E1	/* data register, chips 0 and 1 */
! #define PCIC_INDEX_1	0x3E2	/* index reg, chips 2 and 3 */
! #define PCIC_DATA_1	0x3E3	/* data register, chips 2 and 3 */
  /*
   *	Register index addresses.
   */
--- 57,66 ----
   *	identify the port number, and the lower 6 bits
   *	select one of the 64 possible data registers.
   */
! #define PCIC_INDEX_0	0x3E0			/* index reg, chips 0 and 1 */
! #define PCIC_DATA_0	(PCIC_INDEX_0 + 1)	/* data reg, chips 0 and 1 */
! #define PCIC_INDEX_1	(PCIC_INDEX_0 + 2)	/* index reg, chips 2 and 3 */
! #define PCIC_DATA_1	(PCIC_INDEX_1 + 1)	/* data reg, chips 2 and 3 */
  /*
   *	Register index addresses.
   */
***************
*** 76,82 ****
--- 76,84 ----
  #define PCIC_IO1	0x0c	/* I/O Address 1 */
  #define	PCIC_MEMBASE	0x10	/* Base of memory window registers */
  #define PCIC_CDGC	0x16	/* Card Detect and General Control */
+ #define PCIC_MISC1	0x16	/* PD672x: Misc control register 1 per slot */
  #define PCIC_GLO_CTRL	0x1e	/* Global Control Register */
+ #define PCIC_MISC2	0x1e	/* PD672x: Misc control register 2 per chip */
  
  #define	PCIC_TIME_SETUP0	0x3a
  #define	PCIC_TIME_CMD0		0x3b
***************
*** 197,208 ****
--- 199,216 ----
  #define PCIC_CDRES_EN	0x10	/* card detect resume enable */
  #define PCIC_SW_CD_INT	0x20	/* s/w card detect interrupt */
  
+ /* For Misc. Control Register 1 */
+ #define PCIC_SPKR_EN	0x10	/* Cirrus PD672x: speaker enable */
+ 
  /* For Global Control register (PCIC_GLO_CTRL) */
  #define PCIC_PWR_DOWN	0x01	/* power down */
  #define PCIC_LVL_MODE	0x02	/* level mode interrupt enable */
  #define PCIC_WB_CSCINT	0x04	/* explicit write-back csc intr */
  #define PCIC_IRQ0_LEVEL 0x08	/* irq 14 pulse mode enable */
  #define PCIC_IRQ1_LEVEL 0x10
+ 
+ /* For Misc. Control Register 2 */
+ #define PCIC_LPDM_EN	0x02	/* Cirrus PD672x: low power dynamic mode */
  
  /*
   *	Mask of allowable interrupts.
===================================================================
RCS file: /home/CVS/src/sys/pccard/pccard.c,v
retrieving revision 1.27.2.1
diff -c -r1.27.2.1 pccard.c
*** pccard.c	1997/03/04 00:27:24	1.27.2.1
--- pccard.c	1997/10/21 19:12:30
***************
*** 35,45 ****
--- 35,47 ----
  #include <sys/fcntl.h>
  #include <sys/proc.h>
  #include <sys/malloc.h>
+ #include <sys/sysctl.h>
  #include <sys/conf.h>
  #ifdef DEVFS
  #include <sys/devfsext.h>
  #endif /*DEVFS*/
  #include <sys/uio.h>
+ /*#include <sys/interrupt.h> */
  
  #include <i386/isa/isa_device.h>
  #include <i386/isa/icu.h>
***************
*** 56,61 ****
--- 58,84 ----
  #include <machine/clock.h>
  #include <machine/md_var.h>
  
+ SYSCTL_NODE(_machdep, OID_AUTO, pccard, CTLFLAG_RW, 0, "pccard");
+ 
+ static int pcic_resume_reset =
+ #ifdef PCIC_RESUME_RESET
+ 	1;
+ #else
+ 	0;
+ #endif
+ 
+ SYSCTL_INT(_machdep_pccard, OID_AUTO, pcic_resume_reset, CTLFLAG_RW, 
+ 	&pcic_resume_reset, 0, "");
+ 
+ static int apm_pccard_resume =
+ #ifdef APM_PCCARD_RESUME
+ 	1;
+ #else
+ 	0;
+ #endif
+ 
+ SYSCTL_INT(_machdep_pccard, OID_AUTO, apm_pccard_resume, CTLFLAG_RW, 
+ 	&apm_pccard_resume, 0, "");
  
  #define	PCCARD_MEMSIZE	(4*1024)
  
***************
*** 332,338 ****
  	struct pccard_dev *dp;
  
  	for (dp = sp->devices; dp; dp = dp->next)
! 		(void) dp->drv->suspend(dp);
  	if (!sp->suspend_power)
  		sp->ctrl->disable(sp);
  	return (0);
--- 355,361 ----
  	struct pccard_dev *dp;
  
  	for (dp = sp->devices; dp; dp = dp->next)
! 		(void)dp->drv->suspend(dp);
  	if (!sp->suspend_power)
  		sp->ctrl->disable(sp);
  	return (0);
***************
*** 342,359 ****
  slot_resume(void *arg)
  {
  	struct slot *sp = arg;
- 	struct pccard_dev *dp;
  
! #ifdef PCIC_RESUME_RESET
! 	sp->ctrl->resume(sp);
! #endif
  
! 	if (!sp->suspend_power)
! 		sp->ctrl->power(sp);
! 	if (sp->irq)
! 		sp->ctrl->mapirq(sp, sp->irq);
! 	for (dp = sp->devices; dp; dp = dp->next)
! 		(void) dp->drv->init(dp, 0);
  	return (0);
  }
  #endif	/* NAPM > 0 */
--- 365,396 ----
  slot_resume(void *arg)
  {
  	struct slot *sp = arg;
  
! 	if (pcic_resume_reset)
! 		sp->ctrl->resume(sp);
! 	if (apm_pccard_resume) {
! 		/* Fake card removal/insertion events */
! 		if (sp->state == filled) {
! 			int s;
  
! 			s = splhigh();
! 			disable_slot(sp);
! 			sp->state = empty;
! 			splx(s);
! 			sp->insert_seq = 1;
! 			timeout(inserted, (void *)sp, hz);
! 			selwakeup(&sp->selp);
! 		}
! 	} else {
! 		struct pccard_dev *dp;
! 
! 		if (!sp->suspend_power)
! 			sp->ctrl->power(sp);
! 		if (sp->irq)
! 			sp->ctrl->mapirq(sp, sp->irq);
! 		for (dp = sp->devices; dp; dp = dp->next)
! 			(void)dp->drv->init(dp, 0);
! 	}
  	return (0);
  }
  #endif	/* NAPM > 0 */
***************
*** 439,445 ****
  	int irq;
  	unsigned int mask;
  
! 	for (irq = 1; irq < ICU_LEN; irq++) {
  		mask = 1ul << irq;
  		if (!(mask & imask))
  			continue;
--- 476,482 ----
  	int irq;
  	unsigned int mask;
  
! 	for (irq = ICU_LEN; irq > 0; irq--) {
  		mask = 1ul << irq;
  		if (!(mask & imask))
  			continue;
***************
*** 614,622 ****
  	 */
  	sp->pwr.vcc = 50;
  	sp->pwr.vpp = 0;
! 	untimeout(power_off_slot, (caddr_t)sp);
! 	if (sp->pwr_off_pending)
  		sp->ctrl->disable(sp);
  	sp->pwr_off_pending = 0;
  	sp->ctrl->power(sp);
  	printf("Card inserted, slot %d\n", sp->slot);
--- 651,660 ----
  	 */
  	sp->pwr.vcc = 50;
  	sp->pwr.vpp = 0;
! 	if (sp->pwr_off_pending) {
! 		untimeout(power_off_slot, (caddr_t)sp);
  		sp->ctrl->disable(sp);
+ 	}
  	sp->pwr_off_pending = 0;
  	sp->ctrl->power(sp);
  	printf("Card inserted, slot %d\n", sp->slot);
===================================================================
RCS file: /home/CVS/src/sys/pccard/pcic.c,v
retrieving revision 1.23.2.1
diff -c -r1.23.2.1 pcic.c
*** pcic.c	1997/03/04 00:27:29	1.23.2.1
--- pcic.c	1997/10/21 19:12:30
***************
*** 39,44 ****
--- 39,45 ----
  #include <sys/select.h>
  
  #include <machine/clock.h>
+ #include <machine/ipl.h>
  
  #include <i386/isa/icu.h>
  #include <i386/isa/isa_device.h>
***************
*** 81,86 ****
--- 82,90 ----
  	char controller;		/* Device type */
  	char revision;			/* Device Revision */
  	struct slot *slotp;		/* Back ptr to slot */
+ 	u_char (*getb)(struct pcic_slot *sp, int reg);
+ 	void   (*putb)(struct pcic_slot *sp, int reg, u_char val);
+ 	u_char	*regs;			/* Pointer to regs in mem */
  } pcic_slots[PCIC_MAX_SLOTS];
  
  static int		pcic_irq;
***************
*** 95,114 ****
   * Read a register from the PCIC.
   */
  static inline unsigned char
! getb (struct pcic_slot *sp, int reg)
  {
! 	outb (sp->index, sp->offset + reg);
! 	return inb (sp->data);
  }
  
  /*
   * Write a register on the PCIC
   */
  static inline void
! putb (struct pcic_slot *sp, int reg, unsigned char val)
  {
! 	outb (sp->index, sp->offset + reg);
! 	outb (sp->data, val);
  }
  
  /*
--- 99,130 ----
   * Read a register from the PCIC.
   */
  static inline unsigned char
! getb1(struct pcic_slot *sp, int reg)
  {
! 	outb(sp->index, sp->offset + reg);
! 	return inb(sp->data);
! }
! 
! static inline unsigned char
! getb2(struct pcic_slot *sp, int reg)
! {
! 	return (sp->regs[reg]);
  }
  
  /*
   * Write a register on the PCIC
   */
  static inline void
! putb1(struct pcic_slot *sp, int reg, unsigned char val)
  {
! 	outb(sp->index, sp->offset + reg);
! 	outb(sp->data, val);
! }
! 
! static inline void
! putb2(struct pcic_slot *sp, int reg, unsigned char val)
! {
! 	sp->regs[reg] = val;
  }
  
  /*
***************
*** 117,123 ****
  static inline void
  clrb(struct pcic_slot *sp, int reg, unsigned char mask)
  {
! 	putb (sp, reg, getb (sp, reg) & ~mask);
  }
  
  /*
--- 133,139 ----
  static inline void
  clrb(struct pcic_slot *sp, int reg, unsigned char mask)
  {
! 	sp->putb(sp, reg, sp->getb(sp, reg) & ~mask);
  }
  
  /*
***************
*** 126,142 ****
  static inline void
  setb(struct pcic_slot *sp, int reg, unsigned char mask)
  {
! 	putb (sp, reg, getb (sp, reg) | mask);
  }
  
  /*
   * Write a 16 bit value to 2 adjacent PCIC registers
   */
  static inline void
! putw (struct pcic_slot *sp, int reg, unsigned short word)
  {
! 	putb (sp, reg, word & 0xFF);
! 	putb (sp, reg + 1, (word >> 8) & 0xff);
  }
  
  
--- 142,158 ----
  static inline void
  setb(struct pcic_slot *sp, int reg, unsigned char mask)
  {
! 	sp->putb(sp, reg, sp->getb(sp, reg) | mask);
  }
  
  /*
   * Write a 16 bit value to 2 adjacent PCIC registers
   */
  static inline void
! putw(struct pcic_slot *sp, int reg, unsigned short word)
  {
! 	sp->putb(sp, reg, word & 0xFF);
! 	sp->putb(sp, reg + 1, (word >> 8) & 0xff);
  }
  
  
***************
*** 213,219 ****
  int
  pcic_mod(struct lkm_table *lkmtp, int cmd, int ver)
  {
! 	DISPATCH(lkmtp,cmd,ver,pcic_handle,pcic_handle,lkm_nullcmd);
  }
  
  /*
--- 229,236 ----
  int
  pcic_mod(struct lkm_table *lkmtp, int cmd, int ver)
  {
! 	MOD_DISPATCH(pcic, lkmtp, cmd, ver,
! 		pcic_handle, pcic_handle, lkm_nullcmd);
  }
  
  /*
***************
*** 226,236 ****
  	int	slot;
  	struct pcic_slot *sp = pcic_slots;
  
! 	untimeout(pcictimeout,0);
  	if (pcic_irq) {
  		for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, sp++) {
  			if (sp->slotp)
! 				putb(sp, PCIC_STAT_INT, 0);
  		}
  		unregister_intr(pcic_irq, pcicintr);
  	}
--- 243,253 ----
  	int	slot;
  	struct pcic_slot *sp = pcic_slots;
  
! 	untimeout(pcictimeout, 0);
  	if (pcic_irq) {
  		for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, sp++) {
  			if (sp->slotp)
! 				sp->putb(sp, PCIC_STAT_INT, 0);
  		}
  		unregister_intr(pcic_irq, pcicintr);
  	}
***************
*** 275,281 ****
  	freemask = 0; 
   
  	/* Walk through all of the IRQ's and find any that aren't allocated. */ 
! 	for (irq = 0; irq < ICU_LEN; irq++) { 
  		/* 
  		 * If the PCIC controller can't generate it, don't
  		 * bother checking to see if it it's free. 
--- 292,298 ----
  	freemask = 0; 
   
  	/* Walk through all of the IRQ's and find any that aren't allocated. */ 
! 	for (irq = 1; irq < ICU_LEN; irq++) { 
  		/* 
  		 * If the PCIC controller can't generate it, don't
  		 * bother checking to see if it it's free. 
***************
*** 356,364 ****
  		 * The values are all stored as the upper 12 bits of the
  		 * 24 bit address i.e everything is allocated as 4 Kb chunks.
  		 */
! 		putw (sp, reg, sys_addr & 0xFFF);
! 		putw (sp, reg+2, (sys_addr + (mp->size >> 12) - 1) & 0xFFF);
! 		putw (sp, reg+4, ((mp->card >> 12) - sys_addr) & 0x3FFF);
  #if 0
  		printf("card offs = card_adr = 0x%x 0x%x, sys_addr = 0x%x\n", 
  			mp->card, ((mp->card >> 12) - sys_addr) & 0x3FFF,
--- 373,381 ----
  		 * The values are all stored as the upper 12 bits of the
  		 * 24 bit address i.e everything is allocated as 4 Kb chunks.
  		 */
! 		putw(sp, reg, sys_addr & 0xFFF);
! 		putw(sp, reg+2, (sys_addr + (mp->size >> 12) - 1) & 0xFFF);
! 		putw(sp, reg+4, ((mp->card >> 12) - sys_addr) & 0x3FFF);
  #if 0
  		printf("card offs = card_adr = 0x%x 0x%x, sys_addr = 0x%x\n", 
  			mp->card, ((mp->card >> 12) - sys_addr) & 0x3FFF,
***************
*** 385,408 ****
  	printf("Map window to sys addr 0x%x for %d bytes, card 0x%x\n",
  		mp->start, mp->size, mp->card);
  	printf("regs are: 0x%02x%02x 0x%02x%02x 0x%02x%02x flags 0x%x\n",
! 		getb(sp, reg), getb(sp, reg+1),
! 		getb(sp, reg+2), getb(sp, reg+3),
! 		getb(sp, reg+4), getb(sp, reg+5),
  		mp->flags);
  #endif
  		/*
  		 * Enable the memory window. By experiment, we need a delay.
  		 */
! 		setb (sp, PCIC_ADDRWINE, (1<<win) | PCIC_MEMCS16);
  		DELAY(50);
  	} else {
  #if 0
  		printf("Unmapping window %d\n", win);
  #endif
! 		clrb (sp, PCIC_ADDRWINE, 1<<win);
! 		putw (sp, reg, 0);
! 		putw (sp, reg+2, 0);
! 		putw (sp, reg+4, 0);
  	}
  	return(0);
  }
--- 402,425 ----
  	printf("Map window to sys addr 0x%x for %d bytes, card 0x%x\n",
  		mp->start, mp->size, mp->card);
  	printf("regs are: 0x%02x%02x 0x%02x%02x 0x%02x%02x flags 0x%x\n",
! 		sp->getb(sp, reg), sp->getb(sp, reg+1),
! 		sp->getb(sp, reg+2), sp->getb(sp, reg+3),
! 		sp->getb(sp, reg+4), sp->getb(sp, reg+5),
  		mp->flags);
  #endif
  		/*
  		 * Enable the memory window. By experiment, we need a delay.
  		 */
! 		setb(sp, PCIC_ADDRWINE, (1<<win) | PCIC_MEMCS16);
  		DELAY(50);
  	} else {
  #if 0
  		printf("Unmapping window %d\n", win);
  #endif
! 		clrb(sp, PCIC_ADDRWINE, 1<<win);
! 		putw(sp, reg, 0);
! 		putw(sp, reg+2, 0);
! 		putw(sp, reg+4, 0);
  	}
  	return(0);
  }
***************
*** 474,481 ****
  #ifdef	PCIC_DEBUG
  printf("Map I/O 0x%x (size 0x%x) on Window %d\n", ip->start, ip->size, win);
  #endif	/* PCIC_DEBUG */
! 		putw (sp, reg, ip->start);
! 		putw (sp, reg+2, ip->start+ip->size-1);
  		x = 0;
  		if (ip->flags & IODF_ZEROWS)
  			x |= PCIC_IO_0WS;
--- 491,498 ----
  #ifdef	PCIC_DEBUG
  printf("Map I/O 0x%x (size 0x%x) on Window %d\n", ip->start, ip->size, win);
  #endif	/* PCIC_DEBUG */
! 		putw(sp, reg, ip->start);
! 		putw(sp, reg+2, ip->start+ip->size-1);
  		x = 0;
  		if (ip->flags & IODF_ZEROWS)
  			x |= PCIC_IO_0WS;
***************
*** 490,513 ****
  		 * Flags for window 0 in lower nybble, and in upper nybble
  		 * for window 1.
  		 */
! 		ioctlv = getb(sp, PCIC_IOCTL);
  		DELAY(100);
  		switch (win) {
  		case 0:
! 			putb(sp, PCIC_IOCTL, x | (ioctlv & 0xf0));
  			break;
  		case 1:
! 			putb(sp, PCIC_IOCTL, (x << 4) | (ioctlv & 0xf));
  			break;
  		}
  		DELAY(100);
! 		setb (sp, PCIC_ADDRWINE, mask);
  		DELAY(100);
  	} else {
! 		clrb (sp, PCIC_ADDRWINE, mask);
  		DELAY(100);
! 		putw (sp, reg, 0);
! 		putw (sp, reg + 2, 0);
  	}
  	return(0);
  }
--- 507,530 ----
  		 * Flags for window 0 in lower nybble, and in upper nybble
  		 * for window 1.
  		 */
! 		ioctlv = sp->getb(sp, PCIC_IOCTL);
  		DELAY(100);
  		switch (win) {
  		case 0:
! 			sp->putb(sp, PCIC_IOCTL, x | (ioctlv & 0xf0));
  			break;
  		case 1:
! 			sp->putb(sp, PCIC_IOCTL, (x << 4) | (ioctlv & 0xf));
  			break;
  		}
  		DELAY(100);
! 		setb(sp, PCIC_ADDRWINE, mask);
  		DELAY(100);
  	} else {
! 		clrb(sp, PCIC_ADDRWINE, mask);
  		DELAY(100);
! 		putw(sp, reg, 0);
! 		putw(sp, reg + 2, 0);
  	}
  	return(0);
  }
***************
*** 559,564 ****
--- 576,583 ----
  		/*
  		 *	Initialise the PCIC slot table.
  		 */
+ 		sp->getb = getb1;
+ 		sp->putb = putb1;
  		if (slot < 4) {
  			sp->index = PCIC_INDEX_0;
  			sp->data = PCIC_DATA_0;
***************
*** 575,581 ****
  		 * ones would need to be probed at the new offset we set after
  		 * we assume it's broken.
  		 */
! 		if (slot == 1 && maybe_vlsi && getb(sp, PCIC_ID_REV) != 0x84) {
  			sp->index += 4;
  			sp->data += 4;
  			sp->offset = PCIC_SLOT_SIZE << 1;
--- 594,600 ----
  		 * ones would need to be probed at the new offset we set after
  		 * we assume it's broken.
  		 */
! 		if (slot == 1 && maybe_vlsi && sp->getb(sp, PCIC_ID_REV) != 0x84) {
  			sp->index += 4;
  			sp->data += 4;
  			sp->offset = PCIC_SLOT_SIZE << 1;
***************
*** 585,591 ****
  		 * Intel PCMCIA controllers use 0x82 and 0x83
  		 * IBM clone chips use 0x88 and 0x89, apparently
  		 */
! 		c = getb (sp, PCIC_ID_REV);
  		sp->revision = -1;
  		switch(c) {
  		/*
--- 604,610 ----
  		 * Intel PCMCIA controllers use 0x82 and 0x83
  		 * IBM clone chips use 0x88 and 0x89, apparently
  		 */
! 		c = sp->getb(sp, PCIC_ID_REV);
  		sp->revision = -1;
  		switch(c) {
  		/*
***************
*** 601,607 ****
  			outb(sp->index, 0x0E);
  			outb(sp->index, 0x37);
  			setb(sp, 0x3A, 0x40);
! 			c = getb (sp, PCIC_ID_REV);
  			if (c & 0x08) {
  				sp->controller = ((sp->revision = c & 7) == 4) ?	
  					PCIC_VG469 : PCIC_VG468 ;
--- 620,626 ----
  			outb(sp->index, 0x0E);
  			outb(sp->index, 0x37);
  			setb(sp, 0x3A, 0x40);
! 			c = sp->getb(sp, PCIC_ID_REV);
  			if (c & 0x08) {
  				sp->controller = ((sp->revision = c & 7) == 4) ?	
  					PCIC_VG469 : PCIC_VG468 ;
***************
*** 611,617 ****
  			/*
  			 * Check for RICOH RF5C396 PCMCIA Controller
  			 */
! 			c = getb (sp, 0x3a);
  			if (c == 0xb2) {
  				sp->controller = PCIC_RF5C396;
  			}
--- 630,636 ----
  			/*
  			 * Check for RICOH RF5C396 PCMCIA Controller
  			 */
! 			c = sp->getb(sp, 0x3a);
  			if (c == 0xb2) {
  				sp->controller = PCIC_RF5C396;
  			}
***************
*** 639,648 ****
  		/*
  		 *	Check for Cirrus logic chips.
  		 */
! 		putb(sp, 0x1F, 0);
! 		c = getb(sp, 0x1F);
  		if ((c & 0xC0) == 0xC0) {
! 			c = getb(sp, 0x1F);
  			if ((c & 0xC0) == 0) {
  				if (c & 0x20)
  					sp->controller = PCIC_PD672X;
--- 658,667 ----
  		/*
  		 *	Check for Cirrus logic chips.
  		 */
! 		sp->putb(sp, 0x1F, 0);
! 		c = sp->getb(sp, 0x1F);
  		if ((c & 0xC0) == 0xC0) {
! 			c = sp->getb(sp, 0x1F);
  			if ((c & 0xC0) == 0) {
  				if (c & 0x20)
  					sp->controller = PCIC_PD672X;
***************
*** 688,694 ****
  		 *	clear out the registers.
  		 */
  		for (i = 2; i < 0x40; i++)
! 			putb(sp, i, 0);
  #endif	/* PCIC_NOCLRREGS */
  		/*
  		 *	OK it seems we have a PCIC or lookalike.
--- 707,713 ----
  		 *	clear out the registers.
  		 */
  		for (i = 2; i < 0x40; i++)
! 			sp->putb(sp, i, 0);
  #endif	/* PCIC_NOCLRREGS */
  		/*
  		 *	OK it seems we have a PCIC or lookalike.
***************
*** 715,724 ****
  				printf("pcic: controller irq %d\n", pcic_irq);
  		}
  		/*
  		 *	Check for a card in this slot.
  		 */
! 		setb (sp, PCIC_POWER, PCIC_PCPWRE| PCIC_DISRST);
! 		if ((getb (sp, PCIC_STATUS) & PCIC_CD) != PCIC_CD) {
  			slotp->laststate = slotp->state = empty;
  		} else {
  			slotp->laststate = slotp->state = filled;
--- 734,754 ----
  				printf("pcic: controller irq %d\n", pcic_irq);
  		}
  		/*
+ 		 * Modem cards send the speaker audio (dialing noises)
+ 		 * to the host's speaker.  Cirrus Logic PCIC chips must
+ 		 * enable this.  There is also a Low Power Dynamic Mode bit
+ 		 * that claims to reduce power consumption by 30%, so
+ 		 * enable it and hope for the best.
+ 		 */
+ 		if (sp->controller == PCIC_PD672X) {
+ 			setb(sp, PCIC_MISC1, PCIC_SPKR_EN);
+ 			setb(sp, PCIC_MISC2, PCIC_LPDM_EN);
+ 		}
+ 		/*
  		 *	Check for a card in this slot.
  		 */
! 		setb(sp, PCIC_POWER, PCIC_PCPWRE| PCIC_DISRST);
! 		if ((sp->getb(sp, PCIC_STATUS) & PCIC_CD) != PCIC_CD) {
  			slotp->laststate = slotp->state = empty;
  		} else {
  			slotp->laststate = slotp->state = filled;
***************
*** 728,734 ****
  		 *	Assign IRQ for slot changes
  		 */
  		if (pcic_irq > 0)
! 			putb(sp, PCIC_STAT_INT, (pcic_irq << 4) | 0xF);
  	}
  #ifdef	PC98
  	if (validslots == 0){
--- 758,764 ----
  		 *	Assign IRQ for slot changes
  		 */
  		if (pcic_irq > 0)
! 			sp->putb(sp, PCIC_STAT_INT, (pcic_irq << 4) | 0xF);
  	}
  #ifdef	PC98
  	if (validslots == 0){
***************
*** 775,780 ****
--- 805,811 ----
  static int
  pcic_ioctl(struct slot *slotp, int cmd, caddr_t data)
  {
+ 	struct pcic_slot *sp = slotp->cdata;
  
  	switch(cmd) {
  	default:
***************
*** 784,793 ****
  	 */
  	case PIOCGREG:
  		((struct pcic_reg *)data)->value =
! 			getb(slotp->cdata, ((struct pcic_reg *)data)->reg);
  		break;
  	case PIOCSREG:
! 		putb(slotp->cdata, ((struct pcic_reg *)data)->reg,
  			((struct pcic_reg *)data)->value);
  		break;
  	}
--- 815,824 ----
  	 */
  	case PIOCGREG:
  		((struct pcic_reg *)data)->value =
! 			sp->getb(sp, ((struct pcic_reg *)data)->reg);
  		break;
  	case PIOCSREG:
! 		sp->putb(sp, ((struct pcic_reg *)data)->reg,
  			((struct pcic_reg *)data)->value);
  		break;
  	}
***************
*** 864,870 ****
  				reg |= PCIC_VCC_5V_KING;
  				break;
  			}
! 			reg |= PCIC_VCC_5V;
  			if ((sp->controller == PCIC_VG468)||
  				(sp->controller == PCIC_VG469))
  				setb(sp, 0x2f, 0x03) ;
--- 895,901 ----
  				reg |= PCIC_VCC_5V_KING;
  				break;
  			}
! 			reg |= PCIC_VCC_3V;
  			if ((sp->controller == PCIC_VG468)||
  				(sp->controller == PCIC_VG469))
  				setb(sp, 0x2f, 0x03) ;
***************
*** 886,897 ****
  		}
  		break;
  	}
! 	putb (sp, PCIC_POWER, reg);
  	DELAY(300*1000);
  	if (slotp->pwr.vcc) {
  		reg |= PCIC_OUTENA;
! 		putb (sp, PCIC_POWER, reg);
! 		DELAY (100*1000);
  	}
  	return(0);
  }
--- 917,936 ----
  		}
  		break;
  	}
! 	sp->putb(sp, PCIC_POWER, reg);
  	DELAY(300*1000);
  	if (slotp->pwr.vcc) {
  		reg |= PCIC_OUTENA;
! 		sp->putb(sp, PCIC_POWER, reg);
! 		DELAY(100*1000);
! 	}
! 	/* Some chips are smarter than us it seems, so if we weren't
! 	 * allowed to use 5V, try 3.3 instead
! 	 */
! 	if (!(sp->getb(sp, PCIC_STATUS) &  0x40) && slotp->pwr.vcc == 50) {
! 		slotp->pwr.vcc = 33;
! 		slotp->pwr.vpp = 0;
! 		return (pcic_power(slotp));
  	}
  	return(0);
  }
***************
*** 936,942 ****
  	if (irq == 0)
  		clrb(sp, PCIC_INT_GEN, 0xF);
  	else
! 		putb (sp, PCIC_INT_GEN, (getb (sp, PCIC_INT_GEN) & 0xF0) | irq);
  }
  
  /*
--- 975,982 ----
  	if (irq == 0)
  		clrb(sp, PCIC_INT_GEN, 0xF);
  	else
! 		sp->putb(sp, PCIC_INT_GEN, 
! 		    (sp->getb(sp, PCIC_INT_GEN) & 0xF0) | irq);
  }
  
  /*
***************
*** 965,993 ****
  	    case 0: /* Something funny happended on the way to the pub... */
  		return;
  	    case 1: /* Assert reset */
! 		clrb (sp, PCIC_INT_GEN, PCIC_CARDRESET);
  		slotp->insert_seq = 2;
  		timeout(pcic_reset, (void*) slotp, hz/4);
  		return;
  	    case 2: /* Deassert it again */
! 		setb (sp, PCIC_INT_GEN, PCIC_CARDRESET|PCIC_IOCARD);
  		slotp->insert_seq = 3;
  		timeout(pcic_reset, (void*) slotp, hz/4);
  		return;
  	    case 3: /* Wait if card needs more time */
! 		if (!getb(sp, PCIC_STATUS) & PCIC_READY) {
  			timeout(pcic_reset, (void*) slotp, hz/10);
  			return;
  		}
  	}
  	slotp->insert_seq = 0;
  	if (sp->controller == PCIC_PD672X || sp->controller == PCIC_PD6710) {
! 		putb(sp, PCIC_TIME_SETUP0, 0x1);
! 		putb(sp, PCIC_TIME_CMD0, 0x6);
! 		putb(sp, PCIC_TIME_RECOV0, 0x0);
! 		putb(sp, PCIC_TIME_SETUP1, 1);
! 		putb(sp, PCIC_TIME_CMD1, 0xf);
! 		putb(sp, PCIC_TIME_RECOV1, 0);
  	}
  	selwakeup(&slotp->selp);
  }
--- 1005,1033 ----
  	    case 0: /* Something funny happended on the way to the pub... */
  		return;
  	    case 1: /* Assert reset */
! 		clrb(sp, PCIC_INT_GEN, PCIC_CARDRESET);
  		slotp->insert_seq = 2;
  		timeout(pcic_reset, (void*) slotp, hz/4);
  		return;
  	    case 2: /* Deassert it again */
! 		setb(sp, PCIC_INT_GEN, PCIC_CARDRESET|PCIC_IOCARD);
  		slotp->insert_seq = 3;
  		timeout(pcic_reset, (void*) slotp, hz/4);
  		return;
  	    case 3: /* Wait if card needs more time */
! 		if (!sp->getb(sp, PCIC_STATUS) & PCIC_READY) {
  			timeout(pcic_reset, (void*) slotp, hz/10);
  			return;
  		}
  	}
  	slotp->insert_seq = 0;
  	if (sp->controller == PCIC_PD672X || sp->controller == PCIC_PD6710) {
! 		sp->putb(sp, PCIC_TIME_SETUP0, 0x1);
! 		sp->putb(sp, PCIC_TIME_CMD0, 0x6);
! 		sp->putb(sp, PCIC_TIME_RECOV0, 0x0);
! 		sp->putb(sp, PCIC_TIME_SETUP1, 1);
! 		sp->putb(sp, PCIC_TIME_CMD1, 0xf);
! 		sp->putb(sp, PCIC_TIME_RECOV1, 0);
  	}
  	selwakeup(&slotp->selp);
  }
***************
*** 1005,1012 ****
  	    return;
  	}
  #endif
! 	putb(sp, PCIC_INT_GEN, 0);
! 	putb(sp, PCIC_POWER, 0);
  }
  
  /*
--- 1045,1052 ----
  	    return;
  	}
  #endif
! 	sp->putb(sp, PCIC_INT_GEN, 0);
! 	sp->putb(sp, PCIC_POWER, 0);
  }
  
  /*
***************
*** 1053,1061 ****
  #endif	/* PC98 */
  	s = splhigh();
  	for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, sp++)
! 		if (sp->slotp && (chg = getb(sp, PCIC_STAT_CHG)) != 0)
  			if (chg & PCIC_CDTCH) {
! 				if ((getb(sp, PCIC_STATUS) & PCIC_CD) ==
  						PCIC_CD) {
  					pccard_event(sp->slotp,
  						card_inserted);
--- 1093,1101 ----
  #endif	/* PC98 */
  	s = splhigh();
  	for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, sp++)
! 		if (sp->slotp && (chg = sp->getb(sp, PCIC_STAT_CHG)) != 0)
  			if (chg & PCIC_CDTCH) {
! 				if ((sp->getb(sp, PCIC_STATUS) & PCIC_CD) ==
  						PCIC_CD) {
  					pccard_event(sp->slotp,
  						card_inserted);
***************
*** 1073,1078 ****
  static void
  pcic_resume(struct slot *slotp)
  {
  	if (pcic_irq > 0)
! 		putb(slotp->cdata, PCIC_STAT_INT, (pcic_irq << 4) | 0xF);
  }
--- 1113,1123 ----
  static void
  pcic_resume(struct slot *slotp)
  {
+ 	struct pcic_slot *sp = slotp->cdata;
  	if (pcic_irq > 0)
! 		sp->putb(sp, PCIC_STAT_INT, (pcic_irq << 4) | 0xF);
! 	if (sp->controller == PCIC_PD672X) {
! 		setb(sp, PCIC_MISC1, PCIC_SPKR_EN);
! 		setb(sp, PCIC_MISC2, PCIC_LPDM_EN);
! 	}
  }
Index: i82365.h
Index: pccard.c
Index: pcic.c





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199710211923.NAA07091>