diff options
author | Javier Achirica <jachirica@gmail.com> | 2014-03-20 19:01:19 -0400 |
---|---|---|
committer | Matthew Garrett <matthew.garrett@nebula.com> | 2014-04-06 12:58:12 -0400 |
commit | d58dc780c458d429afa805578c743af4f107139a (patch) | |
tree | b5e3a3a2ca65fdf822c2d2aae19ed830b4eeabb2 /drivers/platform | |
parent | 0380d4711e2a2190d56bf04ecdc3d6dd2621efd7 (diff) |
sony-laptop: add smart connect control function
The current value is not available through the SNC device and therefore
the attribute is writable only.
Signed-off-by: Javier Achirica <jachirica@gmail.com>
Signed-off-by: Mattia Dongili <malattia@linux.it>
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r-- | drivers/platform/x86/sony-laptop.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 48e7e5bdadbf..19d769e0d774 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -177,6 +177,9 @@ static void sony_nc_usb_charge_cleanup(struct platform_device *pd); | |||
177 | static int sony_nc_panelid_setup(struct platform_device *pd); | 177 | static int sony_nc_panelid_setup(struct platform_device *pd); |
178 | static void sony_nc_panelid_cleanup(struct platform_device *pd); | 178 | static void sony_nc_panelid_cleanup(struct platform_device *pd); |
179 | 179 | ||
180 | static int sony_nc_smart_conn_setup(struct platform_device *pd); | ||
181 | static void sony_nc_smart_conn_cleanup(struct platform_device *pd); | ||
182 | |||
180 | static int sony_nc_touchpad_setup(struct platform_device *pd, | 183 | static int sony_nc_touchpad_setup(struct platform_device *pd, |
181 | unsigned int handle); | 184 | unsigned int handle); |
182 | static void sony_nc_touchpad_cleanup(struct platform_device *pd); | 185 | static void sony_nc_touchpad_cleanup(struct platform_device *pd); |
@@ -1422,6 +1425,12 @@ static void sony_nc_function_setup(struct acpi_device *device, | |||
1422 | pr_err("couldn't set up panel ID function (%d)\n", | 1425 | pr_err("couldn't set up panel ID function (%d)\n", |
1423 | result); | 1426 | result); |
1424 | break; | 1427 | break; |
1428 | case 0x0168: | ||
1429 | result = sony_nc_smart_conn_setup(pf_device); | ||
1430 | if (result) | ||
1431 | pr_err("couldn't set up smart connect support (%d)\n", | ||
1432 | result); | ||
1433 | break; | ||
1425 | default: | 1434 | default: |
1426 | continue; | 1435 | continue; |
1427 | } | 1436 | } |
@@ -1498,6 +1507,9 @@ static void sony_nc_function_cleanup(struct platform_device *pd) | |||
1498 | case 0x011D: | 1507 | case 0x011D: |
1499 | sony_nc_panelid_cleanup(pd); | 1508 | sony_nc_panelid_cleanup(pd); |
1500 | break; | 1509 | break; |
1510 | case 0x0168: | ||
1511 | sony_nc_smart_conn_cleanup(pd); | ||
1512 | break; | ||
1501 | default: | 1513 | default: |
1502 | continue; | 1514 | continue; |
1503 | } | 1515 | } |
@@ -2885,6 +2897,61 @@ static void sony_nc_panelid_cleanup(struct platform_device *pd) | |||
2885 | } | 2897 | } |
2886 | } | 2898 | } |
2887 | 2899 | ||
2900 | /* smart connect function */ | ||
2901 | static struct device_attribute *sc_handle; | ||
2902 | |||
2903 | static ssize_t sony_nc_smart_conn_store(struct device *dev, | ||
2904 | struct device_attribute *attr, | ||
2905 | const char *buffer, size_t count) | ||
2906 | { | ||
2907 | unsigned int result; | ||
2908 | unsigned long value; | ||
2909 | |||
2910 | if (count > 31) | ||
2911 | return -EINVAL; | ||
2912 | |||
2913 | if (kstrtoul(buffer, 10, &value) || value > 1) | ||
2914 | return -EINVAL; | ||
2915 | |||
2916 | if (sony_call_snc_handle(0x0168, value << 0x10, &result)) | ||
2917 | return -EIO; | ||
2918 | |||
2919 | return count; | ||
2920 | } | ||
2921 | |||
2922 | static int sony_nc_smart_conn_setup(struct platform_device *pd) | ||
2923 | { | ||
2924 | unsigned int result; | ||
2925 | |||
2926 | sc_handle = kzalloc(sizeof(struct device_attribute), GFP_KERNEL); | ||
2927 | if (!sc_handle) | ||
2928 | return -ENOMEM; | ||
2929 | |||
2930 | sysfs_attr_init(&sc_handle->attr); | ||
2931 | sc_handle->attr.name = "smart_connect"; | ||
2932 | sc_handle->attr.mode = S_IWUSR; | ||
2933 | sc_handle->show = NULL; | ||
2934 | sc_handle->store = sony_nc_smart_conn_store; | ||
2935 | |||
2936 | result = device_create_file(&pd->dev, sc_handle); | ||
2937 | if (result) { | ||
2938 | kfree(sc_handle); | ||
2939 | sc_handle = NULL; | ||
2940 | return result; | ||
2941 | } | ||
2942 | |||
2943 | return 0; | ||
2944 | } | ||
2945 | |||
2946 | static void sony_nc_smart_conn_cleanup(struct platform_device *pd) | ||
2947 | { | ||
2948 | if (sc_handle) { | ||
2949 | device_remove_file(&pd->dev, sc_handle); | ||
2950 | kfree(sc_handle); | ||
2951 | sc_handle = NULL; | ||
2952 | } | ||
2953 | } | ||
2954 | |||
2888 | /* Touchpad enable/disable */ | 2955 | /* Touchpad enable/disable */ |
2889 | struct touchpad_control { | 2956 | struct touchpad_control { |
2890 | struct device_attribute attr; | 2957 | struct device_attribute attr; |