dualsense: give mute button and led to system.

This commit is contained in:
Sorgelig
2021-07-10 16:39:05 +08:00
parent 125cdbd234
commit 774ae18f33

View File

@@ -131,6 +131,7 @@ struct dualsense {
struct led_classdev led; /* player leds */
struct led_classdev rgbled[3]; /* lightbar */
struct led_classdev muteled; /* mute led */
/* Calibration data for accelerometer and gyroscope. */
struct ps_calibration_data accel_calib_data[3];
@@ -155,7 +156,6 @@ struct dualsense {
/* Microphone */
bool update_mic_mute;
bool mic_muted;
bool last_btn_mic_state;
/* Player leds */
bool update_player_leds;
@@ -281,6 +281,7 @@ static const int ps_gamepad_buttons[] = {
BTN_THUMBL, /* L3 */
BTN_THUMBR, /* R3 */
BTN_MODE, /* PS Home */
BTN_Z
};
static const struct {int x; int y; } ps_gamepad_hat_mapping[] = {
@@ -873,7 +874,6 @@ static int dualsense_parse_report(struct ps_device *ps_dev, struct hid_report *r
uint8_t battery_data, battery_capacity, charging_status, value;
int battery_status;
uint32_t sensor_timestamp;
bool btn_mic_state;
unsigned long flags;
int i;
@@ -927,25 +927,9 @@ static int dualsense_parse_report(struct ps_device *ps_dev, struct hid_report *r
input_report_key(ds->gamepad, BTN_THUMBL, ds_report->buttons[1] & DS_BUTTONS1_L3);
input_report_key(ds->gamepad, BTN_THUMBR, ds_report->buttons[1] & DS_BUTTONS1_R3);
input_report_key(ds->gamepad, BTN_MODE, ds_report->buttons[2] & DS_BUTTONS2_PS_HOME);
input_report_key(ds->gamepad, BTN_Z, ds_report->buttons[2] & DS_BUTTONS2_MIC_MUTE);
input_sync(ds->gamepad);
/*
* The DualSense has an internal microphone, which can be muted through a mute button
* on the device. The driver is expected to read the button state and program the device
* to mute/unmute audio at the hardware level.
*/
btn_mic_state = !!(ds_report->buttons[2] & DS_BUTTONS2_MIC_MUTE);
if (btn_mic_state && !ds->last_btn_mic_state) {
spin_lock_irqsave(&ps_dev->lock, flags);
ds->update_mic_mute = true;
ds->mic_muted = !ds->mic_muted; /* toggle */
spin_unlock_irqrestore(&ps_dev->lock, flags);
/* Schedule updating of microphone state at hardware level. */
schedule_work(&ds->output_worker);
}
ds->last_btn_mic_state = btn_mic_state;
/* Parse and calibrate gyroscope data. */
for (i = 0; i < ARRAY_SIZE(ds_report->gyro); i++) {
int raw_data = (short)le16_to_cpu(ds_report->gyro[i]);
@@ -1161,6 +1145,49 @@ static int ds_leds_create(struct dualsense *ds)
return 0;
}
static int dualsense_muteled_brightness_set(struct led_classdev *led, enum led_brightness brightness)
{
struct device *dev = led->dev->parent;
struct hid_device *hdev = to_hid_device(dev);
struct dualsense *ds = hid_get_drvdata(hdev);
if (!ds) {
hid_err(hdev, "No controller data\n");
return -ENODEV;
}
ds->update_mic_mute = true;
ds->mic_muted = brightness;
schedule_work(&ds->output_worker);
return 0;
}
static int ds_muteled_create(struct dualsense *ds)
{
struct hid_device *hdev = ds->base.hdev;
struct device *dev = &hdev->dev;
int ret;
/* configure the player LEDs */
ds->muteled.name = devm_kasprintf(dev, GFP_KERNEL,"%s:mute", dev_name(dev));
if (!ds->muteled.name) return -ENOMEM;
ds->muteled.brightness = 0;
ds->muteled.max_brightness = 1;
ds->muteled.brightness_set_blocking = dualsense_muteled_brightness_set;
ds->muteled.flags = LED_CORE_SUSPENDRESUME | LED_HW_PLUGGABLE;
ret = devm_led_classdev_register(&hdev->dev, &ds->muteled);
if (ret)
{
hid_err(hdev, "Failed registering %s LED\n", ds->muteled.name);
return ret;
}
return 0;
}
static int dualsense_lightbar_brightness_set(struct led_classdev *led, enum led_brightness brightness)
{
struct device *dev = led->dev->parent;
@@ -1293,18 +1320,16 @@ static struct ps_device *dualsense_create(struct hid_device *hdev)
* from software.
*/
ret = dualsense_reset_leds(ds);
if (ret)
goto err;
if (ret) goto err;
ret = ds_lightbar_create(ds);
if (ret)
goto err;
if (ret) goto err;
ret = ds_muteled_create(ds);
if (ret) goto err;
/* Set player LEDs to our player id. */
//dualsense_set_player_leds(ds);
ret = ds_leds_create(ds);
if (ret)
goto err;
if (ret) goto err;
/*
* Reporting hardware and firmware is important as there are frequent updates, which