aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorFrank Praznik <frank.praznik@oh.rr.com>2014-04-14 10:11:36 -0400
committerJiri Kosina <jkosina@suse.cz>2014-04-24 12:53:41 -0400
commitb3ed458c1c24bac3796849ee8ec681fb3b6cbf46 (patch)
treed31bd4d39215c591c430528d2903d35323b1bcad /drivers/hid
parent8025087acf9d2b941bae93b3e0967560e7e03e87 (diff)
HID: sony: Add blink support to the Sixaxis and DualShock 4 LEDs
Add support for setting the blink rate of the LEDs. The Sixaxis allows control over each individual LED, but the Dualshock 4 only has one global control for controlling the hardware blink rate so individual colors will fall back to software timers. Setting the brightness cancels the blinking as per the LED class specifications. The Sixaxis and Dualshock 4 controllers accept delays in decisecond increments from 0 to 255 (2550 milliseconds). The value at index 1 of the DualShock 4 USB output report must be 0xFF or the light bar won't blink. Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-sony.c149
1 files changed, 124 insertions, 25 deletions
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index b41356cacc14..243722bbc3ed 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -773,6 +773,8 @@ struct sony_sc {
773 __u8 battery_charging; 773 __u8 battery_charging;
774 __u8 battery_capacity; 774 __u8 battery_capacity;
775 __u8 led_state[MAX_LEDS]; 775 __u8 led_state[MAX_LEDS];
776 __u8 led_delay_on[MAX_LEDS];
777 __u8 led_delay_off[MAX_LEDS];
776 __u8 led_count; 778 __u8 led_count;
777}; 779};
778 780
@@ -1168,6 +1170,7 @@ static void sony_led_set_brightness(struct led_classdev *led,
1168 struct sony_sc *drv_data; 1170 struct sony_sc *drv_data;
1169 1171
1170 int n; 1172 int n;
1173 int force_update;
1171 1174
1172 drv_data = hid_get_drvdata(hdev); 1175 drv_data = hid_get_drvdata(hdev);
1173 if (!drv_data) { 1176 if (!drv_data) {
@@ -1175,13 +1178,29 @@ static void sony_led_set_brightness(struct led_classdev *led,
1175 return; 1178 return;
1176 } 1179 }
1177 1180
1181 /*
1182 * The Sixaxis on USB will override any LED settings sent to it
1183 * and keep flashing all of the LEDs until the PS button is pressed.
1184 * Updates, even if redundant, must be always be sent to the
1185 * controller to avoid having to toggle the state of an LED just to
1186 * stop the flashing later on.
1187 */
1188 force_update = !!(drv_data->quirks & SIXAXIS_CONTROLLER_USB);
1189
1178 for (n = 0; n < drv_data->led_count; n++) { 1190 for (n = 0; n < drv_data->led_count; n++) {
1179 if (led == drv_data->leds[n]) { 1191 if (led == drv_data->leds[n] && (force_update ||
1180 if (value != drv_data->led_state[n]) { 1192 (value != drv_data->led_state[n] ||
1181 drv_data->led_state[n] = value; 1193 drv_data->led_delay_on[n] ||
1182 sony_set_leds(drv_data, drv_data->led_state, 1194 drv_data->led_delay_off[n]))) {
1183 drv_data->led_count); 1195
1184 } 1196 drv_data->led_state[n] = value;
1197
1198 /* Setting the brightness stops the blinking */
1199 drv_data->led_delay_on[n] = 0;
1200 drv_data->led_delay_off[n] = 0;
1201
1202 sony_set_leds(drv_data, drv_data->led_state,
1203 drv_data->led_count);
1185 break; 1204 break;
1186 } 1205 }
1187 } 1206 }
@@ -1209,6 +1228,53 @@ static enum led_brightness sony_led_get_brightness(struct led_classdev *led)
1209 return LED_OFF; 1228 return LED_OFF;
1210} 1229}
1211 1230
1231static int sony_led_blink_set(struct led_classdev *led, unsigned long *delay_on,
1232 unsigned long *delay_off)
1233{
1234 struct device *dev = led->dev->parent;
1235 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1236 struct sony_sc *drv_data = hid_get_drvdata(hdev);
1237 int n;
1238 __u8 new_on, new_off;
1239
1240 if (!drv_data) {
1241 hid_err(hdev, "No device data\n");
1242 return -EINVAL;
1243 }
1244
1245 /* Max delay is 255 deciseconds or 2550 milliseconds */
1246 if (*delay_on > 2550)
1247 *delay_on = 2550;
1248 if (*delay_off > 2550)
1249 *delay_off = 2550;
1250
1251 /* Blink at 1 Hz if both values are zero */
1252 if (!*delay_on && !*delay_off)
1253 *delay_on = *delay_off = 500;
1254
1255 new_on = *delay_on / 10;
1256 new_off = *delay_off / 10;
1257
1258 for (n = 0; n < drv_data->led_count; n++) {
1259 if (led == drv_data->leds[n])
1260 break;
1261 }
1262
1263 /* This LED is not registered on this device */
1264 if (n >= drv_data->led_count)
1265 return -EINVAL;
1266
1267 /* Don't schedule work if the values didn't change */
1268 if (new_on != drv_data->led_delay_on[n] ||
1269 new_off != drv_data->led_delay_off[n]) {
1270 drv_data->led_delay_on[n] = new_on;
1271 drv_data->led_delay_off[n] = new_off;
1272 schedule_work(&drv_data->state_worker);
1273 }
1274
1275 return 0;
1276}
1277
1212static void sony_leds_remove(struct sony_sc *sc) 1278static void sony_leds_remove(struct sony_sc *sc)
1213{ 1279{
1214 struct led_classdev *led; 1280 struct led_classdev *led;
@@ -1232,22 +1298,23 @@ static int sony_leds_init(struct sony_sc *sc)
1232{ 1298{
1233 struct hid_device *hdev = sc->hdev; 1299 struct hid_device *hdev = sc->hdev;
1234 int n, ret = 0; 1300 int n, ret = 0;
1235 int max_brightness; 1301 int use_ds4_names;
1236 int use_colors;
1237 struct led_classdev *led; 1302 struct led_classdev *led;
1238 size_t name_sz; 1303 size_t name_sz;
1239 char *name; 1304 char *name;
1240 size_t name_len; 1305 size_t name_len;
1241 const char *name_fmt; 1306 const char *name_fmt;
1242 static const char * const color_str[] = { "red", "green", "blue" }; 1307 static const char * const ds4_name_str[] = { "red", "green", "blue",
1308 "global" };
1243 __u8 initial_values[MAX_LEDS] = { 0 }; 1309 __u8 initial_values[MAX_LEDS] = { 0 };
1310 __u8 max_brightness[MAX_LEDS] = { 1 };
1311 __u8 use_hw_blink[MAX_LEDS] = { 0 };
1244 1312
1245 BUG_ON(!(sc->quirks & SONY_LED_SUPPORT)); 1313 BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
1246 1314
1247 if (sc->quirks & BUZZ_CONTROLLER) { 1315 if (sc->quirks & BUZZ_CONTROLLER) {
1248 sc->led_count = 4; 1316 sc->led_count = 4;
1249 max_brightness = 1; 1317 use_ds4_names = 0;
1250 use_colors = 0;
1251 name_len = strlen("::buzz#"); 1318 name_len = strlen("::buzz#");
1252 name_fmt = "%s::buzz%d"; 1319 name_fmt = "%s::buzz%d";
1253 /* Validate expected report characteristics. */ 1320 /* Validate expected report characteristics. */
@@ -1255,16 +1322,18 @@ static int sony_leds_init(struct sony_sc *sc)
1255 return -ENODEV; 1322 return -ENODEV;
1256 } else if (sc->quirks & DUALSHOCK4_CONTROLLER) { 1323 } else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
1257 dualshock4_set_leds_from_id(sc->device_id, initial_values); 1324 dualshock4_set_leds_from_id(sc->device_id, initial_values);
1258 sc->led_count = 3; 1325 initial_values[3] = 1;
1259 max_brightness = 255; 1326 sc->led_count = 4;
1260 use_colors = 1; 1327 memset(max_brightness, 255, 3);
1328 use_hw_blink[3] = 1;
1329 use_ds4_names = 1;
1261 name_len = 0; 1330 name_len = 0;
1262 name_fmt = "%s:%s"; 1331 name_fmt = "%s:%s";
1263 } else { 1332 } else {
1264 sixaxis_set_leds_from_id(sc->device_id, initial_values); 1333 sixaxis_set_leds_from_id(sc->device_id, initial_values);
1265 sc->led_count = 4; 1334 sc->led_count = 4;
1266 max_brightness = 1; 1335 memset(use_hw_blink, 1, 4);
1267 use_colors = 0; 1336 use_ds4_names = 0;
1268 name_len = strlen("::sony#"); 1337 name_len = strlen("::sony#");
1269 name_fmt = "%s::sony%d"; 1338 name_fmt = "%s::sony%d";
1270 } 1339 }
@@ -1280,8 +1349,8 @@ static int sony_leds_init(struct sony_sc *sc)
1280 1349
1281 for (n = 0; n < sc->led_count; n++) { 1350 for (n = 0; n < sc->led_count; n++) {
1282 1351
1283 if (use_colors) 1352 if (use_ds4_names)
1284 name_sz = strlen(dev_name(&hdev->dev)) + strlen(color_str[n]) + 2; 1353 name_sz = strlen(dev_name(&hdev->dev)) + strlen(ds4_name_str[n]) + 2;
1285 1354
1286 led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL); 1355 led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL);
1287 if (!led) { 1356 if (!led) {
@@ -1291,16 +1360,20 @@ static int sony_leds_init(struct sony_sc *sc)
1291 } 1360 }
1292 1361
1293 name = (void *)(&led[1]); 1362 name = (void *)(&led[1]);
1294 if (use_colors) 1363 if (use_ds4_names)
1295 snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), color_str[n]); 1364 snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev),
1365 ds4_name_str[n]);
1296 else 1366 else
1297 snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1); 1367 snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1);
1298 led->name = name; 1368 led->name = name;
1299 led->brightness = initial_values[n]; 1369 led->brightness = initial_values[n];
1300 led->max_brightness = max_brightness; 1370 led->max_brightness = max_brightness[n];
1301 led->brightness_get = sony_led_get_brightness; 1371 led->brightness_get = sony_led_get_brightness;
1302 led->brightness_set = sony_led_set_brightness; 1372 led->brightness_set = sony_led_set_brightness;
1303 1373
1374 if (use_hw_blink[n])
1375 led->blink_set = sony_led_blink_set;
1376
1304 sc->leds[n] = led; 1377 sc->leds[n] = led;
1305 1378
1306 ret = led_classdev_register(&hdev->dev, led); 1379 ret = led_classdev_register(&hdev->dev, led);
@@ -1323,6 +1396,7 @@ error_leds:
1323static void sixaxis_state_worker(struct work_struct *work) 1396static void sixaxis_state_worker(struct work_struct *work)
1324{ 1397{
1325 struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); 1398 struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
1399 int n;
1326 union sixaxis_output_report_01 report = { 1400 union sixaxis_output_report_01 report = {
1327 .buf = { 1401 .buf = {
1328 0x01, 1402 0x01,
@@ -1346,6 +1420,22 @@ static void sixaxis_state_worker(struct work_struct *work)
1346 report.data.leds_bitmap |= sc->led_state[2] << 3; 1420 report.data.leds_bitmap |= sc->led_state[2] << 3;
1347 report.data.leds_bitmap |= sc->led_state[3] << 4; 1421 report.data.leds_bitmap |= sc->led_state[3] << 4;
1348 1422
1423 /*
1424 * The LEDs in the report are indexed in reverse order to their
1425 * corresponding light on the controller.
1426 * Index 0 = LED 4, index 1 = LED 3, etc...
1427 *
1428 * In the case of both delay values being zero (blinking disabled) the
1429 * default report values should be used or the controller LED will be
1430 * always off.
1431 */
1432 for (n = 0; n < 4; n++) {
1433 if (sc->led_delay_on[n] || sc->led_delay_off[n]) {
1434 report.data.led[3 - n].duty_off = sc->led_delay_off[n];
1435 report.data.led[3 - n].duty_on = sc->led_delay_on[n];
1436 }
1437 }
1438
1349 hid_hw_raw_request(sc->hdev, report.data.report_id, report.buf, 1439 hid_hw_raw_request(sc->hdev, report.data.report_id, report.buf,
1350 sizeof(report), HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); 1440 sizeof(report), HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
1351} 1441}
@@ -1360,7 +1450,7 @@ static void dualshock4_state_worker(struct work_struct *work)
1360 1450
1361 if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { 1451 if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
1362 buf[0] = 0x05; 1452 buf[0] = 0x05;
1363 buf[1] = 0x03; 1453 buf[1] = 0xFF;
1364 offset = 4; 1454 offset = 4;
1365 } else { 1455 } else {
1366 buf[0] = 0x11; 1456 buf[0] = 0x11;
@@ -1376,9 +1466,18 @@ static void dualshock4_state_worker(struct work_struct *work)
1376 offset += 2; 1466 offset += 2;
1377#endif 1467#endif
1378 1468
1379 buf[offset++] = sc->led_state[0]; 1469 /* LED 3 is the global control */
1380 buf[offset++] = sc->led_state[1]; 1470 if (sc->led_state[3]) {
1381 buf[offset++] = sc->led_state[2]; 1471 buf[offset++] = sc->led_state[0];
1472 buf[offset++] = sc->led_state[1];
1473 buf[offset++] = sc->led_state[2];
1474 } else {
1475 offset += 3;
1476 }
1477
1478 /* If both delay values are zero the DualShock 4 disables blinking. */
1479 buf[offset++] = sc->led_delay_on[3];
1480 buf[offset++] = sc->led_delay_off[3];
1382 1481
1383 if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) 1482 if (sc->quirks & DUALSHOCK4_CONTROLLER_USB)
1384 hid_hw_output_report(hdev, buf, 32); 1483 hid_hw_output_report(hdev, buf, 32);