View difference between Paste ID: ihzBfkPE and SGNjWUd5
SHOW: | | - or go back to the newest paste.
1
#include <linux/init.h>
2
3
#include <linux/module.h>
4
#include <linux/backlight.h>
5
#include <linux/usb.h>
6
7
#include <linux/kernel.h>
8
#include <linux/slab.h>
9
10
#include "usb-pkk-backlight.h"
11
static void urb_out_complete(struct urb *urb)
12
{
13
	return;
14
}
15
16
static int pkk_bl_get_brightness(struct backlight_device *bdev)
17
{
18
	struct pkk_bl_data *data = bl_get_data(bdev);
19
20
	//uint8_t *brightness = &bdev->props.brightness; //Not sure, that this is right
21
	uint8_t *brightness = &data->brightness;
22
	printk(KERN_INFO PKK_BL_DRIVER_NAME "Brightness get function called. Current brightness: %d.\n", *brightness);
23
	return *brightness;
24
}
25
26
static int pkk_bl_set_brightness(struct backlight_device *bdev)
27
{
28
	struct pkk_bl_data *data = bl_get_data(bdev);
29
30
	//uint8_t *brightness = &bdev->props.brightness; //Not sure, that this is right
31
	uint8_t *brightness = &data->brightness;
32
	unsigned char *transfer_buffer_out = data->transfer_buffer_out;
33
	int error;
34
	printk("%s(): data->transfer_buffer_out = %p\n", __FUNCTION__, data->transfer_buffer_out);
35
	*brightness = bdev->props.brightness;
36
	printk(KERN_INFO PKK_BL_DRIVER_NAME "Brightness set function called. New brightness: %d.\n", *brightness);
37
	*transfer_buffer_out = PKK_BL_CMD_SET_BRIGHTNESS;
38
	transfer_buffer_out++;
39
	*transfer_buffer_out = *brightness;
40
	error = usb_submit_urb(data->urb, GFP_KERNEL);
41
	if (data->urb->status != 0 || error != 0) {
42
		printk(KERN_ERR PKK_BL_DRIVER_NAME "Urb submit failled. Urb status: %d. Usb_submit_urb returned:%d.\n",
43
		       data->urb->status, error);
44
	}
45
	return 0;
46
}
47
48
static const struct backlight_ops pkk_bl_blops = {
49
	.update_status = pkk_bl_set_brightness,
50
	.get_brightness = pkk_bl_get_brightness,
51
};
52
53
static int pkk_bl_init_backlight(struct pkk_bl_data *data)	// I'm not sure that it should be static
54
{
55
	struct device *dev = &data->intf->dev;
56
	struct backlight_device *bdev;
57
	struct backlight_properties props;
58
	printk(KERN_INFO PKK_BL_DRIVER_NAME "Backlight device initialization...\n");
59
	if (data->intf == 0) {
60
		printk(KERN_ERR PKK_BL_DRIVER_NAME "%s(): no such interface\n", __FUNCTION__);
61
		return -ENODEV;
62
	}
63
	/* PicoLCD - There was sommething for hid_report */
64
	memset(&props, 0, sizeof(props));
65
	props.type = BACKLIGHT_RAW;	//I don't know what is it
66
	props.max_brightness = PKK_BL_MAX_BRIGHTNESS;
67
	printk("%s(): data->intf = %p\ndev = %p\ndata = %p\n", __FUNCTION__, data->intf, (void *)dev, data);
68
	printk("%s(): dev_name(dev) = %s\ndev = %p\ndata = %p\n", __FUNCTION__, dev_name(dev), (void *)dev, data);
69
	bdev = backlight_device_register(dev_name(dev), dev, data, &pkk_bl_blops, &props);
70
	if (IS_ERR(bdev)) {
71
		printk(KERN_ERR PKK_BL_DRIVER_NAME "Failed to register backlight.\n");
72
		return PTR_ERR(bdev);
73
	}
74
	printk(KERN_INFO PKK_BL_DRIVER_NAME "%s():%d", __FUNCTION__, __LINE__); 
75
	bdev->props.brightness = PKK_BL_DEFAULT_BRIGHTNESS;
76
	data->bdev = bdev;
77
	pkk_bl_set_brightness(bdev);
78
	printk(KERN_INFO PKK_BL_DRIVER_NAME "Backlight device initialized.\n");
79
	return 0;
80
}
81
82
static void pkk_bl_exit_backlight(struct pkk_bl_data *data)	// I'm not sure that it should be static
83
{
84
	struct backlight_device *bdev = data->bdev;
85
	printk(KERN_INFO PKK_BL_DRIVER_NAME "Backlight device unregistering...\n");
86
	data->bdev = NULL;
87
	if (bdev)
88
		backlight_device_unregister(bdev);
89
	printk(KERN_INFO PKK_BL_DRIVER_NAME "Backlight device unregistered successfully.\n");
90
}
91
92
static int pkk_bl_probe(struct usb_interface *intf, const struct usb_device_id *id)
93
{
94
	struct pkk_bl_data *data;
95
	int error = 0;
96
	struct urb *urb;
97
	unsigned char *transfer_buffer_out;
98
	struct usb_device *udev = interface_to_usbdev(intf);
99
100
	if (intf == NULL) {
101
		printk(KERN_ERR "%s(): no such interface\n", __FUNCTION__);
102
		error = -ENODEV;
103
		goto err_nodev;
104
	}
105
	printk(KERN_INFO PKK_BL_DRIVER_NAME "Hardware probe...\n");
106
107
	/* Varibles initialization and assigments */
108
	data = kzalloc(sizeof(struct pkk_bl_data), GFP_KERNEL);
109
	if (data == NULL) {
110
		printk(KERN_ERR PKK_BL_DRIVER_NAME "Can't allocate space for device data.\n");
111
		error = -ENOMEM;
112
		goto err_no_cleanup;
113
	}
114
115
	/* PicoLCD - There was synchronization elements (initialization & using) */
116
	dev_set_drvdata(&intf->dev, data);
117
	printk("pkk_bl_probe: intf = %p\n", (void *)intf);
118
	printk("pkk_bl_probe: &intf->dev = %p\n", (void *)&intf->dev);
119
120
	/* Filling data structure */
121
	data->udev_id = (struct usb_device_id *)id;
122
	data->udev = udev;
123
	data->intf = intf;
124
125
	/* Modules initialization */
126
	urb = usb_alloc_urb(0, GFP_KERNEL);
127
	if (urb == NULL) {
128
		printk(KERN_ERR PKK_BL_DRIVER_NAME "Can't initializate urb.\n");
129
		goto err_exit_backlight;
130
	}
131
	data->urb = urb;
132
	transfer_buffer_out = kzalloc(sizeof(unsigned char) * PKK_BL_TRANSFER_BUFFER_OUT_SIZE, GFP_KERNEL);
133
	if (transfer_buffer_out == NULL) {
134
		printk(KERN_ERR PKK_BL_DRIVER_NAME "Can't allocate space for transfer buffer (out).\n");
135
		error = -ENOMEM;
136
		goto err_urb_cleanup;
137
	}
138
139
	data->transfer_buffer_out = transfer_buffer_out;
140
	error = pkk_bl_init_backlight(data);
141
	if (error) {
142
		pkk_bl_exit_backlight(data);
143
		printk(KERN_ERR PKK_BL_DRIVER_NAME "Can't initializate backlight device.\n");
144
		goto err_cleanup_data;
145
	}
146
147
    usb_fill_int_urb(urb, udev, usb_rcvintpipe(to_usb_device(&intf->dev), PKK_BL_OUT_ENDPOINT), transfer_buffer_out, PKK_BL_TRANSFER_BUFFER_OUT_SIZE, urb_out_complete, data, PKK_BL_OUT_INTERVAL);
148
	printk(KERN_INFO PKK_BL_DRIVER_NAME "Device activated and initialized.\n");
149
	return 0;
150
 err_cleanup_data:kfree(data);
151
 err_urb_cleanup:usb_free_urb(urb);
152
 err_exit_backlight:pkk_bl_exit_backlight(data);
153
 err_no_cleanup:
154
	//dev_set_drvdata(&intf->dev, NULL); - intf->dev->data Wasn't assigned in this step(dev_setdrvdata wasn't called
155
 err_nodev:
156
	return error;
157
}
158
159
static void pkk_bl_disconnect(struct usb_interface *intf)
160
{
161
	struct pkk_bl_data *data = dev_get_drvdata(&intf->dev);
162
	printk(KERN_INFO PKK_BL_DRIVER_NAME "Hardware remove...\n");
163
164
	/* PicoLCD - There was synchronization elements (removing & using) */
165
	pkk_bl_exit_backlight(data);
166
	dev_set_drvdata(&intf->dev, NULL);
167
	usb_free_urb(data->urb);
168
	kfree(data->transfer_buffer_out);
169
	kfree(data);
170
	printk(KERN_INFO PKK_BL_DRIVER_NAME "Device disconnected successfully.\n");
171
}
172
173
static struct usb_device_id pkk_bl_devices[] = {
174
	{ USB_DEVICE(USB_VENDOR_ID_PKK_BL, USB_DEVICE_ID_PKK_BL) },
175
	{}
176
};
177
178
MODULE_DEVICE_TABLE(usb, pkk_bl_devices);
179
static struct usb_driver pkk_bl_driver = {
180
	.name = "usb_pkk_backlight",
181
	.id_table = pkk_bl_devices,
182
	.probe = pkk_bl_probe,
183
	.disconnect = pkk_bl_disconnect,
184
};
185
186
module_usb_driver(pkk_bl_driver);
187
MODULE_DESCRIPTION("PKK USB backlight driver");
188
MODULE_LICENSE("GPL v2");
189
MODULE_AUTHOR("Dmitry Chepurovskiy <dm3chip@gmail.com>");