コード例 #1
0
static int elan_smbus_write_fw_block(struct i2c_client *client,
				     const u8 *page, u16 checksum, int idx)
{
	struct device *dev = &client->dev;
	int error;
	u16 result;
	u8 val[3];

	/*
	 * Due to the limitation of smbus protocol limiting
	 * transfer to 32 bytes at a time, we must split block
	 * in 2 transfers.
	 */
	error = i2c_smbus_write_block_data(client,
					   ETP_SMBUS_WRITE_FW_BLOCK,
					   ETP_FW_PAGE_SIZE / 2,
					   page);
	if (error) {
		dev_err(dev, "Failed to write page %d (part %d): %d\n",
			idx, 1, error);
		return error;
	}

	error = i2c_smbus_write_block_data(client,
					   ETP_SMBUS_WRITE_FW_BLOCK,
					   ETP_FW_PAGE_SIZE / 2,
					   page + ETP_FW_PAGE_SIZE / 2);
	if (error) {
		dev_err(dev, "Failed to write page %d (part %d): %d\n",
			idx, 2, error);
		return error;
	}


	/* Wait for F/W to update one page ROM data. */
	usleep_range(8000, 10000);

	error = i2c_smbus_read_block_data(client,
					  ETP_SMBUS_IAP_CTRL_CMD, val);
	if (error < 0) {
		dev_err(dev, "Failed to read IAP write result: %d\n",
			error);
		return error;
	}

	result = be16_to_cpup((__be16 *)val);
	if (result & (ETP_FW_IAP_PAGE_ERR | ETP_FW_IAP_INTF_ERR)) {
		dev_err(dev, "IAP reports failed write: %04hx\n",
			result);
		return -EIO;
	}

	return 0;
}
コード例 #2
0
static int elan_smbus_calibrate(struct i2c_client *client)
{
	u8 cmd[4] = { 0x00, 0x08, 0x00, 0x01 };

	return i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD,
					  sizeof(cmd), cmd);
}
コード例 #3
0
ファイル: nic.c プロジェクト: HengWang/openbmc
int oob_nic_start(oob_nic *dev, const uint8_t mac[6]) {
  int rc;
  uint8_t cmd;

  /* force the link up, no matter what the status of the main link */
  rc = oob_nic_set_force_up(dev, 1);
  if (rc != 0) {
    return rc;
  }

  oob_nic_setup_filters(dev, mac);

  /* first byte is the control */
  cmd = NIC_WRITE_RECV_ENABLE_EN
    | NIC_WRITE_RECV_ENABLE_STA
    | NIC_WRITE_RECV_ENABLE_NM_UNSUPP /* TODO, to support ALERT */
    | NIC_WRITE_RECV_ENABLE_RESERVED;

  rc = i2c_smbus_write_block_data(dev->on_file, NIC_WRITE_RECV_ENABLE_CMD,
                                  1, &cmd);
  if (rc < 0) {
    rc = errno;
    LOG_ERR(rc, "Failed to start receive function");
    return -rc;
  }
  LOG_DBG("Started receive function");
  return 0;
}
コード例 #4
0
static int elan_smbus_set_mode(struct i2c_client *client, u8 mode)
{
	u8 cmd[4] = { 0x00, 0x07, 0x00, mode };

	return i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD,
					  sizeof(cmd), cmd);
}
コード例 #5
0
void NaoCamera::initSelectCamera (  unsigned char camera)
{
	unsigned char cmd[2] = {camera, 0};
	int i2cfd = openI2CAdapter();
	assert (i2c_smbus_write_block_data (i2cfd, 220, 1, cmd) != -1); // select camera
	Logger::Instance().WriteMsg ("NaoCamera", "Going to Cam: " + _toString ( (int) camera), Logger::ExtraInfo);
	closeI2CAdapter (i2cfd);
	currentCamera = camera;
}
コード例 #6
0
ファイル: smbus_rw.c プロジェクト: jetma/iotools
static int
smbus_write_op(struct smbus_op_params *params, const struct smbus_op *op)
{
	int result;

	/* FIXME: Why is this needed if the open_i2c_slave performs the ioctl
	 * with I2C_SLAVE? */
	/* Double cast the last argument for compat with klibc. */
	if (ioctl(params->fd, I2C_SLAVE_FORCE,
	          (void *)(intptr_t)params->address) < 0) {
		fprintf(stderr, "can't set address 0x%02X, %s\n",
		        params->address, strerror(errno));
		return -1;
	}

	switch (op->size) {
	case SMBUS_SIZE_8:
		result = i2c_smbus_write_byte_data(params->fd, params->reg,
		             params->data.fixed.u8);
		break;
	case SMBUS_SIZE_16:
		result = i2c_smbus_write_word_data(params->fd, params->reg,
		             params->data.fixed.u16);
		break;
	case SMBUS_SIZE_BLOCK:
		result = i2c_smbus_write_block_data(params->fd, params->reg,
		             params->len, params->data.array);
		break;
	case SMBUS_SIZE_BYTE:
		result = i2c_smbus_write_byte(params->fd,
		                              params->data.fixed.u8);
		break;
	case SMBUS_QUICK:
		result = i2c_smbus_write_quick(params->fd,
		                              params->data.fixed.u8);
		break;
	default:
		fprintf(stderr, "Illegal SMBus size for write operation.\n");
		return -1;
	}

	if (result < 0) {
		if (op->size != SMBUS_SIZE_BYTE && op->size != SMBUS_QUICK) {
			fprintf(stderr, "can't write register 0x%02X, %s\n",
			        params->reg, strerror(errno));
		} else {
			fprintf(stderr, "can't write to device 0x%02X, %s\n",
			        params->address, strerror(errno));
		}
		return -1;
	}

	return 0;
}
コード例 #7
0
static int daca_init_client(struct pmac_keywest *i2c)
{
	unsigned short wdata = 0x00;
	/*                                   */
	/*                                  */
	if (i2c_smbus_write_byte_data(i2c->client, DACA_REG_SR, 0x08) < 0 ||
	    i2c_smbus_write_byte_data(i2c->client, DACA_REG_GCFG, 0x05) < 0)
		return -EINVAL;
	return i2c_smbus_write_block_data(i2c->client, DACA_REG_AVOL,
					  2, (unsigned char*)&wdata);
}
コード例 #8
0
/*
 * initialize / detect DACA
 */
