/* * rmi_set_page - Set RMI page * @xport: The pointer to the rmi_transport_device struct * @page: The new page address. * * RMI devices have 16-bit addressing, but some of the physical * implementations (like SMBus) only have 8-bit addressing. So RMI implements * a page address at 0xff of every page so we can reliable page addresses * every 256 registers. * * The page_mutex lock must be held when this function is entered. * * Returns zero on success, non-zero on failure. */ static int rmi_set_page(struct rmi_transport_device *xport, u8 page) { struct hid_device *hdev = to_hid_device(xport->dev); struct rmi_hid_data *data = xport->data; int retval; if (COMMS_DEBUG(data)) dev_dbg(&hdev->dev, "writes output report: %*ph\n", data->output_report_size, data->writeReport); xport->info.tx_count++; xport->info.tx_bytes += data->output_report_size; data->writeReport[RMI_HID_REPORT_ID] = RMI_WRITE_REPORT_ID; data->writeReport[RMI_HID_WRITE_OUTPUT_COUNT] = 1; data->writeReport[RMI_HID_WRITE_OUTPUT_ADDR] = 0xFF; data->writeReport[RMI_HID_WRITE_OUTPUT_DATA] = page; retval = rmi_hid_write_report(hdev, data->writeReport, data->output_report_size); if (retval != data->output_report_size) { xport->info.tx_errs++; dev_err(&hdev->dev, "%s: set page failed: %d.", __func__, retval); return retval; } data->page = page; return 0; }
static int rmi_i2c_read_block(struct rmi_phys_device *phys, u16 addr, void *buf, const int len) { struct i2c_client *client = to_i2c_client(phys->dev); struct rmi_i2c_data *data = phys->data; u8 txbuf[1] = {addr & 0xff}; int retval; mutex_lock(&data->page_mutex); if (RMI_I2C_PAGE(addr) != data->page) { retval = rmi_set_page(phys, RMI_I2C_PAGE(addr)); if (retval < 0) goto exit; } if (COMMS_DEBUG(data)) dev_dbg(&client->dev, "writes 1 bytes: %02x\n", txbuf[0]); phys->info.tx_count++; phys->info.tx_bytes += sizeof(txbuf); retval = i2c_master_send(client, txbuf, sizeof(txbuf)); if (retval != sizeof(txbuf)) { phys->info.tx_errs++; retval = (retval < 0) ? retval : -EIO; goto exit; } retval = i2c_master_recv(client, (u8 *) buf, len); phys->info.rx_count++; phys->info.rx_bytes += len; if (retval < 0) phys->info.rx_errs++; else if (COMMS_DEBUG(data)) { retval = copy_to_debug_buf(&client->dev, data, (u8 *) buf, len); if (!retval) dev_dbg(&client->dev, "read %d bytes at %#06x:%s\n", len, addr, data->debug_buf); } exit: mutex_unlock(&data->page_mutex); return retval; }
static int rmi_i2c_write_block(struct rmi_phys_device *phys, u16 addr, const void *buf, const int len) { struct i2c_client *client = to_i2c_client(phys->dev); struct rmi_i2c_data *data = phys->data; int retval; int tx_size = len + 1; mutex_lock(&data->page_mutex); 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] = addr & 0xff; memcpy(data->tx_buf + 1, buf, len); if (RMI_I2C_PAGE(addr) != data->page) { retval = rmi_set_page(phys, RMI_I2C_PAGE(addr)); if (retval < 0) goto exit; } if (COMMS_DEBUG(data)) { retval = copy_to_debug_buf(&client->dev, data, (u8 *) buf, len); if (!retval) dev_dbg(&client->dev, "writes %d bytes at %#06x:%s\n", len, addr, data->debug_buf); } phys->info.tx_count++; phys->info.tx_bytes += tx_size; retval = i2c_master_send(client, data->tx_buf, tx_size); if (retval < 0) phys->info.tx_errs++; else retval--; /* don't count the address byte */ exit: mutex_unlock(&data->page_mutex); return retval; }
static int rmi_hid_write_block(struct rmi_transport_device *xport, u16 addr, const void *buf, const int len) { struct hid_device *hdev = to_hid_device(xport->dev); struct rmi_hid_data *data = xport->data; int ret; mutex_lock(&data->page_mutex); if (RMI_HID_PAGE(addr) != data->page) { ret = rmi_set_page(xport, RMI_HID_PAGE(addr)); if (ret < 0) goto exit; } if (COMMS_DEBUG(data)) { ret = copy_to_debug_buf(&hdev->dev, data, (u8 *) buf, len); if (!ret) dev_dbg(&hdev->dev, "writes %d bytes at %#06x:%s\n", len, addr, data->debug_buf); } xport->info.tx_count++; xport->info.tx_bytes += len; data->writeReport[RMI_HID_REPORT_ID] = RMI_WRITE_REPORT_ID; data->writeReport[RMI_HID_WRITE_OUTPUT_COUNT] = len; data->writeReport[RMI_HID_WRITE_OUTPUT_ADDR] = addr & 0xFF; data->writeReport[RMI_HID_WRITE_OUTPUT_ADDR + 1] = (addr >> 8) & 0xFF; memcpy(&data->writeReport[RMI_HID_WRITE_OUTPUT_DATA], buf, len); ret = rmi_hid_write_report(hdev, data->writeReport, data->output_report_size); if (ret != data->output_report_size) { dev_err(&hdev->dev, "failed to send output report (%d)\n", ret); goto exit; } exit: mutex_unlock(&data->page_mutex); return ret; }
/* * rmi_set_page - Set RMI page * @phys: The pointer to the rmi_phys_device struct * @page: The new page address. * * RMI devices have 16-bit addressing, but some of the physical * implementations (like SMBus) only have 8-bit addressing. So RMI implements * a page address at 0xff of every page so we can reliable page addresses * every 256 registers. * * The page_mutex lock must be held when this function is entered. * * Returns zero on success, non-zero on failure. */ static int rmi_set_page(struct rmi_phys_device *phys, u8 page) { struct i2c_client *client = to_i2c_client(phys->dev); struct rmi_i2c_data *data = phys->data; u8 txbuf[2] = {RMI_PAGE_SELECT_REGISTER, page}; int retval; if (COMMS_DEBUG(data)) dev_dbg(&client->dev, "writes 3 bytes: %02x %02x\n", txbuf[0], txbuf[1]); phys->info.tx_count++; phys->info.tx_bytes += sizeof(txbuf); retval = i2c_master_send(client, txbuf, sizeof(txbuf)); if (retval != sizeof(txbuf)) { phys->info.tx_errs++; dev_err(&client->dev, "%s: set page failed: %d.", __func__, retval); return (retval < 0) ? retval : -EIO; } data->page = page; return 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; }
/*SMB version 2 block read - wrapper over ic2_smb_read_block */ static int smb_v2_block_read(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 retval; /* mutex_lock(&data->page_mutex); */ retval = i2c_smbus_read_block_data(client, commandcode, buf); phys->info.rx_count++; phys->info.rx_bytes += len; if (retval < 0) { phys->info.rx_errs++; return retval; } else if (COMMS_DEBUG(data) && !copy_to_debug_buf(&client->dev, data, buf, len)) dev_dbg(&client->dev, "read %d bytes for command %#04x:%s\n", len, commandcode, data->debug_buf); /* mutex_unlock(&data->page_mutex); */ return retval; }
static int rmi_hid_read_block(struct rmi_transport_device *xport, u16 addr, void *buf, const int len) { struct hid_device *hdev = to_hid_device(xport->dev); struct rmi_hid_data *data = xport->data; int ret; int bytes_read; int bytes_needed; int retries; int read_input_count; mutex_lock(&data->page_mutex); if (RMI_HID_PAGE(addr) != data->page) { ret = rmi_set_page(xport, RMI_HID_PAGE(addr)); if (ret < 0) goto exit; } for (retries = 5; retries > 0; retries--) { data->writeReport[RMI_HID_REPORT_ID] = RMI_READ_ADDR_REPORT_ID; data->writeReport[1] = 0; /* old 1 byte read count */ data->writeReport[RMI_HID_READ_OUTPUT_ADDR] = addr & 0xFF; data->writeReport[RMI_HID_READ_OUTPUT_ADDR + 1] = (addr >> 8) & 0xFF; data->writeReport[RMI_HID_READ_OUTPUT_COUNT] = len & 0xFF; data->writeReport[RMI_HID_READ_OUTPUT_COUNT + 1] = (len >> 8) & 0xFF; if (COMMS_DEBUG(data)) { ret = copy_to_debug_buf(&hdev->dev, data, data->writeReport, len); if (!ret) dev_dbg(&hdev->dev, "wrote %d bytes at %#06x:%s\n", len, addr, data->debug_buf); } set_bit(RMI_HID_READ_REQUEST_PENDING, &data->flags); ret = rmi_hid_write_report(hdev, data->writeReport, data->output_report_size); if (ret != data->output_report_size) { clear_bit(RMI_HID_READ_REQUEST_PENDING, &data->flags); dev_err(&hdev->dev, "failed to write request output report (%d)\n", ret); goto exit; } bytes_read = 0; bytes_needed = len; while (bytes_read < len) { if (!wait_event_timeout(data->wait, test_bit(RMI_HID_READ_DATA_PENDING, &data->flags), msecs_to_jiffies(1000))) { dev_info(&hdev->dev, "%s: timeout elapsed\n", __func__); ret = -ENODATA; break; } else { if (data->readReport[RMI_HID_REPORT_ID] != RMI_READ_DATA_REPORT_ID) { ret = -ENODATA; dev_err(&hdev->dev, "%s: Expected data report, but got" " report id %d instead", __func__, data->readReport[RMI_HID_REPORT_ID]); goto exit; } read_input_count = data->readReport[RMI_HID_READ_INPUT_COUNT]; memcpy(buf + bytes_read, &data->readReport[RMI_HID_READ_INPUT_DATA], read_input_count < bytes_needed ? read_input_count : bytes_needed); if (COMMS_DEBUG(data)) { ret = copy_to_debug_buf(&hdev->dev, data, (u8 *) buf + bytes_read, read_input_count); if (!ret) dev_dbg(&hdev->dev, "read %d bytes at %#06x:%s\n", read_input_count, addr, data->debug_buf); } bytes_read += read_input_count; bytes_needed -= read_input_count; clear_bit(RMI_HID_READ_DATA_PENDING, &data->flags); } } if (bytes_read == len) break; } if (bytes_read == len) { xport->info.rx_count++; xport->info.rx_bytes += len; ret = len; } exit: clear_bit(RMI_HID_READ_REQUEST_PENDING, &data->flags); mutex_unlock(&data->page_mutex); return ret; }