diff options
author | Bruno Prémont <bonbons@linux-vserver.org> | 2010-04-25 21:29:16 +0200 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2010-04-27 15:31:26 +0200 |
commit | 0b5adf92ec793c665b0de63ac146d190a921c391 (patch) | |
tree | b2476d2a25ec313128f966e24236fd0af1acd5a0 /drivers/hid/hid-picolcd.c | |
parent | 76d17e6ca30204532c631d092de41febb3f76b77 (diff) | |
download | lwn-0b5adf92ec793c665b0de63ac146d190a921c391.tar.gz lwn-0b5adf92ec793c665b0de63ac146d190a921c391.zip |
HID: split picolcd's operation_mode sysfs attribute
Original operation_mode sysfs attribute accepts the operation mode
as main value with an option delay as second value to change
the start-up delay on mode change.
As it is preferred to have exactly one value per sysfs attribute,
extract this delay into a separate sysfs attribute called
operation_mode_delay.
Signed-off-by: Bruno Prémont <bonbons@linux-vserver.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-picolcd.c')
-rw-r--r-- | drivers/hid/hid-picolcd.c | 62 |
1 files changed, 45 insertions, 17 deletions
diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c index 6f71c60bf653..aa6f2e18d4a6 100644 --- a/drivers/hid/hid-picolcd.c +++ b/drivers/hid/hid-picolcd.c @@ -177,6 +177,7 @@ struct picolcd_data { int addr_sz; #endif u8 version[2]; + unsigned short opmode_delay; /* input stuff */ u8 pressed_keys[2]; struct input_dev *input_keys; @@ -1270,8 +1271,7 @@ static ssize_t picolcd_operation_mode_store(struct device *dev, struct picolcd_data *data = dev_get_drvdata(dev); struct hid_report *report = NULL; size_t cnt = count; - int timeout = 5000; - unsigned u; + int timeout = data->opmode_delay; unsigned long flags; if (cnt >= 3 && strncmp("lcd", buf, 3) == 0) { @@ -1288,20 +1288,10 @@ static ssize_t picolcd_operation_mode_store(struct device *dev, if (!report) return -EINVAL; - while (cnt > 0 && (*buf == ' ' || *buf == '\t')) { - buf++; - cnt--; - } while (cnt > 0 && (buf[cnt-1] == '\n' || buf[cnt-1] == '\r')) cnt--; - if (cnt > 0) { - if (sscanf(buf, "%u", &u) != 1) - return -EINVAL; - if (u > 30000) - return -EINVAL; - else - timeout = u; - } + if (cnt != 0) + return -EINVAL; spin_lock_irqsave(&data->lock, flags); hid_set_field(report->field[0], 0, timeout & 0xff); @@ -1314,6 +1304,34 @@ static ssize_t picolcd_operation_mode_store(struct device *dev, static DEVICE_ATTR(operation_mode, 0644, picolcd_operation_mode_show, picolcd_operation_mode_store); +/* + * The "operation_mode_delay" sysfs attribute + */ +static ssize_t picolcd_operation_mode_delay_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct picolcd_data *data = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%hu\n", data->opmode_delay); +} + +static ssize_t picolcd_operation_mode_delay_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct picolcd_data *data = dev_get_drvdata(dev); + unsigned u; + if (sscanf(buf, "%u", &u) != 1) + return -EINVAL; + if (u > 30000) + return -EINVAL; + else + data->opmode_delay = u; + return count; +} + +static DEVICE_ATTR(operation_mode_delay, 0644, picolcd_operation_mode_delay_show, + picolcd_operation_mode_delay_store); + #ifdef CONFIG_DEBUG_FS /* @@ -2409,6 +2427,7 @@ static int picolcd_probe(struct hid_device *hdev, spin_lock_init(&data->lock); mutex_init(&data->mutex); data->hdev = hdev; + data->opmode_delay = 5000; if (hdev->product == USB_DEVICE_ID_PICOLCD_BOOTLOADER) data->status |= PICOLCD_BOOTLOADER; hid_set_drvdata(hdev, data); @@ -2436,24 +2455,32 @@ static int picolcd_probe(struct hid_device *hdev, goto err_cleanup_hid_hw; } - error = device_create_file(&hdev->dev, &dev_attr_operation_mode); + error = device_create_file(&hdev->dev, &dev_attr_operation_mode_delay); if (error) { dev_err(&hdev->dev, "failed to create sysfs attributes\n"); goto err_cleanup_hid_ll; } + error = device_create_file(&hdev->dev, &dev_attr_operation_mode); + if (error) { + dev_err(&hdev->dev, "failed to create sysfs attributes\n"); + goto err_cleanup_sysfs1; + } + if (data->status & PICOLCD_BOOTLOADER) error = picolcd_probe_bootloader(hdev, data); else error = picolcd_probe_lcd(hdev, data); if (error) - goto err_cleanup_sysfs; + goto err_cleanup_sysfs2; dbg_hid(PICOLCD_NAME " activated and initialized\n"); return 0; -err_cleanup_sysfs: +err_cleanup_sysfs2: device_remove_file(&hdev->dev, &dev_attr_operation_mode); +err_cleanup_sysfs1: + device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay); err_cleanup_hid_ll: hdev->ll_driver->close(hdev); err_cleanup_hid_hw: @@ -2478,6 +2505,7 @@ static void picolcd_remove(struct hid_device *hdev) picolcd_exit_devfs(data); device_remove_file(&hdev->dev, &dev_attr_operation_mode); + device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay); hdev->ll_driver->close(hdev); hid_hw_stop(hdev); hid_set_drvdata(hdev, NULL); |