mirror of
https://github.com/torvalds/linux.git
synced 2026-05-22 22:22:08 +02:00
Merge branch 'for-6.16/hid-gpio-setter-callbacks' into for-linus
- adapt HID drivers to use new gpio_chip's line setter callbacks (Bartosz Golaszewski)
This commit is contained in:
commit
17678759ef
|
|
@ -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>
|
||||
|
|
@ -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,
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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;
|
||||
|
|
@ -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,
|
||||
|
|
@ -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) {
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -127,8 +127,8 @@ static int mcp_cmd_read_all(struct mcp2200 *mcp)
|
|||
return mcp->status;
|
||||
}
|
||||
|
||||
static void mcp_set_multiple(struct gpio_chip *gc, unsigned long *mask,
|
||||
unsigned long *bits)
|
||||
static int mcp_set_multiple(struct gpio_chip *gc, unsigned long *mask,
|
||||
unsigned long *bits)
|
||||
{
|
||||
struct mcp2200 *mcp = gpiochip_get_data(gc);
|
||||
u8 value;
|
||||
|
|
@ -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,
|
||||
|
|
@ -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);
|
||||
return ret;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return mcp_set_multiple(gc, &mask, &bmap_value);
|
||||
}
|
||||
|
||||
static const struct gpio_chip template_chip = {
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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,
|
||||
|
|
@ -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…
Reference in New Issue
Block a user