Loading drivers/hid/hid-cp2112.c +32 −34 Original line number Diff line number Diff line Loading @@ -17,11 +17,13 @@ */ #include <linux/bitops.h> #include <linux/cleanup.h> #include <linux/gpio/driver.h> #include <linux/hid.h> #include <linux/hidraw.h> #include <linux/i2c.h> #include <linux/module.h> #include <linux/mutex.h> #include <linux/nls.h> #include <linux/string_choices.h> #include <linux/usb/ch9.h> Loading Loading @@ -185,7 +187,7 @@ static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset) u8 *buf = dev->in_out_buffer; int ret; mutex_lock(&dev->lock); guard(mutex)(&dev->lock); ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf, CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT, Loading @@ -194,7 +196,7 @@ static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset) hid_err(hdev, "error requesting GPIO config: %d\n", ret); if (ret >= 0) ret = -EIO; goto exit; return ret; } buf[1] &= ~BIT(offset); Loading @@ -207,25 +209,19 @@ static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset) hid_err(hdev, "error setting GPIO config: %d\n", ret); if (ret >= 0) ret = -EIO; goto exit; return ret; } ret = 0; exit: mutex_unlock(&dev->lock); return ret; return 0; } static void cp2112_gpio_set(struct gpio_chip *chip, unsigned offset, int value) static int cp2112_gpio_set_unlocked(struct cp2112_device *dev, unsigned int offset, int value) { struct cp2112_device *dev = gpiochip_get_data(chip); struct hid_device *hdev = dev->hdev; u8 *buf = dev->in_out_buffer; int ret; mutex_lock(&dev->lock); buf[0] = CP2112_GPIO_SET; buf[1] = value ? CP2112_GPIO_ALL_GPIO_MASK : 0; buf[2] = BIT(offset); Loading @@ -236,7 +232,17 @@ static void cp2112_gpio_set(struct gpio_chip *chip, unsigned offset, int value) if (ret < 0) hid_err(hdev, "error setting GPIO values: %d\n", ret); mutex_unlock(&dev->lock); return ret; } static int cp2112_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { struct cp2112_device *dev = gpiochip_get_data(chip); guard(mutex)(&dev->lock); return cp2112_gpio_set_unlocked(dev, offset, value); } static int cp2112_gpio_get_all(struct gpio_chip *chip) Loading @@ -246,23 +252,17 @@ static int cp2112_gpio_get_all(struct gpio_chip *chip) u8 *buf = dev->in_out_buffer; int ret; mutex_lock(&dev->lock); guard(mutex)(&dev->lock); ret = hid_hw_raw_request(hdev, CP2112_GPIO_GET, buf, CP2112_GPIO_GET_LENGTH, HID_FEATURE_REPORT, HID_REQ_GET_REPORT); if (ret != CP2112_GPIO_GET_LENGTH) { hid_err(hdev, "error requesting GPIO values: %d\n", ret); ret = ret < 0 ? ret : -EIO; goto exit; return ret < 0 ? ret : -EIO; } ret = buf[1]; exit: mutex_unlock(&dev->lock); return ret; return buf[1]; } static int cp2112_gpio_get(struct gpio_chip *chip, unsigned int offset) Loading @@ -284,14 +284,14 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip, u8 *buf = dev->in_out_buffer; int ret; mutex_lock(&dev->lock); guard(mutex)(&dev->lock); ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf, CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT, HID_REQ_GET_REPORT); if (ret != CP2112_GPIO_CONFIG_LENGTH) { hid_err(hdev, "error requesting GPIO config: %d\n", ret); goto fail; return ret < 0 ? ret : -EIO; } buf[1] |= 1 << offset; Loading @@ -302,22 +302,16 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip, HID_REQ_SET_REPORT); if (ret < 0) { hid_err(hdev, "error setting GPIO config: %d\n", ret); goto fail; return ret; } mutex_unlock(&dev->lock); /* * Set gpio value when output direction is already set, * as specified in AN495, Rev. 0.2, cpt. 4.4 */ cp2112_gpio_set(chip, offset, value); cp2112_gpio_set_unlocked(dev, offset, value); return 0; fail: mutex_unlock(&dev->lock); return ret < 0 ? ret : -EIO; } static int cp2112_hid_get(struct hid_device *hdev, unsigned char report_number, Loading Loading @@ -1205,7 +1199,11 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id) if (!dev->in_out_buffer) return -ENOMEM; mutex_init(&dev->lock); ret = devm_mutex_init(&hdev->dev, &dev->lock); if (ret) { hid_err(hdev, "mutex init failed\n"); return ret; } ret = hid_parse(hdev); if (ret) { Loading Loading @@ -1290,7 +1288,7 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id) dev->gc.label = "cp2112_gpio"; dev->gc.direction_input = cp2112_gpio_direction_input; dev->gc.direction_output = cp2112_gpio_direction_output; dev->gc.set = cp2112_gpio_set; dev->gc.set_rv = cp2112_gpio_set; dev->gc.get = cp2112_gpio_get; dev->gc.base = -1; dev->gc.ngpio = CP2112_GPIO_MAX_GPIO; Loading drivers/hid/hid-mcp2200.c +14 −9 Original line number Diff line number Diff line Loading @@ -127,7 +127,7 @@ static int mcp_cmd_read_all(struct mcp2200 *mcp) return mcp->status; } static void mcp_set_multiple(struct gpio_chip *gc, unsigned long *mask, static int mcp_set_multiple(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits) { struct mcp2200 *mcp = gpiochip_get_data(gc); Loading @@ -150,16 +150,20 @@ static void mcp_set_multiple(struct gpio_chip *gc, unsigned long *mask, if (status == sizeof(struct mcp_set_clear_outputs)) mcp->gpio_val = value; else status = -EIO; mutex_unlock(&mcp->lock); return status; } static void mcp_set(struct gpio_chip *gc, unsigned int gpio_nr, int value) static int mcp_set(struct gpio_chip *gc, unsigned int gpio_nr, int value) { unsigned long mask = 1 << gpio_nr; unsigned long bmap_value = value << gpio_nr; mcp_set_multiple(gc, &mask, &bmap_value); return mcp_set_multiple(gc, &mask, &bmap_value); } static int mcp_get_multiple(struct gpio_chip *gc, unsigned long *mask, Loading Loading @@ -263,9 +267,10 @@ static int mcp_direction_output(struct gpio_chip *gc, unsigned int gpio_nr, bmap_value = value << gpio_nr; ret = mcp_set_direction(gc, gpio_nr, MCP2200_DIR_OUT); if (!ret) mcp_set_multiple(gc, &mask, &bmap_value); if (ret) return ret; return mcp_set_multiple(gc, &mask, &bmap_value); } static const struct gpio_chip template_chip = { Loading @@ -274,8 +279,8 @@ static const struct gpio_chip template_chip = { .get_direction = mcp_get_direction, .direction_input = mcp_direction_input, .direction_output = mcp_direction_output, .set = mcp_set, .set_multiple = mcp_set_multiple, .set_rv = mcp_set, .set_multiple_rv = mcp_set_multiple, .get = mcp_get, .get_multiple = mcp_get_multiple, .base = -1, Loading drivers/hid/hid-mcp2221.c +6 −4 Original line number Diff line number Diff line Loading @@ -624,10 +624,10 @@ static int mcp_gpio_get(struct gpio_chip *gc, return ret; } static void mcp_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) static int mcp_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) { struct mcp2221 *mcp = gpiochip_get_data(gc); int ret; memset(mcp->txbuf, 0, 18); mcp->txbuf[0] = MCP2221_GPIO_SET; Loading @@ -638,8 +638,10 @@ static void mcp_gpio_set(struct gpio_chip *gc, mcp->txbuf[mcp->gp_idx] = !!value; mutex_lock(&mcp->lock); mcp_send_data_req_status(mcp, mcp->txbuf, 18); ret = mcp_send_data_req_status(mcp, mcp->txbuf, 18); mutex_unlock(&mcp->lock); return ret; } static int mcp_gpio_dir_set(struct mcp2221 *mcp, Loading Loading @@ -1206,7 +1208,7 @@ static int mcp2221_probe(struct hid_device *hdev, mcp->gc->direction_input = mcp_gpio_direction_input; mcp->gc->direction_output = mcp_gpio_direction_output; mcp->gc->get_direction = mcp_gpio_get_direction; mcp->gc->set = mcp_gpio_set; mcp->gc->set_rv = mcp_gpio_set; mcp->gc->get = mcp_gpio_get; mcp->gc->ngpio = MCP_NGPIO; mcp->gc->base = -1; Loading Loading
drivers/hid/hid-cp2112.c +32 −34 Original line number Diff line number Diff line Loading @@ -17,11 +17,13 @@ */ #include <linux/bitops.h> #include <linux/cleanup.h> #include <linux/gpio/driver.h> #include <linux/hid.h> #include <linux/hidraw.h> #include <linux/i2c.h> #include <linux/module.h> #include <linux/mutex.h> #include <linux/nls.h> #include <linux/string_choices.h> #include <linux/usb/ch9.h> Loading Loading @@ -185,7 +187,7 @@ static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset) u8 *buf = dev->in_out_buffer; int ret; mutex_lock(&dev->lock); guard(mutex)(&dev->lock); ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf, CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT, Loading @@ -194,7 +196,7 @@ static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset) hid_err(hdev, "error requesting GPIO config: %d\n", ret); if (ret >= 0) ret = -EIO; goto exit; return ret; } buf[1] &= ~BIT(offset); Loading @@ -207,25 +209,19 @@ static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset) hid_err(hdev, "error setting GPIO config: %d\n", ret); if (ret >= 0) ret = -EIO; goto exit; return ret; } ret = 0; exit: mutex_unlock(&dev->lock); return ret; return 0; } static void cp2112_gpio_set(struct gpio_chip *chip, unsigned offset, int value) static int cp2112_gpio_set_unlocked(struct cp2112_device *dev, unsigned int offset, int value) { struct cp2112_device *dev = gpiochip_get_data(chip); struct hid_device *hdev = dev->hdev; u8 *buf = dev->in_out_buffer; int ret; mutex_lock(&dev->lock); buf[0] = CP2112_GPIO_SET; buf[1] = value ? CP2112_GPIO_ALL_GPIO_MASK : 0; buf[2] = BIT(offset); Loading @@ -236,7 +232,17 @@ static void cp2112_gpio_set(struct gpio_chip *chip, unsigned offset, int value) if (ret < 0) hid_err(hdev, "error setting GPIO values: %d\n", ret); mutex_unlock(&dev->lock); return ret; } static int cp2112_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { struct cp2112_device *dev = gpiochip_get_data(chip); guard(mutex)(&dev->lock); return cp2112_gpio_set_unlocked(dev, offset, value); } static int cp2112_gpio_get_all(struct gpio_chip *chip) Loading @@ -246,23 +252,17 @@ static int cp2112_gpio_get_all(struct gpio_chip *chip) u8 *buf = dev->in_out_buffer; int ret; mutex_lock(&dev->lock); guard(mutex)(&dev->lock); ret = hid_hw_raw_request(hdev, CP2112_GPIO_GET, buf, CP2112_GPIO_GET_LENGTH, HID_FEATURE_REPORT, HID_REQ_GET_REPORT); if (ret != CP2112_GPIO_GET_LENGTH) { hid_err(hdev, "error requesting GPIO values: %d\n", ret); ret = ret < 0 ? ret : -EIO; goto exit; return ret < 0 ? ret : -EIO; } ret = buf[1]; exit: mutex_unlock(&dev->lock); return ret; return buf[1]; } static int cp2112_gpio_get(struct gpio_chip *chip, unsigned int offset) Loading @@ -284,14 +284,14 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip, u8 *buf = dev->in_out_buffer; int ret; mutex_lock(&dev->lock); guard(mutex)(&dev->lock); ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf, CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT, HID_REQ_GET_REPORT); if (ret != CP2112_GPIO_CONFIG_LENGTH) { hid_err(hdev, "error requesting GPIO config: %d\n", ret); goto fail; return ret < 0 ? ret : -EIO; } buf[1] |= 1 << offset; Loading @@ -302,22 +302,16 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip, HID_REQ_SET_REPORT); if (ret < 0) { hid_err(hdev, "error setting GPIO config: %d\n", ret); goto fail; return ret; } mutex_unlock(&dev->lock); /* * Set gpio value when output direction is already set, * as specified in AN495, Rev. 0.2, cpt. 4.4 */ cp2112_gpio_set(chip, offset, value); cp2112_gpio_set_unlocked(dev, offset, value); return 0; fail: mutex_unlock(&dev->lock); return ret < 0 ? ret : -EIO; } static int cp2112_hid_get(struct hid_device *hdev, unsigned char report_number, Loading Loading @@ -1205,7 +1199,11 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id) if (!dev->in_out_buffer) return -ENOMEM; mutex_init(&dev->lock); ret = devm_mutex_init(&hdev->dev, &dev->lock); if (ret) { hid_err(hdev, "mutex init failed\n"); return ret; } ret = hid_parse(hdev); if (ret) { Loading Loading @@ -1290,7 +1288,7 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id) dev->gc.label = "cp2112_gpio"; dev->gc.direction_input = cp2112_gpio_direction_input; dev->gc.direction_output = cp2112_gpio_direction_output; dev->gc.set = cp2112_gpio_set; dev->gc.set_rv = cp2112_gpio_set; dev->gc.get = cp2112_gpio_get; dev->gc.base = -1; dev->gc.ngpio = CP2112_GPIO_MAX_GPIO; Loading
drivers/hid/hid-mcp2200.c +14 −9 Original line number Diff line number Diff line Loading @@ -127,7 +127,7 @@ static int mcp_cmd_read_all(struct mcp2200 *mcp) return mcp->status; } static void mcp_set_multiple(struct gpio_chip *gc, unsigned long *mask, static int mcp_set_multiple(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits) { struct mcp2200 *mcp = gpiochip_get_data(gc); Loading @@ -150,16 +150,20 @@ static void mcp_set_multiple(struct gpio_chip *gc, unsigned long *mask, if (status == sizeof(struct mcp_set_clear_outputs)) mcp->gpio_val = value; else status = -EIO; mutex_unlock(&mcp->lock); return status; } static void mcp_set(struct gpio_chip *gc, unsigned int gpio_nr, int value) static int mcp_set(struct gpio_chip *gc, unsigned int gpio_nr, int value) { unsigned long mask = 1 << gpio_nr; unsigned long bmap_value = value << gpio_nr; mcp_set_multiple(gc, &mask, &bmap_value); return mcp_set_multiple(gc, &mask, &bmap_value); } static int mcp_get_multiple(struct gpio_chip *gc, unsigned long *mask, Loading Loading @@ -263,9 +267,10 @@ static int mcp_direction_output(struct gpio_chip *gc, unsigned int gpio_nr, bmap_value = value << gpio_nr; ret = mcp_set_direction(gc, gpio_nr, MCP2200_DIR_OUT); if (!ret) mcp_set_multiple(gc, &mask, &bmap_value); if (ret) return ret; return mcp_set_multiple(gc, &mask, &bmap_value); } static const struct gpio_chip template_chip = { Loading @@ -274,8 +279,8 @@ static const struct gpio_chip template_chip = { .get_direction = mcp_get_direction, .direction_input = mcp_direction_input, .direction_output = mcp_direction_output, .set = mcp_set, .set_multiple = mcp_set_multiple, .set_rv = mcp_set, .set_multiple_rv = mcp_set_multiple, .get = mcp_get, .get_multiple = mcp_get_multiple, .base = -1, Loading
drivers/hid/hid-mcp2221.c +6 −4 Original line number Diff line number Diff line Loading @@ -624,10 +624,10 @@ static int mcp_gpio_get(struct gpio_chip *gc, return ret; } static void mcp_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) static int mcp_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) { struct mcp2221 *mcp = gpiochip_get_data(gc); int ret; memset(mcp->txbuf, 0, 18); mcp->txbuf[0] = MCP2221_GPIO_SET; Loading @@ -638,8 +638,10 @@ static void mcp_gpio_set(struct gpio_chip *gc, mcp->txbuf[mcp->gp_idx] = !!value; mutex_lock(&mcp->lock); mcp_send_data_req_status(mcp, mcp->txbuf, 18); ret = mcp_send_data_req_status(mcp, mcp->txbuf, 18); mutex_unlock(&mcp->lock); return ret; } static int mcp_gpio_dir_set(struct mcp2221 *mcp, Loading Loading @@ -1206,7 +1208,7 @@ static int mcp2221_probe(struct hid_device *hdev, mcp->gc->direction_input = mcp_gpio_direction_input; mcp->gc->direction_output = mcp_gpio_direction_output; mcp->gc->get_direction = mcp_gpio_get_direction; mcp->gc->set = mcp_gpio_set; mcp->gc->set_rv = mcp_gpio_set; mcp->gc->get = mcp_gpio_get; mcp->gc->ngpio = MCP_NGPIO; mcp->gc->base = -1; Loading