static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status)
{
	DEB2(printk(KERN_INFO
		"i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n",
		 *status));

	/* Cleanup from LAB -- reset and enable ESO.
	 * This resets the PCF8584; since we've lost the bus, no
	 * further attempts should be made by callers to clean up
	 * (no i2c_stop() etc.)
	 */
	set_pcf(adap, 1, I2C_PCF_PIN);
	set_pcf(adap, 1, I2C_PCF_ESO);

	/* We pause for a time period sufficient for any running
	 * I2C transaction to complete -- the arbitration logic won't
	 * work properly until the next START is seen.
	 * It is assumed the bus driver or client has set a proper value.
	 *
	 * REVISIT: should probably use msleep instead of mdelay if we
	 * know we can sleep.
	 */
	if (adap->lab_mdelay)
		mdelay(adap->lab_mdelay);

	DEB2(printk(KERN_INFO
		"i2c-algo-pcf.o: reset LAB condition (CSR 0x%02x)\n",
		get_pcf(adap, 1)));
}
static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status)
{
	DEB2(printk(KERN_INFO
		"i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n",
		*status));
	/*
                                             
                                                         
                                                          
                        
  */
	set_pcf(adap, 1, I2C_PCF_PIN);
	set_pcf(adap, 1, I2C_PCF_ESO);
	/*
                                                         
                                                              
                                               
                                                                  
   
                                                               
                      
  */
	if (adap->lab_mdelay)
		mdelay(adap->lab_mdelay);

	DEB2(printk(KERN_INFO
		"i2c-algo-pcf.o: reset LAB condition (CSR 0x%02x)\n",
		get_pcf(adap, 1)));
}
示例#3
0
/* Called when the module is loaded.  This function starts the
 * cascade of calls up through the heirarchy of i2c modules (i.e. up to the
 *  algorithm layer and into to the core layer)
 */
static int __init iic_avalanche_init(void)
{

	struct iic_avalanche *piic = &iic_avalanche_priv_data;

	DEB2(printk(KERN_INFO "Initialize Avalanche IIC adapter module\n"));




        iic_avalanche_priv_data.iic_clock = avalanche_get_vbus_freq(); /* Clock frequency on the peripheral bus */ 

	iic_avalanche_data.data = (void *)piic;
	init_waitqueue_head(&iic_wait);
	if (iic_hw_resrc_init() == 0) {

                DEB2(printk("calling add bus\n"));

		if (i2c_avalanche_add_bus(&iic_avalanche_ops) < 0)
			return -ENODEV;
	} else {
		return -ENODEV;
	}
	DEB2(printk(KERN_INFO " found device at %#x irq %d.\n",
		piic->iic_base, piic->iic_irq));
	return 0;
}
示例#4
0
/*
 * This should perform the 'PCF8584 initialization sequence' as described
 * in the Philips IC12 data book (1995, Aug 29).
 * There should be a 30 clock cycle wait after reset, I assume this
 * has been fulfilled.
 * There should be a delay at the end equal to the longest I2C message
 * to synchronize the BB-bit (in multimaster systems). How long is
 * this? I assume 1 second is always long enough.
 *
 * vdovikin: added detect code for PCF8584
 */
