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>
This commit is contained in:
parent
76d17e6ca3
commit
0b5adf92ec
|
@ -8,12 +8,21 @@ Description: Make it possible to switch the PicoLCD device between LCD
|
|||
enclosed in brackets ('[' and ']')
|
||||
|
||||
Writing: causes operation mode switch. Permitted values are
|
||||
the non-active mode names listed when read, optionally followed
|
||||
by a delay value expressed in ms.
|
||||
the non-active mode names listed when read.
|
||||
|
||||
Note: when switching mode the current PicoLCD HID device gets
|
||||
disconnected and reconnects after above delay (default value
|
||||
is 5 seconds though this default should not be relied on).
|
||||
disconnected and reconnects after above delay (see attribute
|
||||
operation_mode_delay for its value).
|
||||
|
||||
|
||||
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/operation_mode_delay
|
||||
Date: April 2010
|
||||
Contact: Bruno Prémont <bonbons@linux-vserver.org>
|
||||
Description: Delay PicoLCD waits before restarting in new mode when
|
||||
operation_mode has changed.
|
||||
|
||||
Reading/Writing: It is expressed in ms and permitted range is
|
||||
0..30000ms.
|
||||
|
||||
|
||||
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/fb_update_rate
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue