aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);