static int daca_init_client(struct pmac_keywest *i2c)
{
	unsigned short wdata = 0x00;
	/* SR: no swap, 1bit delay, 32-48kHz */
	/* GCFG: power amp inverted, DAC on */
	if (i2c_smbus_write_byte_data(i2c->client, DACA_REG_SR, 0x08) < 0 ||
	    i2c_smbus_write_byte_data(i2c->client, DACA_REG_GCFG, 0x05) < 0)
		return -EINVAL;
	return i2c_smbus_write_block_data(i2c->client, DACA_REG_AVOL,
					  2, (unsigned char*)&wdata);
}
コード例 #9
0
ファイル: NAOCamera.cpp プロジェクト: dreamfrog/robocup
CameraSettings::Camera NAOCamera::setActiveCamera(CameraSettings::Camera newCamera)
{
    // If no change required, do nothing.
    if(m_settings.activeCamera == newCamera) return m_settings.activeCamera;

    CameraSettings::Camera previous_camera = m_settings.activeCamera;
    int i2cFd = open("/dev/i2c-0", O_RDWR);
    ASSERT(i2cFd != -1);
    VERIFY(ioctl(i2cFd, 0x703, 8) == 0);
    VERIFY(i2c_smbus_read_byte_data(i2cFd, 170) >= 2); // at least Nao V3
    unsigned char cmd[2] = {newCamera, 0};
    VERIFY(i2c_smbus_write_block_data(i2cFd, 220, 1, cmd) != -1); // set camera
    close(i2cFd);

#if DEBUG_NUCAMERA_VERBOSITY > 4
    // Display debug message.
    debug << "NAOCamera: Active camera changed: " << CameraSettings::cameraName(previous_camera);
    debug << " --> " << CameraSettings::cameraName(newCamera) << endl;
#endif

    int horzontal_flip, vertical_flip;
    int cameraSettingsIndex;
    switch(newCamera)
    {
        case CameraSettings::TOP_CAMERA:
            horzontal_flip = 1;
            vertical_flip = 1;
            cameraSettingsIndex = 0;
            break;
        case CameraSettings::BOTTOM_CAMERA:
            horzontal_flip = 0;
            vertical_flip = 0;
            cameraSettingsIndex = 1;
            break;
        default:
            horzontal_flip = 0;
            vertical_flip = 0;
            cameraSettingsIndex = -1;
            break;
    }
    if(cameraSettingsIndex != -1)
    {
        m_cameraSettings[!cameraSettingsIndex] = m_settings;
        m_settings = m_cameraSettings[cameraSettingsIndex];
    }

    m_settings.activeCamera = newCamera;

    VERIFY(applySetting(V4L2_CID_HFLIP, horzontal_flip));
    VERIFY(applySetting(V4L2_CID_VFLIP, vertical_flip));

    return m_settings.activeCamera;
}
コード例 #10
0
s32 tspdrv_i2c_write_block_data(u8 command, u8 length, const u8 *values)
{
	s32 status;
	
	status = i2c_smbus_write_block_data(tspdrv_i2c_client , command, length, values );
	if (status < 0)
	{
		printk("%s : I2C write block fail val[0] : 0x%x, val[1] : 0x%x,  RECOVER !!(%d)\n",__func__, values[0], values[1]);
	}
	
	return status;
}
コード例 #11
0
static int elan_smbus_set_flash_key(struct i2c_client *client)
{
	int error;
	u8 cmd[4] = { 0x00, 0x0B, 0x00, 0x5A };

	error = i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD,
					   sizeof(cmd), cmd);
	if (error) {
		dev_err(&client->dev, "cannot set flash key: %d\n", error);
		return error;
	}

	return 0;
}
コード例 #12
0
ファイル: nic.c プロジェクト: HengWang/openbmc
int oob_nic_stop(oob_nic *dev) {
  int rc;
  uint8_t ctrl;
  /* don't set any enable bits, which turns off the receive func */
  ctrl = NIC_WRITE_RECV_ENABLE_RESERVED;
  rc = i2c_smbus_write_block_data(dev->on_file, NIC_WRITE_RECV_ENABLE_CMD,
                                  1, &ctrl);
  if (rc < 0) {
    rc = errno;
    LOG_ERR(rc, "Failed to stop receive function");
    return -rc;
  }
  LOG_DBG("Stopped receive function");
  return 0;
}
コード例 #13
0
ファイル: rmi_smbus.c プロジェクト: AshishNamdev/linux
/* SMB block write - wrapper over ic2_smb_write_block */
static int smb_block_write(struct rmi_transport_dev *xport,
			      u8 commandcode, const void *buf, size_t len)
{
	struct rmi_smb_xport *rmi_smb =
		container_of(xport, struct rmi_smb_xport, xport);
	struct i2c_client *client = rmi_smb->client;
	int retval;

	retval = i2c_smbus_write_block_data(client, commandcode, len, buf);

	rmi_dbg(RMI_DEBUG_XPORT, &client->dev,
		"wrote %zd bytes at %#04x: %d (%*ph)\n",
		len, commandcode, retval, (int)len, buf);

	return retval;
}
コード例 #14
0
unsigned char NaoCamera::switchCamera (  unsigned char camera)
{
	unsigned char cmd[2] =  {camera, 0};
	int flip = camera == NAO_UPPER_CAMERA ? 1 : 0;
	int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	// disable streaming
	assert (ioctl (fd, VIDIOC_STREAMOFF, &type) != -1);
	// switch camera
	int i2cfd = openI2CAdapter();
	assert (i2c_smbus_write_block_data (i2cfd, 220, 1, cmd) != -1);
	closeI2CAdapter (i2cfd);
	setControlSetting (V4L2_CID_VFLIP, flip);
	setControlSetting (V4L2_CID_HFLIP, flip);
	// enable streaming
	assert (ioctl (fd, VIDIOC_STREAMON, &type) != -1);
	currentCamera = camera;
	return camera;
}
コード例 #15
0
ファイル: nic.c プロジェクト: HengWang/openbmc
static int oob_nic_set_mng_ctrl(oob_nic *dev, const uint8_t *data, int len) {
  int rc;

  if (len <= 0) {
    rc = EINVAL;
    LOG_ERR(rc, "Invalid data length: %d", len);
    return -rc;
  }

  rc = i2c_smbus_write_block_data(dev->on_file, NIC_WRITE_MNG_CTRL_CMD,
                                  len, data);
  if (rc < 0) {
    rc = errno;
    LOG_ERR(rc, "Failed to send management control command for parameter # %d",
            data[0]);
    return -rc;
  }

  return 0;
}
コード例 #16
0
ファイル: bfin_twi_lcd.c プロジェクト: ysei/linux-2.6.x
static void drv_HD_I2C_nibble(unsigned char controller, unsigned char nibble)
{
	unsigned char enable;
	unsigned char command;	/* this is actually the first data byte on the PCF8574 */
	unsigned char data_block[2];
	/* enable signal: 'controller' is a bitmask */
	/* bit n .. send to controller #n */
	/* so we can send a byte to more controllers at the same time! */
	enable = 0;
	if (controller & 0x01)
		enable |= SIGNAL_ENABLE;
	if (controller & 0x02)
		enable |= SIGNAL_ENABLE2;

	command = nibble;
	data_block[0] = nibble | enable;
	data_block[1] = nibble;

	i2c_smbus_write_block_data(pcf8574_lcd_client, command, 2, data_block);
}
コード例 #17
0
/*SMB version 2 block write - wrapper over ic2_smb_write_block */
static int smb_v2_block_write(struct rmi_phys_device *phys,
			u8 commandcode, u8 *buf, int len)
{
	struct i2c_client *client = to_i2c_client(phys->dev);
	struct rmi_smb_data *data = phys->data;
	int tx_size = len + 1;
	int retval;

	if (!data->tx_buf || data->tx_buf_size < tx_size) {
		if (data->tx_buf)
			devm_kfree(&client->dev, data->tx_buf);
		data->tx_buf_size = tx_size + BUFFER_SIZE_INCREMENT;
		data->tx_buf = devm_kzalloc(&client->dev, data->tx_buf_size,
					    GFP_KERNEL);
		if (!data->tx_buf) {
			data->tx_buf_size = 0;
			retval = -ENOMEM;
			goto exit;
		}
	}
	data->tx_buf[0] = commandcode & 0xff;
	memcpy(data->tx_buf + 1, buf, len);

	if (COMMS_DEBUG(data) &&
			!copy_to_debug_buf(&client->dev, data, buf, len))
		dev_dbg(&client->dev, "writes command %#04x %d bytes:%s\n",
			commandcode, len, data->debug_buf);

	phys->info.tx_count++;
	phys->info.tx_bytes += tx_size;

	retval = i2c_smbus_write_block_data(client, commandcode,
					    tx_size, data->tx_buf);
	if (retval < 0)
		phys->info.tx_errs++;

	return retval;
}
コード例 #18
0
static int daca_set_volume(struct pmac_daca *mix)
{
	unsigned char data[2];
  
	if (! mix->i2c.client)
		return -ENODEV;
  
	if (mix->left_vol > DACA_VOL_MAX)
		data[0] = DACA_VOL_MAX;
	else
		data[0] = mix->left_vol;
	if (mix->right_vol > DACA_VOL_MAX)
		data[1] = DACA_VOL_MAX;
	else
		data[1] = mix->right_vol;
	data[1] |= mix->deemphasis ? 0x40 : 0;
	if (i2c_smbus_write_block_data(mix->i2c.client, DACA_REG_AVOL,
				       2, data) < 0) {
		snd_printk(KERN_ERR "failed to set volume \n");
		return -EINVAL;
	}
	return 0;
}
コード例 #19
0
ファイル: i2c-acpi.c プロジェクト: mikuhatsune001/linux2.6.32
static acpi_status
acpi_i2c_space_handler(u32 function, acpi_physical_address command,
			u32 bits, u64 *value64,
			void *handler_context, void *region_context)
{
	struct gsb_buffer *gsb = (struct gsb_buffer *)value64;
	struct acpi_i2c_handler_data *data = handler_context;
	struct acpi_connection_info *info = &data->info;
	struct acpi_resource_i2c_serialbus *sb;
	struct i2c_adapter *adapter = data->adapter;
	struct i2c_client client;
	struct acpi_resource *ares;
	u32 accessor_type = function >> 16;
	u8 action = function & ACPI_IO_MASK;
	acpi_status ret = AE_OK;
	int status;

	ret = acpi_buffer_to_resource(info->connection, info->length, &ares);
	if (ACPI_FAILURE(ret))
		return ret;

	if (!value64 || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) {
		ret = AE_BAD_PARAMETER;
		goto err;
	}

	sb = &ares->data.i2c_serial_bus;
	if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C) {
		ret = AE_BAD_PARAMETER;
		goto err;
	}

	memset(&client, 0, sizeof(client));
	client.adapter = adapter;
	client.addr = sb->slave_address;
	client.flags = 0;

	if (sb->access_mode == ACPI_I2C_10BIT_MODE)
		client.flags |= I2C_CLIENT_TEN;

	switch (accessor_type) {
	case ACPI_GSB_ACCESS_ATTRIB_SEND_RCV:
		if (action == ACPI_READ) {
			status = i2c_smbus_read_byte(&client);
			if (status >= 0) {
				gsb->bdata = status;
				status = 0;
			}
		} else {
			status = i2c_smbus_write_byte(&client, gsb->bdata);
		}
		break;

	case ACPI_GSB_ACCESS_ATTRIB_BYTE:
		if (action == ACPI_READ) {
			status = i2c_smbus_read_byte_data(&client, command);
			if (status >= 0) {
				gsb->bdata = status;
				status = 0;
			}
		} else {
			status = i2c_smbus_write_byte_data(&client, command,
					gsb->bdata);
		}
		break;

	case ACPI_GSB_ACCESS_ATTRIB_WORD:
		if (action == ACPI_READ) {
			status = i2c_smbus_read_word_data(&client, command);
			if (status >= 0) {
				gsb->wdata = status;
				status = 0;
			}
		} else {
			status = i2c_smbus_write_word_data(&client, command,
					gsb->wdata);
		}
		break;

	case ACPI_GSB_ACCESS_ATTRIB_BLOCK:
		if (action == ACPI_READ) {
			status = i2c_smbus_read_block_data(&client, command,
					gsb->data);
			if (status >= 0) {
				gsb->len = status;
				status = 0;
			}
		} else {
			status = i2c_smbus_write_block_data(&client, command,
					gsb->len, gsb->data);
		}
		break;

	case ACPI_GSB_ACCESS_ATTRIB_MULTIBYTE:
		if (action == ACPI_READ) {
			status = acpi_gsb_i2c_read_bytes(&client, command,
					gsb->data, info->access_length);
			if (status > 0)
				status = 0;
		} else {
			status = acpi_gsb_i2c_write_bytes(&client, command,
					gsb->data, info->access_length);
		}
		break;

	default:
		pr_info("protocol(0x%02x) is not supported.\n", accessor_type);
		ret = AE_BAD_PARAMETER;
		goto err;
	}

	gsb->status = status;

 err:
	ACPI_FREE(ares);
	return ret;
}
コード例 #20
0
ファイル: nic.c プロジェクト: HengWang/openbmc
static int oob_nic_setup_filters(oob_nic *dev, const uint8_t mac[6]) {
  int rc;
  int i;
  uint32_t cmd32;
  uint8_t buf[32];
  uint8_t *cmd;

  /*
   * Command to set MAC filter
   * Seven bytes are required to load the MAC address filters.
   * Data 2—MAC address filters pair number (3:0).
   * Data 3—MSB of MAC address.
   * ...
   * Data 8: LSB of MAC address.
   */
  /* set MAC filter to pair 0 */
  cmd = buf;
  *cmd++ = NIC_FILTER_MAC_NUM;
  *cmd++ = NIC_FILTER_MAC_PAIR0; /* pair 0 */
  for (i = 0; i < 6; i++) {
    *cmd++ = mac[i];
  }
  rc = i2c_smbus_write_block_data(dev->on_file, NIC_WRITE_FILTER_CMD,
                                  cmd - buf, buf);
  if (rc < 0) {
    rc = errno;
    LOG_ERR(rc, "Failed to set MAC filter");
    return -rc;
  }

  /*
   * Command to enable filter
   *
   * 9 bytes to load the extended decision filters (MDEF_EXT & MDEF)
   * Data 2—MDEF filter index (valid values are 0...6)
   * Data 3—MSB of MDEF_EXT (DecisionFilter0)
   * ....
   * Data 6—LSB of MDEF_EXT (DecisionFilter0)
   * Data 7—MSB of MDEF (DecisionFilter0)
   * ....
   * Data 10—LSB of MDEF (DecisionFilter0)
   */

  /* enable MAC filter pair 0 on filter 0 */
  cmd = buf;
  *cmd++ = NIC_FILTER_DECISION_EXT_NUM;
  *cmd++ = NIC_FILTER_MDEF0;
  /* enable filter for traffic from network and host */
  cmd32 = NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_EXT_NET_EN_OFFSET)
    | NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_EXT_HOST_EN_OFFSET);
  for (i = 0; i < sizeof(cmd32); i++) {
    *cmd++ = (cmd32 >> (24 - 8 * i)) & 0xFF;
  }
  /* enable mac pair 0 */
  cmd32 = NIC_FILTER_MDEF_BIT_VAL(NIC_FILTER_MDEF_MAC_AND_OFFSET,
                                  NIC_FILTER_MAC_PAIR0);
  for (i = 0; i < sizeof(cmd32); i++) {
    *cmd++ = (cmd32 >> (24 - 8 * i)) & 0xFF;
  }
  rc = i2c_smbus_write_block_data(dev->on_file, NIC_WRITE_FILTER_CMD,
                                  cmd - buf, buf);
  if (rc < 0) {
    rc = errno;
    LOG_ERR(rc, "Failed to set MAC filter to MDEF 0");
    return -rc;
  }
  /* enable ARP and ND on filter 1*/
  cmd = buf;
  *cmd++ = NIC_FILTER_DECISION_EXT_NUM;
  *cmd++ = NIC_FILTER_MDEF1;
  /* enable filter for traffic from network and host */
  cmd32 = NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_EXT_NET_EN_OFFSET)
    | NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_EXT_HOST_EN_OFFSET);
  for (i = 0; i < sizeof(cmd32); i++) {
    *cmd++ = (cmd32 >> (24 - 8 * i)) & 0xFF;
  }
  /* enable ARP and ND */
  cmd32 = NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_ARP_REQ_OR_OFFSET)
    | NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_ARP_RES_OR_OFFSET)
    | NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_NBG_OR_OFFSET);
  for (i = 0; i < sizeof(cmd32); i++) {
    *cmd++ = (cmd32 >> (24 - 8 * i)) & 0xFF;
  }
  rc = i2c_smbus_write_block_data(dev->on_file, NIC_WRITE_FILTER_CMD,
                                  cmd - buf, buf);
  if (rc < 0) {
    rc = errno;
    LOG_ERR(rc, "Failed to set ARP and ND filter to MDEF 1");
    return -rc;
  }

  /* make filter 0, matching MAC, to be mng only */
  cmd = buf;
  *cmd++ = NIC_FILTER_MNG_ONLY_NUM;
  cmd32 = NIC_FILTER_MNG_ONLY_FILTER0;
  for (i = 0; i < sizeof(cmd32); i++) {
    *cmd++ = (cmd32 >> (24 - 8 * i)) & 0xFF;
  }
  rc = i2c_smbus_write_block_data(dev->on_file, NIC_WRITE_FILTER_CMD,
                                  cmd - buf, buf);
  if (rc < 0) {
    rc = errno;
    LOG_ERR(rc, "Failed to enabled management only filter");
    return -rc;
  }

  return 0;
}
コード例 #21
0
ファイル: matrixLEDi2c.c プロジェクト: jungeml/MiniProject02
int main(int argc, char *argv[])
{
	int res, i2cbus, address, size, file;
	int value, daddress;
	char filename[20];
	int force = 0, readback = 1;
	__u16 block[I2C_SMBUS_BLOCK_MAX];
	int len;

	i2cbus = lookup_i2c_bus("3");
	printf("i2cbus = %d\n", i2cbus);
	if (i2cbus < 0)
		help();

	address = parse_i2c_address("0x70");
	printf("address = 0x%2x\n", address);
	if (address < 0)
		help();

	size = I2C_SMBUS_BYTE;

	daddress = 0x21;
	if (daddress < 0 || daddress > 0xff) {
		fprintf(stderr, "Error: Data address invalid!\n");
		help();
	}

	file = open_i2c_dev(i2cbus, filename, sizeof(filename), 0);
	printf("file = %d\n", file);
	if (file < 0
		|| check_funcs(file, size)
		|| set_slave_addr(file, address, force))
		exit(1);


	switch (size) {
	case I2C_SMBUS_BYTE:
		daddress = 0x21; // Start oscillator (page 10)
		printf("writing: 0x%02x\n", daddress);
		res = i2c_smbus_write_byte(file, daddress);

		daddress = 0x81; // Display on, blinking off (page 11)
		printf("writing: 0x%02x\n", daddress);
		res = i2c_smbus_write_byte(file, daddress);

		daddress = 0xe7; // Full brightness (page 15)
		printf("writing: 0x%02x\n", daddress);
		res = i2c_smbus_write_byte(file, daddress);

		daddress = 0x00; // Start writing to address 0 (page 13)
		printf("writing: 0x%02x\n", daddress);
		res = i2c_smbus_write_byte(file, daddress);

		int i;

		displayImage(smile_bmp,res, daddress, file);
		displayImage(frown_bmp,res, daddress, file);
		displayImage(neutral_bmp,res, daddress, file);
		displayImage(my_bmp,res, daddress, file);
		sleep(4);
		

		// Closing file and turning off Matrix
		printf("Closing file and turning off the LED Matrix\n");
		daddress = 0x20;		
		//for(daddress = 0xef; daddress >= 0xe0; daddress--) {
		printf("writing: 0x%02x\n", daddress);
		res = i2c_smbus_write_byte(file, daddress);

		usleep(500000); // Sleep 0.5 seconds
		

		break;

	case I2C_SMBUS_WORD_DATA:
		res = i2c_smbus_write_word_data(file, daddress, value);
		break;
	case I2C_SMBUS_BLOCK_DATA:
		res = i2c_smbus_write_block_data(file, daddress, len, (const __u8 *)block);
		break;
	case I2C_SMBUS_I2C_BLOCK_DATA:
		res = i2c_smbus_write_i2c_block_data(file, daddress, len, (const __u8 *)block);
		break;
	default: /* I2C_SMBUS_BYTE_DATA */
		res = i2c_smbus_write_byte_data(file, daddress, value);
		break;
	}
	if (res < 0) {
		fprintf(stderr, "Error: Write failed\n");
		close(file);
		exit(1);
		}

	if (!readback) { /* We're done */
		close(file);
		exit(0);
		}

	switch (size) {
		case I2C_SMBUS_BYTE:
			res = i2c_smbus_read_byte(file);
			value = daddress;
			break;
		case I2C_SMBUS_WORD_DATA:
			res = i2c_smbus_read_word_data(file, daddress);
			break;
		default: /* I2C_SMBUS_BYTE_DATA */
			res = i2c_smbus_read_byte_data(file, daddress);
			}
	close(file);

	exit(0);
}
コード例 #22
0
ファイル: i2c_tools.c プロジェクト: AlexShiLucky/busybox
int i2cset_main(int argc, char **argv)
{
	const unsigned opt_f = (1 << 0), opt_y = (1 << 1),
			      opt_m = (1 << 2), opt_r = (1 << 3);
	const char *const optstr = "fym:r";

	int bus_num, bus_addr, data_addr, mode = I2C_SMBUS_BYTE, pec = 0;
	int val, blen = 0, mask = 0, fd, status;
	unsigned char block[I2C_SMBUS_BLOCK_MAX];
	char *opt_m_arg = NULL;
	unsigned opts;

        opt_complementary = "-3"; /* from 3 to ? args */
	opts = getopt32(argv, optstr, &opt_m_arg);
	argv += optind;
	argc -= optind;

	bus_num = i2c_bus_lookup(argv[0]);
	bus_addr = i2c_parse_bus_addr(argv[1]);
	data_addr = i2c_parse_data_addr(argv[2]);

	if (argv[3]) {
		if (!argv[4] && argv[3][0] != 'c') {
			mode = I2C_SMBUS_BYTE_DATA; /* Implicit b */
		} else {
			switch (argv[argc-1][0]) {
			case 'c': /* Already set */			break;
			case 'b': mode = I2C_SMBUS_BYTE_DATA;		break;
			case 'w': mode = I2C_SMBUS_WORD_DATA;		break;
			case 's': mode = I2C_SMBUS_BLOCK_DATA;		break;
			case 'i': mode = I2C_SMBUS_I2C_BLOCK_DATA;	break;
			default:
				bb_error_msg("invalid mode");
				bb_show_usage();
			}

			pec = argv[argc-1][1] == 'p';
			if (mode == I2C_SMBUS_BLOCK_DATA ||
					mode == I2C_SMBUS_I2C_BLOCK_DATA) {
				if (pec && mode == I2C_SMBUS_I2C_BLOCK_DATA)
					bb_error_msg_and_die(
						"PEC not supported for I2C "
						"block writes");
				if (opts & opt_m)
					bb_error_msg_and_die(
						"mask not supported for block "
						"writes");
			}
		}
	}

	/* Prepare the value(s) to be written according to current mode. */
	switch (mode) {
	case I2C_SMBUS_BYTE_DATA:
		val = xstrtou_range(argv[3], 0, 0, 0xff);
		break;
	case I2C_SMBUS_WORD_DATA:
		val = xstrtou_range(argv[3], 0, 0, 0xffff);
		break;
	case I2C_SMBUS_BLOCK_DATA:
	case I2C_SMBUS_I2C_BLOCK_DATA:
		for (blen = 3; blen < (argc - 1); blen++)
			block[blen] = xstrtou_range(argv[blen], 0, 0, 0xff);
		val = -1;
		break;
	default:
		val = -1;
		break;
	}

	if (opts & opt_m) {
		mask = xstrtou_range(opt_m_arg, 0, 0,
				(mode == I2C_SMBUS_BYTE ||
				 mode == I2C_SMBUS_BYTE_DATA) ? 0xff : 0xffff);
	}

	fd = i2c_dev_open(bus_num);
	check_write_funcs(fd, mode, pec);
	i2c_set_slave_addr(fd, bus_addr, opts & opt_f);

	if (!(opts & opt_y))
		confirm_action(bus_addr, mode, data_addr, pec);

	/*
	 * If we're using mask - read the current value here and adjust the
	 * value to be written.
	 */
	if (opts & opt_m) {
		int tmpval;

		switch (mode) {
		case I2C_SMBUS_BYTE:
			tmpval = i2c_smbus_read_byte(fd);
			break;
		case I2C_SMBUS_WORD_DATA:
			tmpval = i2c_smbus_read_word_data(fd, data_addr);
			break;
		default:
			tmpval = i2c_smbus_read_byte_data(fd, data_addr);
		}

		if (tmpval < 0)
			bb_perror_msg_and_die("can't read old value");

		val = (val & mask) | (tmpval & ~mask);

		if (!(opts & opt_y)) {
			bb_error_msg("old value 0x%0*x, write mask "
				"0x%0*x, will write 0x%0*x to register "
				"0x%02x",
				mode == I2C_SMBUS_WORD_DATA ? 4 : 2, tmpval,
				mode == I2C_SMBUS_WORD_DATA ? 4 : 2, mask,
				mode == I2C_SMBUS_WORD_DATA ? 4 : 2, val,
				data_addr);
			confirm_or_abort();
		}
	}

	if (pec)
		i2c_set_pec(fd, 1);

	switch (mode) {
	case I2C_SMBUS_BYTE:
		status = i2c_smbus_write_byte(fd, data_addr);
		break;
	case I2C_SMBUS_WORD_DATA:
		status = i2c_smbus_write_word_data(fd, data_addr, val);
		break;
	case I2C_SMBUS_BLOCK_DATA:
		status = i2c_smbus_write_block_data(fd, data_addr,
						    blen, block);
		break;
	case I2C_SMBUS_I2C_BLOCK_DATA:
		status = i2c_smbus_write_i2c_block_data(fd, data_addr,
							blen, block);
		break;
	default: /* I2C_SMBUS_BYTE_DATA */
		status = i2c_smbus_write_byte_data(fd, data_addr, val);
		break;
	}
	if (status < 0)
		bb_perror_msg_and_die("write failed");

	if (pec)
		i2c_set_pec(fd, 0); /* Clear PEC. */

	/* No readback required - we're done. */
	if (!(opts & opt_r))
		return 0;

	switch (mode) {
	case I2C_SMBUS_BYTE:
		status = i2c_smbus_read_byte(fd);
		val = data_addr;
		break;
	case I2C_SMBUS_WORD_DATA:
		status = i2c_smbus_read_word_data(fd, data_addr);
		break;
	default: /* I2C_SMBUS_BYTE_DATA */
		status = i2c_smbus_read_byte_data(fd, data_addr);
	}

	if (status < 0) {
		puts("Warning - readback failed");
	} else
	if (status != val) {
		printf("Warning - data mismatch - wrote "
		       "0x%0*x, read back 0x%0*x\n",
		       mode == I2C_SMBUS_WORD_DATA ? 4 : 2, val,
		       mode == I2C_SMBUS_WORD_DATA ? 4 : 2, status);
	} else {
		printf("Value 0x%0*x written, readback matched\n",
		       mode == I2C_SMBUS_WORD_DATA ? 4 : 2, val);
	}

	return 0;
}
コード例 #23
0
/* No writes yet (PAE) */
int icspll_write_value(struct i2c_client *client, u8 reg, u16 value)
{
	return i2c_smbus_write_block_data(client->adapter, client->addr,
					  reg, value);
}
コード例 #24
0
ファイル: TranscriberModule.cpp プロジェクト: dmcavoy/nbites
void ImageTranscriber::initSelectCamera() {
    unsigned char cmd[2] = { (unsigned char) cameraType, 0 };
    i2c_smbus_write_block_data(cameraAdapterFd, 220, 1, cmd);
}
コード例 #25
0
ファイル: test3.c プロジェクト: BenSeverson/LaFoneraI2C
int main(int argc, char *argv[]) {
   char *end;
   int res,file;
   int e1;
   char filename[20] ;
   long funcs;
   char msg[16];
   unsigned char r,g,b;
   
   
   sprintf(filename,"/dev/i2c/0");
   if ((file = open(filename,O_RDWR)) < 0) {
     e1 = errno;
     if (e1 != ENOENT) {
       fprintf(stderr,"Error: Could not open file '%s' : %s\n",
               filename,strerror(e1));
       if(e1 == EACCES)
         fprintf(stderr,"Run as root?\n");
     }
   } 
   
   if (ioctl(file,I2C_FUNCS,&funcs) < 0) {
     fprintf(stderr,
             "Error: Could not get the adapter functionality maxtrix: %s\n",
             strerror(errno));
     exit(1);
   }
   if (! (funcs & I2C_FUNC_SMBUS_QUICK)) {
     fprintf(stderr,
             "Error: Can't use SMBus Quick Write command "
             "on this bus (ISA bus?)\n");
     exit(1);
   }
   fprintf(stderr, "I2C functionality: %08X\n", funcs);
   
   if (ioctl(file,I2C_SLAVE,CHIP1_ADDR) < 0) {
     if (errno == EBUSY) {
       printf("device is busy\n");
     }
     exit(0);
   }
   res = i2c_smbus_read_byte_data(file, CONFIG_ADDR);
   if (res < 0) {
     printf("Cannot read config register\n");
   } else {
     printf("Config register: %02x\n", res);
   }
   res = i2c_smbus_write_byte_data(file, CONFIG_ADDR, 0x08);
   if (res < 0) {
     printf("Cannot write command register\n");
   }
   res = i2c_smbus_read_byte_data(file, CONFIG_ADDR);
   if (res < 0) {
     printf("Cannot read config register\n");
   } else {
     printf("Config register: %02x\n", res);
   }
   
   msg[0]=0x00;
   msg[1]=0x00;
   res = i2c_smbus_write_block_data(file, 0x06, 2, msg);
   if (res < 0) {
     printf("Cannot write port config register\n");
   }
   
   msg[0]=0xFF;
   msg[1]=0xFF;
   res = i2c_smbus_write_block_data(file, 0x02, 2, msg);
   if (res < 0) {
     printf("Cannot write blink phase 0 register\n");
   }

   res = i2c_smbus_write_byte_data(file, 0x0E, 0xFF);
   if (res < 0) {
     printf("Cannot write master intensity register\n");
   }

   msg[0]=0xFF;
   msg[1]=0xFF;
   msg[2]=0xFF;
   msg[3]=0xFF;
   msg[4]=0xFF;
   msg[5]=0xFF;
   msg[6]=0xFF;
   msg[7]=0xFF;

   res = i2c_smbus_write_block_data(file, 0x10, 8, msg);
   if (res < 0) {
     printf("Cannot write intensity register\n");  
   }




   printf("*************Now using chip 2*****************\n");

      if (ioctl(file,I2C_SLAVE,CHIP2_ADDR) < 0) {
     if (errno == EBUSY) {
       printf("device is busy\n");
     }
     exit(0);
   }
   res = i2c_smbus_read_byte_data(file, CONFIG_ADDR);
   if (res < 0) {
     printf("Cannot read config register\n");
   } else {
     printf("Config register: %02x\n", res);
   }
   res = i2c_smbus_write_byte_data(file, CONFIG_ADDR, 0x08);
   if (res < 0) {
     printf("Cannot write command register\n");
   }
   res = i2c_smbus_read_byte_data(file, CONFIG_ADDR);
   if (res < 0) {
     printf("Cannot read config register\n");
   } else {
     printf("Config register: %02x\n", res);
   }
   
   msg[0]=0x00;
   msg[1]=0x00;
   res = i2c_smbus_write_block_data(file, 0x06, 2, msg);
   if (res < 0) {
     printf("Cannot write port config register\n");
   }
   
   msg[0]=0xFF;
   msg[1]=0xFF;
   res = i2c_smbus_write_block_data(file, 0x02, 2, msg);
   if (res < 0) {
     printf("Cannot write blink phase 0 register\n");
   }

   res = i2c_smbus_write_byte_data(file, 0x0E, 0xFF);
   if (res < 0) {
     printf("Cannot write master intensity register\n");
   }

   msg[0]=0xFF;
   msg[1]=0xFF;
   msg[2]=0xFF;
   msg[3]=0xFF;
   msg[4]=0xFF;
   msg[5]=0xFF;
   msg[6]=0xFF;
   msg[7]=0xFF;

   res = i2c_smbus_write_block_data(file, 0x10, 8, msg);
   if (res < 0) {
     printf("Cannot write intensity register\n");  
   }



 //  	for(r=0;r<16;r++)
	//{
	//	for(g=0;g<16;g++)
	//	{
	//		//I2CSendByte(0x10);
	//		//I2CSendByte( ( r<<4 ) | g );
	//		//I2CSendByte(b);
	//		i2c_smbus_write_byte_data(file, 0x10, (r<<4) | g);
	//		printf("red-green: 0x%X\n",(r<<4)|g);
   while(1)
   {
			for(b=0;b<16;b++)
			{
				i2c_smbus_write_byte_data(file, 0x10, b| (b<<4));
				i2c_smbus_write_byte_data(file, 0x11, b);
				printf("R: 0x%02X\tG: 0x%02X\tB:%02X\n",b,b,b);
				usleep(70000);
			}
			for(b=1;b<16;b++)
			{
				i2c_smbus_write_byte_data(file, 0x10, 15-b| ((15-b)<<4));
				i2c_smbus_write_byte_data(file, 0x11, 15-b);
				printf("R: 0x%02X\tG: 0x%02X\tB:%02X\n",15-b,15-b,15-b);
				usleep(70000);
			}
   }
		//}
	//}
   //while (1) { /* loop forever */
  /*   res = i2c_smbus_write_byte_data(file, SRF08_CMD_REG, 0x50);
     if (res < 0) {
       printf("Cannot write command registern");
     }
     usleep(70000);
     while (1) {
       res = i2c_smbus_read_byte_data(file, SRF08_SOFT_REV);
       if (res != 0xff)
         break;
     }
     res = i2c_smbus_read_byte_data(file, SRF08_ECHO_0L);
     printf("Echo Lo %d inches ", res);
     res = i2c_smbus_read_byte_data(file, SRF08_ECHO_0H);
     printf("Echo Hi %d inches n", res);*/
   //}
   //while(1){}
   
}
コード例 #26
0
static int elan_smbus_prepare_fw_update(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	int len;
	int error;
	enum tp_mode mode;
	u8 val[3];
	u8 cmd[4] = {0x0F, 0x78, 0x00, 0x06};
	u16 password;

	/* Get FW in which mode	(IAP_MODE/MAIN_MODE)  */
	error = elan_smbus_iap_get_mode(client, &mode);
	if (error)
		return error;

	if (mode == MAIN_MODE) {

		/* set flash key */
		error = elan_smbus_set_flash_key(client);
		if (error)
			return error;

		/* write iap password */
		if (i2c_smbus_write_byte(client,
					 ETP_SMBUS_IAP_PASSWORD_WRITE) < 0) {
			dev_err(dev, "cannot write iap password\n");
			return -EIO;
		}

		error = i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD,
						   sizeof(cmd), cmd);
		if (error) {
			dev_err(dev, "failed to write iap password: %d\n",
				error);
			return error;
		}

		/*
		 * Read back password to make sure we enabled flash
		 * successfully.
		 */
		len = i2c_smbus_read_block_data(client,
						ETP_SMBUS_IAP_PASSWORD_READ,
						val);
		if (len != sizeof(ETP_SMBUS_IAP_PASSWORD)) {
			error = len < 0 ? len : -EIO;
			dev_err(dev, "failed to read iap password: %d\n",
				error);
			return error;
		}

		password = be16_to_cpup((__be16 *)val);
		if (password != ETP_SMBUS_IAP_PASSWORD) {
			dev_err(dev, "wrong iap password = 0x%X\n", password);
			return -EIO;
		}

		/* Wait 30ms for MAIN_MODE change to IAP_MODE */
		msleep(30);
	}

	error = elan_smbus_set_flash_key(client);
	if (error)
		return error;

	/* Reset IC */
	error = elan_smbus_iap_reset(client);
	if (error)
		return error;

	return 0;
}
コード例 #27
0
ファイル: drv_generic_i2c.c プロジェクト: KP1533TM2/lcd4linux
void drv_generic_i2c_command(const unsigned char command, /*const */ unsigned char *data, const unsigned char length)
{
    i2c_smbus_write_block_data(i2c_device, command, length, data);
}
コード例 #28
0
ファイル: i2cset.c プロジェクト: heartpursue/i2c-tools
int main(int argc, char *argv[])
{
	char *end;
	const char *maskp = NULL;
	int res, i2cbus, address, size, file;
	int value, daddress, vmask = 0;
	char filename[20];
	int pec = 0;
	int flags = 0;
	int force = 0, yes = 0, version = 0, readback = 0;
	unsigned char block[I2C_SMBUS_BLOCK_MAX];
	int len;

	/* handle (optional) flags first */
	while (1+flags < argc && argv[1+flags][0] == '-') {
		switch (argv[1+flags][1]) {
		case 'V': version = 1; break;
		case 'f': force = 1; break;
		case 'y': yes = 1; break;
		case 'm':
			if (2+flags < argc)
				maskp = argv[2+flags];
			flags++;
			break;
		case 'r': readback = 1; break;
		default:
			fprintf(stderr, "Error: Unsupported option "
				"\"%s\"!\n", argv[1+flags]);
			help();
			exit(1);
		}
		flags++;
	}

	if (version) {
		fprintf(stderr, "i2cset version %s\n", VERSION);
		exit(0);
	}

	if (argc < flags + 4)
		help();

	i2cbus = lookup_i2c_bus(argv[flags+1]);
	if (i2cbus < 0)
		help();

	address = parse_i2c_address(argv[flags+2]);
	if (address < 0)
		help();

	daddress = strtol(argv[flags+3], &end, 0);
	if (*end || daddress < 0 || daddress > 0xff) {
		fprintf(stderr, "Error: Data address invalid!\n");
		help();
	}

	/* check for command/mode */
	if (argc == flags + 4) {
		/* Implicit "c" */
		size = I2C_SMBUS_BYTE;
	} else if (argc == flags + 5) {
		/* "c", "cp",  or implicit "b" */
		if (!strcmp(argv[flags+4], "c")
		 || !strcmp(argv[flags+4], "cp")) {
			size = I2C_SMBUS_BYTE;
			pec = argv[flags+4][1] == 'p';
		} else {
			size = I2C_SMBUS_BYTE_DATA;
		}
	} else {
		/* All other commands */
		if (strlen(argv[argc-1]) > 2
		    || (strlen(argv[argc-1]) == 2 && argv[argc-1][1] != 'p')) {
			fprintf(stderr, "Error: Invalid mode '%s'!\n", argv[argc-1]);
			help();
		}
		switch (argv[argc-1][0]) {
		case 'b': size = I2C_SMBUS_BYTE_DATA; break;
		case 'w': size = I2C_SMBUS_WORD_DATA; break;
		case 's': size = I2C_SMBUS_BLOCK_DATA; break;
		case 'i': size = I2C_SMBUS_I2C_BLOCK_DATA; break;
		default:
			fprintf(stderr, "Error: Invalid mode '%s'!\n", argv[argc-1]);
			help();
		}
		pec = argv[argc-1][1] == 'p';
		if (size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA) {
			if (pec && size == I2C_SMBUS_I2C_BLOCK_DATA) {
				fprintf(stderr, "Error: PEC not supported for I2C block writes!\n");
				help();
			}
			if (maskp) {
				fprintf(stderr, "Error: Mask not supported for block writes!\n");
				help();
			}
			if (argc > (int)sizeof(block) + flags + 5) {
				fprintf(stderr, "Error: Too many arguments!\n");
				help();
			}
		} else if (argc != flags + 6) {
			fprintf(stderr, "Error: Too many arguments!\n");
			help();
		}
	}

	len = 0; /* Must always initialize len since it is passed to confirm() */

	/* read values from command line */
	switch (size) {
	case I2C_SMBUS_BYTE_DATA:
	case I2C_SMBUS_WORD_DATA:
		value = strtol(argv[flags+4], &end, 0);
		if (*end || value < 0) {
			fprintf(stderr, "Error: Data value invalid!\n");
			help();
		}
		if ((size == I2C_SMBUS_BYTE_DATA && value > 0xff)
		    || (size == I2C_SMBUS_WORD_DATA && value > 0xffff)) {
			fprintf(stderr, "Error: Data value out of range!\n");
			help();
		}
		break;
	case I2C_SMBUS_BLOCK_DATA:
	case I2C_SMBUS_I2C_BLOCK_DATA:
		for (len = 0; len + flags + 5 < argc; len++) {
			value = strtol(argv[flags + len + 4], &end, 0);
			if (*end || value < 0) {
				fprintf(stderr, "Error: Data value invalid!\n");
				help();
			}
			if (value > 0xff) {
				fprintf(stderr, "Error: Data value out of range!\n");
				help();
			}
			block[len] = value;
		}
		value = -1;
		break;
	default:
		value = -1;
		break;
	}

	if (maskp) {
		vmask = strtol(maskp, &end, 0);
		if (*end || vmask == 0) {
			fprintf(stderr, "Error: Data value mask invalid!\n");
			help();
		}
		if (((size == I2C_SMBUS_BYTE || size == I2C_SMBUS_BYTE_DATA)
		     && vmask > 0xff) || vmask > 0xffff) {
			fprintf(stderr, "Error: Data value mask out of range!\n");
			help();
		}
	}

	file = open_i2c_dev(i2cbus, filename, sizeof(filename), 0);
	if (file < 0
	 || check_funcs(file, size, pec)
	 || set_slave_addr(file, address, force))
		exit(1);

	if (!yes && !confirm(filename, address, size, daddress,
			     value, vmask, block, len, pec))
		exit(0);

	if (vmask) {
		int oldvalue;

		switch (size) {
		case I2C_SMBUS_BYTE:
			oldvalue = i2c_smbus_read_byte(file);
			break;
		case I2C_SMBUS_WORD_DATA:
			oldvalue = i2c_smbus_read_word_data(file, daddress);
			break;
		default:
			oldvalue = i2c_smbus_read_byte_data(file, daddress);
		}

		if (oldvalue < 0) {
			fprintf(stderr, "Error: Failed to read old value\n");
			exit(1);
		}

		value = (value & vmask) | (oldvalue & ~vmask);

		if (!yes) {
			fprintf(stderr, "Old value 0x%0*x, write mask "
				"0x%0*x: Will write 0x%0*x to register "
				"0x%02x\n",
				size == I2C_SMBUS_WORD_DATA ? 4 : 2, oldvalue,
				size == I2C_SMBUS_WORD_DATA ? 4 : 2, vmask,
				size == I2C_SMBUS_WORD_DATA ? 4 : 2, value,
				daddress);

			fprintf(stderr, "Continue? [Y/n] ");
			fflush(stderr);
			if (!user_ack(1)) {
				fprintf(stderr, "Aborting on user request.\n");
				exit(0);
			}
		}
	}

	if (pec && ioctl(file, I2C_PEC, 1) < 0) {
		fprintf(stderr, "Error: Could not set PEC: %s\n",
			strerror(errno));
		close(file);
		exit(1);
	}

	switch (size) {
	case I2C_SMBUS_BYTE:
		res = i2c_smbus_write_byte(file, daddress);
		break;
	case I2C_SMBUS_WORD_DATA:
		res = i2c_smbus_write_word_data(file, daddress, value);
		break;
	case I2C_SMBUS_BLOCK_DATA:
		res = i2c_smbus_write_block_data(file, daddress, len, block);
		break;
	case I2C_SMBUS_I2C_BLOCK_DATA:
		res = i2c_smbus_write_i2c_block_data(file, daddress, len, block);
		break;
	default: /* I2C_SMBUS_BYTE_DATA */
		res = i2c_smbus_write_byte_data(file, daddress, value);
		break;
	}
	if (res < 0) {
		fprintf(stderr, "Error: Write failed\n");
		close(file);
		exit(1);
	}

	if (pec) {
		if (ioctl(file, I2C_PEC, 0) < 0) {
			fprintf(stderr, "Error: Could not clear PEC: %s\n",
				strerror(errno));
			close(file);
			exit(1);
		}
	}

	if (!readback) { /* We're done */
		close(file);
		exit(0);
	}

	switch (size) {
	case I2C_SMBUS_BYTE:
		res = i2c_smbus_read_byte(file);
		value = daddress;
		break;
	case I2C_SMBUS_WORD_DATA:
		res = i2c_smbus_read_word_data(file, daddress);
		break;
	default: /* I2C_SMBUS_BYTE_DATA */
		res = i2c_smbus_read_byte_data(file, daddress);
	}
	close(file);

	if (res < 0) {
		printf("Warning - readback failed\n");
	} else
	if (res != value) {
		printf("Warning - data mismatch - wrote "
		       "0x%0*x, read back 0x%0*x\n",
		       size == I2C_SMBUS_WORD_DATA ? 4 : 2, value,
		       size == I2C_SMBUS_WORD_DATA ? 4 : 2, res);
	} else {
		printf("Value 0x%0*x written, readback matched\n",
		       size == I2C_SMBUS_WORD_DATA ? 4 : 2, value);
	}

	exit(0);
}