static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
{
	unsigned char temp;

	DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n",
				get_pcf(adap, 1)));

	/* S1=0x80: S0 selected, serial interface off */
	set_pcf(adap, 1, I2C_PCF_PIN);
	/*
	 * check to see S1 now used as R/W ctrl -
	 * PCF8584 does that when ESO is zero
	 */
	if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) {
		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp));
		return -ENXIO; /* definitely not PCF8584 */
	}

	/* load own address in S0, effective address is (own << 1) */
	i2c_outb(adap, get_own(adap));
	/* check it's really written */
	if ((temp = i2c_inb(adap)) != get_own(adap)) {
		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp));
		return -ENXIO;
	}

	/* S1=0xA0, next byte in S2 */
	set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1);
	/* check to see S2 now selected */
	if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) {
		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp));
		return -ENXIO;
	}

	/* load clock register S2 */
	i2c_outb(adap, get_clock(adap));
	/* check it's really written, the only 5 lowest bits does matter */
	if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) {
		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp));
		return -ENXIO;
	}

	/* Enable serial interface, idle, S0 selected */
	set_pcf(adap, 1, I2C_PCF_IDLE);

	/* check to see PCF is really idled and we can access status register */
	if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) {
		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp));
		return -ENXIO;
	}

	printk(KERN_DEBUG "i2c-algo-pcf.o: detected and initialized PCF8584.\n");

	return 0;
}
static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
{
	unsigned char temp;

	DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n",
				get_pcf(adap, 1)));

	/*                                            */
	set_pcf(adap, 1, I2C_PCF_PIN);
	/*
                                          
                                      
  */
	if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) {
		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp));
		return -ENXIO; /*                        */
	}

	/*                                                         */
	i2c_outb(adap, get_own(adap));
	/*                           */
	if ((temp = i2c_inb(adap)) != get_own(adap)) {
		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp));
		return -ENXIO;
	}

	/*                          */
	set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1);
	/*                              */
	if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) {
		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp));
		return -ENXIO;
	}

	/*                        */
	i2c_outb(adap, get_clock(adap));
	/*                                                               */
	if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) {
		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp));
		return -ENXIO;
	}

	/*                                            */
	set_pcf(adap, 1, I2C_PCF_IDLE);

	/*                                                                    */
	if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) {
		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp));
		return -ENXIO;
	}

	printk(KERN_DEBUG "i2c-algo-pcf.o: detected and initialized PCF8584.\n");

	return 0;
}
static int
mlib_read_mthd (mlib_desc * desc)
{
  char sig[5];
  unsigned char hi, lo;
  int len;

  if (!mlib_chkdesc (desc))
    return 0;

  if (!mlib_rdstr (desc, sig, 4))
    return 0;

  if (strcmp (sig, "MThd"))
    {
      mlib_seterr ("Invalid header signature (!= MThd)");
      return 0;
    }

  if (mlib_rdint32 (desc, &len))

    if (mlib_rdint16 (desc, &desc->hdr.MThd_fmt))
      DEB2 (printf ("Header: Format %d\n", desc->hdr.MThd_fmt));

  if (mlib_rdint16 (desc, &desc->hdr.MThd_ntrk))
    DEB2 (printf ("Header: ntrks %d\n", desc->hdr.MThd_ntrk));

  if (mlib_rdbyte (desc, &hi))
    if (mlib_rdbyte (desc, &lo))

      if (hi & 0x80)		/* Negative */
	{
	  DEB2 (printf ("SMPTE timing: format = %d, resolution = %d\n",
			(char) hi, lo));
	  desc->hdr.time_mode = TIME_SMPTE;
	  desc->hdr.SMPTE_format = (char) hi;
	  desc->hdr.SMPTE_resolution = lo;
	}
      else
	{
	  desc->hdr.time_mode = TIME_MIDI;
	  desc->hdr.division = (hi << 8) + lo;
	  DEB2 (printf ("Midi timing: timebase = %d ppqn\n",
			desc->hdr.division));
	}

  desc->curr_trk = -1;
  desc->trk_offs = 0;
  desc->next_trk_offs = 4 + 4 + len;;

  return mlib_seek (desc, desc->trk_offs);	/* Point to the first track */
}
示例#7
0
//
// Description: The registered interrupt handler
//
static void iic_ibmocp_handler(int this_irq, void *dev_id, struct pt_regs *regs) 
{
   int ret;
   struct iic_regs *iic;
   struct iic_ibm *priv_data = dev_id;
   iic = (struct iic_regs *) priv_data->iic_base;
   iic_pending = 1;
   DEB2(printk("iic_ibmocp_handler: in interrupt handler\n"));
   // Read status register
   ret = readb((int) &(iic->sts));
   DEB2(printk("iic_ibmocp_handler: status = %x\n", ret));
   // Clear status register.  See IBM PPC 405 reference manual for details
   writeb(0x0a, (int) &(iic->sts));
   wake_up_interruptible(&(iic_wait[priv_data->index]));
}
示例#8
0
static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf,
			 int count, int last)
{
	struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
	int wrcount, status, timeout;

	for (wrcount=0; wrcount<count; ++wrcount) {
		DEB2(dev_dbg(&i2c_adap->dev, "i2c_write: writing %2.2X\n",
				buf[wrcount] & 0xff));
		i2c_outb(adap, buf[wrcount]);
		timeout = wait_for_pin(adap, &status);
		if (timeout) {
			if (timeout == -EINTR)
				return -EINTR; /* arbitration lost */

			i2c_stop(adap);
			dev_err(&i2c_adap->dev, "i2c_write: error - timeout.\n");
			return -EREMOTEIO; /* got a better one ?? */
		}
		if (status & I2C_PCF_LRB) {
			i2c_stop(adap);
			dev_err(&i2c_adap->dev, "i2c_write: error - no ack.\n");
			return -EREMOTEIO; /* got a better one ?? */
		}
	}
	if (last)
		i2c_stop(adap);
	else
		i2c_repstart(adap);

	return wrcount;
}
示例#9
0
static void iic_avalanche_handler(int this_irq, void *dev_id, struct pt_regs *regs)
{

   iic_pending = 1;

   DEB2(printk("iic_avalanche_handler: in interrupt handler\n"));
   wake_up_interruptible(&iic_wait);
}
static void pca_stop(struct i2c_algo_pca_data *adap)
{
	int sta = pca_get_con(adap);
	DEB2("=== STOP\n");
	sta |= I2C_PCA_CON_STO;
	sta &= ~(I2C_PCA_CON_STA|I2C_PCA_CON_SI);
	pca_set_con(adap, sta);
}
static int pca_repeated_start(struct i2c_algo_pca_data *adap)
{
	int sta = pca_get_con(adap);
	DEB2("=== REPEATED START\n");
	sta |= I2C_PCA_CON_STA;
	sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_SI);
	pca_set_con(adap, sta);
	return pca_wait(adap);
}
示例#12
0
/*
 * Generate a start condition on the i2c bus.
 *
 * returns after the start condition has occured
 */
static void pca_start(struct i2c_algo_pca_data *adap)
{
	int sta = pca_get_con(adap);
	DEB2("=== START\n");
	sta |= I2C_PCA_CON_STA;
	sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_SI);
	pca_set_con(adap, sta);
	pca_wait(adap);
}
static int pca_tx_byte(struct i2c_algo_pca_data *adap,
		       __u8 b)
{
	int sta = pca_get_con(adap);
	DEB2("=== WRITE %#04x\n", b);
	pca_outw(adap, I2C_PCA_DAT, b);

	sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI);
	pca_set_con(adap, sta);

	return pca_wait(adap);
}
示例#14
0
/*
 * Description: This performs the IBM PPC 405 IIC initialization sequence
 * as described in the PPC405GP data book.
 */
