Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
fc73697b
Commit
fc73697b
authored
Aug 04, 2010
by
Jiri Kosina
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'upstream' into for-linus
Conflicts: drivers/hid/hid-ids.h
parents
1c5474a6
8c8b01c3
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
276 additions
and
74 deletions
+276
-74
drivers/hid/Kconfig
drivers/hid/Kconfig
+6
-0
drivers/hid/Makefile
drivers/hid/Makefile
+1
-0
drivers/hid/hid-core.c
drivers/hid/hid-core.c
+1
-0
drivers/hid/hid-elecom.c
drivers/hid/hid-elecom.c
+57
-0
drivers/hid/hid-ids.h
drivers/hid/hid-ids.h
+42
-39
drivers/hid/hid-input.c
drivers/hid/hid-input.c
+3
-0
drivers/hid/hid-picolcd.c
drivers/hid/hid-picolcd.c
+166
-33
drivers/hid/hidraw.c
drivers/hid/hidraw.c
+0
-2
No files found.
drivers/hid/Kconfig
View file @
fc73697b
...
@@ -148,6 +148,12 @@ config HID_EGALAX
...
@@ -148,6 +148,12 @@ config HID_EGALAX
---help---
---help---
Support for the eGalax dual-touch panel.
Support for the eGalax dual-touch panel.
config HID_ELECOM
tristate "ELECOM"
depends on BT_HIDP
---help---
Support for the ELECOM BM084 (bluetooth mouse).
config HID_EZKEY
config HID_EZKEY
tristate "Ezkey" if EMBEDDED
tristate "Ezkey" if EMBEDDED
depends on USB_HID
depends on USB_HID
...
...
drivers/hid/Makefile
View file @
fc73697b
...
@@ -32,6 +32,7 @@ obj-$(CONFIG_HID_CHICONY) += hid-chicony.o
...
@@ -32,6 +32,7 @@ obj-$(CONFIG_HID_CHICONY) += hid-chicony.o
obj-$(CONFIG_HID_CYPRESS)
+=
hid-cypress.o
obj-$(CONFIG_HID_CYPRESS)
+=
hid-cypress.o
obj-$(CONFIG_HID_DRAGONRISE)
+=
hid-drff.o
obj-$(CONFIG_HID_DRAGONRISE)
+=
hid-drff.o
obj-$(CONFIG_HID_EGALAX)
+=
hid-egalax.o
obj-$(CONFIG_HID_EGALAX)
+=
hid-egalax.o
obj-$(CONFIG_HID_ELECOM)
+=
hid-elecom.o
obj-$(CONFIG_HID_EZKEY)
+=
hid-ezkey.o
obj-$(CONFIG_HID_EZKEY)
+=
hid-ezkey.o
obj-$(CONFIG_HID_GYRATION)
+=
hid-gyration.o
obj-$(CONFIG_HID_GYRATION)
+=
hid-gyration.o
obj-$(CONFIG_HID_KENSINGTON)
+=
hid-kensington.o
obj-$(CONFIG_HID_KENSINGTON)
+=
hid-kensington.o
...
...
drivers/hid/hid-core.c
View file @
fc73697b
...
@@ -1294,6 +1294,7 @@ static const struct hid_device_id hid_blacklist[] = {
...
@@ -1294,6 +1294,7 @@ static const struct hid_device_id hid_blacklist[] = {
{
HID_USB_DEVICE
(
USB_VENDOR_ID_CYPRESS
,
USB_DEVICE_ID_CYPRESS_MOUSE
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_CYPRESS
,
USB_DEVICE_ID_CYPRESS_MOUSE
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_DRAGONRISE
,
0x0006
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_DRAGONRISE
,
0x0006
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_DWAV
,
USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_DWAV
,
USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH
)
},
{
HID_BLUETOOTH_DEVICE
(
USB_VENDOR_ID_ELECOM
,
USB_DEVICE_ID_ELECOM_BM084
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_EZKEY
,
USB_DEVICE_ID_BTC_8193
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_EZKEY
,
USB_DEVICE_ID_BTC_8193
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_GAMERON
,
USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_GAMERON
,
USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_GAMERON
,
USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_GAMERON
,
USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR
)
},
...
...
drivers/hid/hid-elecom.c
0 → 100644
View file @
fc73697b
/*
* HID driver for Elecom BM084 (bluetooth mouse).
* Removes a non-existing horizontal wheel from
* the HID descriptor.
* (This module is based on "hid-ortek".)
*
* Copyright (c) 2010 Richard Nauber <Richard.Nauber@gmail.com>
*/
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*/
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
#include "hid-ids.h"
static
void
elecom_report_fixup
(
struct
hid_device
*
hdev
,
__u8
*
rdesc
,
unsigned
int
rsize
)
{
if
(
rsize
>=
48
&&
rdesc
[
46
]
==
0x05
&&
rdesc
[
47
]
==
0x0c
)
{
dev_info
(
&
hdev
->
dev
,
"Fixing up Elecom BM084 "
"report descriptor.
\n
"
);
rdesc
[
47
]
=
0x00
;
}
}
static
const
struct
hid_device_id
elecom_devices
[]
=
{
{
HID_BLUETOOTH_DEVICE
(
USB_VENDOR_ID_ELECOM
,
USB_DEVICE_ID_ELECOM_BM084
)},
{
}
};
MODULE_DEVICE_TABLE
(
hid
,
elecom_devices
);
static
struct
hid_driver
elecom_driver
=
{
.
name
=
"elecom"
,
.
id_table
=
elecom_devices
,
.
report_fixup
=
elecom_report_fixup
};
static
int
__init
elecom_init
(
void
)
{
return
hid_register_driver
(
&
elecom_driver
);
}
static
void
__exit
elecom_exit
(
void
)
{
hid_unregister_driver
(
&
elecom_driver
);
}
module_init
(
elecom_init
);
module_exit
(
elecom_exit
);
MODULE_LICENSE
(
"GPL"
);
drivers/hid/hid-ids.h
View file @
fc73697b
...
@@ -187,18 +187,21 @@
...
@@ -187,18 +187,21 @@
#define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001
#define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d
#define USB_VENDOR_ID_ELECOM 0x056e
#define USB_DEVICE_ID_ELECOM_BM084 0x0061
#define USB_VENDOR_ID_ELO 0x04E7
#define USB_VENDOR_ID_ELO 0x04E7
#define USB_DEVICE_ID_ELO_TS2700 0x0020
#define USB_DEVICE_ID_ELO_TS2700 0x0020
#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
#define USB_VENDOR_ID_ETURBOTOUCH 0x22b9
#define USB_DEVICE_ID_ETURBOTOUCH 0x0006
#define USB_VENDOR_ID_ETT 0x0664
#define USB_VENDOR_ID_ETT 0x0664
#define USB_DEVICE_ID_TC5UH 0x0309
#define USB_DEVICE_ID_TC5UH 0x0309
#define USB_VENDOR_ID_ETURBOTOUCH 0x22b9
#define USB_DEVICE_ID_ETURBOTOUCH 0x0006
#define USB_VENDOR_ID_EZKEY 0x0518
#define USB_VENDOR_ID_EZKEY 0x0518
#define USB_DEVICE_ID_BTC_8193 0x0002
#define USB_DEVICE_ID_BTC_8193 0x0002
...
@@ -296,9 +299,16 @@
...
@@ -296,9 +299,16 @@
#define USB_VENDOR_ID_KBGEAR 0x084e
#define USB_VENDOR_ID_KBGEAR 0x084e
#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001
#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001
#define USB_VENDOR_ID_KENSINGTON 0x047d
#define USB_DEVICE_ID_KS_SLIMBLADE 0x2041
#define USB_VENDOR_ID_KWORLD 0x1b80
#define USB_VENDOR_ID_KWORLD 0x1b80
#define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700
#define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700
#define USB_VENDOR_ID_KYE 0x0458
#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087
#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
#define USB_VENDOR_ID_LABTEC 0x1020
#define USB_VENDOR_ID_LABTEC 0x1020
#define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006
#define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006
...
@@ -318,9 +328,6 @@
...
@@ -318,9 +328,6 @@
#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030
#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030
#define USB_DEVICE_ID_LD_MACHINETEST 0x2040
#define USB_DEVICE_ID_LD_MACHINETEST 0x2040
#define USB_VENDOR_ID_KENSINGTON 0x047d
#define USB_DEVICE_ID_KS_SLIMBLADE 0x2041
#define USB_VENDOR_ID_LOGITECH 0x046d
#define USB_VENDOR_ID_LOGITECH 0x046d
#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110
#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110
...
@@ -376,16 +383,16 @@
...
@@ -376,16 +383,16 @@
#define USB_VENDOR_ID_MONTEREY 0x0566
#define USB_VENDOR_ID_MONTEREY 0x0566
#define USB_DEVICE_ID_GENIUS_KB29E 0x3004
#define USB_DEVICE_ID_GENIUS_KB29E 0x3004
#define USB_VENDOR_ID_NCR 0x0404
#define USB_DEVICE_ID_NCR_FIRST 0x0300
#define USB_DEVICE_ID_NCR_LAST 0x03ff
#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400
#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400
#define USB_DEVICE_ID_N_S_HARMONY 0xc359
#define USB_DEVICE_ID_N_S_HARMONY 0xc359
#define USB_VENDOR_ID_NATSU 0x08b7
#define USB_VENDOR_ID_NATSU 0x08b7
#define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001
#define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001
#define USB_VENDOR_ID_NCR 0x0404
#define USB_DEVICE_ID_NCR_FIRST 0x0300
#define USB_DEVICE_ID_NCR_LAST 0x03ff
#define USB_VENDOR_ID_NEC 0x073e
#define USB_VENDOR_ID_NEC 0x073e
#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301
#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301
...
@@ -439,16 +446,16 @@
...
@@ -439,16 +446,16 @@
#define USB_VENDOR_ID_PRODIGE 0x05af
#define USB_VENDOR_ID_PRODIGE 0x05af
#define USB_DEVICE_ID_PRODIGE_CORDLESS 0x3062
#define USB_DEVICE_ID_PRODIGE_CORDLESS 0x3062
#define USB_VENDOR_ID_QUANTA 0x0408
#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH 0x3000
#define USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN 0x3001
#define USB_VENDOR_ID_ROCCAT 0x1e7d
#define USB_VENDOR_ID_ROCCAT 0x1e7d
#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced
#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced
#define USB_VENDOR_ID_SAITEK 0x06a3
#define USB_VENDOR_ID_SAITEK 0x06a3
#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
#define USB_VENDOR_ID_QUANTA 0x0408
#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH 0x3000
#define USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN 0x3001
#define USB_VENDOR_ID_SAMSUNG 0x0419
#define USB_VENDOR_ID_SAMSUNG 0x0419
#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600
#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600
...
@@ -472,15 +479,15 @@
...
@@ -472,15 +479,15 @@
#define USB_VENDOR_ID_THRUSTMASTER 0x044f
#define USB_VENDOR_ID_THRUSTMASTER 0x044f
#define USB_VENDOR_ID_TOUCHPACK 0x1bfd
#define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688
#define USB_VENDOR_ID_TOPMAX 0x0663
#define USB_VENDOR_ID_TOPMAX 0x0663
#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103
#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103
#define USB_VENDOR_ID_TOPSEED 0x0766
#define USB_VENDOR_ID_TOPSEED 0x0766
#define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204
#define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204
#define USB_VENDOR_ID_TOUCHPACK 0x1bfd
#define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688
#define USB_VENDOR_ID_TURBOX 0x062a
#define USB_VENDOR_ID_TURBOX 0x062a
#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201
#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201
...
@@ -522,9 +529,5 @@
...
@@ -522,9 +529,5 @@
#define USB_VENDOR_ID_ZYDACRON 0x13EC
#define USB_VENDOR_ID_ZYDACRON 0x13EC
#define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006
#define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006
#define USB_VENDOR_ID_KYE 0x0458
#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087
#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
#endif
#endif
drivers/hid/hid-input.c
View file @
fc73697b
...
@@ -301,6 +301,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
...
@@ -301,6 +301,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case
HID_UP_DIGITIZER
:
case
HID_UP_DIGITIZER
:
switch
(
usage
->
hid
&
0xff
)
{
switch
(
usage
->
hid
&
0xff
)
{
case
0x00
:
/* Undefined */
goto
ignore
;
case
0x30
:
/* TipPressure */
case
0x30
:
/* TipPressure */
if
(
!
test_bit
(
BTN_TOUCH
,
input
->
keybit
))
{
if
(
!
test_bit
(
BTN_TOUCH
,
input
->
keybit
))
{
device
->
quirks
|=
HID_QUIRK_NOTOUCH
;
device
->
quirks
|=
HID_QUIRK_NOTOUCH
;
...
...
drivers/hid/hid-picolcd.c
View file @
fc73697b
...
@@ -127,6 +127,26 @@ static const struct fb_var_screeninfo picolcdfb_var = {
...
@@ -127,6 +127,26 @@ static const struct fb_var_screeninfo picolcdfb_var = {
.
height
=
26
,
.
height
=
26
,
.
bits_per_pixel
=
1
,
.
bits_per_pixel
=
1
,
.
grayscale
=
1
,
.
grayscale
=
1
,
.
red
=
{
.
offset
=
0
,
.
length
=
1
,
.
msb_right
=
0
,
},
.
green
=
{
.
offset
=
0
,
.
length
=
1
,
.
msb_right
=
0
,
},
.
blue
=
{
.
offset
=
0
,
.
length
=
1
,
.
msb_right
=
0
,
},
.
transp
=
{
.
offset
=
0
,
.
length
=
0
,
.
msb_right
=
0
,
},
};
};
#endif
/* CONFIG_HID_PICOLCD_FB */
#endif
/* CONFIG_HID_PICOLCD_FB */
...
@@ -188,6 +208,7 @@ struct picolcd_data {
...
@@ -188,6 +208,7 @@ struct picolcd_data {
/* Framebuffer stuff */
/* Framebuffer stuff */
u8
fb_update_rate
;
u8
fb_update_rate
;
u8
fb_bpp
;
u8
fb_bpp
;
u8
fb_force
;
u8
*
fb_vbitmap
;
/* local copy of what was sent to PicoLCD */
u8
*
fb_vbitmap
;
/* local copy of what was sent to PicoLCD */
u8
*
fb_bitmap
;
/* framebuffer */
u8
*
fb_bitmap
;
/* framebuffer */
struct
fb_info
*
fb_info
;
struct
fb_info
*
fb_info
;
...
@@ -346,7 +367,7 @@ static int picolcd_fb_update_tile(u8 *vbitmap, const u8 *bitmap, int bpp,
...
@@ -346,7 +367,7 @@ static int picolcd_fb_update_tile(u8 *vbitmap, const u8 *bitmap, int bpp,
const
u8
*
bdata
=
bitmap
+
tile
*
256
+
chip
*
8
+
b
*
32
;
const
u8
*
bdata
=
bitmap
+
tile
*
256
+
chip
*
8
+
b
*
32
;
for
(
i
=
0
;
i
<
64
;
i
++
)
{
for
(
i
=
0
;
i
<
64
;
i
++
)
{
tdata
[
i
]
<<=
1
;
tdata
[
i
]
<<=
1
;
tdata
[
i
]
|=
(
bdata
[
i
/
8
]
>>
(
7
-
i
%
8
))
&
0x01
;
tdata
[
i
]
|=
(
bdata
[
i
/
8
]
>>
(
i
%
8
))
&
0x01
;
}
}
}
}
}
else
if
(
bpp
==
8
)
{
}
else
if
(
bpp
==
8
)
{
...
@@ -399,13 +420,10 @@ static int picolcd_fb_reset(struct picolcd_data *data, int clear)
...
@@ -399,13 +420,10 @@ static int picolcd_fb_reset(struct picolcd_data *data, int clear)
if
(
data
->
fb_bitmap
)
{
if
(
data
->
fb_bitmap
)
{
if
(
clear
)
{
if
(
clear
)
{
memset
(
data
->
fb_vbitmap
,
0
xff
,
PICOLCDFB_SIZE
);
memset
(
data
->
fb_vbitmap
,
0
,
PICOLCDFB_SIZE
);
memset
(
data
->
fb_bitmap
,
0
,
PICOLCDFB_SIZE
*
data
->
fb_bpp
);
memset
(
data
->
fb_bitmap
,
0
,
PICOLCDFB_SIZE
*
data
->
fb_bpp
);
}
else
{
/* invert 1 byte in each tile to force resend */
for
(
i
=
0
;
i
<
PICOLCDFB_SIZE
;
i
+=
64
)
data
->
fb_vbitmap
[
i
]
=
~
data
->
fb_vbitmap
[
i
];
}
}
data
->
fb_force
=
1
;
}
}
/* schedule first output of framebuffer */
/* schedule first output of framebuffer */
...
@@ -421,6 +439,9 @@ static void picolcd_fb_update(struct picolcd_data *data)
...
@@ -421,6 +439,9 @@ static void picolcd_fb_update(struct picolcd_data *data)
int
chip
,
tile
,
n
;
int
chip
,
tile
,
n
;
unsigned
long
flags
;
unsigned
long
flags
;
if
(
!
data
)
return
;
spin_lock_irqsave
(
&
data
->
lock
,
flags
);
spin_lock_irqsave
(
&
data
->
lock
,
flags
);
if
(
!
(
data
->
status
&
PICOLCD_READY_FB
))
{
if
(
!
(
data
->
status
&
PICOLCD_READY_FB
))
{
spin_unlock_irqrestore
(
&
data
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
data
->
lock
,
flags
);
...
@@ -440,14 +461,18 @@ static void picolcd_fb_update(struct picolcd_data *data)
...
@@ -440,14 +461,18 @@ static void picolcd_fb_update(struct picolcd_data *data)
for
(
chip
=
0
;
chip
<
4
;
chip
++
)
for
(
chip
=
0
;
chip
<
4
;
chip
++
)
for
(
tile
=
0
;
tile
<
8
;
tile
++
)
for
(
tile
=
0
;
tile
<
8
;
tile
++
)
if
(
picolcd_fb_update_tile
(
data
->
fb_vbitmap
,
if
(
picolcd_fb_update_tile
(
data
->
fb_vbitmap
,
data
->
fb_bitmap
,
data
->
fb_bpp
,
chip
,
tile
))
{
data
->
fb_bitmap
,
data
->
fb_bpp
,
chip
,
tile
)
||
data
->
fb_force
)
{
n
+=
2
;
n
+=
2
;
if
(
!
data
->
fb_info
->
par
)
return
;
/* device lost! */
if
(
n
>=
HID_OUTPUT_FIFO_SIZE
/
2
)
{
if
(
n
>=
HID_OUTPUT_FIFO_SIZE
/
2
)
{
usbhid_wait_io
(
data
->
hdev
);
usbhid_wait_io
(
data
->
hdev
);
n
=
0
;
n
=
0
;
}
}
picolcd_fb_send_tile
(
data
->
hdev
,
chip
,
tile
);
picolcd_fb_send_tile
(
data
->
hdev
,
chip
,
tile
);
}
}
data
->
fb_force
=
false
;
if
(
n
)
if
(
n
)
usbhid_wait_io
(
data
->
hdev
);
usbhid_wait_io
(
data
->
hdev
);
}
}
...
@@ -511,11 +536,23 @@ static int picolcd_fb_blank(int blank, struct fb_info *info)
...
@@ -511,11 +536,23 @@ static int picolcd_fb_blank(int blank, struct fb_info *info)
static
void
picolcd_fb_destroy
(
struct
fb_info
*
info
)
static
void
picolcd_fb_destroy
(
struct
fb_info
*
info
)
{
{
struct
picolcd_data
*
data
=
info
->
par
;
struct
picolcd_data
*
data
=
info
->
par
;
u32
*
ref_cnt
=
info
->
pseudo_palette
;
int
may_release
;
info
->
par
=
NULL
;
info
->
par
=
NULL
;
if
(
data
)
if
(
data
)
data
->
fb_info
=
NULL
;
data
->
fb_info
=
NULL
;
fb_deferred_io_cleanup
(
info
);
fb_deferred_io_cleanup
(
info
);
ref_cnt
--
;
mutex_lock
(
&
info
->
lock
);
(
*
ref_cnt
)
--
;
may_release
=
!
ref_cnt
;
mutex_unlock
(
&
info
->
lock
);
if
(
may_release
)
{
framebuffer_release
(
info
);
framebuffer_release
(
info
);
vfree
((
u8
*
)
info
->
fix
.
smem_start
);
}
}
}
static
int
picolcd_fb_check_var
(
struct
fb_var_screeninfo
*
var
,
struct
fb_info
*
info
)
static
int
picolcd_fb_check_var
(
struct
fb_var_screeninfo
*
var
,
struct
fb_info
*
info
)
...
@@ -526,17 +563,26 @@ static int picolcd_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *i
...
@@ -526,17 +563,26 @@ static int picolcd_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *i
/* only allow 1/8 bit depth (8-bit is grayscale) */
/* only allow 1/8 bit depth (8-bit is grayscale) */
*
var
=
picolcdfb_var
;
*
var
=
picolcdfb_var
;
var
->
activate
=
activate
;
var
->
activate
=
activate
;
if
(
bpp
>=
8
)
if
(
bpp
>=
8
)
{
var
->
bits_per_pixel
=
8
;
var
->
bits_per_pixel
=
8
;
else
var
->
red
.
length
=
8
;
var
->
green
.
length
=
8
;
var
->
blue
.
length
=
8
;
}
else
{
var
->
bits_per_pixel
=
1
;
var
->
bits_per_pixel
=
1
;
var
->
red
.
length
=
1
;
var
->
green
.
length
=
1
;
var
->
blue
.
length
=
1
;
}
return
0
;
return
0
;
}
}
static
int
picolcd_set_par
(
struct
fb_info
*
info
)
static
int
picolcd_set_par
(
struct
fb_info
*
info
)
{
{
struct
picolcd_data
*
data
=
info
->
par
;
struct
picolcd_data
*
data
=
info
->
par
;
u8
*
o_fb
,
*
n_fb
;
u8
*
tmp_fb
,
*
o_fb
;
if
(
!
data
)
return
-
ENODEV
;
if
(
info
->
var
.
bits_per_pixel
==
data
->
fb_bpp
)
if
(
info
->
var
.
bits_per_pixel
==
data
->
fb_bpp
)
return
0
;
return
0
;
/* switch between 1/8 bit depths */
/* switch between 1/8 bit depths */
...
@@ -544,11 +590,10 @@ static int picolcd_set_par(struct fb_info *info)
...
@@ -544,11 +590,10 @@ static int picolcd_set_par(struct fb_info *info)
return
-
EINVAL
;
return
-
EINVAL
;
o_fb
=
data
->
fb_bitmap
;
o_fb
=
data
->
fb_bitmap
;
n_fb
=
vmalloc
(
PICOLCDFB_SIZE
*
info
->
var
.
bits_per_pixel
);
tmp_fb
=
kmalloc
(
PICOLCDFB_SIZE
*
info
->
var
.
bits_per_pixel
,
GFP_KERNEL
);
if
(
!
n
_fb
)
if
(
!
tmp
_fb
)
return
-
ENOMEM
;
return
-
ENOMEM
;
fb_deferred_io_cleanup
(
info
);
/* translate FB content to new bits-per-pixel */
/* translate FB content to new bits-per-pixel */
if
(
info
->
var
.
bits_per_pixel
==
1
)
{
if
(
info
->
var
.
bits_per_pixel
==
1
)
{
int
i
,
b
;
int
i
,
b
;
...
@@ -558,24 +603,87 @@ static int picolcd_set_par(struct fb_info *info)
...
@@ -558,24 +603,87 @@ static int picolcd_set_par(struct fb_info *info)
p
<<=
1
;
p
<<=
1
;
p
|=
o_fb
[
i
*
8
+
b
]
?
0x01
:
0x00
;
p
|=
o_fb
[
i
*
8
+
b
]
?
0x01
:
0x00
;
}
}
tmp_fb
[
i
]
=
p
;
}
}
memcpy
(
o_fb
,
tmp_fb
,
PICOLCDFB_SIZE
);
info
->
fix
.
visual
=
FB_VISUAL_MONO01
;
info
->
fix
.
visual
=
FB_VISUAL_MONO01
;
info
->
fix
.
line_length
=
PICOLCDFB_WIDTH
/
8
;
info
->
fix
.
line_length
=
PICOLCDFB_WIDTH
/
8
;
}
else
{
}
else
{
int
i
;
int
i
;
memcpy
(
tmp_fb
,
o_fb
,
PICOLCDFB_SIZE
);
for
(
i
=
0
;
i
<
PICOLCDFB_SIZE
*
8
;
i
++
)
for
(
i
=
0
;
i
<
PICOLCDFB_SIZE
*
8
;
i
++
)
n_fb
[
i
]
=
o
_fb
[
i
/
8
]
&
(
0x01
<<
(
7
-
i
%
8
))
?
0xff
:
0x00
;
o_fb
[
i
]
=
tmp
_fb
[
i
/
8
]
&
(
0x01
<<
(
7
-
i
%
8
))
?
0xff
:
0x00
;
info
->
fix
.
visual
=
FB_VISUAL_
TRUE
COLOR
;
info
->
fix
.
visual
=
FB_VISUAL_
DIRECT
COLOR
;
info
->
fix
.
line_length
=
PICOLCDFB_WIDTH
;
info
->
fix
.
line_length
=
PICOLCDFB_WIDTH
;
}
}
data
->
fb_bitmap
=
n_fb
;
kfree
(
tmp_fb
)
;
data
->
fb_bpp
=
info
->
var
.
bits_per_pixel
;
data
->
fb_bpp
=
info
->
var
.
bits_per_pixel
;
info
->
screen_base
=
(
char
__force
__iomem
*
)
n_fb
;
return
0
;
info
->
fix
.
smem_start
=
(
unsigned
long
)
n_fb
;
}
info
->
fix
.
smem_len
=
PICOLCDFB_SIZE
*
data
->
fb_bpp
;
fb_deferred_io_init
(
info
);
/* Do refcounting on our FB and cleanup per worker if FB is
vfree
(
o_fb
);
* closed after unplug of our device
* (fb_release holds info->lock and still touches info after
* we return so we can't release it immediately.
*/
struct
picolcd_fb_cleanup_item
{
struct
fb_info
*
info
;
struct
picolcd_fb_cleanup_item
*
next
;
};
static
struct
picolcd_fb_cleanup_item
*
fb_pending
;
DEFINE_SPINLOCK
(
fb_pending_lock
);
static
void
picolcd_fb_do_cleanup
(
struct
work_struct
*
data
)
{
struct
picolcd_fb_cleanup_item
*
item
;
unsigned
long
flags
;
do
{
spin_lock_irqsave
(
&
fb_pending_lock
,
flags
);
item
=
fb_pending
;
fb_pending
=
item
?
item
->
next
:
NULL
;
spin_unlock_irqrestore
(
&
fb_pending_lock
,
flags
);
if
(
item
)
{
u8
*
fb
=
(
u8
*
)
item
->
info
->
fix
.
smem_start
;
/* make sure we do not race against fb core when
* releasing */
mutex_lock
(
&
item
->
info
->
lock
);
mutex_unlock
(
&
item
->
info
->
lock
);
framebuffer_release
(
item
->
info
);
vfree
(
fb
);
}
}
while
(
item
);
}
DECLARE_WORK
(
picolcd_fb_cleanup
,
picolcd_fb_do_cleanup
);
static
int
picolcd_fb_open
(
struct
fb_info
*
info
,
int
u
)
{
u32
*
ref_cnt
=
info
->
pseudo_palette
;
ref_cnt
--
;
(
*
ref_cnt
)
++
;
return
0
;
}
static
int
picolcd_fb_release
(
struct
fb_info
*
info
,
int
u
)
{
u32
*
ref_cnt
=
info
->
pseudo_palette
;
ref_cnt
--
;
(
*
ref_cnt
)
++
;
if
(
!*
ref_cnt
)
{
unsigned
long
flags
;
struct
picolcd_fb_cleanup_item
*
item
=
(
struct
picolcd_fb_cleanup_item
*
)
ref_cnt
;
item
--
;
spin_lock_irqsave
(
&
fb_pending_lock
,
flags
);
item
->
next
=
fb_pending
;
fb_pending
=
item
;
spin_unlock_irqrestore
(
&
fb_pending_lock
,
flags
);
schedule_work
(
&
picolcd_fb_cleanup
);
}
return
0
;
return
0
;
}
}
...
@@ -583,6 +691,8 @@ static int picolcd_set_par(struct fb_info *info)
...
@@ -583,6 +691,8 @@ static int picolcd_set_par(struct fb_info *info)
static
struct
fb_ops
picolcdfb_ops
=
{
static
struct
fb_ops
picolcdfb_ops
=
{
.
owner
=
THIS_MODULE
,
.
owner
=
THIS_MODULE
,
.
fb_destroy
=
picolcd_fb_destroy
,
.
fb_destroy
=
picolcd_fb_destroy
,
.
fb_open
=
picolcd_fb_open
,
.
fb_release
=
picolcd_fb_release
,
.
fb_read
=
fb_sys_read
,
.
fb_read
=
fb_sys_read
,
.
fb_write
=
picolcd_fb_write
,
.
fb_write
=
picolcd_fb_write
,
.
fb_blank
=
picolcd_fb_blank
,
.
fb_blank
=
picolcd_fb_blank
,
...
@@ -660,11 +770,12 @@ static int picolcd_init_framebuffer(struct picolcd_data *data)
...
@@ -660,11 +770,12 @@ static int picolcd_init_framebuffer(struct picolcd_data *data)
{
{
struct
device
*
dev
=
&
data
->
hdev
->
dev
;
struct
device
*
dev
=
&
data
->
hdev
->
dev
;
struct
fb_info
*
info
=
NULL
;
struct
fb_info
*
info
=
NULL
;
int
error
=
-
ENOMEM
;
int
i
,
error
=
-
ENOMEM
;
u8
*
fb_vbitmap
=
NULL
;
u8
*
fb_vbitmap
=
NULL
;
u8
*
fb_bitmap
=
NULL
;
u8
*
fb_bitmap
=
NULL
;
u32
*
palette
;
fb_bitmap
=
vmalloc
(
PICOLCDFB_SIZE
*
picolcdfb_var
.
bits_per_pixel
);
fb_bitmap
=
vmalloc
(
PICOLCDFB_SIZE
*
8
);
if
(
fb_bitmap
==
NULL
)
{
if
(
fb_bitmap
==
NULL
)
{
dev_err
(
dev
,
"can't get a free page for framebuffer
\n
"
);
dev_err
(
dev
,
"can't get a free page for framebuffer
\n
"
);
goto
err_nomem
;
goto
err_nomem
;
...
@@ -678,18 +789,29 @@ static int picolcd_init_framebuffer(struct picolcd_data *data)
...
@@ -678,18 +789,29 @@ static int picolcd_init_framebuffer(struct picolcd_data *data)
data
->
fb_update_rate
=
PICOLCDFB_UPDATE_RATE_DEFAULT
;
data
->
fb_update_rate
=
PICOLCDFB_UPDATE_RATE_DEFAULT
;
data
->
fb_defio
=
picolcd_fb_defio
;
data
->
fb_defio
=
picolcd_fb_defio
;
info
=
framebuffer_alloc
(
0
,
dev
);
/* The extra memory is:
* - struct picolcd_fb_cleanup_item
* - u32 for ref_count
* - 256*u32 for pseudo_palette
*/
info
=
framebuffer_alloc
(
257
*
sizeof
(
u32
)
+
sizeof
(
struct
picolcd_fb_cleanup_item
),
dev
);
if
(
info
==
NULL
)
{
if
(
info
==
NULL
)
{
dev_err
(
dev
,
"failed to allocate a framebuffer
\n
"
);
dev_err
(
dev
,
"failed to allocate a framebuffer
\n
"
);
goto
err_nomem
;
goto
err_nomem
;
}
}
palette
=
info
->
par
+
sizeof
(
struct
picolcd_fb_cleanup_item
);
*
palette
=
1
;
palette
++
;
for
(
i
=
0
;
i
<
256
;
i
++
)
palette
[
i
]
=
i
>
0
&&
i
<
16
?
0xff
:
0
;
info
->
pseudo_palette
=
palette
;
info
->
fbdefio
=
&
data
->
fb_defio
;
info
->
fbdefio
=
&
data
->
fb_defio
;
info
->
screen_base
=
(
char
__force
__iomem
*
)
fb_bitmap
;
info
->
screen_base
=
(
char
__force
__iomem
*
)
fb_bitmap
;
info
->
fbops
=
&
picolcdfb_ops
;
info
->
fbops
=
&
picolcdfb_ops
;
info
->
var
=
picolcdfb_var
;
info
->
var
=
picolcdfb_var
;
info
->
fix
=
picolcdfb_fix
;
info
->
fix
=
picolcdfb_fix
;
info
->
fix
.
smem_len
=
PICOLCDFB_SIZE
;
info
->
fix
.
smem_len
=
PICOLCDFB_SIZE
*
8
;
info
->
fix
.
smem_start
=
(
unsigned
long
)
fb_bitmap
;
info
->
fix
.
smem_start
=
(
unsigned
long
)
fb_bitmap
;
info
->
par
=
data
;
info
->
par
=
data
;
info
->
flags
=
FBINFO_FLAG_DEFAULT
;
info
->
flags
=
FBINFO_FLAG_DEFAULT
;
...
@@ -707,18 +829,20 @@ static int picolcd_init_framebuffer(struct picolcd_data *data)
...
@@ -707,18 +829,20 @@ static int picolcd_init_framebuffer(struct picolcd_data *data)
dev_err
(
dev
,
"failed to create sysfs attributes
\n
"
);
dev_err
(
dev
,
"failed to create sysfs attributes
\n
"
);
goto
err_cleanup
;
goto
err_cleanup
;
}
}
fb_deferred_io_init
(
info
);
data
->
fb_info
=
info
;
data
->
fb_info
=
info
;
error
=
register_framebuffer
(
info
);
error
=
register_framebuffer
(
info
);
if
(
error
)
{
if
(
error
)
{
dev_err
(
dev
,
"failed to register framebuffer
\n
"
);
dev_err
(
dev
,
"failed to register framebuffer
\n
"
);
goto
err_sysfs
;
goto
err_sysfs
;
}
}
fb_deferred_io_init
(
info
);
/* schedule first output of framebuffer */
/* schedule first output of framebuffer */
data
->
fb_force
=
1
;
schedule_delayed_work
(
&
info
->
deferred_work
,
0
);
schedule_delayed_work
(
&
info
->
deferred_work
,
0
);
return
0
;
return
0
;
err_sysfs:
err_sysfs:
fb_deferred_io_cleanup
(
info
);
device_remove_file
(
dev
,
&
dev_attr_fb_update_rate
);
device_remove_file
(
dev
,
&
dev_attr_fb_update_rate
);
err_cleanup:
err_cleanup:
data
->
fb_vbitmap
=
NULL
;
data
->
fb_vbitmap
=
NULL
;
...
@@ -737,19 +861,17 @@ static void picolcd_exit_framebuffer(struct picolcd_data *data)
...
@@ -737,19 +861,17 @@ static void picolcd_exit_framebuffer(struct picolcd_data *data)
{
{
struct
fb_info
*
info
=
data
->
fb_info
;
struct
fb_info
*
info
=
data
->
fb_info
;
u8
*
fb_vbitmap
=
data
->
fb_vbitmap
;
u8
*
fb_vbitmap
=
data
->
fb_vbitmap
;
u8
*
fb_bitmap
=
data
->
fb_bitmap
;
if
(
!
info
)
if
(
!
info
)
return
;
return
;
info
->
par
=
NULL
;
device_remove_file
(
&
data
->
hdev
->
dev
,
&
dev_attr_fb_update_rate
);
unregister_framebuffer
(
info
);
data
->
fb_vbitmap
=
NULL
;
data
->
fb_vbitmap
=
NULL
;
data
->
fb_bitmap
=
NULL
;
data
->
fb_bitmap
=
NULL
;
data
->
fb_bpp
=
0
;
data
->
fb_bpp
=
0
;
data
->
fb_info
=
NULL
;
data
->
fb_info
=
NULL
;
device_remove_file
(
&
data
->
hdev
->
dev
,
&
dev_attr_fb_update_rate
);
fb_deferred_io_cleanup
(
info
);
unregister_framebuffer
(
info
);
vfree
(
fb_bitmap
);
kfree
(
fb_vbitmap
);
kfree
(
fb_vbitmap
);
}
}
...
@@ -2566,6 +2688,13 @@ static void picolcd_remove(struct hid_device *hdev)
...
@@ -2566,6 +2688,13 @@ static void picolcd_remove(struct hid_device *hdev)
spin_lock_irqsave
(
&
data
->
lock
,
flags
);
spin_lock_irqsave
(
&
data
->
lock
,
flags
);
data
->
status
|=
PICOLCD_FAILED
;
data
->
status
|=
PICOLCD_FAILED
;
spin_unlock_irqrestore
(
&
data
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
data
->
lock
,
flags
);
#ifdef CONFIG_HID_PICOLCD_FB
/* short-circuit FB as early as possible in order to
* avoid long delays if we host console.
*/
if
(
data
->
fb_info
)
data
->
fb_info
->
par
=
NULL
;
#endif
picolcd_exit_devfs
(
data
);
picolcd_exit_devfs
(
data
);
device_remove_file
(
&
hdev
->
dev
,
&
dev_attr_operation_mode
);
device_remove_file
(
&
hdev
->
dev
,
&
dev_attr_operation_mode
);
...
@@ -2623,6 +2752,10 @@ static int __init picolcd_init(void)
...
@@ -2623,6 +2752,10 @@ static int __init picolcd_init(void)
static
void
__exit
picolcd_exit
(
void
)
static
void
__exit
picolcd_exit
(
void
)
{
{
hid_unregister_driver
(
&
picolcd_driver
);
hid_unregister_driver
(
&
picolcd_driver
);
#ifdef CONFIG_HID_PICOLCD_FB
flush_scheduled_work
();
WARN_ON
(
fb_pending
);
#endif
}
}
module_init
(
picolcd_init
);
module_init
(
picolcd_init
);
...
...
drivers/hid/hidraw.c
View file @
fc73697b
...
@@ -46,7 +46,6 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
...
@@ -46,7 +46,6 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
{
{
struct
hidraw_list
*
list
=
file
->
private_data
;
struct
hidraw_list
*
list
=
file
->
private_data
;
int
ret
=
0
,
len
;
int
ret
=
0
,
len
;
char
*
report
;
DECLARE_WAITQUEUE
(
wait
,
current
);
DECLARE_WAITQUEUE
(
wait
,
current
);
mutex_lock
(
&
list
->
read_mutex
);
mutex_lock
(
&
list
->
read_mutex
);
...
@@ -84,7 +83,6 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
...
@@ -84,7 +83,6 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
if
(
ret
)
if
(
ret
)
goto
out
;
goto
out
;
report
=
list
->
buffer
[
list
->
tail
].
value
;
len
=
list
->
buffer
[
list
->
tail
].
len
>
count
?
len
=
list
->
buffer
[
list
->
tail
].
len
>
count
?
count
:
list
->
buffer
[
list
->
tail
].
len
;
count
:
list
->
buffer
[
list
->
tail
].
len
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment