Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
7c27fd19
Commit
7c27fd19
authored
Apr 05, 2009
by
Len Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'sony-laptop' into release
parents
336d63b8
16dd55f3
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
402 additions
and
138 deletions
+402
-138
drivers/platform/x86/Kconfig
drivers/platform/x86/Kconfig
+1
-0
drivers/platform/x86/sony-laptop.c
drivers/platform/x86/sony-laptop.c
+393
-138
include/linux/sonypi.h
include/linux/sonypi.h
+8
-0
No files found.
drivers/platform/x86/Kconfig
View file @
7c27fd19
...
...
@@ -165,6 +165,7 @@ config SONY_LAPTOP
depends on ACPI
select BACKLIGHT_CLASS_DEVICE
depends on INPUT
depends on RFKILL
---help---
This mini-driver drives the SNC and SPIC devices present in the ACPI
BIOS of the Sony Vaio laptops.
...
...
drivers/platform/x86/sony-laptop.c
View file @
7c27fd19
...
...
@@ -2,7 +2,7 @@
* ACPI Sony Notebook Control Driver (SNC and SPIC)
*
* Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net>
* Copyright (C) 2007 Mattia Dongili <malattia@linux.it>
* Copyright (C) 2007
-2009
Mattia Dongili <malattia@linux.it>
*
* Parts of this driver inspired from asus_acpi.c and ibm_acpi.c
* which are copyrighted by their respective authors.
...
...
@@ -46,7 +46,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/backlight.h>
#include <linux/platform_device.h>
...
...
@@ -64,6 +63,7 @@
#include <asm/uaccess.h>
#include <linux/sonypi.h>
#include <linux/sony-laptop.h>
#include <linux/rfkill.h>
#ifdef CONFIG_SONYPI_COMPAT
#include <linux/poll.h>
#include <linux/miscdevice.h>
...
...
@@ -123,6 +123,18 @@ MODULE_PARM_DESC(minor,
"default is -1 (automatic)"
);
#endif
enum
sony_nc_rfkill
{
SONY_WIFI
,
SONY_BLUETOOTH
,
SONY_WWAN
,
SONY_WIMAX
,
SONY_RFKILL_MAX
,
};
static
struct
rfkill
*
sony_rfkill_devices
[
SONY_RFKILL_MAX
];
static
int
sony_rfkill_address
[
SONY_RFKILL_MAX
]
=
{
0x300
,
0x500
,
0x700
,
0x900
};
static
void
sony_nc_rfkill_update
(
void
);
/*********** Input Devices ***********/
#define SONY_LAPTOP_BUF_SIZE 128
...
...
@@ -134,6 +146,7 @@ struct sony_laptop_input_s {
spinlock_t
fifo_lock
;
struct
workqueue_struct
*
wq
;
};
static
struct
sony_laptop_input_s
sony_laptop_input
=
{
.
users
=
ATOMIC_INIT
(
0
),
};
...
...
@@ -211,6 +224,14 @@ static int sony_laptop_input_index[] = {
48
,
/* 61 SONYPI_EVENT_WIRELESS_OFF */
49
,
/* 62 SONYPI_EVENT_ZOOM_IN_PRESSED */
50
,
/* 63 SONYPI_EVENT_ZOOM_OUT_PRESSED */
51
,
/* 64 SONYPI_EVENT_CD_EJECT_PRESSED */
52
,
/* 65 SONYPI_EVENT_MODEKEY_PRESSED */
53
,
/* 66 SONYPI_EVENT_PKEY_P4 */
54
,
/* 67 SONYPI_EVENT_PKEY_P5 */
55
,
/* 68 SONYPI_EVENT_SETTINGKEY_PRESSED */
56
,
/* 69 SONYPI_EVENT_VOLUME_INC_PRESSED */
57
,
/* 70 SONYPI_EVENT_VOLUME_DEC_PRESSED */
-
1
,
/* 71 SONYPI_EVENT_BRIGHTNESS_PRESSED */
};
static
int
sony_laptop_input_keycode_map
[]
=
{
...
...
@@ -264,7 +285,14 @@ static int sony_laptop_input_keycode_map[] = {
KEY_WLAN
,
/* 47 SONYPI_EVENT_WIRELESS_ON */
KEY_WLAN
,
/* 48 SONYPI_EVENT_WIRELESS_OFF */
KEY_ZOOMIN
,
/* 49 SONYPI_EVENT_ZOOM_IN_PRESSED */
KEY_ZOOMOUT
/* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */
KEY_ZOOMOUT
,
/* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */
KEY_EJECTCD
,
/* 51 SONYPI_EVENT_CD_EJECT_PRESSED */
KEY_F13
,
/* 52 SONYPI_EVENT_MODEKEY_PRESSED */
KEY_PROG4
,
/* 53 SONYPI_EVENT_PKEY_P4 */
KEY_F14
,
/* 54 SONYPI_EVENT_PKEY_P5 */
KEY_F15
,
/* 55 SONYPI_EVENT_SETTINGKEY_PRESSED */
KEY_VOLUMEUP
,
/* 56 SONYPI_EVENT_VOLUME_INC_PRESSED */
KEY_VOLUMEDOWN
,
/* 57 SONYPI_EVENT_VOLUME_DEC_PRESSED */
};
/* release buttons after a short delay if pressed */
...
...
@@ -369,7 +397,7 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device)
sony_laptop_input
.
wq
=
create_singlethread_workqueue
(
"sony-laptop"
);
if
(
!
sony_laptop_input
.
wq
)
{
printk
(
KERN_ERR
DRV_PFX
"Unabe to create workqueue.
\n
"
);
"Unab
l
e to create workqueue.
\n
"
);
error
=
-
ENXIO
;
goto
err_free_kfifo
;
}
...
...
@@ -689,6 +717,31 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value,
return
-
1
;
}
static
int
sony_find_snc_handle
(
int
handle
)
{
int
i
;
int
result
;
for
(
i
=
0x20
;
i
<
0x30
;
i
++
)
{
acpi_callsetfunc
(
sony_nc_acpi_handle
,
"SN00"
,
i
,
&
result
);
if
(
result
==
handle
)
return
i
-
0x20
;
}
return
-
1
;
}
static
int
sony_call_snc_handle
(
int
handle
,
int
argument
,
int
*
result
)
{
int
offset
=
sony_find_snc_handle
(
handle
);
if
(
offset
<
0
)
return
-
1
;
return
acpi_callsetfunc
(
sony_nc_acpi_handle
,
"SN07"
,
offset
|
argument
,
result
);
}
/*
* sony_nc_values input/output validate functions
*/
...
...
@@ -809,87 +862,53 @@ struct sony_nc_event {
u8
event
;
};
static
struct
sony_nc_event
*
sony_nc_events
;
/* Vaio C* --maybe also FE*, N* and AR* ?-- special init sequence
* for Fn keys
*/
static
int
sony_nc_C_enable
(
const
struct
dmi_system_id
*
id
)
{
int
result
=
0
;
printk
(
KERN_NOTICE
DRV_PFX
"detected %s
\n
"
,
id
->
ident
);
sony_nc_events
=
id
->
driver_data
;
if
(
acpi_callsetfunc
(
sony_nc_acpi_handle
,
"SN02"
,
0x4
,
&
result
)
<
0
||
acpi_callsetfunc
(
sony_nc_acpi_handle
,
"SN07"
,
0x2
,
&
result
)
<
0
||
acpi_callsetfunc
(
sony_nc_acpi_handle
,
"SN02"
,
0x10
,
&
result
)
<
0
||
acpi_callsetfunc
(
sony_nc_acpi_handle
,
"SN07"
,
0x0
,
&
result
)
<
0
||
acpi_callsetfunc
(
sony_nc_acpi_handle
,
"SN03"
,
0x2
,
&
result
)
<
0
||
acpi_callsetfunc
(
sony_nc_acpi_handle
,
"SN07"
,
0x101
,
&
result
)
<
0
)
{
printk
(
KERN_WARNING
DRV_PFX
"failed to initialize SNC, some "
"functionalities may be missing
\n
"
);
return
1
;
}
return
0
;
}
static
struct
sony_nc_event
sony_C_events
[]
=
{
static
struct
sony_nc_event
sony_100_events
[]
=
{
{
0x90
,
SONYPI_EVENT_PKEY_P1
},
{
0x10
,
SONYPI_EVENT_ANYBUTTON_RELEASED
},
{
0x91
,
SONYPI_EVENT_PKEY_P2
},
{
0x11
,
SONYPI_EVENT_ANYBUTTON_RELEASED
},
{
0x81
,
SONYPI_EVENT_FNKEY_F1
},
{
0x01
,
SONYPI_EVENT_FNKEY_RELEASED
},
{
0x82
,
SONYPI_EVENT_FNKEY_F2
},
{
0x02
,
SONYPI_EVENT_FNKEY_RELEASED
},
{
0x83
,
SONYPI_EVENT_FNKEY_F3
},
{
0x03
,
SONYPI_EVENT_FNKEY_RELEASED
},
{
0x84
,
SONYPI_EVENT_FNKEY_F4
},
{
0x04
,
SONYPI_EVENT_FNKEY_RELEASED
},
{
0x85
,
SONYPI_EVENT_FNKEY_F5
},
{
0x05
,
SONYPI_EVENT_FNKEY_RELEASED
},
{
0x86
,
SONYPI_EVENT_FNKEY_F6
},
{
0x06
,
SONYPI_EVENT_FNKEY_RELEASED
},
{
0x87
,
SONYPI_EVENT_FNKEY_F7
},
{
0x07
,
SONYPI_EVENT_FNKEY_RELEASED
},
{
0x89
,
SONYPI_EVENT_FNKEY_F9
},
{
0x09
,
SONYPI_EVENT_FNKEY_RELEASED
},
{
0x8A
,
SONYPI_EVENT_FNKEY_F10
},
{
0x0A
,
SONYPI_EVENT_FNKEY_RELEASED
},
{
0x8C
,
SONYPI_EVENT_FNKEY_F12
},
{
0x0C
,
SONYPI_EVENT_FNKEY_RELEASED
},
{
0x9f
,
SONYPI_EVENT_CD_EJECT_PRESSED
},
{
0x1f
,
SONYPI_EVENT_ANYBUTTON_RELEASED
},
{
0
,
0
},
};
/* SNC-only model map */
static
const
struct
dmi_system_id
sony_nc_ids
[]
=
{
{
.
ident
=
"Sony Vaio FE Series"
,
.
callback
=
sony_nc_C_enable
,
.
driver_data
=
sony_C_events
,
.
matches
=
{
DMI_MATCH
(
DMI_SYS_VENDOR
,
"Sony Corporation"
),
DMI_MATCH
(
DMI_PRODUCT_NAME
,
"VGN-FE"
),
},
},
{
.
ident
=
"Sony Vaio FZ Series"
,
.
callback
=
sony_nc_C_enable
,
.
driver_data
=
sony_C_events
,
.
matches
=
{
DMI_MATCH
(
DMI_SYS_VENDOR
,
"Sony Corporation"
),
DMI_MATCH
(
DMI_PRODUCT_NAME
,
"VGN-FZ"
),
},
},
{
.
ident
=
"Sony Vaio C Series"
,
.
callback
=
sony_nc_C_enable
,
.
driver_data
=
sony_C_events
,
.
matches
=
{
DMI_MATCH
(
DMI_SYS_VENDOR
,
"Sony Corporation"
),
DMI_MATCH
(
DMI_PRODUCT_NAME
,
"VGN-C"
),
},
},
{
.
ident
=
"Sony Vaio N Series"
,
.
callback
=
sony_nc_C_enable
,
.
driver_data
=
sony_C_events
,
.
matches
=
{
DMI_MATCH
(
DMI_SYS_VENDOR
,
"Sony Corporation"
),
DMI_MATCH
(
DMI_PRODUCT_NAME
,
"VGN-N"
),
},
},
{
}
static
struct
sony_nc_event
sony_127_events
[]
=
{
{
0x81
,
SONYPI_EVENT_MODEKEY_PRESSED
},
{
0x01
,
SONYPI_EVENT_ANYBUTTON_RELEASED
},
{
0x82
,
SONYPI_EVENT_PKEY_P1
},
{
0x02
,
SONYPI_EVENT_ANYBUTTON_RELEASED
},
{
0x83
,
SONYPI_EVENT_PKEY_P2
},
{
0x03
,
SONYPI_EVENT_ANYBUTTON_RELEASED
},
{
0x84
,
SONYPI_EVENT_PKEY_P3
},
{
0x04
,
SONYPI_EVENT_ANYBUTTON_RELEASED
},
{
0x85
,
SONYPI_EVENT_PKEY_P4
},
{
0x05
,
SONYPI_EVENT_ANYBUTTON_RELEASED
},
{
0x86
,
SONYPI_EVENT_PKEY_P5
},
{
0x06
,
SONYPI_EVENT_ANYBUTTON_RELEASED
},
{
0x06
,
SONYPI_EVENT_ANYBUTTON_RELEASED
},
{
0x87
,
SONYPI_EVENT_SETTINGKEY_PRESSED
},
{
0x07
,
SONYPI_EVENT_ANYBUTTON_RELEASED
},
{
0
,
0
},
};
/*
...
...
@@ -897,38 +916,59 @@ static const struct dmi_system_id sony_nc_ids[] = {
*/
static
void
sony_acpi_notify
(
acpi_handle
handle
,
u32
event
,
void
*
data
)
{
struct
sony_nc_event
*
evmap
;
u32
ev
=
event
;
int
result
;
if
(
ev
==
0x92
)
{
/* read the key pressed from EC.GECR
* A call to SN07 with 0x0202 will do it as well respecting
* the current protocol on different OSes
*
* Note: the path for GECR may be
* \_SB.PCI0.LPCB.EC (C, FE, AR, N and friends)
* \_SB.PCI0.PIB.EC0 (VGN-FR notifications are sent directly, no GECR)
*
* TODO: we may want to do the same for the older GHKE -need
* dmi list- so this snippet may become one more callback.
*/
if
(
acpi_callsetfunc
(
handle
,
"SN07"
,
0x0202
,
&
result
)
<
0
)
dprintk
(
"sony_acpi_notify, unable to decode event 0x%.2x
\n
"
,
ev
);
else
ev
=
result
&
0xFF
;
}
if
(
ev
>=
0x90
)
{
/* New-style event */
int
result
;
int
key_handle
=
0
;
ev
-=
0x90
;
if
(
sony_find_snc_handle
(
0x100
)
==
ev
)
key_handle
=
0x100
;
if
(
sony_find_snc_handle
(
0x127
)
==
ev
)
key_handle
=
0x127
;
if
(
key_handle
)
{
struct
sony_nc_event
*
key_event
;
if
(
sony_call_snc_handle
(
key_handle
,
0x200
,
&
result
))
{
dprintk
(
"sony_acpi_notify, unable to decode"
" event 0x%.2x 0x%.2x
\n
"
,
key_handle
,
ev
);
/* restore the original event */
ev
=
event
;
}
else
{
ev
=
result
&
0xFF
;
if
(
key_handle
==
0x100
)
key_event
=
sony_100_events
;
else
key_event
=
sony_127_events
;
for
(;
key_event
->
data
;
key_event
++
)
{
if
(
key_event
->
data
==
ev
)
{
ev
=
key_event
->
event
;
break
;
}
}
if
(
sony_nc_events
)
for
(
evmap
=
sony_nc_events
;
evmap
->
event
;
evmap
++
)
{
if
(
evmap
->
data
==
ev
)
{
ev
=
evmap
->
event
;
break
;
if
(
!
key_event
->
data
)
printk
(
KERN_INFO
DRV_PFX
"Unknown event: 0x%x 0x%x
\n
"
,
key_handle
,
ev
);
else
sony_laptop_report_input_event
(
ev
);
}
}
else
if
(
sony_find_snc_handle
(
0x124
)
==
ev
)
{
sony_nc_rfkill_update
();
return
;
}
}
else
sony_laptop_report_input_event
(
ev
);
dprintk
(
"sony_acpi_notify, event: 0x%.2x
\n
"
,
ev
);
sony_laptop_report_input_event
(
ev
);
acpi_bus_generate_proc_event
(
sony_nc_acpi_device
,
1
,
ev
);
}
...
...
@@ -953,9 +993,25 @@ static acpi_status sony_walk_callback(acpi_handle handle, u32 level,
/*
* ACPI device
*/
static
int
sony_nc_function_setup
(
struct
acpi_device
*
device
)
{
int
result
;
/* Enable all events */
acpi_callsetfunc
(
sony_nc_acpi_handle
,
"SN02"
,
0xffff
,
&
result
);
/* Setup hotkeys */
sony_call_snc_handle
(
0x0100
,
0
,
&
result
);
sony_call_snc_handle
(
0x0101
,
0
,
&
result
);
sony_call_snc_handle
(
0x0102
,
0x100
,
&
result
);
return
0
;
}
static
int
sony_nc_resume
(
struct
acpi_device
*
device
)
{
struct
sony_nc_value
*
item
;
acpi_handle
handle
;
for
(
item
=
sony_nc_values
;
item
->
name
;
item
++
)
{
int
ret
;
...
...
@@ -970,13 +1026,188 @@ static int sony_nc_resume(struct acpi_device *device)
}
}
if
(
ACPI_SUCCESS
(
acpi_get_handle
(
sony_nc_acpi_handle
,
"ECON"
,
&
handle
)))
{
if
(
acpi_callsetfunc
(
sony_nc_acpi_handle
,
"ECON"
,
1
,
NULL
))
dprintk
(
"ECON Method failed
\n
"
);
}
if
(
ACPI_SUCCESS
(
acpi_get_handle
(
sony_nc_acpi_handle
,
"SN00"
,
&
handle
)))
{
dprintk
(
"Doing SNC setup
\n
"
);
sony_nc_function_setup
(
device
);
}
/* set the last requested brightness level */
if
(
sony_backlight_device
&&
!
sony_backlight_update_status
(
sony_backlight_device
))
printk
(
KERN_WARNING
DRV_PFX
"unable to restore brightness level
\n
"
);
/* re-initialize models with specific requirements */
dmi_check_system
(
sony_nc_ids
);
return
0
;
}
static
void
sony_nc_rfkill_cleanup
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
SONY_RFKILL_MAX
;
i
++
)
{
if
(
sony_rfkill_devices
[
i
])
rfkill_unregister
(
sony_rfkill_devices
[
i
]);
}
}
static
int
sony_nc_rfkill_get
(
void
*
data
,
enum
rfkill_state
*
state
)
{
int
result
;
int
argument
=
sony_rfkill_address
[(
long
)
data
];
sony_call_snc_handle
(
0x124
,
0x200
,
&
result
);
if
(
result
&
0x1
)
{
sony_call_snc_handle
(
0x124
,
argument
,
&
result
);
if
(
result
&
0xf
)
*
state
=
RFKILL_STATE_UNBLOCKED
;
else
*
state
=
RFKILL_STATE_SOFT_BLOCKED
;
}
else
{
*
state
=
RFKILL_STATE_HARD_BLOCKED
;
}
return
0
;
}
static
int
sony_nc_rfkill_set
(
void
*
data
,
enum
rfkill_state
state
)
{
int
result
;
int
argument
=
sony_rfkill_address
[(
long
)
data
]
+
0x100
;
if
(
state
==
RFKILL_STATE_UNBLOCKED
)
argument
|=
0xff0000
;
return
sony_call_snc_handle
(
0x124
,
argument
,
&
result
);
}
static
int
sony_nc_setup_wifi_rfkill
(
struct
acpi_device
*
device
)
{
int
err
=
0
;
struct
rfkill
*
sony_wifi_rfkill
;
sony_wifi_rfkill
=
rfkill_allocate
(
&
device
->
dev
,
RFKILL_TYPE_WLAN
);
if
(
!
sony_wifi_rfkill
)
return
-
1
;
sony_wifi_rfkill
->
name
=
"sony-wifi"
;
sony_wifi_rfkill
->
toggle_radio
=
sony_nc_rfkill_set
;
sony_wifi_rfkill
->
get_state
=
sony_nc_rfkill_get
;
sony_wifi_rfkill
->
user_claim_unsupported
=
1
;
sony_wifi_rfkill
->
data
=
(
void
*
)
SONY_WIFI
;
err
=
rfkill_register
(
sony_wifi_rfkill
);
if
(
err
)
rfkill_free
(
sony_wifi_rfkill
);
else
sony_rfkill_devices
[
SONY_WIFI
]
=
sony_wifi_rfkill
;
return
err
;
}
static
int
sony_nc_setup_bluetooth_rfkill
(
struct
acpi_device
*
device
)
{
int
err
=
0
;
struct
rfkill
*
sony_bluetooth_rfkill
;
sony_bluetooth_rfkill
=
rfkill_allocate
(
&
device
->
dev
,
RFKILL_TYPE_BLUETOOTH
);
if
(
!
sony_bluetooth_rfkill
)
return
-
1
;
sony_bluetooth_rfkill
->
name
=
"sony-bluetooth"
;
sony_bluetooth_rfkill
->
toggle_radio
=
sony_nc_rfkill_set
;
sony_bluetooth_rfkill
->
get_state
=
sony_nc_rfkill_get
;
sony_bluetooth_rfkill
->
user_claim_unsupported
=
1
;
sony_bluetooth_rfkill
->
data
=
(
void
*
)
SONY_BLUETOOTH
;
err
=
rfkill_register
(
sony_bluetooth_rfkill
);
if
(
err
)
rfkill_free
(
sony_bluetooth_rfkill
);
else
sony_rfkill_devices
[
SONY_BLUETOOTH
]
=
sony_bluetooth_rfkill
;
return
err
;
}
static
int
sony_nc_setup_wwan_rfkill
(
struct
acpi_device
*
device
)
{
int
err
=
0
;
struct
rfkill
*
sony_wwan_rfkill
;
sony_wwan_rfkill
=
rfkill_allocate
(
&
device
->
dev
,
RFKILL_TYPE_WWAN
);
if
(
!
sony_wwan_rfkill
)
return
-
1
;
sony_wwan_rfkill
->
name
=
"sony-wwan"
;
sony_wwan_rfkill
->
toggle_radio
=
sony_nc_rfkill_set
;
sony_wwan_rfkill
->
get_state
=
sony_nc_rfkill_get
;
sony_wwan_rfkill
->
user_claim_unsupported
=
1
;
sony_wwan_rfkill
->
data
=
(
void
*
)
SONY_WWAN
;
err
=
rfkill_register
(
sony_wwan_rfkill
);
if
(
err
)
rfkill_free
(
sony_wwan_rfkill
);
else
sony_rfkill_devices
[
SONY_WWAN
]
=
sony_wwan_rfkill
;
return
err
;
}
static
int
sony_nc_setup_wimax_rfkill
(
struct
acpi_device
*
device
)
{
int
err
=
0
;
struct
rfkill
*
sony_wimax_rfkill
;
sony_wimax_rfkill
=
rfkill_allocate
(
&
device
->
dev
,
RFKILL_TYPE_WIMAX
);
if
(
!
sony_wimax_rfkill
)
return
-
1
;
sony_wimax_rfkill
->
name
=
"sony-wimax"
;
sony_wimax_rfkill
->
toggle_radio
=
sony_nc_rfkill_set
;
sony_wimax_rfkill
->
get_state
=
sony_nc_rfkill_get
;
sony_wimax_rfkill
->
user_claim_unsupported
=
1
;
sony_wimax_rfkill
->
data
=
(
void
*
)
SONY_WIMAX
;
err
=
rfkill_register
(
sony_wimax_rfkill
);
if
(
err
)
rfkill_free
(
sony_wimax_rfkill
);
else
sony_rfkill_devices
[
SONY_WIMAX
]
=
sony_wimax_rfkill
;
return
err
;
}
static
void
sony_nc_rfkill_update
()
{
int
i
;
enum
rfkill_state
state
;
for
(
i
=
0
;
i
<
SONY_RFKILL_MAX
;
i
++
)
{
if
(
sony_rfkill_devices
[
i
])
{
sony_rfkill_devices
[
i
]
->
get_state
(
sony_rfkill_devices
[
i
]
->
data
,
&
state
);
rfkill_force_state
(
sony_rfkill_devices
[
i
],
state
);
}
}
}
static
int
sony_nc_rfkill_setup
(
struct
acpi_device
*
device
)
{
int
result
,
ret
;
if
(
sony_find_snc_handle
(
0x124
)
==
-
1
)
return
-
1
;
ret
=
sony_call_snc_handle
(
0x124
,
0xb00
,
&
result
);
if
(
ret
)
{
printk
(
KERN_INFO
DRV_PFX
"Unable to enumerate rfkill devices: %x
\n
"
,
ret
);
return
ret
;
}
if
(
result
&
0x1
)
sony_nc_setup_wifi_rfkill
(
device
);
if
(
result
&
0x2
)
sony_nc_setup_bluetooth_rfkill
(
device
);
if
(
result
&
0x1c
)
sony_nc_setup_wwan_rfkill
(
device
);
if
(
result
&
0x20
)
sony_nc_setup_wimax_rfkill
(
device
);
return
0
;
}
...
...
@@ -1024,11 +1255,24 @@ static int sony_nc_add(struct acpi_device *device)
dprintk
(
"_INI Method failed
\n
"
);
}
if
(
ACPI_SUCCESS
(
acpi_get_handle
(
sony_nc_acpi_handle
,
"ECON"
,
&
handle
)))
{
if
(
acpi_callsetfunc
(
sony_nc_acpi_handle
,
"ECON"
,
1
,
NULL
))
dprintk
(
"ECON Method failed
\n
"
);
}
if
(
ACPI_SUCCESS
(
acpi_get_handle
(
sony_nc_acpi_handle
,
"SN00"
,
&
handle
)))
{
dprintk
(
"Doing SNC setup
\n
"
);
sony_nc_function_setup
(
device
);
sony_nc_rfkill_setup
(
device
);
}
/* setup input devices and helper fifo */
result
=
sony_laptop_setup_input
(
device
);
if
(
result
)
{
printk
(
KERN_ERR
DRV_PFX
"Unabe to create input devices.
\n
"
);
"Unab
l
e to create input devices.
\n
"
);
goto
outwalk
;
}
...
...
@@ -1063,9 +1307,6 @@ static int sony_nc_add(struct acpi_device *device)
}
/* initialize models with specific requirements */
dmi_check_system
(
sony_nc_ids
);
result
=
sony_pf_add
();
if
(
result
)
goto
outbacklight
;
...
...
@@ -1131,6 +1372,7 @@ static int sony_nc_add(struct acpi_device *device)
sony_laptop_remove_input
();
outwalk:
sony_nc_rfkill_cleanup
();
return
result
;
}
...
...
@@ -1156,6 +1398,7 @@ static int sony_nc_remove(struct acpi_device *device, int type)
sony_pf_remove
();
sony_laptop_remove_input
();
sony_nc_rfkill_cleanup
();
dprintk
(
SONY_NC_DRIVER_NAME
" removed.
\n
"
);
return
0
;
...
...
@@ -1195,7 +1438,6 @@ static struct acpi_driver sony_nc_driver = {
#define SONYPI_TYPE1_OFFSET 0x04
#define SONYPI_TYPE2_OFFSET 0x12
#define SONYPI_TYPE3_OFFSET 0x12
#define SONYPI_TYPE4_OFFSET 0x12
struct
sony_pic_ioport
{
struct
acpi_resource_io
io1
;
...
...
@@ -1328,6 +1570,7 @@ static struct sonypi_event sonypi_pkeyev[] = {
{
0x01
,
SONYPI_EVENT_PKEY_P1
},
{
0x02
,
SONYPI_EVENT_PKEY_P2
},
{
0x04
,
SONYPI_EVENT_PKEY_P3
},
{
0x20
,
SONYPI_EVENT_PKEY_P1
},
{
0
,
0
}
};
...
...
@@ -1371,6 +1614,7 @@ static struct sonypi_event sonypi_zoomev[] = {
{
0x39
,
SONYPI_EVENT_ZOOM_PRESSED
},
{
0x10
,
SONYPI_EVENT_ZOOM_IN_PRESSED
},
{
0x20
,
SONYPI_EVENT_ZOOM_OUT_PRESSED
},
{
0x04
,
SONYPI_EVENT_ZOOM_PRESSED
},
{
0
,
0
}
};
...
...
@@ -1401,6 +1645,19 @@ static struct sonypi_event sonypi_batteryev[] = {
{
0
,
0
}
};
/* The set of possible volume events */
static
struct
sonypi_event
sonypi_volumeev
[]
=
{
{
0x01
,
SONYPI_EVENT_VOLUME_INC_PRESSED
},
{
0x02
,
SONYPI_EVENT_VOLUME_DEC_PRESSED
},
{
0
,
0
}
};
/* The set of possible brightness events */
static
struct
sonypi_event
sonypi_brightnessev
[]
=
{
{
0x80
,
SONYPI_EVENT_BRIGHTNESS_PRESSED
},
{
0
,
0
}
};
static
struct
sonypi_eventtypes
type1_events
[]
=
{
{
0
,
0xffffffff
,
sonypi_releaseev
},
{
0x70
,
SONYPI_MEYE_MASK
,
sonypi_meyeev
},
...
...
@@ -1438,17 +1695,11 @@ static struct sonypi_eventtypes type3_events[] = {
{
0x31
,
SONYPI_MEMORYSTICK_MASK
,
sonypi_memorystickev
},
{
0x41
,
SONYPI_BATTERY_MASK
,
sonypi_batteryev
},
{
0x31
,
SONYPI_PKEY_MASK
,
sonypi_pkeyev
},
{
0
},
};
static
struct
sonypi_eventtypes
type4_events
[]
=
{
{
0
,
0xffffffff
,
sonypi_releaseev
},
{
0x21
,
SONYPI_FNKEY_MASK
,
sonypi_fnkeyev
},
{
0x31
,
SONYPI_WIRELESS_MASK
,
sonypi_wlessev
},
{
0x31
,
SONYPI_MEMORYSTICK_MASK
,
sonypi_memorystickev
},
{
0x41
,
SONYPI_BATTERY_MASK
,
sonypi_batteryev
},
{
0x05
,
SONYPI_PKEY_MASK
,
sonypi_pkeyev
},
{
0x05
,
SONYPI_ZOOM_MASK
,
sonypi_zoomev
},
{
0x05
,
SONYPI_CAPTURE_MASK
,
sonypi_captureev
},
{
0x05
,
SONYPI_PKEY_MASK
,
sonypi_volumeev
},
{
0x05
,
SONYPI_PKEY_MASK
,
sonypi_brightnessev
},
{
0
},
};
...
...
@@ -1511,11 +1762,11 @@ static u8 sony_pic_call3(u8 dev, u8 fn, u8 v)
/*
* minidrivers for SPIC models
*/
static
int
type
4
_handle_irq
(
const
u8
data_mask
,
const
u8
ev
)
static
int
type
3
_handle_irq
(
const
u8
data_mask
,
const
u8
ev
)
{
/*
* 0x31 could mean we have to take some extra action and wait for
* the next irq for some Type
4
models, it will generate a new
* the next irq for some Type
3
models, it will generate a new
* irq and we can read new data from the device:
* - 0x5c and 0x5f requires 0xA0
* - 0x61 requires 0xB3
...
...
@@ -1545,16 +1796,10 @@ static struct device_ctrl spic_types[] = {
},
{
.
model
=
SONYPI_DEVICE_TYPE3
,
.
handle_irq
=
NULL
,
.
handle_irq
=
type3_handle_irq
,
.
evport_offset
=
SONYPI_TYPE3_OFFSET
,
.
event_types
=
type3_events
,
},
{
.
model
=
SONYPI_DEVICE_TYPE4
,
.
handle_irq
=
type4_handle_irq
,
.
evport_offset
=
SONYPI_TYPE4_OFFSET
,
.
event_types
=
type4_events
,
},
};
static
void
sony_pic_detect_device_type
(
struct
sony_pic_dev
*
dev
)
...
...
@@ -1578,14 +1823,21 @@ static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
pcidev
=
pci_get_device
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_ICH7_1
,
NULL
);
if
(
pcidev
)
{
dev
->
control
=
&
spic_types
[
3
];
dev
->
control
=
&
spic_types
[
2
];
goto
out
;
}
pcidev
=
pci_get_device
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_ICH8_4
,
NULL
);
if
(
pcidev
)
{
dev
->
control
=
&
spic_types
[
3
];
dev
->
control
=
&
spic_types
[
2
];
goto
out
;
}
pcidev
=
pci_get_device
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_ICH9_1
,
NULL
);
if
(
pcidev
)
{
dev
->
control
=
&
spic_types
[
2
];
goto
out
;
}
...
...
@@ -1598,8 +1850,7 @@ out:
printk
(
KERN_INFO
DRV_PFX
"detected Type%d model
\n
"
,
dev
->
control
->
model
==
SONYPI_DEVICE_TYPE1
?
1
:
dev
->
control
->
model
==
SONYPI_DEVICE_TYPE2
?
2
:
dev
->
control
->
model
==
SONYPI_DEVICE_TYPE3
?
3
:
4
);
dev
->
control
->
model
==
SONYPI_DEVICE_TYPE2
?
2
:
3
);
}
/* camera tests and poweron/poweroff */
...
...
@@ -1754,17 +2005,14 @@ int sony_pic_camera_command(int command, u8 value)
EXPORT_SYMBOL
(
sony_pic_camera_command
);
/* gprs/edge modem (SZ460N and SZ210P), thanks to Joshua Wise */
static
void
sony_pic_set_wwanpower
(
u8
state
)
static
void
__
sony_pic_set_wwanpower
(
u8
state
)
{
state
=
!!
state
;
mutex_lock
(
&
spic_dev
.
lock
);
if
(
spic_dev
.
wwan_power
==
state
)
{
mutex_unlock
(
&
spic_dev
.
lock
);
if
(
spic_dev
.
wwan_power
==
state
)
return
;
}
sony_pic_call2
(
0xB0
,
state
);
sony_pic_call1
(
0x82
);
spic_dev
.
wwan_power
=
state
;
mutex_unlock
(
&
spic_dev
.
lock
);
}
static
ssize_t
sony_pic_wwanpower_store
(
struct
device
*
dev
,
...
...
@@ -1776,7 +2024,9 @@ static ssize_t sony_pic_wwanpower_store(struct device *dev,
return
-
EINVAL
;
value
=
simple_strtoul
(
buffer
,
NULL
,
10
);
sony_pic_set_wwanpower
(
value
);
mutex_lock
(
&
spic_dev
.
lock
);
__sony_pic_set_wwanpower
(
value
);
mutex_unlock
(
&
spic_dev
.
lock
);
return
count
;
}
...
...
@@ -1934,10 +2184,15 @@ static int sonypi_misc_release(struct inode *inode, struct file *file)
static
int
sonypi_misc_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
/* Flush input queue on first open */
lock_kernel
();
unsigned
long
flags
;
spin_lock_irqsave
(
sonypi_compat
.
fifo
->
lock
,
flags
);
if
(
atomic_inc_return
(
&
sonypi_compat
.
open_count
)
==
1
)
kfifo_reset
(
sonypi_compat
.
fifo
);
unlock_kernel
();
__kfifo_reset
(
sonypi_compat
.
fifo
);
spin_unlock_irqrestore
(
sonypi_compat
.
fifo
->
lock
,
flags
);
return
0
;
}
...
...
@@ -1990,8 +2245,8 @@ static int ec_read16(u8 addr, u16 *value)
return
0
;
}
static
int
sonypi_misc_ioctl
(
struct
inode
*
ip
,
struct
file
*
fp
,
unsigned
int
cmd
,
unsigned
long
arg
)
static
long
sonypi_misc_ioctl
(
struct
file
*
fp
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
int
ret
=
0
;
void
__user
*
argp
=
(
void
__user
*
)
arg
;
...
...
@@ -2125,7 +2380,7 @@ static const struct file_operations sonypi_misc_fops = {
.
open
=
sonypi_misc_open
,
.
release
=
sonypi_misc_release
,
.
fasync
=
sonypi_misc_fasync
,
.
ioctl
=
sonypi_misc_ioctl
,
.
unlocked_ioctl
=
sonypi_misc_ioctl
,
};
static
struct
miscdevice
sonypi_misc_device
=
{
...
...
@@ -2566,7 +2821,7 @@ static int sony_pic_add(struct acpi_device *device)
result
=
sony_pic_possible_resources
(
device
);
if
(
result
)
{
printk
(
KERN_ERR
DRV_PFX
"Unabe to read possible resources.
\n
"
);
"Unab
l
e to read possible resources.
\n
"
);
goto
err_free_resources
;
}
...
...
@@ -2574,7 +2829,7 @@ static int sony_pic_add(struct acpi_device *device)
result
=
sony_laptop_setup_input
(
device
);
if
(
result
)
{
printk
(
KERN_ERR
DRV_PFX
"Unabe to create input devices.
\n
"
);
"Unab
l
e to create input devices.
\n
"
);
goto
err_free_resources
;
}
...
...
include/linux/sonypi.h
View file @
7c27fd19
...
...
@@ -103,6 +103,14 @@
#define SONYPI_EVENT_WIRELESS_OFF 61
#define SONYPI_EVENT_ZOOM_IN_PRESSED 62
#define SONYPI_EVENT_ZOOM_OUT_PRESSED 63
#define SONYPI_EVENT_CD_EJECT_PRESSED 64
#define SONYPI_EVENT_MODEKEY_PRESSED 65
#define SONYPI_EVENT_PKEY_P4 66
#define SONYPI_EVENT_PKEY_P5 67
#define SONYPI_EVENT_SETTINGKEY_PRESSED 68
#define SONYPI_EVENT_VOLUME_INC_PRESSED 69
#define SONYPI_EVENT_VOLUME_DEC_PRESSED 70
#define SONYPI_EVENT_BRIGHTNESS_PRESSED 71
/* get/set brightness */
#define SONYPI_IOCGBRT _IOR('v', 0, __u8)
...
...
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