unplugged-kernel/drivers/misc/mediatek/sensors-1.0/step_counter/stepsignhub/stepsignhub.c

437 lines
9.6 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2019 MediaTek Inc.
*/
#define pr_fmt(fmt) "[stepsignhub] " fmt
#include <hwmsensor.h>
#include "stepsignhub.h"
#include <step_counter.h>
#include <SCP_sensorHub.h>
#include <linux/notifier.h>
#include "include/scp.h"
enum STEP_CDS_TRC {
STEP_CDSH_TRC_INFO = 0X10,
};
static struct step_c_init_info step_cdshub_init_info;
struct step_chub_ipi_data {
atomic_t trace;
atomic_t suspend;
};
static struct step_chub_ipi_data obj_ipi_data;
static ssize_t trace_store(struct device_driver *ddri,
const char *buf, size_t count)
{
struct step_chub_ipi_data *obj = &obj_ipi_data;
int trace = 0;
if (obj == NULL) {
pr_err("obj is null!!\n");
return 0;
}
if (sscanf(buf, "0x%x", &trace) == 1) {
atomic_set(&obj->trace, trace);
} else {
pr_err("invalid content: '%s', length = %zu\n",
buf, count);
return 0;
}
return count;
}
static DRIVER_ATTR_WO(trace);
static struct driver_attribute *step_chub_attr_list[] = {
&driver_attr_trace,
};
static int step_chub_create_attr(struct device_driver *driver)
{
int idx, err = 0;
int num = (int)(ARRAY_SIZE(step_chub_attr_list));
if (driver == NULL)
return -EINVAL;
for (idx = 0; idx < num; idx++) {
err = driver_create_file(driver, step_chub_attr_list[idx]);
if (err != 0) {
pr_err("driver_create_file (%s) = %d\n",
step_chub_attr_list[idx]->attr.name, err);
break;
}
}
return err;
}
static int step_chub_delete_attr(struct device_driver *driver)
{
int idx, err = 0;
int num = (int)(ARRAY_SIZE(step_chub_attr_list));
if (driver == NULL)
return -EINVAL;
for (idx = 0; idx < num; idx++)
driver_remove_file(driver, step_chub_attr_list[idx]);
return err;
}
static int step_c_enable_nodata(int en)
{
int ret = 0;
#if defined CONFIG_MTK_SCP_SENSORHUB_V1
if (en == 1)
ret = sensor_set_delay_to_hub(ID_STEP_COUNTER, 120);
#endif
ret = sensor_enable_to_hub(ID_STEP_COUNTER, en);
return ret;
}
static int step_d_enable_nodata(int en)
{
int ret = 0;
#if defined CONFIG_MTK_SCP_SENSORHUB_V1
if (en == 1)
ret = sensor_set_delay_to_hub(ID_STEP_DETECTOR, 120);
#endif
ret = sensor_enable_to_hub(ID_STEP_DETECTOR, en);
return ret;
}
static int step_s_enable_nodata(int en)
{
int ret = 0;
#if defined CONFIG_MTK_SCP_SENSORHUB_V1
if (en == 1)
ret = sensor_set_delay_to_hub(ID_SIGNIFICANT_MOTION, 120);
#endif
ret = sensor_enable_to_hub(ID_SIGNIFICANT_MOTION, en);
return ret;
}
static int floor_c_enable_nodata(int en)
{
int ret = 0;
ret = sensor_enable_to_hub(ID_FLOOR_COUNTER, en);
return ret;
}
static int step_c_set_delay(u64 delay)
{
unsigned int ret = 0;
#if defined CONFIG_MTK_SCP_SENSORHUB_V1
unsigned int delayms = 0;
delayms = delay / 1000 / 1000;
ret = sensor_set_delay_to_hub(ID_STEP_COUNTER, delayms);
#elif defined CONFIG_NANOHUB
#else
#endif
return ret;
}
static int step_c_batch(int flag,
int64_t samplingPeriodNs, int64_t maxBatchReportLatencyNs)
{
return sensor_batch_to_hub(ID_STEP_COUNTER,
flag, samplingPeriodNs, maxBatchReportLatencyNs);
}
static int step_c_flush(void)
{
return sensor_flush_to_hub(ID_STEP_COUNTER);
}
static int step_d_set_delay(u64 delay)
{
unsigned int ret = 0;
#if defined CONFIG_MTK_SCP_SENSORHUB_V1
unsigned int delayms = 0;
delayms = delay / 1000 / 1000;
ret = sensor_set_delay_to_hub(ID_STEP_DETECTOR, delayms);
#elif defined CONFIG_NANOHUB
#else
#endif
return ret;
}
static int step_d_batch(int flag,
int64_t samplingPeriodNs, int64_t maxBatchReportLatencyNs)
{
return sensor_batch_to_hub(ID_STEP_DETECTOR,
flag, samplingPeriodNs, maxBatchReportLatencyNs);
}
static int step_d_flush(void)
{
return sensor_flush_to_hub(ID_STEP_DETECTOR);
}
static int floor_c_set_delay(u64 delay)
{
unsigned int ret = 0;
#if defined CONFIG_MTK_SCP_SENSORHUB_V1
unsigned int delayms = 0;
delayms = delay / 1000 / 1000;
ret = sensor_set_delay_to_hub(ID_FLOOR_COUNTER, delayms);
#elif defined CONFIG_NANOHUB
#else
#endif
return ret;
}
static int floor_c_batch(int flag,
int64_t samplingPeriodNs, int64_t maxBatchReportLatencyNs)
{
return sensor_batch_to_hub(ID_FLOOR_COUNTER,
flag, samplingPeriodNs, maxBatchReportLatencyNs);
}
static int floor_c_flush(void)
{
return sensor_flush_to_hub(ID_FLOOR_COUNTER);
}
static int step_counter_get_data(uint32_t *counter, int *status)
{
int err = 0;
struct data_unit_t data;
uint64_t time_stamp = 0;
err = sensor_get_data_from_hub(ID_STEP_COUNTER, &data);
if (err < 0) {
pr_err("sensor_get_data_from_hub fail!!\n");
return -1;
}
time_stamp = data.time_stamp;
*counter = data.step_counter_t.accumulated_step_count;
return 0;
}
static int step_detector_get_data(uint32_t *counter, int *status)
{
return 0;
}
static int smd_batch(int flag,
int64_t samplingPeriodNs, int64_t maxBatchReportLatencyNs)
{
return sensor_batch_to_hub(ID_SIGNIFICANT_MOTION,
flag, samplingPeriodNs, maxBatchReportLatencyNs);
}
static int smd_flush(void)
{
return sensor_flush_to_hub(ID_SIGNIFICANT_MOTION);
}
static int significant_get_data(uint32_t *counter, int *status)
{
return 0;
}
static int floor_counter_get_data(uint32_t *counter, int *status)
{
int err = 0;
struct data_unit_t data;
uint64_t time_stamp = 0;
err = sensor_get_data_from_hub(ID_FLOOR_COUNTER, &data);
if (err < 0) {
pr_err("%s fail!!\n", __func__);
return -1;
}
time_stamp = data.time_stamp;
*counter = data.floor_counter_t.accumulated_floor_count;
return 0;
}
static int step_cds_open_report_data(int open)
{
return 0;
}
static int step_detect_recv_data(struct data_unit_t *event,
void *reserved)
{
int err = 0;
if (event->flush_action == FLUSH_ACTION)
err = step_d_flush_report();
else if (event->flush_action == DATA_ACTION)
err = step_notify_t(TYPE_STEP_DETECTOR,
(int64_t)event->time_stamp);
return err;
}
static int step_count_recv_data(struct data_unit_t *event, void *reserved)
{
int err = 0;
if (event->flush_action == FLUSH_ACTION)
err = step_c_flush_report();
else if (event->flush_action == DATA_ACTION)
err = step_c_data_report_t(
event->step_counter_t.accumulated_step_count,
2, (int64_t)event->time_stamp);
return err;
}
static int sign_recv_data(struct data_unit_t *event, void *reserved)
{
int err = 0;
if (event->flush_action == FLUSH_ACTION)
pr_err("sign do not support flush\n");
else if (event->flush_action == DATA_ACTION)
err = step_notify_t(TYPE_SIGNIFICANT,
(int64_t)event->time_stamp);
return err;
}
static int floor_count_recv_data(struct data_unit_t *event, void *reserved)
{
int err = 0;
struct floor_counter_event_t *pfloor_counter = &event->floor_counter_t;
if (event->flush_action == FLUSH_ACTION)
err = floor_c_flush_report();
else if (event->flush_action == DATA_ACTION)
err = floor_c_data_report_t(
pfloor_counter->accumulated_floor_count, 2,
(int64_t)event->time_stamp);
return err;
}
static int step_chub_local_init(void)
{
struct step_c_control_path ctl = { 0 };
struct step_c_data_path data = { 0 };
int err = 0;
struct platform_driver *paddr =
step_cdshub_init_info.platform_diver_addr;
err = step_chub_create_attr(&paddr->driver);
if (err) {
pr_err("create attribute err = %d\n", err);
goto exit_create_attr_failed;
}
ctl.open_report_data = step_cds_open_report_data;
ctl.enable_nodata = step_c_enable_nodata;
ctl.enable_step_detect = step_d_enable_nodata;
ctl.enable_significant = step_s_enable_nodata;
ctl.enable_floor_c = floor_c_enable_nodata;
ctl.step_c_set_delay = step_c_set_delay;
ctl.step_d_set_delay = step_d_set_delay;
ctl.floor_c_set_delay = floor_c_set_delay;
ctl.step_c_batch = step_c_batch;
ctl.step_c_flush = step_c_flush;
ctl.step_d_batch = step_d_batch;
ctl.step_d_flush = step_d_flush;
ctl.floor_c_batch = floor_c_batch;
ctl.floor_c_flush = floor_c_flush;
ctl.smd_batch = smd_batch;
ctl.smd_flush = smd_flush;
ctl.is_report_input_direct = true;
ctl.is_counter_support_batch = false;
ctl.is_detector_support_batch = true;
ctl.is_smd_support_batch = false;
err = step_c_register_control_path(&ctl);
if (err) {
pr_err("register step_cds control path err\n");
goto exit;
}
data.get_data = step_counter_get_data;
data.get_data_step_d = step_detector_get_data;
data.get_data_significant = significant_get_data;
data.get_data_floor_c = floor_counter_get_data;
err = step_c_register_data_path(&data);
if (err) {
pr_err("register step_cds data path err\n");
goto exit;
}
err = scp_sensorHub_data_registration(ID_STEP_DETECTOR,
step_detect_recv_data);
if (err) {
pr_err("SCP_sensorHub_data_registration fail!!\n");
goto exit_create_attr_failed;
}
err =
scp_sensorHub_data_registration(ID_SIGNIFICANT_MOTION,
sign_recv_data);
if (err) {
pr_err("SCP_sensorHub_data_registration fail!!\n");
goto exit_create_attr_failed;
}
err = scp_sensorHub_data_registration(ID_STEP_COUNTER,
step_count_recv_data);
if (err) {
pr_err("SCP_sensorHub_data_registration fail!!\n");
goto exit_create_attr_failed;
}
err = scp_sensorHub_data_registration(ID_FLOOR_COUNTER,
floor_count_recv_data);
if (err) {
pr_err("SCP_sensorHub_data_registration fail!!\n");
goto exit_create_attr_failed;
}
return 0;
exit:
step_chub_delete_attr(&paddr->driver);
exit_create_attr_failed:
return -1;
}
static int step_chub_local_uninit(void)
{
return 0;
}
static struct step_c_init_info step_cdshub_init_info = {
.name = "step_cds_hub",
.init = step_chub_local_init,
.uninit = step_chub_local_uninit,
};
static int __init step_chub_init(void)
{
step_c_driver_add(&step_cdshub_init_info);
return 0;
}
static void __exit step_chub_exit(void)
{
pr_debug("%s\n", __func__);
}
module_init(step_chub_init);
module_exit(step_chub_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("GLANCE_GESTURE_HUB driver");
MODULE_AUTHOR("hongxu.zhao@mediatek.com");