/*
 * Raise scl line, and do checking for delays. This is necessary for slower
 * devices.
 */
static int sclhi(struct i2c_algo_bit_data *adap)
{
	unsigned long start;

	setscl(adap, 1);

	/* Not all adapters have scl sense line... */
	if (!adap->getscl)
		goto done;

	start = jiffies;
	while (!getscl(adap)) {
		/* This hw knows how to read the clock line, so we wait
		 * until it actually gets high.  This is safer as some
		 * chips may hold it low ("clock stretching") while they
		 * are processing data internally.
		 */
<<<<<<< HEAD
		if (time_after(jiffies, start + adap->timeout)) {
			/* Test one last time, as we may have been preempted
			 * between last check and timeout test.
			 */
			if (getscl(adap))
				break;
			return -ETIMEDOUT;
		}
=======
		if (time_after(jiffies, start + adap->timeout))
Esempio n. 2
0
/* I2C receiving of bytes - does not send an offset byte */
int efx_i2c_recv_bytes(struct efx_i2c_interface *i2c, u8 device_id,
		       u8 *bytes, unsigned int len)
{
	int i;
	int rc;

	EFX_WARN_ON_PARANOID(getsda(i2c) != 1);
	EFX_WARN_ON_PARANOID(getscl(i2c) != 1);
	EFX_WARN_ON_PARANOID(len < 1);

	/* Select device */
	i2c_start(i2c);

	/* Read data from device */
	rc = i2c_send_byte(i2c, i2c_read_cmd(device_id));
	if (rc)
		goto out;

	for (i = 0; i < (len - 1); i++)
		/* Read and acknowledge all but the last byte */
		bytes[i] = i2c_recv_byte(i2c, 1);
	/* Read last byte with no acknowledgement */
	bytes[i] = i2c_recv_byte(i2c, 0);

 out:
	i2c_stop(i2c);
	i2c_release(i2c);

	return rc;
}
Esempio n. 3
0
/* This performs a fast write of one or more consecutive bytes to an
 * I2C device.  Not all devices support consecutive writes of more
 * than one byte; for these devices use efx_i2c_write() instead.
 */
int efx_i2c_fast_write(struct efx_i2c_interface *i2c,
		       u8 device_id, u8 offset,
		       const u8 *data, unsigned int len)
{
	int i;
	int rc;

	EFX_WARN_ON_PARANOID(getsda(i2c) != 1);
	EFX_WARN_ON_PARANOID(getscl(i2c) != 1);
	EFX_WARN_ON_PARANOID(len < 1);

	/* Select device and starting offset */
	i2c_start(i2c);
	rc = i2c_send_byte(i2c, i2c_write_cmd(device_id));
	if (rc)
		goto out;
	rc = i2c_send_byte(i2c, offset);
	if (rc)
		goto out;

	/* Write data to device */
	for (i = 0; i < len; i++) {
		rc = i2c_send_byte(i2c, data[i]);
		if (rc)
			goto out;
	}

 out:
	i2c_stop(i2c);
	i2c_release(i2c);

	return rc;
}
Esempio n. 4
0
static inline void i2c_release(struct efx_i2c_interface *i2c)
{
	EFX_WARN_ON_PARANOID(!i2c->scl);
	EFX_WARN_ON_PARANOID(!i2c->sda);
	/* Devices may time out if operations do not end */
	setscl(i2c, 1);
	setsda(i2c, 1);
	EFX_BUG_ON_PARANOID(getsda(i2c) != 1);
	EFX_BUG_ON_PARANOID(getscl(i2c) != 1);
}
Esempio n. 5
0
File: rtc.c Progetto: 7LK/McWRT
/*
 * We shouldn't simply set the SCL pin to high. Like SDA, the SCL line is
 * bidirectional too. According to the I2C spec, the slave is allowed to
 * pull down the SCL line to slow down the clock, so we need to check this.
 * Generally, we'd need a timeout here, but in our case, we just check the
 * line, assuming the RTC chip behaves well.
 */
static int sclhi(void)
{
	gpio_direction_input(scl_index);
	udelay(ADAP_DELAY);
	if (!getscl()) {
		printk(KERN_ERR "SCL pin should be low\n");
		return -ETIMEDOUT;
	}
	return 0;
}
Esempio n. 6
0
int efx_i2c_check_presence(struct efx_i2c_interface *i2c, u8 device_id)
{
	int rc;

	/* If someone is driving the bus low we just give up. */
	if (getsda(i2c) == 0 || getscl(i2c) == 0) {
		EFX_ERR(i2c->efx, "%s someone is holding the I2C bus low."
			" Giving up.\n", __func__);
		return -EFAULT;
	}

	/* Pretend to initiate a device write */
	i2c_start(i2c);
	rc = i2c_send_byte(i2c, i2c_write_cmd(device_id));
	if (rc)
		goto out;

 out:
	i2c_stop(i2c);
	i2c_release(i2c);

	return rc;
}
Esempio n. 7
0
/* initialize the length of axis and the number of tics */
void vp_axis_init (const sf_file in)
{
    float ftmp, num;
    bool want;
    char *stmp, *label, *unit;
    size_t len;
    struct Axis axis;

    if (!sf_getint ("axisfat",&axisfat)) axisfat=0;
    if (!sf_getint ("axiscol",&axiscol)) axiscol=7;
    if (!sf_getint ("labelfat",&labelfat)) labelfat=0;
    if (!sf_getfloat ("labelsz",&labelsz)) labelsz=8.;
    
    if ((NULL == (label=sf_getstring("label1"))) &&
	(NULL == (label=sf_histstring(in,"label1")))) {  
	axis1.label = blank;
    } else if ((NULL == (unit=sf_getstring("unit1"))) &&
	       (NULL == (unit=sf_histstring(in,"unit1")))) {
	axis1.label = label;
    } else {
	len = strlen(label)+strlen(unit)+4;
	axis1.label = sf_charalloc(len);
	snprintf(axis1.label,len,"%s (%s)",label,unit);
	free(label);
	free(unit);
    }

    if ((NULL == (label=sf_getstring("label2"))) &&
	(NULL == (label=sf_histstring(in,"label2")))) {
	axis2.label = blank;
    } else if ((NULL == (unit=sf_getstring("unit2"))) &&
	       (NULL == (unit=sf_histstring(in,"unit2")))) {
	axis2.label = label;           
    } else {
	len = strlen(label)+strlen(unit)+4;
	axis2.label = sf_charalloc(len);
	snprintf(axis2.label,len,"%s (%s)",label,unit);
	free(label);
	free(unit);
    }

    where1 = (NULL != (stmp = sf_getstring ("wherexlabel")) &&
	      'b' == *stmp);
    where2 = (NULL != (stmp = sf_getstring ("whereylabel")) &&
	      'r' == *stmp);
    
    /* checking to see if wantaxis is fetched */
    if (!sf_getbool ("wantaxis", &want)) {
	/* setting the default to put the axes on the plot */
        want = true;
	axis1.want = true;
	axis2.want = true;
    } else if (!want) {
	axis1.want = false;
	axis2.want = false;
    } else {
	if (!sf_getbool ("wantaxis1",&(axis1.want)))
	    axis1.want = true;
	if (!sf_getbool ("wantaxis2",&(axis2.want)))
	    axis2.want = true;
    }

    /* frame or axis */
    wheretics = NULL != (stmp = sf_getstring ("wheretics")) &&
	'a' == *stmp;

    if (!sf_getfloat ("axisor1",&(axis1.or)))
	axis1.or = where1? min2: max2;

    if (!sf_getfloat ("axisor2",&(axis2.or)))
	axis2.or = where2? min1: max1;

    if (!sf_getint ("n1tic",&(axis1.ntic))) axis1.ntic = 1;
    if (!sf_getint ("n2tic",&(axis2.ntic))) axis2.ntic = 1;

    if (!sf_getfloat ("d1num", &(axis1.dnum))) getscl (&axis1);
    if (!sf_getfloat ("d2num", &(axis2.dnum))) getscl (&axis2);

    if (0. == axis1.dnum) sf_error("%s: zero d1num",__FILE__);
    if (0. == axis2.dnum) sf_error("%s: zero d2num",__FILE__);

    if (!sf_getfloat("o1num",&(axis1.num0))) {
	ftmp = (min1 < max1)? min1: max1;
	for (num = floorf(ftmp / axis1.dnum) * axis1.dnum - axis1.dnum; 
	     num < ftmp; num += axis1.dnum) ;
	axis1.num0 = num;
    }

    if (!sf_getfloat("o2num",&(axis2.num0))) {
	ftmp = (min2 < max2)? min2: max2;
	for (num = floorf(ftmp / axis2.dnum) * axis2.dnum - axis2.dnum; 
	     num < ftmp; num += axis2.dnum) ;
	axis2.num0 = num;
    }

    axis1.dtic = axis1.dnum / axis1.ntic ;
    ftmp = (min1 < max1)? min1: max1;
    for (num = axis1.num0 - axis1.ntic * axis1.dtic;
	 num < ftmp; num += axis1.dtic);
    axis1.tic0 = num;

    axis2.dtic = axis2.dnum / axis2.ntic ;
    ftmp = (min2 < max2)? min2: max2;
    for (num = axis2.num0 - axis2.ntic * axis2.dtic;
	 num < ftmp; num += axis2.dtic);
    axis2.tic0 = num;

    if (transp) { /* swap */
	axis = axis1;
	axis1 = axis2;
	axis2 = axis;
    }
    
    if(yreverse) axis1.or = (min2+max2)-axis1.or;    
    if(xreverse) axis2.or = (min1+max1)-axis2.or;
}