drivers/usb/misc/usbsevseg.c

Source file repositories/reference/linux-study-clean/drivers/usb/misc/usbsevseg.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/misc/usbsevseg.c
Extension
.c
Size
9612 bytes
Lines
396
Domain
Driver Families
Bucket
drivers/usb
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct usb_sevsegdev {
	struct usb_device *udev;
	struct usb_interface *intf;

	u8 powered;
	u8 mode_msb;
	u8 mode_lsb;
	u8 decimals[MAXLEN];
	u8 textmode;
	u8 text[MAXLEN];
	u16 textlength;

	u8 shadow_power; /* for PM */
	u8 has_interface_pm;
};

/* sysfs_streq can't replace this completely
 * If the device was in hex mode, and the user wanted a 0,
 * if str commands are used, we would assume the end of string
 * so mem commands are used.
 */
static inline size_t my_memlen(const char *buf, size_t count)
{
	if (count > 0 && buf[count-1] == '\n')
		return count - 1;
	else
		return count;
}

static void update_display_powered(struct usb_sevsegdev *mydev)
{
	int rc;

	if (mydev->powered && !mydev->has_interface_pm) {
		rc = usb_autopm_get_interface(mydev->intf);
		if (rc < 0)
			return;
		mydev->has_interface_pm = 1;
	}

	if (mydev->shadow_power != 1)
		return;

	rc = usb_control_msg_send(mydev->udev, 0, 0x12, 0x48,
				  (80 * 0x100) + 10, /*  (power mode) */
				  (0x00 * 0x100) + (mydev->powered ? 1 : 0),
				  NULL, 0, 2000, GFP_KERNEL);
	if (rc < 0)
		dev_dbg(&mydev->udev->dev, "power retval = %d\n", rc);

	if (!mydev->powered && mydev->has_interface_pm) {
		usb_autopm_put_interface(mydev->intf);
		mydev->has_interface_pm = 0;
	}
}

static void update_display_mode(struct usb_sevsegdev *mydev)
{
	int rc;

	if(mydev->shadow_power != 1)
		return;

	rc = usb_control_msg_send(mydev->udev, 0, 0x12, 0x48,
				  (82 * 0x100) + 10, /* (set mode) */
				  (mydev->mode_msb * 0x100) + mydev->mode_lsb,
				  NULL, 0, 2000, GFP_NOIO);

	if (rc < 0)
		dev_dbg(&mydev->udev->dev, "mode retval = %d\n", rc);
}

static void update_display_visual(struct usb_sevsegdev *mydev, gfp_t mf)
{
	int rc;
	int i;
	unsigned char buffer[MAXLEN] = {0};
	u8 decimals = 0;

	if(mydev->shadow_power != 1)
		return;

	/* The device is right to left, where as you write left to right */
	for (i = 0; i < mydev->textlength; i++)
		buffer[i] = mydev->text[mydev->textlength-1-i];

	rc = usb_control_msg_send(mydev->udev, 0, 0x12, 0x48,
				  (85 * 0x100) + 10, /* (write text) */
				  (0 * 0x100) + mydev->textmode, /* mode  */
				  &buffer, mydev->textlength, 2000, mf);

Annotation

Implementation Notes