Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 196315
b: refs/heads/master
c: 0b5adf9
h: refs/heads/master
i:
  196313: 1a10209
  196311: 1bb8134
v: v3
  • Loading branch information
Bruno Prémont authored and Jiri Kosina committed Apr 27, 2010
1 parent e0dbb1c commit e10e944
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 22 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 76d17e6ca30204532c631d092de41febb3f76b77
refs/heads/master: 0b5adf92ec793c665b0de63ac146d190a921c391
17 changes: 13 additions & 4 deletions trunk/Documentation/ABI/testing/sysfs-driver-hid-picolcd
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
62 changes: 45 additions & 17 deletions trunk/drivers/hid/hid-picolcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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);
Expand All @@ -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
/*
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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:
Expand All @@ -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);
Expand Down

0 comments on commit e10e944

Please sign in to comment.