static int
iic_init(struct i2c_adapter *adap)
{
	struct iic_regs *iic;
	unsigned short retval;

	iic = (struct iic_regs *) ((struct ocp_dev *) adap->data)->vaddr;

	/* Clear master low master address */
	iic_outb(iic->lmadr, 0);

	/* Clear high master address */
	iic_outb(iic->hmadr, 0);

	/* Clear low slave address */
	iic_outb(iic->lsadr, 0);

	/* Clear high slave address */
	iic_outb(iic->hsadr, 0);

	/* Clear status */
	iic_outb(iic->sts, 0x0a);

	/* Clear extended status */
	iic_outb(iic->extsts, 0x8f);

	/* Set clock division */
	iic_outb(iic->clkdiv, 0x04);

	retval = iic_inb(iic->clkdiv);
	DEB(printk("iic_init: CLKDIV register = %x\n", retval));

	/* Enable interrupts on Requested Master Transfer Complete */
	iic_outb(iic->intmsk, 0x01);

	/* Clear transfer count */
	iic_outb(iic->xfrcnt, 0x0);

	/* Clear extended control and status */
	iic_outb(iic->xtcntlss, 0xf0);

	/* Set mode control (flush master data buf, enable hold SCL, exit */
	/* unknown state.                                                 */
	iic_outb(iic->mdcntl, 0x47);

	/* Clear control register */
	iic_outb(iic->cntl, 0x0);

	DEB2(printk(KERN_DEBUG "iic_init: Initialized IIC on PPC 405\n"));
	return 0;
}
示例#15
0
static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) {

    int timeout = DEF_TIMEOUT;

    *status = get_pcf(adap, 1);
#ifndef STUB_I2C
    while (timeout-- && (*status & I2C_PCF_PIN)) {
        adap->waitforpin();
        *status = get_pcf(adap, 1);
    }
    if (*status & I2C_PCF_LAB) {
        DEB2(printk(KERN_INFO 
            "i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n",
             *status));
        /* Cleanup from LAB-- reset and enable ESO.
         * This resets the PCF8584; since we've lost the bus, no
         * further attempts should be made by callers to clean up 
         * (no i2c_stop() etc.)
         */
        set_pcf(adap, 1, I2C_PCF_PIN);
        set_pcf(adap, 1, I2C_PCF_ESO);
        /* TODO: we should pause for a time period sufficient for any
         * running I2C transaction to complete-- the arbitration
         * logic won't work properly until the next START is seen.
         */
        DEB2(printk(KERN_INFO 
            "i2c-algo-pcf.o: reset LAB condition (CSR 0x%02x)\n", 
            get_pcf(adap,1)));
        return(-EINTR);
    }
#endif
    if (timeout <= 0)
        return(-1);
    else
        return(0);
}
示例#16
0
/*
 * registering functions to load algorithms at runtime
 */
int i2c_pcf_add_bus(struct i2c_adapter *adap)
{
	struct i2c_algo_pcf_data *pcf_adap = adap->algo_data;
	int rval;

	DEB2(dev_dbg(&adap->dev, "hw routines registered.\n"));

	/* register new adapter to i2c module... */
	adap->algo = &pcf_algo;

	if ((rval = pcf_init_8584(pcf_adap)))
		return rval;

	rval = i2c_add_adapter(adap);

	return rval;
}
示例#17
0
/*
 * Description: Whenever we initiate a transaction, the first byte clocked
 * onto the bus after the start condition is the address (7 bit) of the
 * device we want to talk to.  This function manipulates the address specified
 * so that it makes sense to the hardware when written to the IIC peripheral.
 *
 * Note: 10 bit addresses are not supported in this driver, although they are
 * supported by the hardware.  This functionality needs to be implemented.
 */
static inline int
iic_doAddress(struct i2c_adapter *adap, struct i2c_msg *msg, int retries)
{
	struct iic_regs *iic;
	unsigned short flags = msg->flags;
	unsigned char addr;

	iic = (struct iic_regs *) IIC_DEV(vaddr);

/*
 * The following segment for 10 bit addresses needs to be ported
 */
#if 0
	/* Ten bit addresses not supported right now */
	if ((flags & I2C_M_TEN)) {
		/* a ten bit address */
		addr = 0xf0 | ((msg->addr >> 7) & 0x03);
		DEB2(printk(KERN_DEBUG "addr0: %d\n", addr));
		/* try extended address code... */
		ret = try_address(adap, addr, retries);
		if (ret != 1) {
			printk(KERN_ERR
			       "iic_doAddress: died at extended address code.\n");
			return -EREMOTEIO;
		}
		/* the remaining 8 bit address */
		iic_outb(msg->addr & 0x7f);
		/* Status check comes here */
		if (ret != 1) {
			printk(KERN_ERR
			       "iic_doAddress: died at 2nd address code.\n");
			return -EREMOTEIO;
		}
		if (flags & I2C_M_RD) {
			i2c_repstart(adap);
			/* okay, now switch into reading mode */
			addr |= 0x01;
			ret = try_address(adap, addr, retries);
			if (ret != 1) {
				printk(KERN_ERR
				       "iic_doAddress: died at extended address code.\n");
				return -EREMOTEIO;
			}
		}
	} else
static int pca_address(struct i2c_algo_pca_data *adap,
		       struct i2c_msg *msg)
{
	int sta = pca_get_con(adap);
	int addr;

	addr = ((0x7f & msg->addr) << 1);
	if (msg->flags & I2C_M_RD)
		addr |= 1;
	DEB2("=== SLAVE ADDRESS %#04x+%c=%#04x\n",
	     msg->addr, msg->flags & I2C_M_RD ? 'R' : 'W', addr);

	pca_outw(adap, I2C_PCA_DAT, addr);

	sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI);
	pca_set_con(adap, sta);

	return pca_wait(adap);
}
示例#19
0
/*
 * Description:  This function implements combined transactions.  Combined
 * transactions consist of combinations of reading and writing blocks of data.
 * Each transfer (i.e. a read or a write) is separated by a repeated start
 * condition.
 */
static int
iic_combined_transaction(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[],
			 int num)
{
	int i;
	struct i2c_msg *pmsg;
	int ret;

	DEB2(printk(KERN_DEBUG "Beginning combined transaction\n"));
	for (i = 0; i < num; i++) {
		pmsg = &msgs[i];
		if (pmsg->flags & I2C_M_RD) {

			/* Last read or write segment needs to be terminated with a stop */
			if (i < num - 1) {
				DEB2(printk(KERN_DEBUG "This one is a read\n"));
			} else {
				DEB2(printk
				     (KERN_DEBUG "Doing the last read\n"));
			}
			ret =
			    iic_readbytes(i2c_adap, pmsg->buf, pmsg->len,
					  (i <
					   num -
					   1) ? IIC_COMBINED_XFER :
					  IIC_SINGLE_XFER);

			if (ret != pmsg->len) {
				DEB2(printk("i2c-algo-ppc405.o: fail: "
					    "only read %d bytes.\n", ret));
				return i;
			} else {
				DEB2(printk
				     ("i2c-algo-ppc405.o: read %d bytes.\n",
				      ret));
			}
		} else if (!(pmsg->flags & I2C_M_RD)) {

			/* Last read or write segment needs to be terminated with a stop */
			if (i < num - 1) {
				DEB2(printk
				     (KERN_DEBUG "This one is a write\n"));
			} else {
				DEB2(printk
				     (KERN_DEBUG "Doing the last write\n"));
			}
			ret =
			    iic_sendbytes(i2c_adap, pmsg->buf, pmsg->len,
					  (i <
					   num -
					   1) ? IIC_COMBINED_XFER :
					  IIC_SINGLE_XFER);

			if (ret != pmsg->len) {
				DEB2(printk("i2c-algo-ppc405.o: fail: "
					    "only wrote %d bytes.\n", ret));
				return i;
			} else {
				DEB2(printk
				     ("i2c-algo-ppc405.o: wrote %d bytes.\n",
				      ret));
			}
		}
	}

	return num;
}
示例#20
0
文件: i2c-core.c 项目: cilynx/dd-wrt
int i2c_del_driver(struct i2c_driver *driver)
{
	int i,j,k,res;

	DRV_LOCK();
	for (i = 0; i < I2C_DRIVER_MAX; i++)
		if (driver == drivers[i])
			break;
	if (I2C_DRIVER_MAX == i) {
		printk(KERN_WARNING " i2c-core.o: unregister_driver: "
				    "[%s] not found\n",
			driver->name);
		DRV_UNLOCK();
		return -ENODEV;
	}
	/* Have a look at each adapter, if clients of this driver are still
	 * attached. If so, detach them to be able to kill the driver 
	 * afterwards.
	 */
	DEB2(printk(KERN_DEBUG "i2c-core.o: unregister_driver - looking for clients.\n"));
	/* removing clients does not depend on the notify flag, else 
	 * invalid operation might (will!) result, when using stale client
	 * pointers.
	 */
	ADAP_LOCK(); /* should be moved inside the if statement... */
	for (k=0;k<I2C_ADAP_MAX;k++) {
		struct i2c_adapter *adap = adapters[k];
		if (adap == NULL) /* skip empty entries. */
			continue;
		DEB2(printk(KERN_DEBUG "i2c-core.o: examining adapter %s:\n",
			    adap->name));
		if (driver->flags & I2C_DF_DUMMY) {
		/* DUMMY drivers do not register their clients, so we have to
		 * use a trick here: we call driver->attach_adapter to
		 * *detach* it! Of course, each dummy driver should know about
		 * this or hell will break loose...  
		 */
			if ((res = driver->attach_adapter(adap))) {
				printk(KERN_WARNING "i2c-core.o: while unregistering "
				       "dummy driver %s, adapter %s could "
				       "not be detached properly; driver "
				       "not unloaded!\n", driver->name,
				       adap->name);
				ADAP_UNLOCK();
				return res;
			}
		} else {
			for (j=0;j<I2C_CLIENT_MAX;j++) { 
				struct i2c_client *client = adap->clients[j];
				if (client != NULL && 
				    client->driver == driver) {
					DEB2(printk(KERN_DEBUG "i2c-core.o: "
						    "detaching client %s:\n",
					            client->name));
					if ((res = driver->
							detach_client(client)))
					{
						printk(KERN_ERR "i2c-core.o: while "
						       "unregistering driver "
						       "`%s', the client at "
						       "address %02x of "
						       "adapter `%s' could not "
						       "be detached; driver "
						       "not unloaded!\n",
						       driver->name,
						       client->addr,
						       adap->name);
						ADAP_UNLOCK();
						return res;
					}
				}
			}
		}
	}
	ADAP_UNLOCK();
	drivers[i] = NULL;
	driver_count--;
	DRV_UNLOCK();
	
	DEB(printk(KERN_DEBUG "i2c-core.o: driver unregistered: %s\n",driver->name));
	return 0;
}
示例#21
0
static int
iic_sendbytes(struct i2c_adapter *adap, const char *buf,
	      int count, int xfer_flag)
{
	struct iic_regs *iic;
	int wrcount, status, timeout;
	int loops, remainder, i, j;
	int ret, error_code;

	iic = (struct iic_regs *) IIC_DEV(vaddr);

	if (count == 0)
		return 0;
	wrcount = 0;
	loops = count / 4;
	remainder = count % 4;

	if ((loops > 1) && (remainder == 0)) {
		for (i = 0; i < (loops - 1); i++) {

			/* Write four bytes to master data buffer */

			for (j = 0; j < 4; j++) {
				iic_outb(iic->mdbuf, buf[wrcount++]);
			}

			/* Issue command to IICO device to begin transmission */

			iic_outb(iic->cntl, 0x35);

			/*    Wait for transmission to complete.  When it does,  
			 *    loop to the top of the for statement and write the  
			 *    next four bytes. 
			 */

			timeout = wait_for_pin(adap, &status);
			if (timeout < 0) {

				/* Error handling */

				return wrcount;
			}
			ret = analyze_status(adap, &error_code);
			if (ret < 0) {
				if (error_code == IIC_ERR_INCOMPLETE_XFR) {
					/* Return the number of bytes transferred */
					ret = iic_inb(iic->xfrcnt);
					ret = ret & 0x07;
					return (wrcount - 4 + ret);
				} else
					return error_code;
			}
		}
	} else if ((loops >= 1) && (remainder > 0)) {
		/*printk(KERN_DEBUG "iic_sendbytes: (loops >= 1)\n"); */
		for (i = 0; i < loops; i++) {
			/*
			 * Write four bytes to master data buffer
			 */
			for (j = 0; j < 4; j++) {
				iic_outb(iic->mdbuf, buf[wrcount++]);
			}
			/*
			 * Issue command to IICO device to begin transmission
			 */
			iic_outb(iic->cntl, 0x35);
			/*
			 * Wait for transmission to complete.  When it does,
			 * loop to the top of the for statement and write the
			 * next four bytes.
			 */
			timeout = wait_for_pin(adap, &status);
			if (timeout < 0)
				return wrcount;

			ret = analyze_status(adap, &error_code);
			if (ret < 0) {
				if (error_code == IIC_ERR_INCOMPLETE_XFR) {
					/* Return the number of bytes transferred */
					ret = iic_inb(iic->xfrcnt);
					ret = ret & 0x07;
					return (wrcount - 4 + ret);
				} else
					return error_code;
			}
		}
	}

	if (remainder == 0)
		remainder = 4;
	/* Write the remaining bytes (less than or equal to 4) */

	for (i = 0; i < remainder; i++)
		iic_outb(iic->mdbuf, buf[wrcount++]);

	if (xfer_flag == IIC_COMBINED_XFER) {
		iic_outb(iic->cntl, (0x09 | ((remainder - 1) << 4)));
	} else {
		iic_outb(iic->cntl, (0x01 | ((remainder - 1) << 4)));
	}
	DEB2(printk(KERN_DEBUG "iic_sendbytes: Waiting for interrupt\n"));
	timeout = wait_for_pin(adap, &status);
	if (timeout < 0)
		return wrcount;
	ret = analyze_status(adap, &error_code);
	if (ret < 0) {
		if (error_code == IIC_ERR_INCOMPLETE_XFR) {
			/* Return the number of bytes transferred */
			ret = iic_inb(iic->xfrcnt);
			ret = ret & 0x07;
			return (wrcount - 4 + ret);
		} else
			return error_code;
	}
	DEB2(printk(KERN_DEBUG "iic_sendbytes: Got interrupt\n"));
	return wrcount;
}
示例#22
0
/*
 * Description: Called by the upper layers to do the grunt work for
 * a master read transaction.
 */
static int
iic_readbytes(struct i2c_adapter *adap, char *buf, int count, int xfer_type)
{
	struct iic_regs *iic;
	int rdcount = 0, i, status, timeout;
	int loops, remainder, j;
	int ret, error_code;

	iic = (struct iic_regs *) IIC_DEV(vaddr);

	if (count == 0)
		return 0;
	loops = count / 4;
	remainder = count % 4;

	if ((loops > 1) && (remainder == 0)) {
		for (i = 0; i < (loops - 1); i++) {
			/* Issue command to begin master read (4 bytes maximum) */
			iic_outb(iic->cntl, 0x37);
			/*
			 * Wait for transmission to complete.  When it does,
			 * loop to the top of the for statement and write the
			 * next four bytes.
			 */
			timeout = wait_for_pin(adap, &status);
			if (timeout < 0)
				return rdcount;

			ret = analyze_status(adap, &error_code);
			if (ret < 0) {
				if (error_code == IIC_ERR_INCOMPLETE_XFR)
					return rdcount;
				else
					return error_code;
			}

			for (j = 0; j < 4; j++) {
				/* Wait for data to shuffle to top of data buffer
				 * This value needs to optimized.
				 */
				udelay(1);
				buf[rdcount] = iic_inb(iic->mdbuf);
				rdcount++;
			}
		}
	}

	else if ((loops >= 1) && (remainder > 0)) {
		for (i = 0; i < loops; i++) {
			/* Issue command to begin master read (4 bytes maximum) */
			iic_outb(iic->cntl, 0x37);
			/*
			 * Wait for transmission to complete.  When it does,
			 * loop to the top of the for statement and write the
			 * next four bytes.
			 */
			timeout = wait_for_pin(adap, &status);
			if (timeout < 0)
				return rdcount;

			ret = analyze_status(adap, &error_code);
			if (ret < 0) {
				if (error_code == IIC_ERR_INCOMPLETE_XFR)
					return rdcount;
				else
					return error_code;
			}

			for (j = 0; j < 4; j++) {
				/* Wait for data to shuffle to top of data buffer
				 * This value needs to optimized.
				 */
				udelay(1);
				buf[rdcount] = iic_inb(iic->mdbuf);
				rdcount++;
			}
		}
	}

	if (remainder == 0)
		remainder = 4;
	DEB2(printk
	     (KERN_DEBUG "iic_readbytes: writing %x to IICO_CNTL\n",
	      (0x03 | ((remainder - 1) << 4))));

	if (xfer_type == IIC_COMBINED_XFER) {
		iic_outb(iic->cntl, (0x0b | ((remainder - 1) << 4)));
	} else {
		iic_outb(iic->cntl, (0x03 | ((remainder - 1) << 4)));
	}
	DEB2(printk(KERN_DEBUG "iic_readbytes: Wait for pin\n"));
	timeout = wait_for_pin(adap, &status);
	DEB2(printk(KERN_DEBUG "iic_readbytes: Got the interrupt\n"));
	if (timeout < 0)
		return rdcount;

	ret = analyze_status(adap, &error_code);
	if (ret < 0) {
		if (error_code == IIC_ERR_INCOMPLETE_XFR)
			return rdcount;
		else
			return error_code;
	}

	for (i = 0; i < remainder; i++) {
		buf[rdcount] = iic_inb(iic->mdbuf);
		rdcount++;
	}

	return rdcount;
}
示例#23
0
static int pca_xfer(struct i2c_adapter *i2c_adap,
                    struct i2c_msg msgs[],
                    int num)
{
        struct i2c_algo_pca_data *adap = i2c_adap->algo_data;
        struct i2c_msg *msg = NULL;
        int curmsg;
	int numbytes = 0;
	int state;

	state = pca_status(adap);
	if ( state != 0xF8 ) {
		printk(KERN_ERR DRIVER ": bus is not idle. status is %#04x\n", state );
		/* FIXME: what to do. Force stop ? */
		return -EREMOTEIO;
	}

	DEB1("{{{ XFER %d messages\n", num);

	if (i2c_debug>=2) {
		for (curmsg = 0; curmsg < num; curmsg++) {
			int addr, i;
			msg = &msgs[curmsg];
			
			addr = (0x7f & msg->addr) ;
		
			if (msg->flags & I2C_M_RD )
				printk(KERN_INFO "    [%02d] RD %d bytes from %#02x [%#02x, ...]\n", 
				       curmsg, msg->len, addr, (addr<<1) | 1);
			else {
				printk(KERN_INFO "    [%02d] WR %d bytes to %#02x [%#02x%s", 
				       curmsg, msg->len, addr, addr<<1,
				       msg->len == 0 ? "" : ", ");
				for(i=0; i < msg->len; i++)
					printk("%#04x%s", msg->buf[i], i == msg->len - 1 ? "" : ", ");
				printk("]\n");
			}
		}
	}

	curmsg = 0;
	while (curmsg < num) {
		state = pca_status(adap);

		DEB3("STATE is 0x%02x\n", state);
		msg = &msgs[curmsg];

		switch (state) {
		case 0xf8: /* On reset or stop the bus is idle */
			pca_start(adap);
			break;

		case 0x08: /* A START condition has been transmitted */
		case 0x10: /* A repeated start condition has been transmitted */
			pca_address(adap, msg);
			break;
			
		case 0x18: /* SLA+W has been transmitted; ACK has been received */
		case 0x28: /* Data byte in I2CDAT has been transmitted; ACK has been received */
			if (numbytes < msg->len) {
				pca_tx_byte(adap, msg->buf[numbytes]);
				numbytes++;
				break;
			}
			curmsg++; numbytes = 0;
			if (curmsg == num)
				pca_stop(adap);
			else
				pca_repeated_start(adap);
			break;

		case 0x20: /* SLA+W has been transmitted; NOT ACK has been received */
			DEB2("NOT ACK received after SLA+W\n");
			pca_stop(adap);
			return -EREMOTEIO;

		case 0x40: /* SLA+R has been transmitted; ACK has been received */
			pca_rx_ack(adap, msg->len > 1);
			break;

		case 0x50: /* Data bytes has been received; ACK has been returned */
			if (numbytes < msg->len) {
				pca_rx_byte(adap, &msg->buf[numbytes], 1);
				numbytes++;
				pca_rx_ack(adap, numbytes < msg->len - 1);
				break;
			} 
			curmsg++; numbytes = 0;
			if (curmsg == num)
				pca_stop(adap);
			else
				pca_repeated_start(adap);
			break;

		case 0x48: /* SLA+R has been transmitted; NOT ACK has been received */
			DEB2("NOT ACK received after SLA+R\n");
			pca_stop(adap);
			return -EREMOTEIO;

		case 0x30: /* Data byte in I2CDAT has been transmitted; NOT ACK has been received */
			DEB2("NOT ACK received after data byte\n");
			return -EREMOTEIO;

		case 0x38: /* Arbitration lost during SLA+W, SLA+R or data bytes */
			DEB2("Arbitration lost\n");
			return -EREMOTEIO;
			
		case 0x58: /* Data byte has been received; NOT ACK has been returned */
			if ( numbytes == msg->len - 1 ) {
				pca_rx_byte(adap, &msg->buf[numbytes], 0);
				curmsg++; numbytes = 0;
				if (curmsg == num)
					pca_stop(adap);
				else
					pca_repeated_start(adap);
			} else {
				DEB2("NOT ACK sent after data byte received. "
				     "Not final byte. numbytes %d. len %d\n",
				     numbytes, msg->len);
				pca_stop(adap);
				return -EREMOTEIO;
			}
			break;
		case 0x70: /* Bus error - SDA stuck low */
			DEB2("BUS ERROR - SDA Stuck low\n");
			pca_reset(adap);
			return -EREMOTEIO;
		case 0x90: /* Bus error - SCL stuck low */
			DEB2("BUS ERROR - SCL Stuck low\n");
			pca_reset(adap);
			return -EREMOTEIO;
		case 0x00: /* Bus error during master or slave mode due to illegal START or STOP condition */
			DEB2("BUS ERROR - Illegal START or STOP\n");
			pca_reset(adap);
			return -EREMOTEIO;
		default:
			printk(KERN_ERR DRIVER ": unhandled SIO state 0x%02x\n", state);
			break;
		}
		
	}

	DEB1(KERN_CRIT "}}} transfered %d messages. "
	     "status is %#04x. control is %#04x\n", 
	     num, pca_status(adap),
	     pca_get_con(adap));
	return curmsg;
}
static int pca_xfer(struct i2c_adapter *i2c_adap,
		    struct i2c_msg *msgs,
		    int num)
{
	struct i2c_algo_pca_data *adap = i2c_adap->algo_data;
	struct i2c_msg *msg = NULL;
	int curmsg;
	int numbytes = 0;
	int state;
	int ret;
	int completed = 1;
	unsigned long timeout = jiffies + i2c_adap->timeout;

	while ((state = pca_status(adap)) != 0xf8) {
		if (time_before(jiffies, timeout)) {
			msleep(10);
		} else {
			dev_dbg(&i2c_adap->dev, "bus is not idle. status is "
				"%#04x\n", state);
			return -EAGAIN;
		}
	}

	DEB1("{{{ XFER %d messages\n", num);

	if (i2c_debug >= 2) {
		for (curmsg = 0; curmsg < num; curmsg++) {
			int addr, i;
			msg = &msgs[curmsg];

			addr = (0x7f & msg->addr) ;

			if (msg->flags & I2C_M_RD)
				printk(KERN_INFO "    [%02d] RD %d bytes from %#02x [%#02x, ...]\n",
				       curmsg, msg->len, addr, (addr << 1) | 1);
			else {
				printk(KERN_INFO "    [%02d] WR %d bytes to %#02x [%#02x%s",
				       curmsg, msg->len, addr, addr << 1,
				       msg->len == 0 ? "" : ", ");
				for (i = 0; i < msg->len; i++)
					printk("%#04x%s", msg->buf[i], i == msg->len - 1 ? "" : ", ");
				printk("]\n");
			}
		}
	}

	curmsg = 0;
	ret = -EREMOTEIO;
	while (curmsg < num) {
		state = pca_status(adap);

		DEB3("STATE is 0x%02x\n", state);
		msg = &msgs[curmsg];

		switch (state) {
		case 0xf8: /* On reset or stop the bus is idle */
			completed = pca_start(adap);
			break;

		case 0x08: /* A START condition has been transmitted */
		case 0x10: /* A repeated start condition has been transmitted */
			completed = pca_address(adap, msg);
			break;

		case 0x18: /* SLA+W has been transmitted; ACK has been received */
		case 0x28: /* Data byte in I2CDAT has been transmitted; ACK has been received */
			if (numbytes < msg->len) {
				completed = pca_tx_byte(adap,
							msg->buf[numbytes]);
				numbytes++;
				break;
			}
			curmsg++; numbytes = 0;
			if (curmsg == num)
				pca_stop(adap);
			else
				completed = pca_repeated_start(adap);
			break;

		case 0x20: /* SLA+W has been transmitted; NOT ACK has been received */
			DEB2("NOT ACK received after SLA+W\n");
			pca_stop(adap);
			goto out;

		case 0x40: /* SLA+R has been transmitted; ACK has been received */
			completed = pca_rx_ack(adap, msg->len > 1);
			break;

		case 0x50: /* Data bytes has been received; ACK has been returned */
			if (numbytes < msg->len) {
				pca_rx_byte(adap, &msg->buf[numbytes], 1);
				numbytes++;
				completed = pca_rx_ack(adap,
						       numbytes < msg->len - 1);
				break;
			}
			curmsg++; numbytes = 0;
			if (curmsg == num)
				pca_stop(adap);
			else
				completed = pca_repeated_start(adap);
			break;

		case 0x48: /* SLA+R has been transmitted; NOT ACK has been received */
			DEB2("NOT ACK received after SLA+R\n");
			pca_stop(adap);
			goto out;

		case 0x30: /* Data byte in I2CDAT has been transmitted; NOT ACK has been received */
			DEB2("NOT ACK received after data byte\n");
			pca_stop(adap);
			goto out;

		case 0x38: /* Arbitration lost during SLA+W, SLA+R or data bytes */
			DEB2("Arbitration lost\n");
			/*
			 * The PCA9564 data sheet (2006-09-01) says "A
			 * START condition will be transmitted when the
			 * bus becomes free (STOP or SCL and SDA high)"
			 * when the STA bit is set (p. 11).
			 *
			 * In case this won't work, try pca_reset()
			 * instead.
			 */
			pca_start(adap);
			goto out;

		case 0x58: /* Data byte has been received; NOT ACK has been returned */
			if (numbytes == msg->len - 1) {
				pca_rx_byte(adap, &msg->buf[numbytes], 0);
				curmsg++; numbytes = 0;
				if (curmsg == num)
					pca_stop(adap);
				else
					completed = pca_repeated_start(adap);
			} else {
				DEB2("NOT ACK sent after data byte received. "
				     "Not final byte. numbytes %d. len %d\n",
				     numbytes, msg->len);
				pca_stop(adap);
				goto out;
			}
			break;
		case 0x70: /* Bus error - SDA stuck low */
			DEB2("BUS ERROR - SDA Stuck low\n");
			pca_reset(adap);
			goto out;
		case 0x90: /* Bus error - SCL stuck low */
			DEB2("BUS ERROR - SCL Stuck low\n");
			pca_reset(adap);
			goto out;
		case 0x00: /* Bus error during master or slave mode due to illegal START or STOP condition */
			DEB2("BUS ERROR - Illegal START or STOP\n");
			pca_reset(adap);
			goto out;
		default:
			dev_err(&i2c_adap->dev, "unhandled SIO state 0x%02x\n", state);
			break;
		}

		if (!completed)
			goto out;
	}

	ret = curmsg;
 out:
	DEB1("}}} transfered %d/%d messages. "
	     "status is %#04x. control is %#04x\n",
	     curmsg, num, pca_status(adap),
	     pca_get_con(adap));
	return ret;
}
static void pca_rx_byte(struct i2c_algo_pca_data *adap,
			__u8 *b, int ack)
{
	*b = pca_inw(adap, I2C_PCA_DAT);
	DEB2("=== READ %#04x %s\n", *b, ack ? "ACK" : "NACK");
}
static int octeon_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int combined)
{
    uint64_t data = 0;
    int i;
    int timeout = 0;
    octeon_mio_tws_sw_twsi_t temp, mio_tws_sw_twsi;
    octeon_mio_tws_sw_twsi_ext_t mio_tws_sw_twsi_ext;

    DEB2("addr: 0x%04x, len: %d, flags: 0x%x, buf[0] = %x\n", msg->addr, msg->len, msg->flags, msg->buf[0]);


    mio_tws_sw_twsi.u64 = 0x0;

    mio_tws_sw_twsi.s.v = 1;

    //ten bit address op<1> = 1
    if( msg->flags & I2C_M_TEN) mio_tws_sw_twsi.s.op |= 0x2;
    mio_tws_sw_twsi.s.a = msg->addr & 0x3ff;

    // check the msg->len  0<=len <8
    if( msg->len > 8 ){
	printk("%s %d Error len msg->len %d\n", __FILE__, __LINE__, msg->len);
	return (-1);
    }
    mio_tws_sw_twsi.s.sovr = 1;			// size override.
    if ( msg->len == 0 )	
       mio_tws_sw_twsi.s.size = 0;
    else
       mio_tws_sw_twsi.s.size = msg->len-1;	// Size: 0 = 1 byte, 1 = 2 bytes, ..., 7 = 8 bytes

    if( msg->flags & I2C_M_RD ){
	mio_tws_sw_twsi.s.r = 1;		// Enable Read bit 
    }else{	
	for(i =0; i <= mio_tws_sw_twsi.s.size; i++){
	    data = data << 8;	
	    data |= msg->buf[i];
	}

	mio_tws_sw_twsi.s.d = data;
	mio_tws_sw_twsi_ext.s.d = data >> 32;	
    }
	
#ifdef I2C_OCTEON_DEBUG
    if ( mio_tws_sw_twsi.s.r == 1 )
	printk("twsi-read  op: data=%llx %llx len=%d\n", mio_tws_sw_twsi.u64, mio_tws_sw_twsi_ext.u64, msg->len);
    else
        printk("twsi-write op: data=%llx %llx len=%d\n", mio_tws_sw_twsi.u64, mio_tws_sw_twsi_ext.u64, msg->len);
#endif

    octeon_write_csr(OCTEON_MIO_TWS_SW_TWSI_EXT, mio_tws_sw_twsi_ext.u64);
    octeon_write_csr(OCTEON_MIO_TWS_SW_TWSI, mio_tws_sw_twsi.u64);


    //Poll! wait the transfer complete and timeout (10ms).
    do{
	temp.u64 = octeon_read_csr(OCTEON_MIO_TWS_SW_TWSI);	
	udelay(1);
    }while (temp.s.v && (timeout++ < I2C_MAX_TIMEOUT));

    mio_tws_sw_twsi.u64 = octeon_read_csr(OCTEON_MIO_TWS_SW_TWSI);

    if (timeout >= I2C_MAX_TIMEOUT) {
	printk("Octeon twsi I2C Timeout!\n");
	octeon_i2c_reset();
	return -EIO;
    }

    //transfer ERROR
    if (!mio_tws_sw_twsi.s.r){
	octeon_i2c_reset();
	return -EIO;
    }

    if (msg->flags & I2C_M_RD){

	mio_tws_sw_twsi_ext.u64 = octeon_read_csr(OCTEON_MIO_TWS_SW_TWSI_EXT);
	data = ((uint64_t) mio_tws_sw_twsi_ext.s.d << 32) | mio_tws_sw_twsi.s.d;
	
#ifdef I2C_OCTEON_DEBUG
	printk("twsi-read result: data=%llx %llx len=%d\n", mio_tws_sw_twsi.u64, mio_tws_sw_twsi_ext.u64, msg->len);
#endif

	for(i = mio_tws_sw_twsi.s.size; i >= 0; i--){
		msg->buf[i] = data;
		data = data >> 8; 
	}	
    }