aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/sony-laptop.c
diff options
context:
space:
mode:
authorMarco Chiappero <marco@absence.it>2012-05-19 09:35:55 -0400
committerMatthew Garrett <mjg@redhat.com>2012-05-31 14:34:42 -0400
commit88bf170646c3673877f4449127c2940c0bc307ca (patch)
treebc91a1040075947892faad50eb39bf292f84f73b /drivers/platform/x86/sony-laptop.c
parent54535d083f0ae6ee51a43a7a3e17e3ca89774937 (diff)
sony-laptop: add high speed battery charging function
Signed-off-by: Marco Chiappero <marco@absence.it> Signed-off-by: Mattia Dongili <malattia@linux.it> Signed-off-by: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'drivers/platform/x86/sony-laptop.c')
-rw-r--r--drivers/platform/x86/sony-laptop.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index bc7f40bcd9c..fcbedc97202 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -155,6 +155,9 @@ static void sony_nc_thermal_resume(void);
155static int sony_nc_lid_resume_setup(struct platform_device *pd); 155static int sony_nc_lid_resume_setup(struct platform_device *pd);
156static void sony_nc_lid_resume_cleanup(struct platform_device *pd); 156static void sony_nc_lid_resume_cleanup(struct platform_device *pd);
157 157
158static int sony_nc_highspeed_charging_setup(struct platform_device *pd);
159static void sony_nc_highspeed_charging_cleanup(struct platform_device *pd);
160
158enum sony_nc_rfkill { 161enum sony_nc_rfkill {
159 SONY_WIFI, 162 SONY_WIFI,
160 SONY_BLUETOOTH, 163 SONY_BLUETOOTH,
@@ -1301,6 +1304,12 @@ static void sony_nc_function_setup(struct acpi_device *device,
1301 pr_err("couldn't set up thermal profile function (%d)\n", 1304 pr_err("couldn't set up thermal profile function (%d)\n",
1302 result); 1305 result);
1303 break; 1306 break;
1307 case 0x0131:
1308 result = sony_nc_highspeed_charging_setup(pf_device);
1309 if (result)
1310 pr_err("couldn't set up high speed charging function (%d)\n",
1311 result);
1312 break;
1304 case 0x0124: 1313 case 0x0124:
1305 case 0x0135: 1314 case 0x0135:
1306 sony_nc_rfkill_setup(device); 1315 sony_nc_rfkill_setup(device);
@@ -1348,6 +1357,9 @@ static void sony_nc_function_cleanup(struct platform_device *pd)
1348 case 0x0122: 1357 case 0x0122:
1349 sony_nc_thermal_cleanup(pd); 1358 sony_nc_thermal_cleanup(pd);
1350 break; 1359 break;
1360 case 0x0131:
1361 sony_nc_highspeed_charging_cleanup(pd);
1362 break;
1351 case 0x0124: 1363 case 0x0124:
1352 case 0x0135: 1364 case 0x0135:
1353 sony_nc_rfkill_cleanup(); 1365 sony_nc_rfkill_cleanup();
@@ -2246,6 +2258,80 @@ static void sony_nc_lid_resume_cleanup(struct platform_device *pd)
2246 } 2258 }
2247} 2259}
2248 2260
2261/* High speed charging function */
2262static struct device_attribute *hsc_handle;
2263
2264static ssize_t sony_nc_highspeed_charging_store(struct device *dev,
2265 struct device_attribute *attr,
2266 const char *buffer, size_t count)
2267{
2268 unsigned int result;
2269 unsigned long value;
2270
2271 if (count > 31)
2272 return -EINVAL;
2273
2274 if (kstrtoul(buffer, 10, &value) || value > 1)
2275 return -EINVAL;
2276
2277 if (sony_call_snc_handle(0x0131, value << 0x10 | 0x0200, &result))
2278 return -EIO;
2279
2280 return count;
2281}
2282
2283static ssize_t sony_nc_highspeed_charging_show(struct device *dev,
2284 struct device_attribute *attr, char *buffer)
2285{
2286 unsigned int result;
2287
2288 if (sony_call_snc_handle(0x0131, 0x0100, &result))
2289 return -EIO;
2290
2291 return snprintf(buffer, PAGE_SIZE, "%d\n", result & 0x01);
2292}
2293
2294static int sony_nc_highspeed_charging_setup(struct platform_device *pd)
2295{
2296 unsigned int result;
2297
2298 if (sony_call_snc_handle(0x0131, 0x0000, &result) || !(result & 0x01)) {
2299 /* some models advertise the handle but have no implementation
2300 * for it
2301 */
2302 pr_info("No High Speed Charging capability found\n");
2303 return 0;
2304 }
2305
2306 hsc_handle = kzalloc(sizeof(struct device_attribute), GFP_KERNEL);
2307 if (!hsc_handle)
2308 return -ENOMEM;
2309
2310 sysfs_attr_init(&hsc_handle->attr);
2311 hsc_handle->attr.name = "battery_highspeed_charging";
2312 hsc_handle->attr.mode = S_IRUGO | S_IWUSR;
2313 hsc_handle->show = sony_nc_highspeed_charging_show;
2314 hsc_handle->store = sony_nc_highspeed_charging_store;
2315
2316 result = device_create_file(&pd->dev, hsc_handle);
2317 if (result) {
2318 kfree(hsc_handle);
2319 hsc_handle = NULL;
2320 return result;
2321 }
2322
2323 return 0;
2324}
2325
2326static void sony_nc_highspeed_charging_cleanup(struct platform_device *pd)
2327{
2328 if (hsc_handle) {
2329 device_remove_file(&pd->dev, hsc_handle);
2330 kfree(hsc_handle);
2331 hsc_handle = NULL;
2332 }
2333}
2334
2249static void sony_nc_backlight_ng_read_limits(int handle, 2335static void sony_nc_backlight_ng_read_limits(int handle,
2250 struct sony_backlight_props *props) 2336 struct sony_backlight_props *props)
2251{ 2337{