15fd54aceSGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 2eb86be54SHarrison Metzger /* 3eb86be54SHarrison Metzger * USB 7 Segment Driver 4eb86be54SHarrison Metzger * 5eb86be54SHarrison Metzger * Copyright (C) 2008 Harrison Metzger <harrisonmetz@gmail.com> 6eb86be54SHarrison Metzger * Based on usbled.c by Greg Kroah-Hartman (greg@kroah.com) 7eb86be54SHarrison Metzger */ 8eb86be54SHarrison Metzger 9eb86be54SHarrison Metzger #include <linux/kernel.h> 10eb86be54SHarrison Metzger #include <linux/errno.h> 11eb86be54SHarrison Metzger #include <linux/slab.h> 12eb86be54SHarrison Metzger #include <linux/module.h> 13eb86be54SHarrison Metzger #include <linux/string.h> 14eb86be54SHarrison Metzger #include <linux/usb.h> 15eb86be54SHarrison Metzger 16eb86be54SHarrison Metzger 17eb86be54SHarrison Metzger #define DRIVER_AUTHOR "Harrison Metzger <harrisonmetz@gmail.com>" 18eb86be54SHarrison Metzger #define DRIVER_DESC "USB 7 Segment Driver" 19eb86be54SHarrison Metzger 20eb86be54SHarrison Metzger #define VENDOR_ID 0x0fc5 21eb86be54SHarrison Metzger #define PRODUCT_ID 0x1227 221097ccebSHarrison Metzger #define MAXLEN 8 23eb86be54SHarrison Metzger 24eb86be54SHarrison Metzger /* table of devices that work with this driver */ 2533b9e162SNémeth Márton static const struct usb_device_id id_table[] = { 26eb86be54SHarrison Metzger { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, 27eb86be54SHarrison Metzger { }, 28eb86be54SHarrison Metzger }; 29eb86be54SHarrison Metzger MODULE_DEVICE_TABLE(usb, id_table); 30eb86be54SHarrison Metzger 31eb86be54SHarrison Metzger /* the different text display modes the device is capable of */ 320bd08fc8SAndy Shevchenko static const char *display_textmodes[] = {"raw", "hex", "ascii"}; 33eb86be54SHarrison Metzger 34eb86be54SHarrison Metzger struct usb_sevsegdev { 35eb86be54SHarrison Metzger struct usb_device *udev; 364d155eb5SOliver Neukum struct usb_interface *intf; 37eb86be54SHarrison Metzger 38eb86be54SHarrison Metzger u8 powered; 39eb86be54SHarrison Metzger u8 mode_msb; 40eb86be54SHarrison Metzger u8 mode_lsb; 41eb86be54SHarrison Metzger u8 decimals[MAXLEN]; 42eb86be54SHarrison Metzger u8 textmode; 43eb86be54SHarrison Metzger u8 text[MAXLEN]; 44eb86be54SHarrison Metzger u16 textlength; 454d155eb5SOliver Neukum 464d155eb5SOliver Neukum u8 shadow_power; /* for PM */ 474c1f5c88SHarrison Metzger u8 has_interface_pm; 48eb86be54SHarrison Metzger }; 49eb86be54SHarrison Metzger 50eb86be54SHarrison Metzger /* sysfs_streq can't replace this completely 51eb86be54SHarrison Metzger * If the device was in hex mode, and the user wanted a 0, 52eb86be54SHarrison Metzger * if str commands are used, we would assume the end of string 53eb86be54SHarrison Metzger * so mem commands are used. 54eb86be54SHarrison Metzger */ 55ff4708e6SRashika Kheria static inline size_t my_memlen(const char *buf, size_t count) 56eb86be54SHarrison Metzger { 57eb86be54SHarrison Metzger if (count > 0 && buf[count-1] == '\n') 58eb86be54SHarrison Metzger return count - 1; 59eb86be54SHarrison Metzger else 60eb86be54SHarrison Metzger return count; 61eb86be54SHarrison Metzger } 62eb86be54SHarrison Metzger 63eb86be54SHarrison Metzger static void update_display_powered(struct usb_sevsegdev *mydev) 64eb86be54SHarrison Metzger { 65eb86be54SHarrison Metzger int rc; 66eb86be54SHarrison Metzger 674c1f5c88SHarrison Metzger if (mydev->powered && !mydev->has_interface_pm) { 684d155eb5SOliver Neukum rc = usb_autopm_get_interface(mydev->intf); 694d155eb5SOliver Neukum if (rc < 0) 704d155eb5SOliver Neukum return; 714c1f5c88SHarrison Metzger mydev->has_interface_pm = 1; 724d155eb5SOliver Neukum } 734d155eb5SOliver Neukum 744c1f5c88SHarrison Metzger if (mydev->shadow_power != 1) 754c1f5c88SHarrison Metzger return; 764c1f5c88SHarrison Metzger 7738833cbdSAnant Thazhemadam rc = usb_control_msg_send(mydev->udev, 0, 0x12, 0x48, 78eb86be54SHarrison Metzger (80 * 0x100) + 10, /* (power mode) */ 79eb86be54SHarrison Metzger (0x00 * 0x100) + (mydev->powered ? 1 : 0), 8038833cbdSAnant Thazhemadam NULL, 0, 2000, GFP_KERNEL); 81eb86be54SHarrison Metzger if (rc < 0) 82eb86be54SHarrison Metzger dev_dbg(&mydev->udev->dev, "power retval = %d\n", rc); 834d155eb5SOliver Neukum 844c1f5c88SHarrison Metzger if (!mydev->powered && mydev->has_interface_pm) { 854d155eb5SOliver Neukum usb_autopm_put_interface(mydev->intf); 864c1f5c88SHarrison Metzger mydev->has_interface_pm = 0; 874c1f5c88SHarrison Metzger } 88eb86be54SHarrison Metzger } 89eb86be54SHarrison Metzger 90eb86be54SHarrison Metzger static void update_display_mode(struct usb_sevsegdev *mydev) 91eb86be54SHarrison Metzger { 92eb86be54SHarrison Metzger int rc; 93eb86be54SHarrison Metzger 944d155eb5SOliver Neukum if(mydev->shadow_power != 1) 954d155eb5SOliver Neukum return; 964d155eb5SOliver Neukum 9738833cbdSAnant Thazhemadam rc = usb_control_msg_send(mydev->udev, 0, 0x12, 0x48, 98eb86be54SHarrison Metzger (82 * 0x100) + 10, /* (set mode) */ 99eb86be54SHarrison Metzger (mydev->mode_msb * 0x100) + mydev->mode_lsb, 10038833cbdSAnant Thazhemadam NULL, 0, 2000, GFP_NOIO); 101eb86be54SHarrison Metzger 102eb86be54SHarrison Metzger if (rc < 0) 103eb86be54SHarrison Metzger dev_dbg(&mydev->udev->dev, "mode retval = %d\n", rc); 104eb86be54SHarrison Metzger } 105eb86be54SHarrison Metzger 1064d155eb5SOliver Neukum static void update_display_visual(struct usb_sevsegdev *mydev, gfp_t mf) 107eb86be54SHarrison Metzger { 108eb86be54SHarrison Metzger int rc; 109eb86be54SHarrison Metzger int i; 11038833cbdSAnant Thazhemadam unsigned char buffer[MAXLEN] = {0}; 111eb86be54SHarrison Metzger u8 decimals = 0; 112eb86be54SHarrison Metzger 1134d155eb5SOliver Neukum if(mydev->shadow_power != 1) 1144d155eb5SOliver Neukum return; 1154d155eb5SOliver Neukum 116eb86be54SHarrison Metzger /* The device is right to left, where as you write left to right */ 117eb86be54SHarrison Metzger for (i = 0; i < mydev->textlength; i++) 118eb86be54SHarrison Metzger buffer[i] = mydev->text[mydev->textlength-1-i]; 119eb86be54SHarrison Metzger 12038833cbdSAnant Thazhemadam rc = usb_control_msg_send(mydev->udev, 0, 0x12, 0x48, 121eb86be54SHarrison Metzger (85 * 0x100) + 10, /* (write text) */ 122eb86be54SHarrison Metzger (0 * 0x100) + mydev->textmode, /* mode */ 12338833cbdSAnant Thazhemadam &buffer, mydev->textlength, 2000, mf); 124eb86be54SHarrison Metzger 125eb86be54SHarrison Metzger if (rc < 0) 126eb86be54SHarrison Metzger dev_dbg(&mydev->udev->dev, "write retval = %d\n", rc); 127eb86be54SHarrison Metzger 128eb86be54SHarrison Metzger /* The device is right to left, where as you write left to right */ 129eb86be54SHarrison Metzger for (i = 0; i < sizeof(mydev->decimals); i++) 130eb86be54SHarrison Metzger decimals |= mydev->decimals[i] << i; 131eb86be54SHarrison Metzger 13238833cbdSAnant Thazhemadam rc = usb_control_msg_send(mydev->udev, 0, 0x12, 0x48, 133eb86be54SHarrison Metzger (86 * 0x100) + 10, /* (set decimal) */ 134eb86be54SHarrison Metzger (0 * 0x100) + decimals, /* decimals */ 13538833cbdSAnant Thazhemadam NULL, 0, 2000, mf); 136eb86be54SHarrison Metzger 137eb86be54SHarrison Metzger if (rc < 0) 138eb86be54SHarrison Metzger dev_dbg(&mydev->udev->dev, "decimal retval = %d\n", rc); 139eb86be54SHarrison Metzger } 140eb86be54SHarrison Metzger 141eb86be54SHarrison Metzger #define MYDEV_ATTR_SIMPLE_UNSIGNED(name, update_fcn) \ 142a86856dbSGreg Kroah-Hartman static ssize_t name##_show(struct device *dev, \ 143eb86be54SHarrison Metzger struct device_attribute *attr, char *buf) \ 144eb86be54SHarrison Metzger { \ 145eb86be54SHarrison Metzger struct usb_interface *intf = to_usb_interface(dev); \ 146eb86be54SHarrison Metzger struct usb_sevsegdev *mydev = usb_get_intfdata(intf); \ 147eb86be54SHarrison Metzger \ 148eb86be54SHarrison Metzger return sprintf(buf, "%u\n", mydev->name); \ 149eb86be54SHarrison Metzger } \ 150eb86be54SHarrison Metzger \ 151a86856dbSGreg Kroah-Hartman static ssize_t name##_store(struct device *dev, \ 152eb86be54SHarrison Metzger struct device_attribute *attr, const char *buf, size_t count) \ 153eb86be54SHarrison Metzger { \ 154eb86be54SHarrison Metzger struct usb_interface *intf = to_usb_interface(dev); \ 155eb86be54SHarrison Metzger struct usb_sevsegdev *mydev = usb_get_intfdata(intf); \ 156eb86be54SHarrison Metzger \ 157eb86be54SHarrison Metzger mydev->name = simple_strtoul(buf, NULL, 10); \ 158eb86be54SHarrison Metzger update_fcn(mydev); \ 159eb86be54SHarrison Metzger \ 160eb86be54SHarrison Metzger return count; \ 161eb86be54SHarrison Metzger } \ 162a86856dbSGreg Kroah-Hartman static DEVICE_ATTR_RW(name); 163eb86be54SHarrison Metzger 164ed5bd7a4SGreg Kroah-Hartman static ssize_t text_show(struct device *dev, 165eb86be54SHarrison Metzger struct device_attribute *attr, char *buf) 166eb86be54SHarrison Metzger { 167eb86be54SHarrison Metzger struct usb_interface *intf = to_usb_interface(dev); 168eb86be54SHarrison Metzger struct usb_sevsegdev *mydev = usb_get_intfdata(intf); 169eb86be54SHarrison Metzger 170e0c6b1f3SXuezhi Zhang return sysfs_emit(buf, "%s\n", mydev->text); 171eb86be54SHarrison Metzger } 172eb86be54SHarrison Metzger 173ed5bd7a4SGreg Kroah-Hartman static ssize_t text_store(struct device *dev, 174eb86be54SHarrison Metzger struct device_attribute *attr, const char *buf, size_t count) 175eb86be54SHarrison Metzger { 176eb86be54SHarrison Metzger struct usb_interface *intf = to_usb_interface(dev); 177eb86be54SHarrison Metzger struct usb_sevsegdev *mydev = usb_get_intfdata(intf); 178eb86be54SHarrison Metzger size_t end = my_memlen(buf, count); 179eb86be54SHarrison Metzger 180eb86be54SHarrison Metzger if (end > sizeof(mydev->text)) 181eb86be54SHarrison Metzger return -EINVAL; 182eb86be54SHarrison Metzger 183eb86be54SHarrison Metzger memset(mydev->text, 0, sizeof(mydev->text)); 184eb86be54SHarrison Metzger mydev->textlength = end; 185eb86be54SHarrison Metzger 186eb86be54SHarrison Metzger if (end > 0) 187eb86be54SHarrison Metzger memcpy(mydev->text, buf, end); 188eb86be54SHarrison Metzger 1894d155eb5SOliver Neukum update_display_visual(mydev, GFP_KERNEL); 190eb86be54SHarrison Metzger return count; 191eb86be54SHarrison Metzger } 192eb86be54SHarrison Metzger 193ed5bd7a4SGreg Kroah-Hartman static DEVICE_ATTR_RW(text); 194eb86be54SHarrison Metzger 195ed5bd7a4SGreg Kroah-Hartman static ssize_t decimals_show(struct device *dev, 196eb86be54SHarrison Metzger struct device_attribute *attr, char *buf) 197eb86be54SHarrison Metzger { 198eb86be54SHarrison Metzger struct usb_interface *intf = to_usb_interface(dev); 199eb86be54SHarrison Metzger struct usb_sevsegdev *mydev = usb_get_intfdata(intf); 200eb86be54SHarrison Metzger int i; 201eb86be54SHarrison Metzger int pos; 202eb86be54SHarrison Metzger 203eb86be54SHarrison Metzger for (i = 0; i < sizeof(mydev->decimals); i++) { 204eb86be54SHarrison Metzger pos = sizeof(mydev->decimals) - 1 - i; 205eb86be54SHarrison Metzger if (mydev->decimals[i] == 0) 206eb86be54SHarrison Metzger buf[pos] = '0'; 207eb86be54SHarrison Metzger else if (mydev->decimals[i] == 1) 208eb86be54SHarrison Metzger buf[pos] = '1'; 209eb86be54SHarrison Metzger else 210eb86be54SHarrison Metzger buf[pos] = 'x'; 211eb86be54SHarrison Metzger } 212eb86be54SHarrison Metzger 213eb86be54SHarrison Metzger buf[sizeof(mydev->decimals)] = '\n'; 214eb86be54SHarrison Metzger return sizeof(mydev->decimals) + 1; 215eb86be54SHarrison Metzger } 216eb86be54SHarrison Metzger 217ed5bd7a4SGreg Kroah-Hartman static ssize_t decimals_store(struct device *dev, 218eb86be54SHarrison Metzger struct device_attribute *attr, const char *buf, size_t count) 219eb86be54SHarrison Metzger { 220eb86be54SHarrison Metzger struct usb_interface *intf = to_usb_interface(dev); 221eb86be54SHarrison Metzger struct usb_sevsegdev *mydev = usb_get_intfdata(intf); 222eb86be54SHarrison Metzger size_t end = my_memlen(buf, count); 223eb86be54SHarrison Metzger int i; 224eb86be54SHarrison Metzger 225eb86be54SHarrison Metzger if (end > sizeof(mydev->decimals)) 226eb86be54SHarrison Metzger return -EINVAL; 227eb86be54SHarrison Metzger 228eb86be54SHarrison Metzger for (i = 0; i < end; i++) 229eb86be54SHarrison Metzger if (buf[i] != '0' && buf[i] != '1') 230eb86be54SHarrison Metzger return -EINVAL; 231eb86be54SHarrison Metzger 232eb86be54SHarrison Metzger memset(mydev->decimals, 0, sizeof(mydev->decimals)); 233eb86be54SHarrison Metzger for (i = 0; i < end; i++) 234eb86be54SHarrison Metzger if (buf[i] == '1') 235eb86be54SHarrison Metzger mydev->decimals[end-1-i] = 1; 236eb86be54SHarrison Metzger 2374d155eb5SOliver Neukum update_display_visual(mydev, GFP_KERNEL); 238eb86be54SHarrison Metzger 239eb86be54SHarrison Metzger return count; 240eb86be54SHarrison Metzger } 241eb86be54SHarrison Metzger 242ed5bd7a4SGreg Kroah-Hartman static DEVICE_ATTR_RW(decimals); 243eb86be54SHarrison Metzger 244ed5bd7a4SGreg Kroah-Hartman static ssize_t textmode_show(struct device *dev, 245eb86be54SHarrison Metzger struct device_attribute *attr, char *buf) 246eb86be54SHarrison Metzger { 247eb86be54SHarrison Metzger struct usb_interface *intf = to_usb_interface(dev); 248eb86be54SHarrison Metzger struct usb_sevsegdev *mydev = usb_get_intfdata(intf); 249eb86be54SHarrison Metzger int i; 250eb86be54SHarrison Metzger 251eb86be54SHarrison Metzger buf[0] = 0; 252eb86be54SHarrison Metzger 2530bd08fc8SAndy Shevchenko for (i = 0; i < ARRAY_SIZE(display_textmodes); i++) { 254eb86be54SHarrison Metzger if (mydev->textmode == i) { 255eb86be54SHarrison Metzger strcat(buf, " ["); 256eb86be54SHarrison Metzger strcat(buf, display_textmodes[i]); 257eb86be54SHarrison Metzger strcat(buf, "] "); 258eb86be54SHarrison Metzger } else { 259eb86be54SHarrison Metzger strcat(buf, " "); 260eb86be54SHarrison Metzger strcat(buf, display_textmodes[i]); 261eb86be54SHarrison Metzger strcat(buf, " "); 262eb86be54SHarrison Metzger } 263eb86be54SHarrison Metzger } 264eb86be54SHarrison Metzger strcat(buf, "\n"); 265eb86be54SHarrison Metzger 266eb86be54SHarrison Metzger 267eb86be54SHarrison Metzger return strlen(buf); 268eb86be54SHarrison Metzger } 269eb86be54SHarrison Metzger 270ed5bd7a4SGreg Kroah-Hartman static ssize_t textmode_store(struct device *dev, 271eb86be54SHarrison Metzger struct device_attribute *attr, const char *buf, size_t count) 272eb86be54SHarrison Metzger { 273eb86be54SHarrison Metzger struct usb_interface *intf = to_usb_interface(dev); 274eb86be54SHarrison Metzger struct usb_sevsegdev *mydev = usb_get_intfdata(intf); 275eb86be54SHarrison Metzger int i; 276eb86be54SHarrison Metzger 2770bd08fc8SAndy Shevchenko i = sysfs_match_string(display_textmodes, buf); 2780bd08fc8SAndy Shevchenko if (i < 0) 2790bd08fc8SAndy Shevchenko return i; 2800bd08fc8SAndy Shevchenko 281eb86be54SHarrison Metzger mydev->textmode = i; 2824d155eb5SOliver Neukum update_display_visual(mydev, GFP_KERNEL); 283eb86be54SHarrison Metzger return count; 284eb86be54SHarrison Metzger } 285eb86be54SHarrison Metzger 286ed5bd7a4SGreg Kroah-Hartman static DEVICE_ATTR_RW(textmode); 287eb86be54SHarrison Metzger 288eb86be54SHarrison Metzger 289eb86be54SHarrison Metzger MYDEV_ATTR_SIMPLE_UNSIGNED(powered, update_display_powered); 290eb86be54SHarrison Metzger MYDEV_ATTR_SIMPLE_UNSIGNED(mode_msb, update_display_mode); 291eb86be54SHarrison Metzger MYDEV_ATTR_SIMPLE_UNSIGNED(mode_lsb, update_display_mode); 292eb86be54SHarrison Metzger 293a21350feSGreg Kroah-Hartman static struct attribute *sevseg_attrs[] = { 294eb86be54SHarrison Metzger &dev_attr_powered.attr, 295eb86be54SHarrison Metzger &dev_attr_text.attr, 296eb86be54SHarrison Metzger &dev_attr_textmode.attr, 297eb86be54SHarrison Metzger &dev_attr_decimals.attr, 298eb86be54SHarrison Metzger &dev_attr_mode_msb.attr, 299eb86be54SHarrison Metzger &dev_attr_mode_lsb.attr, 300eb86be54SHarrison Metzger NULL 301eb86be54SHarrison Metzger }; 302a21350feSGreg Kroah-Hartman ATTRIBUTE_GROUPS(sevseg); 303eb86be54SHarrison Metzger 304eb86be54SHarrison Metzger static int sevseg_probe(struct usb_interface *interface, 305eb86be54SHarrison Metzger const struct usb_device_id *id) 306eb86be54SHarrison Metzger { 307eb86be54SHarrison Metzger struct usb_device *udev = interface_to_usbdev(interface); 308*f87ba66aSRuan Jinjie struct usb_sevsegdev *mydev; 309eb86be54SHarrison Metzger int rc = -ENOMEM; 310eb86be54SHarrison Metzger 311eb86be54SHarrison Metzger mydev = kzalloc(sizeof(struct usb_sevsegdev), GFP_KERNEL); 312bcf0848dSWolfram Sang if (!mydev) 313eb86be54SHarrison Metzger goto error_mem; 314eb86be54SHarrison Metzger 315eb86be54SHarrison Metzger mydev->udev = usb_get_dev(udev); 3164d155eb5SOliver Neukum mydev->intf = interface; 317eb86be54SHarrison Metzger usb_set_intfdata(interface, mydev); 318eb86be54SHarrison Metzger 3194c1f5c88SHarrison Metzger /* PM */ 3204c1f5c88SHarrison Metzger mydev->shadow_power = 1; /* currently active */ 3214c1f5c88SHarrison Metzger mydev->has_interface_pm = 0; /* have not issued autopm_get */ 3224c1f5c88SHarrison Metzger 323eb86be54SHarrison Metzger /*set defaults */ 324eb86be54SHarrison Metzger mydev->textmode = 0x02; /* ascii mode */ 325eb86be54SHarrison Metzger mydev->mode_msb = 0x06; /* 6 characters */ 326eb86be54SHarrison Metzger mydev->mode_lsb = 0x3f; /* scanmode for 6 chars */ 327eb86be54SHarrison Metzger 328eb86be54SHarrison Metzger dev_info(&interface->dev, "USB 7 Segment device now attached\n"); 329eb86be54SHarrison Metzger return 0; 330eb86be54SHarrison Metzger 331eb86be54SHarrison Metzger error_mem: 332eb86be54SHarrison Metzger return rc; 333eb86be54SHarrison Metzger } 334eb86be54SHarrison Metzger 335eb86be54SHarrison Metzger static void sevseg_disconnect(struct usb_interface *interface) 336eb86be54SHarrison Metzger { 337eb86be54SHarrison Metzger struct usb_sevsegdev *mydev; 338eb86be54SHarrison Metzger 339eb86be54SHarrison Metzger mydev = usb_get_intfdata(interface); 340eb86be54SHarrison Metzger usb_set_intfdata(interface, NULL); 341eb86be54SHarrison Metzger usb_put_dev(mydev->udev); 342eb86be54SHarrison Metzger kfree(mydev); 343eb86be54SHarrison Metzger dev_info(&interface->dev, "USB 7 Segment now disconnected\n"); 344eb86be54SHarrison Metzger } 345eb86be54SHarrison Metzger 3464d155eb5SOliver Neukum static int sevseg_suspend(struct usb_interface *intf, pm_message_t message) 3474d155eb5SOliver Neukum { 3484d155eb5SOliver Neukum struct usb_sevsegdev *mydev; 3494d155eb5SOliver Neukum 3504d155eb5SOliver Neukum mydev = usb_get_intfdata(intf); 3514d155eb5SOliver Neukum mydev->shadow_power = 0; 3524d155eb5SOliver Neukum 3534d155eb5SOliver Neukum return 0; 3544d155eb5SOliver Neukum } 3554d155eb5SOliver Neukum 3564d155eb5SOliver Neukum static int sevseg_resume(struct usb_interface *intf) 3574d155eb5SOliver Neukum { 3584d155eb5SOliver Neukum struct usb_sevsegdev *mydev; 3594d155eb5SOliver Neukum 3604d155eb5SOliver Neukum mydev = usb_get_intfdata(intf); 3614d155eb5SOliver Neukum mydev->shadow_power = 1; 3624d155eb5SOliver Neukum update_display_mode(mydev); 3634d155eb5SOliver Neukum update_display_visual(mydev, GFP_NOIO); 3644d155eb5SOliver Neukum 3654d155eb5SOliver Neukum return 0; 3664d155eb5SOliver Neukum } 3674d155eb5SOliver Neukum 3684d155eb5SOliver Neukum static int sevseg_reset_resume(struct usb_interface *intf) 3694d155eb5SOliver Neukum { 3704d155eb5SOliver Neukum struct usb_sevsegdev *mydev; 3714d155eb5SOliver Neukum 3724d155eb5SOliver Neukum mydev = usb_get_intfdata(intf); 3734d155eb5SOliver Neukum mydev->shadow_power = 1; 3744d155eb5SOliver Neukum update_display_mode(mydev); 3754d155eb5SOliver Neukum update_display_visual(mydev, GFP_NOIO); 3764d155eb5SOliver Neukum 3774d155eb5SOliver Neukum return 0; 3784d155eb5SOliver Neukum } 3794d155eb5SOliver Neukum 380eb86be54SHarrison Metzger static struct usb_driver sevseg_driver = { 381eb86be54SHarrison Metzger .name = "usbsevseg", 382eb86be54SHarrison Metzger .probe = sevseg_probe, 383eb86be54SHarrison Metzger .disconnect = sevseg_disconnect, 3844d155eb5SOliver Neukum .suspend = sevseg_suspend, 3854d155eb5SOliver Neukum .resume = sevseg_resume, 3864d155eb5SOliver Neukum .reset_resume = sevseg_reset_resume, 387eb86be54SHarrison Metzger .id_table = id_table, 388a21350feSGreg Kroah-Hartman .dev_groups = sevseg_groups, 3894d155eb5SOliver Neukum .supports_autosuspend = 1, 390eb86be54SHarrison Metzger }; 391eb86be54SHarrison Metzger 39265db4305SGreg Kroah-Hartman module_usb_driver(sevseg_driver); 393eb86be54SHarrison Metzger 394eb86be54SHarrison Metzger MODULE_AUTHOR(DRIVER_AUTHOR); 395eb86be54SHarrison Metzger MODULE_DESCRIPTION(DRIVER_DESC); 396eb86be54SHarrison Metzger MODULE_LICENSE("GPL"); 397