Пример #1
0
int i2ctool_get(FAR struct i2ctool_s *i2ctool, FAR struct i2c_dev_s *dev,
                uint8_t regaddr, uint16_t *result)
{
  struct i2c_msg_s msg[2];
  union
  {
    uint16_t data16;
    uint8_t  data8;
  } u;
  int ret;

  /* Set up data structures */

  msg[0].addr   = i2ctool->addr;
  msg[0].flags  = 0;
  msg[0].buffer = &regaddr;
  msg[0].length = 1;

  msg[1].addr   = i2ctool->addr;
  msg[1].flags  = I2C_M_READ;
  if (i2ctool->width == 8)
    {
      msg[1].buffer = &u.data8;
      msg[1].length = 1;
    }
  else
    {
      msg[1].buffer = (uint8_t*)&u.data16;
      msg[1].length = 2;
    }

  if (i2ctool->start)
    {
      ret = I2C_TRANSFER(dev, &msg[0], 1);
      if (ret== OK)
        {
          ret = I2C_TRANSFER(dev, &msg[1], 1);
        }
    }
  else
    {
      ret = I2C_TRANSFER(dev, msg, 2);
    }

  /* Return the result of the read operation */

  if (ret == OK)
    {
      if (i2ctool->width == 8)
        {
          *result = (uint16_t)u.data8;
        }
      else
        {
          *result =  u.data16;
        }
    }
  return ret;
}
Пример #2
0
static int cs2100_read_ratio(FAR const struct cs2100_config_s *config,
                             uint32_t *ratio)
{
  struct i2c_msg_s msg;
  uint8_t buffer[4];
  int ret;

  DEBUGASSERT(config->i2c->ops && config->i2c->ops->transfer);

  /* Construct the I2C message (write N+1 bytes with no restart) */

  buffer[0]     = CS2100_RATIO0;

  msg.frequency = config->i2cfreq;
  msg.addr      = config->i2caddr;
  msg.flags     = 0;
  msg.buffer    = buffer;
  msg.length    = 1;

  /* Send the address followed by a STOP */

  ret = I2C_TRANSFER(config->i2c, &msg, 1);
  if (ret == OK)
    {
      msg.frequency = config->i2cfreq;
      msg.addr      = config->i2caddr;
      msg.flags     = I2C_M_READ;
      msg.buffer    = buffer;
      msg.length    = 4;

      /* Read the ratio registers beginning with another START */

      ret = I2C_TRANSFER(config->i2c, &msg, 1);

      /* Return the ratio */

      if (ret == OK)
        {
           *ratio = ((uint32_t)buffer[0] << 24) |
                    ((uint32_t)buffer[1] << 16) |
                    ((uint32_t)buffer[2] << 8) |
                     (uint32_t)buffer[0];

           regdbg("%02x->%04l\n", CS2100_RATIO0, (unsigned long)*ratio);
        }
    }

  return ret;
}
Пример #3
0
static int lps25h_do_transfer(FAR struct lps25h_dev_t *dev,
                              FAR struct i2c_msg_s *msgv,
                              size_t nmsg)
{
    int ret = -EIO;
    int retries;

    for (retries = 0; retries < LPS25H_I2C_RETRIES; retries++)
    {
        ret = I2C_TRANSFER(dev->i2c, msgv, nmsg);
        if (ret >= 0)
        {
            return 0;
        }
        else
        {
            /* Some error. Try to reset I2C bus and keep trying. */
#ifdef CONFIG_I2C_RESET
            ret = up_i2creset(dev->i2c);
            if (ret < 0)
            {
                lps25h_dbg("up_i2creset failed: %d\n", ret);
                return ret;
            }
#endif
            continue;
        }
    }

    lps25h_dbg("xfer failed: %d\n", ret);
    return ret;
}
Пример #4
0
int
I2C::transfer(i2c_msg_s *msgv, unsigned msgs)
{
	int ret;
	unsigned retry_count = 0;

	/* force the device address and Frequency into the message vector */
	for (unsigned i = 0; i < msgs; i++) {
		msgv[i].frequency = _bus_clocks[_bus - 1];
		msgv[i].addr = _address;
	}


	do {
		ret = I2C_TRANSFER(_dev, msgv, msgs);

		/* success */
		if (ret == OK) {
			break;
		}

		/* if we have already retried once, or we are going to give up, then reset the bus */
		if ((retry_count >= 1) || (retry_count >= _retries)) {
			I2C_RESET(_dev);
		}

	} while (retry_count++ < _retries);

	return ret;
}
Пример #5
0
static int cs2100_write_reg(FAR const struct cs2100_config_s *config,
                            uint8_t regaddr, uint8_t regval)
{
  struct i2c_msg_s msgs[2];

  regdbg("%02x<-%02x\n", regaddr, regval);
  DEBUGASSERT(config->i2c->ops && config->i2c->ops->transfer);

  /* Construct the I2C message (write N+1 bytes with no restart) */

  msga[0].frequency = config->i2cfreq;
  msgs[0].addr      = config->i2caddr;
  msgs[0].flags     = 0;
  msgs[0].buffer    = &regaddr;
  msgs[0].length    = 1;

  msga[1].frequency = config->i2cfreq;
  msgs[1].addr      = config->i2caddr;
  msgs[1].flags     = I2C_M_NORESTART;
  msgs[1].buffer    = &regval;
  msgs[1].length    = 1;

  /* Send the message */

  return I2C_TRANSFER(config->i2c, msgs, 2);
}
Пример #6
0
static int cs2100_write_ratio(FAR const struct cs2100_config_s *config,
                              uint32_t ratio)
{
  struct i2c_msg_s msg;
  uint8_t buffer[5];

  regdbg("%02x<-%04l\n", CS2100_RATIO0, (unsigned long)ratio);
  DEBUGASSERT(config->i2c->ops && config->i2c->ops->transfer);

  /* Construct the I2C message (write N+1 bytes with no restart) */

  buffer[0]  = CS2100_RATIO0;
  buffer[1]  = (uint8_t)(ratio >> 24);
  buffer[2]  = (uint8_t)((ratio >> 16) & 0xff);
  buffer[3]  = (uint8_t)((ratio >> 8) & 0xff);
  buffer[4]  = (uint8_t)(ratio  & 0xff);

  msg.addr   = config->i2caddr;
  msg.flags  = 0;
  msg.buffer = buffer;
  msg.length = 5;

  /* Send the message */

  return I2C_TRANSFER(config->i2c, &msg, 1);
}
Пример #7
0
int
I2C::transfer(i2c_msg_s *msgv, unsigned msgs)
{
	int ret;
	unsigned retry_count = 0;

	/* force the device address into the message vector */
	for (unsigned i = 0; i < msgs; i++)
		msgv[i].addr = _address;


	do {
		ret = I2C_TRANSFER(_dev, msgv, msgs);

		/* success */
		if (ret == OK)
			break;

		/* if we have already retried once, or we are going to give up, then reset the bus */
		if ((retry_count >= 1) || (retry_count >= _retries))
			up_i2creset(_dev);

	} while (retry_count++ < _retries);

	return ret;
}
Пример #8
0
int
I2C::transfer(i2c_msg_s *msgv, unsigned msgs)
{
	int ret;
	unsigned retry_count = 0;

	/* force the device address into the message vector */
	for (unsigned i = 0; i < msgs; i++)
		msgv[i].addr = _address;


	do {
		/*
		 * I2C architecture means there is an unavoidable race here
		 * if there are any devices on the bus with a different frequency
		 * preference.  Really, this is pointless.
		 */
		I2C_SETFREQUENCY(_dev, _frequency);
		ret = I2C_TRANSFER(_dev, msgv, msgs);

		/* success */
		if (ret == OK)
			break;

		/* if we have already retried once, or we are going to give up, then reset the bus */
		if ((retry_count >= 1) || (retry_count >= _retries))
			up_i2creset(_dev);

	} while (retry_count++ < _retries);

	return ret;
}
Пример #9
0
int
I2C::transfer(const uint8_t *send, unsigned send_len, uint8_t *recv, unsigned recv_len)
{
	struct i2c_msg_s msgv[2];
	unsigned msgs;
	int ret;
	unsigned retry_count = 0;

	do {
		//	debug("transfer out %p/%u  in %p/%u", send, send_len, recv, recv_len);

		msgs = 0;

		if (send_len > 0) {
			msgv[msgs].addr = _address;
			msgv[msgs].flags = 0;
			msgv[msgs].buffer = const_cast<uint8_t *>(send);
			msgv[msgs].length = send_len;
			msgs++;
		}

		if (recv_len > 0) {
			msgv[msgs].addr = _address;
			msgv[msgs].flags = I2C_M_READ;
			msgv[msgs].buffer = recv;
			msgv[msgs].length = recv_len;
			msgs++;
		}

		if (msgs == 0)
			return -EINVAL;

		/*
		 * I2C architecture means there is an unavoidable race here
		 * if there are any devices on the bus with a different frequency
		 * preference.  Really, this is pointless.
		 */
		I2C_SETFREQUENCY(_dev, _frequency);
		ret = I2C_TRANSFER(_dev, &msgv[0], msgs);

		/* success */
		if (ret == OK)
			break;

		/* if we have already retried once, or we are going to give up, then reset the bus */
		if ((retry_count >= 1) || (retry_count >= _retries))
			up_i2creset(_dev);

	} while (retry_count++ < _retries);

	return ret;

}
Пример #10
0
int
I2C::transfer(const uint8_t *send, unsigned send_len, uint8_t *recv, unsigned recv_len)
{
	struct i2c_msg_s msgv[2];
	unsigned msgs;
	int ret;
	unsigned retry_count = 0;

	do {
		//	DEVICE_DEBUG("transfer out %p/%u  in %p/%u", send, send_len, recv, recv_len);

		msgs = 0;

		if (send_len > 0) {
			msgv[msgs].frequency = _bus_clocks[_bus - 1];
			msgv[msgs].addr = _address;
			msgv[msgs].flags = 0;
			msgv[msgs].buffer = const_cast<uint8_t *>(send);
			msgv[msgs].length = send_len;
			msgs++;
		}

		if (recv_len > 0) {
			msgv[msgs].frequency = _bus_clocks[_bus - 1];;
			msgv[msgs].addr = _address;
			msgv[msgs].flags = I2C_M_READ;
			msgv[msgs].buffer = recv;
			msgv[msgs].length = recv_len;
			msgs++;
		}

		if (msgs == 0) {
			return -EINVAL;
		}

		ret = I2C_TRANSFER(_dev, &msgv[0], msgs);

		/* success */
		if (ret == OK) {
			break;
		}

		/* if we have already retried once, or we are going to give up, then reset the bus */
		if ((retry_count >= 1) || (retry_count >= _retries)) {
			I2C_RESET(_dev);
		}

	} while (retry_count++ < _retries);

	return ret;

}
Пример #11
0
static int cs2100_read_reg(FAR const struct cs2100_config_s *config,
                           uint8_t regaddr, uint8_t *regval)
{
  struct i2c_msg_s msg;
  int ret;

  DEBUGASSERT(config->i2c->ops && config->i2c->ops->transfer);

  /* Construct the I2C message (write 1 bytes, restart, read N bytes) */

  msg.frequency = config->i2cfreq;
  msg.addr      = config->i2caddr;
  msg.flags     = 0;
  msg.buffer    = &regaddr;
  msg.length    = 1;

  /* Send the address followed by a STOP */

  ret = I2C_TRANSFER(config->i2c, &msg, 1);
  if (ret == OK)
    {
      msg.frequency = config->i2cfreq;
      msg.addr      = config->i2caddr;
      msg.flags     = I2C_M_READ;
      msg.buffer    = regval;
      msg.length    = 1;

      /* Read the register beginning with another START */

      ret = I2C_TRANSFER(config->i2c, &msg, 1);
      if (ret == OK)
        {
          regdbg("%02x->%02x\n", regaddr, *regval);
        }
    }

  return ret;
}
Пример #12
0
static int lm75_i2c_write(FAR struct lm75_dev_s *priv,
                          FAR const uint8_t *buffer, int buflen)
{
  struct i2c_msg_s msg;

  /* Setup for the transfer */

  msg.frequency = CONFIG_LM75_I2C_FREQUENCY,
  msg.addr      = priv->addr;
  msg.flags     = 0;
  msg.buffer    = (FAR uint8_t *)buffer;  /* Override const */
  msg.length    = buflen;

  /* Then perform the transfer. */

  return I2C_TRANSFER(priv->i2c, &msg, 1);
}
Пример #13
0
static int lm75_i2c_read(FAR struct lm75_dev_s *priv,
                         FAR uint8_t *buffer, int buflen)
{
  struct i2c_msg_s msg;

  /* Setup for the transfer */

  msg.frequency = CONFIG_LM75_I2C_FREQUENCY,
  msg.addr      = priv->addr,
  msg.flags     = I2C_M_READ;
  msg.buffer    = buffer;
  msg.length    = buflen;

  /* Then perform the transfer. */

  return I2C_TRANSFER(priv->i2c, &msg, 1);
}
Пример #14
0
int i2c_writeread(FAR struct i2c_dev_s *dev, FAR const struct i2c_config_s *config, FAR const uint8_t *wbuffer, int wbuflen, FAR uint8_t *rbuffer, int rbuflen)
{
	struct i2c_msg_s msg[2];
	unsigned int flags;
	int ret = -1;

	/* 7- or 10-bit address? */

	DEBUGASSERT(config->addrlen == 10 || config->addrlen == 7);
	flags = (config->addrlen == 10) ? I2C_M_TEN : 0;

	/* Format two messages: The first is a write */

	msg[0].addr = config->address;
	msg[0].flags = flags;
	msg[0].buffer = (FAR uint8_t *)wbuffer;	/* Override const */
	msg[0].length = wbuflen;

	/* The second is either a read (rbuflen > 0) or a write (rbuflen < 0) with
	 * no restart.
	 */

	if (rbuflen > 0) {
		msg[1].flags = (flags | I2C_M_READ);
	} else {
		msg[1].flags = (flags | I2C_M_NORESTART);
		rbuflen = -rbuflen;
	}

	msg[1].addr = config->address;
	msg[1].buffer = rbuffer;
	msg[1].length = rbuflen;

	/* Then perform the transfer
	 *
	 * REVISIT:  The following two operations must become atomic in order to
	 * assure thread safety.
	 */

	if (dev != 0x0) {
		I2C_SETFREQUENCY(dev, config->frequency);
		ret = I2C_TRANSFER(dev, msg, 2);
	}

	return ret;
}
Пример #15
0
uint16_t stmpe811_getreg16(FAR struct stmpe811_dev_s *priv, uint8_t regaddr)
{
  /* 16-bit data read sequence:
   *
   *  Start - I2C_Write_Address - STMPE811_Reg_Address -
   *    Repeated_Start - I2C_Read_Address  - STMPE811_Read_Data_1 -
   *      STMPE811_Read_Data_2 - STOP
   */


  struct i2c_msg_s msg[2];
  uint8_t rxbuffer[2];
  int ret;

  /* Setup 8-bit STMPE811 address write message */

  msg[0].addr   = priv->config->address; /* 7-bit address */
  msg[0].flags  = 0;                     /* Write transaction, beginning with START */
  msg[0].buffer = &regaddr;              /* Transfer from this address */
  msg[0].length = 1;                     /* Send one byte following the address
                                          * (no STOP) */

  /* Set up the 8-bit STMPE811 data read message */

  msg[1].addr   = priv->config->address; /* 7-bit address */
  msg[1].flags  = I2C_M_READ;            /* Read transaction, beginning with Re-START */
  msg[1].buffer = rxbuffer;              /* Transfer to this address */
  msg[1].length = 2;                     /* Receive two bytes following the address
                                          * (then STOP) */

  /* Perform the transfer */

  ret = I2C_TRANSFER(priv->i2c, msg, 2);
  if (ret < 0)
    {
      idbg("I2C_TRANSFER failed: %d\n", ret);
      return 0;
    }

#ifdef CONFIG_STMPE811_REGDEBUG
  dbg("%02x->%02x%02x\n", regaddr, rxbuffer[0], rxbuffer[1]);
#endif
  return (uint16_t)rxbuffer[0] << 8 | (uint16_t)rxbuffer[1];
}
Пример #16
0
static int
transfer(uint8_t address, uint8_t *send, unsigned send_len, uint8_t *recv, unsigned recv_len)
{
	struct i2c_msg_s msgv[2];
	unsigned msgs;
	int ret;

	//	debug("transfer out %p/%u  in %p/%u", send, send_len, recv, recv_len);

	msgs = 0;

	if (send_len > 0) {
		msgv[msgs].addr = address;
		msgv[msgs].flags = 0;
		msgv[msgs].buffer = send;
		msgv[msgs].length = send_len;
		msgs++;
	}

	if (recv_len > 0) {
		msgv[msgs].addr = address;
		msgv[msgs].flags = I2C_M_READ;
		msgv[msgs].buffer = recv;
		msgv[msgs].length = recv_len;
		msgs++;
	}

	if (msgs == 0)
		return -1;

	/*
	 * I2C architecture means there is an unavoidable race here
	 * if there are any devices on the bus with a different frequency
	 * preference.  Really, this is pointless.
	 */
	I2C_SETFREQUENCY(i2c, 400000);
	ret = I2C_TRANSFER(i2c, &msgv[0], msgs);

	// reset the I2C bus to unwedge on error
	if (ret != OK)
		up_i2creset(i2c);

	return ret;
}
Пример #17
0
uint8_t adxl345_getreg8(FAR struct adxl345_dev_s *priv, uint8_t regaddr)
{
  /* 8-bit data read sequence:
   *
   *  Start - I2C_Write_Address - ADXL345_Reg_Address -
   *    Repeated_Start - I2C_Read_Address  - ADXL345_Read_Data - STOP
   */

  struct i2c_msg_s msg[2];
  uint8_t regval;
  int ret;

  /* Setup 8-bit ADXL345 address write message */

  msg[0].addr   = priv->config->address; /* 7-bit address */
  msg[0].flags  = 0;                     /* Write transaction, beginning with START */
  msg[0].buffer = &regaddr;              /* Transfer from this address */
  msg[0].length = 1;                     /* Send one byte following the address
                                          * (no STOP) */

  /* Set up the 8-bit ADXL345 data read message */

  msg[1].addr   = priv->config->address; /* 7-bit address */
  msg[1].flags  = I2C_M_READ;            /* Read transaction, beginning with Re-START */
  msg[1].buffer = &regval;               /* Transfer to this address */
  msg[1].length = 1;                     /* Receive one byte following the address
                                          * (then STOP) */

  /* Perform the transfer */

  ret = I2C_TRANSFER(priv->i2c, msg, 2);
  if (ret < 0)
    {
      sndbg("I2C_TRANSFER failed: %d\n", ret);
      return 0;
    }

#ifdef CONFIG_ADXL345_REGDEBUG
  dbg("%02x->%02x\n", regaddr, regval);
#endif
  return regval;
}
Пример #18
0
int ssd1306_sendbyte(FAR struct ssd1306_dev_s *priv, uint8_t regval)
{
  /* 8-bit data read sequence:
   *
   *  Start - I2C_Write_Address - SSD1306_Reg_Address - SSD1306_Write_Data - STOP
   */

  struct i2c_msg_s msg;
  uint8_t txbuffer[2];
  int ret;

#ifdef CONFIG_LCD_SSD1306_REGDEBUG
  _err("-> 0x%02x\n", regval);
#endif

  /* Setup to the data to be transferred.  Two bytes:  The SSD1306 register
   * address followed by one byte of data.
   */

  txbuffer[0]   = 0x00;
  txbuffer[1]   = regval;

  /* Setup 8-bit SSD1306 address write message */

  msg.frequency = CONFIG_SSD1306_I2CFREQ;  /* I2C frequency */
  msg.addr      = priv->addr;              /* 7-bit address */
  msg.flags     = 0;                       /* Write transaction, beginning with START */
  msg.buffer    = txbuffer;                /* Transfer from this address */
  msg.length    = 2;                       /* Send two bytes following the address
                                            * then STOP */

  /* Perform the transfer */

  ret = I2C_TRANSFER(priv->i2c, &msg, 1);
  if (ret < 0)
    {
      lcderr("ERROR: I2C_TRANSFER failed: %d\n", ret);
    }

  return ret;
}
Пример #19
0
void stmpe811_putreg8(FAR struct stmpe811_dev_s *priv,
                      uint8_t regaddr, uint8_t regval)
{
  /* 8-bit data read sequence:
   *
   *  Start - I2C_Write_Address - STMPE811_Reg_Address - STMPE811_Write_Data - STOP
   */

  struct i2c_msg_s msg;
  uint8_t txbuffer[2];
  int ret;

#ifdef CONFIG_STMPE811_REGDEBUG
  dbg("%02x<-%02x\n", regaddr, regval);
#endif

  /* Setup to the data to be transferred.  Two bytes:  The STMPE811 register
   * address followed by one byte of data.
   */

  txbuffer[0] = regaddr;
  txbuffer[1] = regval;

  /* Setup 8-bit STMPE811 address write message */

  msg.addr   = priv->config->address; /* 7-bit address */
  msg.flags  = 0;                     /* Write transaction, beginning with START */
  msg.buffer = txbuffer;              /* Transfer from this address */
  msg.length = 2;                     /* Send two byte following the address
                                       * (then STOP) */

  /* Perform the transfer */

  ret = I2C_TRANSFER(priv->i2c, &msg, 1);
  if (ret < 0)
    {
      idbg("I2C_TRANSFER failed: %d\n", ret);
    }
}
Пример #20
0
int ssd1306_sendblk(FAR struct ssd1306_dev_s *priv, uint8_t *data, uint8_t len)
{
  struct i2c_msg_s msg[2];
  uint8_t transfer_mode;
  int ret;

  /* 8-bit data read sequence:
   *
   *  Start - I2C_Write_Address - Data transfer select - SSD1306_Write_Data - STOP
   */

  /* Send the SSD1306 register address (with no STOP) */

  transfer_mode    = 0x40;                    /* Select data transfer */

  msg[0].frequency = CONFIG_SSD1306_I2CFREQ;  /* I2C frequency */
  msg[0].addr      = priv->addr;              /* 7-bit address */
  msg[0].flags     = 0;                       /* Write transaction, beginning with START */
  msg[0].buffer    = &transfer_mode;          /* Transfer mode send */
  msg[0].length    = 1;                       /* Send the one byte register address */

  /* Followed by the SSD1306 write data (with no RESTART, then STOP) */

  msg[1].frequency = CONFIG_SSD1306_I2CFREQ;  /* I2C frequency */
  msg[1].addr      = priv->addr;              /* 7-bit address */
  msg[1].flags     = I2C_M_NORESTART;         /* Write transaction with no RESTART */
  msg[1].buffer    = data;                    /* Transfer from this address */
  msg[1].length    = len;                     /* Send the data, then STOP */

  ret = I2C_TRANSFER(priv->i2c, msg, 2);
  if (ret < 0)
    {
      lcderr("ERROR: I2C_TRANSFER failed: %d\n", ret);
    }

  return ret;
}
Пример #21
0
static int i2cdrvr_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
  FAR struct inode *inode = filep->f_inode;
  FAR struct i2c_driver_s *priv;
  FAR struct i2c_transfer_s *transfer;
  int ret;

  i2cvdbg("cmd=%d arg=%lu\n", cmd, arg);

  /* Get our private data structure */

  DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
  inode = filep->f_inode;

  priv = (FAR struct i2c_driver_s *)inode->i_private;
  DEBUGASSERT(priv);

  /* Get exclusive access to the I2C driver state structure */

  ret = sem_wait(&priv->exclsem);
  if (ret < 0)
    {
      int errcode = errno;
      DEBUGASSERT(errcode < 0);
      return -errcode;
    }

  /* Process the IOCTL command */

  switch (cmd)
    {
      /* Command:      I2CIOC_TRANSFER
       * Description:  Perform an I2C transfer
       * Argument:     A reference to an instance of struct i2c_transfer_s.
       * Dependencies: CONFIG_I2C_DRIVER
       */

      case I2CIOC_TRANSFER:
        {
          /* Get the reference to the i2c_transfer_s structure */

          transfer = (FAR struct i2c_transfer_s *)((uintptr_t)arg);
          DEBUGASSERT(transfer != NULL);

          /* Perform the transfer */

          ret = I2C_TRANSFER(priv->i2c, transfer->msgv, transfer->msgc);
        }
        break;

#ifdef CONFIG_I2C_RESET
      /* Command:      I2CIOC_RESET
       * Description:  Perform an I2C bus reset in an attempt to break loose
       *               stuck I2C devices.
       * Argument:     None
       * Dependencies: CONFIG_I2C_DRIVER && CONFIG_I2C_RESET
       */

      case I2CIOC_RESET:
        {
          ret = I2C_RESET(priv->i2c);
        }
        break;
#endif

      default:
        ret = -ENOTTY;
        break;
    }

  sem_post(&priv->exclsem);
  return ret;
}