Lines Matching +full:report +full:- +full:error
1 // SPDX-License-Identifier: GPL-2.0-only
3 * hid-cp2112.c - Silicon Labs HID USB to SMBus master bridge
16 …* https://www.silabs.com/documents/public/application-notes/an495-cp2112-interface-specification…
28 #include "hid-ids.h"
73 u8 report; /* CP2112_SMBUS_CONFIG */ member
84 u8 report; /* CP2112_USB_CONFIG */ member
97 u8 report; /* CP2112_DATA_READ_REQUEST */ member
103 u8 report; /* CP2112_DATA_WRITE_READ_REQUEST */ member
111 u8 report; /* CP2112_DATA_WRITE_REQUEST */ member
118 u8 report; /* CP2112_DATA_READ_FORCE_SEND */ member
123 u8 report; /* CP2112_TRANSFER_STATUS_RESPONSE */ member
132 u8 report; /* CP2112_*_STRING */ member
133 u8 length; /* length in bytes of everyting after .report */
177 MODULE_PARM_DESC(gpio_push_pull, "GPIO push-pull configuration bitmask");
182 struct hid_device *hdev = dev->hdev; in cp2112_gpio_direction_input()
183 u8 *buf = dev->in_out_buffer; in cp2112_gpio_direction_input()
186 mutex_lock(&dev->lock); in cp2112_gpio_direction_input()
192 hid_err(hdev, "error requesting GPIO config: %d\n", ret); in cp2112_gpio_direction_input()
194 ret = -EIO; in cp2112_gpio_direction_input()
205 hid_err(hdev, "error setting GPIO config: %d\n", ret); in cp2112_gpio_direction_input()
207 ret = -EIO; in cp2112_gpio_direction_input()
214 mutex_unlock(&dev->lock); in cp2112_gpio_direction_input()
221 struct hid_device *hdev = dev->hdev; in cp2112_gpio_set()
222 u8 *buf = dev->in_out_buffer; in cp2112_gpio_set()
225 mutex_lock(&dev->lock); in cp2112_gpio_set()
235 hid_err(hdev, "error setting GPIO values: %d\n", ret); in cp2112_gpio_set()
237 mutex_unlock(&dev->lock); in cp2112_gpio_set()
243 struct hid_device *hdev = dev->hdev; in cp2112_gpio_get_all()
244 u8 *buf = dev->in_out_buffer; in cp2112_gpio_get_all()
247 mutex_lock(&dev->lock); in cp2112_gpio_get_all()
253 hid_err(hdev, "error requesting GPIO values: %d\n", ret); in cp2112_gpio_get_all()
254 ret = ret < 0 ? ret : -EIO; in cp2112_gpio_get_all()
261 mutex_unlock(&dev->lock); in cp2112_gpio_get_all()
281 struct hid_device *hdev = dev->hdev; in cp2112_gpio_direction_output()
282 u8 *buf = dev->in_out_buffer; in cp2112_gpio_direction_output()
285 mutex_lock(&dev->lock); in cp2112_gpio_direction_output()
291 hid_err(hdev, "error requesting GPIO config: %d\n", ret); in cp2112_gpio_direction_output()
302 hid_err(hdev, "error setting GPIO config: %d\n", ret); in cp2112_gpio_direction_output()
306 mutex_unlock(&dev->lock); in cp2112_gpio_direction_output()
317 mutex_unlock(&dev->lock); in cp2112_gpio_direction_output()
318 return ret < 0 ? ret : -EIO; in cp2112_gpio_direction_output()
329 return -ENOMEM; in cp2112_hid_get()
346 return -ENOMEM; in cp2112_hid_output()
370 ret = wait_event_interruptible_timeout(dev->wait, in cp2112_wait()
372 if (-ERESTARTSYS == ret) in cp2112_wait()
375 return -ETIMEDOUT; in cp2112_wait()
383 struct hid_device *hdev = dev->hdev; in cp2112_xfer_status()
389 atomic_set(&dev->xfer_avail, 0); in cp2112_xfer_status()
393 hid_warn(hdev, "Error requesting status: %d\n", ret); in cp2112_xfer_status()
397 ret = cp2112_wait(dev, &dev->xfer_avail); in cp2112_xfer_status()
401 return dev->xfer_status; in cp2112_xfer_status()
406 struct hid_device *hdev = dev->hdev; in cp2112_read()
407 struct cp2112_force_read_report report; in cp2112_read() local
410 if (size > sizeof(dev->read_data)) in cp2112_read()
411 size = sizeof(dev->read_data); in cp2112_read()
412 report.report = CP2112_DATA_READ_FORCE_SEND; in cp2112_read()
413 report.length = cpu_to_be16(size); in cp2112_read()
415 atomic_set(&dev->read_avail, 0); in cp2112_read()
417 ret = cp2112_hid_output(hdev, &report.report, sizeof(report), in cp2112_read()
420 hid_warn(hdev, "Error requesting data: %d\n", ret); in cp2112_read()
424 ret = cp2112_wait(dev, &dev->read_avail); in cp2112_read()
429 dev->read_length, size); in cp2112_read()
431 if (size > dev->read_length) in cp2112_read()
432 size = dev->read_length; in cp2112_read()
434 memcpy(data, dev->read_data, size); in cp2112_read()
435 return dev->read_length; in cp2112_read()
440 struct cp2112_read_req_report *report = buf; in cp2112_read_req() local
443 return -EINVAL; in cp2112_read_req()
445 report->report = CP2112_DATA_READ_REQUEST; in cp2112_read_req()
446 report->slave_address = slave_address << 1; in cp2112_read_req()
447 report->length = cpu_to_be16(length); in cp2112_read_req()
448 return sizeof(*report); in cp2112_read_req()
454 struct cp2112_write_read_req_report *report = buf; in cp2112_write_read_req() local
457 || data_length > sizeof(report->target_address) - 1) in cp2112_write_read_req()
458 return -EINVAL; in cp2112_write_read_req()
460 report->report = CP2112_DATA_WRITE_READ_REQUEST; in cp2112_write_read_req()
461 report->slave_address = slave_address << 1; in cp2112_write_read_req()
462 report->length = cpu_to_be16(length); in cp2112_write_read_req()
463 report->target_address_length = data_length + 1; in cp2112_write_read_req()
464 report->target_address[0] = command; in cp2112_write_read_req()
465 memcpy(&report->target_address[1], data, data_length); in cp2112_write_read_req()
472 struct cp2112_write_req_report *report = buf; in cp2112_write_req() local
474 if (data_length > sizeof(report->data) - 1) in cp2112_write_req()
475 return -EINVAL; in cp2112_write_req()
477 report->report = CP2112_DATA_WRITE_REQUEST; in cp2112_write_req()
478 report->slave_address = slave_address << 1; in cp2112_write_req()
479 report->length = data_length + 1; in cp2112_write_req()
480 report->data[0] = command; in cp2112_write_req()
481 memcpy(&report->data[1], data, data_length); in cp2112_write_req()
488 struct cp2112_write_req_report *report = buf; in cp2112_i2c_write_req() local
490 if (data_length > sizeof(report->data)) in cp2112_i2c_write_req()
491 return -EINVAL; in cp2112_i2c_write_req()
493 report->report = CP2112_DATA_WRITE_REQUEST; in cp2112_i2c_write_req()
494 report->slave_address = slave_address << 1; in cp2112_i2c_write_req()
495 report->length = data_length; in cp2112_i2c_write_req()
496 memcpy(report->data, data, data_length); in cp2112_i2c_write_req()
504 struct cp2112_write_read_req_report *report = buf; in cp2112_i2c_write_read_req() local
507 addr_length > sizeof(report->target_address)) in cp2112_i2c_write_read_req()
508 return -EINVAL; in cp2112_i2c_write_read_req()
510 report->report = CP2112_DATA_WRITE_READ_REQUEST; in cp2112_i2c_write_read_req()
511 report->slave_address = slave_address << 1; in cp2112_i2c_write_read_req()
512 report->length = cpu_to_be16(read_length); in cp2112_i2c_write_read_req()
513 report->target_address_length = addr_length; in cp2112_i2c_write_read_req()
514 memcpy(report->target_address, addr, addr_length); in cp2112_i2c_write_read_req()
521 struct cp2112_device *dev = (struct cp2112_device *)adap->algo_data; in cp2112_i2c_xfer()
522 struct hid_device *hdev = dev->hdev; in cp2112_i2c_xfer()
533 if (msgs->flags & I2C_M_RD) { in cp2112_i2c_xfer()
535 msgs->addr, msgs->len); in cp2112_i2c_xfer()
536 read_length = msgs->len; in cp2112_i2c_xfer()
537 read_buf = msgs->buf; in cp2112_i2c_xfer()
538 count = cp2112_read_req(buf, msgs->addr, msgs->len); in cp2112_i2c_xfer()
541 msgs->addr, msgs->len); in cp2112_i2c_xfer()
542 count = cp2112_i2c_write_req(buf, msgs->addr, in cp2112_i2c_xfer()
543 msgs->buf, msgs->len); in cp2112_i2c_xfer()
547 } else if (dev->hwversion > 1 && /* no repeated start in rev 1 */ in cp2112_i2c_xfer()
551 hid_dbg(hdev, "I2C write-read %#04x wlen %d rlen %d\n", in cp2112_i2c_xfer()
561 "Multi-message I2C transactions not supported\n"); in cp2112_i2c_xfer()
562 return -EOPNOTSUPP; in cp2112_i2c_xfer()
567 hid_err(hdev, "power management error: %d\n", ret); in cp2112_i2c_xfer()
573 hid_warn(hdev, "Error starting transaction: %d\n", ret); in cp2112_i2c_xfer()
579 if (-EBUSY == ret) in cp2112_i2c_xfer()
593 hid_warn(hdev, "Error cancelling transaction: %d\n", in cp2112_i2c_xfer()
596 ret = -ETIMEDOUT; in cp2112_i2c_xfer()
601 ret = cp2112_read(dev, read_buf + count, read_length - count); in cp2112_i2c_xfer()
606 ret = -EIO; in cp2112_i2c_xfer()
615 * buffer. Nevertheless, we return an error in cp2112_i2c_xfer()
620 ret, read_length - count + ret); in cp2112_i2c_xfer()
621 ret = -EIO; in cp2112_i2c_xfer()
639 struct cp2112_device *dev = (struct cp2112_device *)adap->algo_data; in cp2112_xfer()
640 struct hid_device *hdev = dev->hdev; in cp2112_xfer()
670 &data->byte, 1); in cp2112_xfer()
674 word = cpu_to_le16(data->word); in cp2112_xfer()
687 word = cpu_to_le16(data->word); in cp2112_xfer()
694 read_length = data->block[0]; in cp2112_xfer()
699 data->block + 1, in cp2112_xfer()
700 data->block[0]); in cp2112_xfer()
710 data->block, in cp2112_xfer()
711 data->block[0] + 1); in cp2112_xfer()
719 command, data->block, in cp2112_xfer()
720 data->block[0] + 1); in cp2112_xfer()
724 return -EOPNOTSUPP; in cp2112_xfer()
732 hid_err(hdev, "power management error: %d\n", ret); in cp2112_xfer()
738 hid_warn(hdev, "Error starting transaction: %d\n", ret); in cp2112_xfer()
744 if (-EBUSY == ret) in cp2112_xfer()
758 hid_warn(hdev, "Error cancelling transaction: %d\n", in cp2112_xfer()
761 ret = -ETIMEDOUT; in cp2112_xfer()
778 ret = -EIO; in cp2112_xfer()
785 data->byte = buf[0]; in cp2112_xfer()
788 data->word = le16_to_cpup((__le16 *)buf); in cp2112_xfer()
792 ret = -EINVAL; in cp2112_xfer()
796 memcpy(data->block + 1, buf, read_length); in cp2112_xfer()
800 ret = -EPROTO; in cp2112_xfer()
804 memcpy(data->block, buf, read_length); in cp2112_xfer()
841 hid_err(hdev, "error reading usb config: %d\n", ret); in cp2112_get_usb_config()
844 return -EIO; in cp2112_get_usb_config()
855 BUG_ON(cfg->report != CP2112_USB_CONFIG); in cp2112_set_usb_config()
860 hid_err(hdev, "error writing usb config: %d\n", ret); in cp2112_set_usb_config()
863 return -EIO; in cp2112_set_usb_config()
904 return -EINVAL;
914 return -EINVAL;
924 return -EINVAL;
932 return -EINVAL;
940 return -EINVAL;
949 unsigned char report; member
959 struct cp2112_string_report report; in pstr_store() local
962 memset(&report, 0, sizeof(report)); in pstr_store()
965 report.string, ARRAY_SIZE(report.string)); in pstr_store()
966 report.report = attr->report; in pstr_store()
967 report.length = ret * sizeof(report.string[0]) + 2; in pstr_store()
968 report.type = USB_DT_STRING; in pstr_store()
970 ret = cp2112_hid_output(hdev, &report.report, report.length + 1, in pstr_store()
972 if (ret != report.length + 1) { in pstr_store()
973 hid_err(hdev, "error writing %s string: %d\n", kattr->attr.name, in pstr_store()
977 return -EIO; in pstr_store()
990 struct cp2112_string_report report; in pstr_show() local
994 ret = cp2112_hid_get(hdev, attr->report, &report.report, in pstr_show()
995 sizeof(report) - 1, HID_FEATURE_REPORT); in pstr_show()
997 hid_err(hdev, "error reading %s string: %d\n", kattr->attr.name, in pstr_show()
1001 return -EIO; in pstr_show()
1004 if (report.length < 2) { in pstr_show()
1006 kattr->attr.name, report.length); in pstr_show()
1007 return -EIO; in pstr_show()
1010 length = report.length > ret - 1 ? ret - 1 : report.length; in pstr_show()
1011 length = (length - 2) / sizeof(report.string[0]); in pstr_show()
1012 ret = utf16s_to_utf8s(report.string, length, UTF16_LITTLE_ENDIAN, buf, in pstr_show()
1013 PAGE_SIZE - 1); in pstr_show()
1021 .report = _report, \
1047 * already-programmed fields. This is why there is no sense in fixing this
1059 hid_err(hdev, "error reading lock byte: %d\n", ret); in chmod_sysfs_attrs()
1065 ret = sysfs_chmod_file(&hdev->dev.kobj, *attr, mode); in chmod_sysfs_attrs()
1067 hid_err(hdev, "error chmoding sysfs file %s\n", in chmod_sysfs_attrs()
1068 (*attr)->name); in chmod_sysfs_attrs()
1082 __clear_bit(d->hwirq, &dev->irq_mask); in cp2112_gpio_irq_mask()
1090 __set_bit(d->hwirq, &dev->irq_mask); in cp2112_gpio_irq_unmask()
1099 u8 virqs = (u8)dev->irq_mask; in cp2112_gpio_poll_callback()
1103 ret = cp2112_gpio_get_all(&dev->gc); in cp2112_gpio_poll_callback()
1104 if (ret == -ENODEV) /* the hardware has been disconnected */ in cp2112_gpio_poll_callback()
1112 virq = ffs(virqs) - 1; in cp2112_gpio_poll_callback()
1115 if (!dev->gc.to_irq) in cp2112_gpio_poll_callback()
1118 irq = dev->gc.to_irq(&dev->gc, virq); in cp2112_gpio_poll_callback()
1133 !(dev->gpio_prev_state & BIT(virq))) in cp2112_gpio_poll_callback()
1142 (dev->gpio_prev_state & BIT(virq))) in cp2112_gpio_poll_callback()
1147 dev->gpio_prev_state = gpio_mask; in cp2112_gpio_poll_callback()
1150 if (dev->gpio_poll) in cp2112_gpio_poll_callback()
1151 schedule_delayed_work(&dev->gpio_poll_worker, 10); in cp2112_gpio_poll_callback()
1160 INIT_DELAYED_WORK(&dev->gpio_poll_worker, cp2112_gpio_poll_callback); in cp2112_gpio_irq_startup()
1162 if (!dev->gpio_poll) { in cp2112_gpio_irq_startup()
1163 dev->gpio_poll = true; in cp2112_gpio_irq_startup()
1164 schedule_delayed_work(&dev->gpio_poll_worker, 0); in cp2112_gpio_irq_startup()
1176 cancel_delayed_work_sync(&dev->gpio_poll_worker); in cp2112_gpio_irq_shutdown()
1189 if (dev->desc[pin]) in cp2112_allocate_irq()
1190 return -EINVAL; in cp2112_allocate_irq()
1192 dev->desc[pin] = gpiochip_request_own_desc(&dev->gc, pin, in cp2112_allocate_irq()
1196 if (IS_ERR(dev->desc[pin])) { in cp2112_allocate_irq()
1197 dev_err(dev->gc.parent, "Failed to request GPIO\n"); in cp2112_allocate_irq()
1198 return PTR_ERR(dev->desc[pin]); in cp2112_allocate_irq()
1201 ret = cp2112_gpio_direction_input(&dev->gc, pin); in cp2112_allocate_irq()
1203 dev_err(dev->gc.parent, "Failed to set GPIO to input dir\n"); in cp2112_allocate_irq()
1207 ret = gpiochip_lock_as_irq(&dev->gc, pin); in cp2112_allocate_irq()
1209 dev_err(dev->gc.parent, "Failed to lock GPIO as interrupt\n"); in cp2112_allocate_irq()
1213 ret = gpiod_to_irq(dev->desc[pin]); in cp2112_allocate_irq()
1215 dev_err(dev->gc.parent, "Failed to translate GPIO to IRQ\n"); in cp2112_allocate_irq()
1222 gpiochip_unlock_as_irq(&dev->gc, pin); in cp2112_allocate_irq()
1224 gpiochip_free_own_desc(dev->desc[pin]); in cp2112_allocate_irq()
1225 dev->desc[pin] = NULL; in cp2112_allocate_irq()
1237 dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL); in cp2112_probe()
1239 return -ENOMEM; in cp2112_probe()
1241 dev->in_out_buffer = devm_kzalloc(&hdev->dev, CP2112_REPORT_MAX_LENGTH, in cp2112_probe()
1243 if (!dev->in_out_buffer) in cp2112_probe()
1244 return -ENOMEM; in cp2112_probe()
1246 mutex_init(&dev->lock); in cp2112_probe()
1268 hid_err(hdev, "power management error: %d\n", ret); in cp2112_probe()
1275 hid_err(hdev, "error requesting version\n"); in cp2112_probe()
1277 ret = -EIO; in cp2112_probe()
1287 hid_err(hdev, "error requesting SMBus config\n"); in cp2112_probe()
1289 ret = -EIO; in cp2112_probe()
1298 hid_err(hdev, "error setting SMBus config\n"); in cp2112_probe()
1300 ret = -EIO; in cp2112_probe()
1305 dev->hdev = hdev; in cp2112_probe()
1306 dev->adap.owner = THIS_MODULE; in cp2112_probe()
1307 dev->adap.class = I2C_CLASS_HWMON; in cp2112_probe()
1308 dev->adap.algo = &smbus_algorithm; in cp2112_probe()
1309 dev->adap.algo_data = dev; in cp2112_probe()
1310 dev->adap.dev.parent = &hdev->dev; in cp2112_probe()
1311 snprintf(dev->adap.name, sizeof(dev->adap.name), in cp2112_probe()
1313 ((struct hidraw *)hdev->hidraw)->minor); in cp2112_probe()
1314 dev->hwversion = buf[2]; in cp2112_probe()
1315 init_waitqueue_head(&dev->wait); in cp2112_probe()
1318 ret = i2c_add_adapter(&dev->adap); in cp2112_probe()
1322 hid_err(hdev, "error registering i2c adapter\n"); in cp2112_probe()
1328 dev->gc.label = "cp2112_gpio"; in cp2112_probe()
1329 dev->gc.direction_input = cp2112_gpio_direction_input; in cp2112_probe()
1330 dev->gc.direction_output = cp2112_gpio_direction_output; in cp2112_probe()
1331 dev->gc.set = cp2112_gpio_set; in cp2112_probe()
1332 dev->gc.get = cp2112_gpio_get; in cp2112_probe()
1333 dev->gc.base = -1; in cp2112_probe()
1334 dev->gc.ngpio = 8; in cp2112_probe()
1335 dev->gc.can_sleep = 1; in cp2112_probe()
1336 dev->gc.parent = &hdev->dev; in cp2112_probe()
1338 dev->irq.name = "cp2112-gpio"; in cp2112_probe()
1339 dev->irq.irq_startup = cp2112_gpio_irq_startup; in cp2112_probe()
1340 dev->irq.irq_shutdown = cp2112_gpio_irq_shutdown; in cp2112_probe()
1341 dev->irq.irq_ack = cp2112_gpio_irq_ack; in cp2112_probe()
1342 dev->irq.irq_mask = cp2112_gpio_irq_mask; in cp2112_probe()
1343 dev->irq.irq_unmask = cp2112_gpio_irq_unmask; in cp2112_probe()
1344 dev->irq.irq_set_type = cp2112_gpio_irq_type; in cp2112_probe()
1345 dev->irq.flags = IRQCHIP_MASK_ON_SUSPEND; in cp2112_probe()
1347 girq = &dev->gc.irq; in cp2112_probe()
1348 girq->chip = &dev->irq; in cp2112_probe()
1350 girq->parent_handler = NULL; in cp2112_probe()
1351 girq->num_parents = 0; in cp2112_probe()
1352 girq->parents = NULL; in cp2112_probe()
1353 girq->default_type = IRQ_TYPE_NONE; in cp2112_probe()
1354 girq->handler = handle_simple_irq; in cp2112_probe()
1356 ret = gpiochip_add_data(&dev->gc, dev); in cp2112_probe()
1358 hid_err(hdev, "error registering gpio chip\n"); in cp2112_probe()
1362 ret = sysfs_create_group(&hdev->dev.kobj, &cp2112_attr_group); in cp2112_probe()
1364 hid_err(hdev, "error creating sysfs attrs\n"); in cp2112_probe()
1374 gpiochip_remove(&dev->gc); in cp2112_probe()
1376 i2c_del_adapter(&dev->adap); in cp2112_probe()
1391 sysfs_remove_group(&hdev->dev.kobj, &cp2112_attr_group); in cp2112_remove()
1392 i2c_del_adapter(&dev->adap); in cp2112_remove()
1394 if (dev->gpio_poll) { in cp2112_remove()
1395 dev->gpio_poll = false; in cp2112_remove()
1396 cancel_delayed_work_sync(&dev->gpio_poll_worker); in cp2112_remove()
1399 for (i = 0; i < ARRAY_SIZE(dev->desc); i++) { in cp2112_remove()
1400 gpiochip_unlock_as_irq(&dev->gc, i); in cp2112_remove()
1401 gpiochip_free_own_desc(dev->desc[i]); in cp2112_remove()
1404 gpiochip_remove(&dev->gc); in cp2112_remove()
1408 * waited for device_unregister(&adap->dev) to complete. Therefore we in cp2112_remove()
1415 static int cp2112_raw_event(struct hid_device *hdev, struct hid_report *report, in cp2112_raw_event() argument
1424 xfer->status0, xfer->status1, in cp2112_raw_event()
1425 be16_to_cpu(xfer->retries), be16_to_cpu(xfer->length)); in cp2112_raw_event()
1427 switch (xfer->status0) { in cp2112_raw_event()
1429 dev->xfer_status = -EAGAIN; in cp2112_raw_event()
1432 dev->xfer_status = -EBUSY; in cp2112_raw_event()
1435 dev->xfer_status = be16_to_cpu(xfer->length); in cp2112_raw_event()
1438 switch (xfer->status1) { in cp2112_raw_event()
1441 dev->xfer_status = -ETIMEDOUT; in cp2112_raw_event()
1444 dev->xfer_status = -EIO; in cp2112_raw_event()
1449 dev->xfer_status = -EINVAL; in cp2112_raw_event()
1453 atomic_set(&dev->xfer_avail, 1); in cp2112_raw_event()
1458 dev->read_length = data[2]; in cp2112_raw_event()
1459 if (dev->read_length > sizeof(dev->read_data)) in cp2112_raw_event()
1460 dev->read_length = sizeof(dev->read_data); in cp2112_raw_event()
1462 memcpy(dev->read_data, &data[3], dev->read_length); in cp2112_raw_event()
1463 atomic_set(&dev->read_avail, 1); in cp2112_raw_event()
1466 hid_err(hdev, "unknown report\n"); in cp2112_raw_event()
1471 wake_up_interruptible(&dev->wait); in cp2112_raw_event()