Skip to content

Commit

Permalink
HID: amd_sfh: Add a new interface for exporting HPD data
Browse files Browse the repository at this point in the history
AMDSFH has information about the User presence information via the Human
Presence Detection (HPD) sensor which is part of the AMD sensor fusion hub.

Add a new interface to export this information, where other drivers like
PMF can use this information to enhance user experiences.

Link: https://lore.kernel.org/all/ad064333-48a4-4cfa-9428-69e8a7c44667@redhat.com/
Co-developed-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
  • Loading branch information
Basavaraj Natikar authored and Jiri Kosina committed Jan 4, 2024
1 parent 4e71d26 commit b5b0774
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 0 deletions.
5 changes: 5 additions & 0 deletions drivers/hid/amd-sfh-hid/amd_sfh_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ struct amd_mp2_sensor_info {
dma_addr_t dma_address;
};

struct sfh_dev_status {
bool is_hpd_present;
};

struct amd_mp2_dev {
struct pci_dev *pdev;
struct amdtp_cl_data *cl_data;
Expand All @@ -47,6 +51,7 @@ struct amd_mp2_dev {
struct amd_input_data in_data;
/* mp2 active control status */
u32 mp2_acs;
struct sfh_dev_status dev_en;
};

struct amd_mp2_ops {
Expand Down
14 changes: 14 additions & 0 deletions drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ static int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata)
int i, status;

for (i = 0; i < cl_data->num_hid_devices; i++) {
switch (cl_data->sensor_idx[i]) {
case HPD_IDX:
privdata->dev_en.is_hpd_present = false;
break;
}

if (cl_data->sensor_sts[i] == SENSOR_ENABLED) {
privdata->mp2_ops->stop(privdata, cl_data->sensor_idx[i]);
status = amd_sfh_wait_for_response
Expand Down Expand Up @@ -178,6 +184,11 @@ static int amd_sfh1_1_hid_client_init(struct amd_mp2_dev *privdata)
rc = amdtp_hid_probe(i, cl_data);
if (rc)
goto cleanup;
switch (cl_data->sensor_idx[i]) {
case HPD_IDX:
privdata->dev_en.is_hpd_present = true;
break;
}
}
dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n",
cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]),
Expand Down Expand Up @@ -259,6 +270,7 @@ static void amd_mp2_pci_remove(void *privdata)
{
struct amd_mp2_dev *mp2 = privdata;

sfh_deinit_emp2();
amd_sfh_hid_client_deinit(privdata);
mp2->mp2_ops->stop_all(mp2);
pci_intx(mp2->pdev, false);
Expand Down Expand Up @@ -311,12 +323,14 @@ int amd_sfh1_1_init(struct amd_mp2_dev *mp2)

rc = amd_sfh_irq_init(mp2);
if (rc) {
sfh_deinit_emp2();
dev_err(dev, "amd_sfh_irq_init failed\n");
return rc;
}

rc = amd_sfh1_1_hid_client_init(mp2);
if (rc) {
sfh_deinit_emp2();
dev_err(dev, "amd_sfh1_1_hid_client_init failed\n");
return rc;
}
Expand Down
37 changes: 37 additions & 0 deletions drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
*
* Author: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
*/
#include <linux/amd-pmf-io.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/iopoll.h>

#include "amd_sfh_interface.h"

static struct amd_mp2_dev *emp2;

static int amd_sfh_wait_response(struct amd_mp2_dev *mp2, u8 sid, u32 cmd_id)
{
struct sfh_cmd_response cmd_resp;
Expand Down Expand Up @@ -73,7 +76,41 @@ static struct amd_mp2_ops amd_sfh_ops = {
.response = amd_sfh_wait_response,
};

void sfh_deinit_emp2(void)
{
emp2 = NULL;
}

void sfh_interface_init(struct amd_mp2_dev *mp2)
{
mp2->mp2_ops = &amd_sfh_ops;
emp2 = mp2;
}

static int amd_sfh_hpd_info(u8 *user_present)
{
struct hpd_status hpdstatus;

if (!user_present)
return -EINVAL;

if (!emp2 || !emp2->dev_en.is_hpd_present)
return -ENODEV;

hpdstatus.val = readl(emp2->mmio + AMD_C2P_MSG(4));
*user_present = hpdstatus.shpd.presence;

return 0;
}

int amd_get_sfh_info(struct amd_sfh_info *sfh_info, enum sfh_message_type op)
{
if (sfh_info) {
switch (op) {
case MT_HPD:
return amd_sfh_hpd_info(&sfh_info->user_present);
}
}
return -EINVAL;
}
EXPORT_SYMBOL_GPL(amd_get_sfh_info);
1 change: 1 addition & 0 deletions drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ struct hpd_status {
};

void sfh_interface_init(struct amd_mp2_dev *mp2);
void sfh_deinit_emp2(void);
void amd_sfh1_1_set_desc_ops(struct amd_mp2_ops *mp2_ops);
int amd_sfh_float_to_int(u32 flt32_val);
#endif
46 changes: 46 additions & 0 deletions include/linux/amd-pmf-io.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* AMD Platform Management Framework Interface
*
* Copyright (c) 2023, Advanced Micro Devices, Inc.
* All Rights Reserved.
*
* Authors: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
* Basavaraj Natikar <Basavaraj.Natikar@amd.com>
*/

#ifndef AMD_PMF_IO_H
#define AMD_PMF_IO_H

#include <linux/types.h>

/**
* enum sfh_message_type - Query the SFH message type
* @MT_HPD: Message ID to know the Human presence info from MP2 FW
*/
enum sfh_message_type {
MT_HPD,
};

/**
* enum sfh_hpd_info - Query the Human presence information
* @SFH_NOT_DETECTED: Check the HPD connection information from MP2 FW
* @SFH_USER_PRESENT: Check if the user is present from HPD sensor
* @SFH_USER_AWAY: Check if the user is away from HPD sensor
*/
enum sfh_hpd_info {
SFH_NOT_DETECTED,
SFH_USER_PRESENT,
SFH_USER_AWAY,
};

/**
* struct amd_sfh_info - get HPD sensor info from MP2 FW
* @user_present: Populates the user presence information
*/
struct amd_sfh_info {
u8 user_present;
};

int amd_get_sfh_info(struct amd_sfh_info *sfh_info, enum sfh_message_type op);
#endif

0 comments on commit b5b0774

Please sign in to comment.