Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
2818ccb4
Commit
2818ccb4
authored
Feb 22, 2023
by
Benjamin Tissoires
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-6.3/hid-sensor' into for-linus
Allow more custom IIO sensors through HID (Philipp Jungkamp)
parents
1f3a9573
f1f73651
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
207 additions
and
100 deletions
+207
-100
drivers/hid/hid-sensor-custom.c
drivers/hid/hid-sensor-custom.c
+169
-73
drivers/iio/light/hid-sensor-als.c
drivers/iio/light/hid-sensor-als.c
+14
-13
drivers/iio/light/hid-sensor-prox.c
drivers/iio/light/hid-sensor-prox.c
+23
-14
include/linux/hid-sensor-ids.h
include/linux/hid-sensor-ids.h
+1
-0
No files found.
drivers/hid/hid-sensor-custom.c
View file @
2818ccb4
...
@@ -5,6 +5,7 @@
...
@@ -5,6 +5,7 @@
*/
*/
#include <linux/ctype.h>
#include <linux/ctype.h>
#include <linux/dmi.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/init.h>
...
@@ -750,114 +751,209 @@ static void hid_sensor_custom_dev_if_remove(struct hid_sensor_custom
...
@@ -750,114 +751,209 @@ static void hid_sensor_custom_dev_if_remove(struct hid_sensor_custom
}
}
/* luid defined in FW (e.g. ISH). Maybe used to identify sensor. */
/*
static
const
char
*
const
known_sensor_luid
[]
=
{
"020B000000000000"
};
* Match a known custom sensor.
* tag and luid is mandatory.
*/
struct
hid_sensor_custom_match
{
const
char
*
tag
;
const
char
*
luid
;
const
char
*
model
;
const
char
*
manufacturer
;
bool
check_dmi
;
struct
dmi_system_id
dmi
;
};
static
int
get_luid_table_index
(
unsigned
char
*
usage_str
)
/*
{
* Custom sensor properties used for matching.
int
i
;
*/
struct
hid_sensor_custom_properties
{
u16
serial_num
[
HID_CUSTOM_MAX_FEATURE_BYTES
];
u16
model
[
HID_CUSTOM_MAX_FEATURE_BYTES
];
u16
manufacturer
[
HID_CUSTOM_MAX_FEATURE_BYTES
];
};
static
const
struct
hid_sensor_custom_match
hid_sensor_custom_known_table
[]
=
{
/*
* Intel Integrated Sensor Hub (ISH)
*/
{
/* Intel ISH hinge */
.
tag
=
"INT"
,
.
luid
=
"020B000000000000"
,
.
manufacturer
=
"INTEL"
,
},
/*
* Lenovo Intelligent Sensing Solution (LISS)
*/
{
/* ambient light */
.
tag
=
"LISS"
,
.
luid
=
"0041010200000082"
,
.
model
=
"STK3X3X Sensor"
,
.
manufacturer
=
"Vendor 258"
,
.
check_dmi
=
true
,
.
dmi
.
matches
=
{
DMI_MATCH
(
DMI_SYS_VENDOR
,
"LENOVO"
),
}
},
{
/* human presence */
.
tag
=
"LISS"
,
.
luid
=
"0226000171AC0081"
,
.
model
=
"VL53L1_HOD Sensor"
,
.
manufacturer
=
"ST_MICRO"
,
.
check_dmi
=
true
,
.
dmi
.
matches
=
{
DMI_MATCH
(
DMI_SYS_VENDOR
,
"LENOVO"
),
}
},
{}
};
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
known_sensor_luid
);
i
++
)
{
static
bool
hid_sensor_custom_prop_match_str
(
const
u16
*
prop
,
const
char
*
match
,
if
(
!
strncmp
(
usage_str
,
known_sensor_luid
[
i
],
size_t
count
)
strlen
(
known_sensor_luid
[
i
])))
{
return
i
;
while
(
count
--
&&
*
prop
&&
*
match
)
{
if
(
*
prop
!=
(
u16
)
*
match
)
return
false
;
prop
++
;
match
++
;
}
}
return
-
ENODEV
;
return
(
count
==
-
1
)
||
*
prop
==
(
u16
)
*
match
;
}
}
static
int
get_known_custom_sensor_index
(
struct
hid_sensor_hub_device
*
hsdev
)
static
int
hid_sensor_custom_get_prop
(
struct
hid_sensor_hub_device
*
hsdev
,
u32
prop_usage_id
,
size_t
prop_size
,
u16
*
prop
)
{
{
struct
hid_sensor_hub_attribute_info
sensor_manufacturer
=
{
0
};
struct
hid_sensor_hub_attribute_info
prop_attr
=
{
0
};
struct
hid_sensor_hub_attribute_info
sensor_luid_info
=
{
0
};
int
report_size
;
int
ret
;
int
ret
;
static
u16
w_buf
[
HID_CUSTOM_MAX_FEATURE_BYTES
];
static
char
buf
[
HID_CUSTOM_MAX_FEATURE_BYTES
];
int
i
;
memset
(
w_buf
,
0
,
sizeof
(
w_buf
));
memset
(
prop
,
0
,
prop_size
);
memset
(
buf
,
0
,
sizeof
(
buf
));
/* get manufacturer info */
ret
=
sensor_hub_input_get_attribute_info
(
hsdev
,
HID_FEATURE_REPORT
,
ret
=
sensor_hub_input_get_attribute_info
(
hsdev
,
hsdev
->
usage
,
prop_usage_id
,
HID_FEATURE_REPORT
,
hsdev
->
usage
,
&
prop_attr
);
HID_USAGE_SENSOR_PROP_MANUFACTURER
,
&
sensor_manufacturer
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
report_size
=
ret
=
sensor_hub_get_feature
(
hsdev
,
prop_attr
.
report_id
,
sensor_hub_get_feature
(
hsdev
,
sensor_manufacturer
.
report_id
,
prop_attr
.
index
,
prop_size
,
prop
);
sensor_manufacturer
.
index
,
sizeof
(
w_buf
),
if
(
ret
<
0
)
{
w_buf
);
hid_err
(
hsdev
->
hdev
,
"Failed to get sensor property %08x %d
\n
"
,
if
(
report_size
<=
0
)
{
prop_usage_id
,
ret
);
hid_err
(
hsdev
->
hdev
,
return
ret
;
"Failed to get sensor manufacturer info %d
\n
"
,
report_size
);
return
-
ENODEV
;
}
}
/* convert from wide char to char */
return
0
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
buf
)
-
1
&&
w_buf
[
i
];
i
++
)
}
buf
[
i
]
=
(
char
)
w_buf
[
i
];
/* ensure it's ISH sensor */
static
bool
if
(
strncmp
(
buf
,
"INTEL"
,
strlen
(
"INTEL"
)))
hid_sensor_custom_do_match
(
struct
hid_sensor_hub_device
*
hsdev
,
return
-
ENODEV
;
const
struct
hid_sensor_custom_match
*
match
,
const
struct
hid_sensor_custom_properties
*
prop
)
{
struct
dmi_system_id
dmi
[]
=
{
match
->
dmi
,
{
0
}
};
memset
(
w_buf
,
0
,
sizeof
(
w_buf
));
if
(
!
hid_sensor_custom_prop_match_str
(
prop
->
serial_num
,
"LUID:"
,
5
)
||
memset
(
buf
,
0
,
sizeof
(
buf
));
!
hid_sensor_custom_prop_match_str
(
prop
->
serial_num
+
5
,
match
->
luid
,
HID_CUSTOM_MAX_FEATURE_BYTES
-
5
))
return
false
;
/* get real usage id */
if
(
match
->
model
&&
ret
=
sensor_hub_input_get_attribute_info
(
hsdev
,
!
hid_sensor_custom_prop_match_str
(
prop
->
model
,
match
->
model
,
HID_FEATURE_REPORT
,
hsdev
->
usage
,
HID_CUSTOM_MAX_FEATURE_BYTES
))
HID_USAGE_SENSOR_PROP_SERIAL_NUM
,
&
sensor_luid_info
);
return
false
;
if
(
match
->
manufacturer
&&
!
hid_sensor_custom_prop_match_str
(
prop
->
manufacturer
,
match
->
manufacturer
,
HID_CUSTOM_MAX_FEATURE_BYTES
))
return
false
;
if
(
match
->
check_dmi
&&
!
dmi_check_system
(
dmi
))
return
false
;
return
true
;
}
static
int
hid_sensor_custom_properties_get
(
struct
hid_sensor_hub_device
*
hsdev
,
struct
hid_sensor_custom_properties
*
prop
)
{
int
ret
;
ret
=
hid_sensor_custom_get_prop
(
hsdev
,
HID_USAGE_SENSOR_PROP_SERIAL_NUM
,
HID_CUSTOM_MAX_FEATURE_BYTES
,
prop
->
serial_num
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
report_size
=
sensor_hub_get_feature
(
hsdev
,
sensor_luid_info
.
report_id
,
/*
sensor_luid_info
.
index
,
sizeof
(
w_buf
),
* Ignore errors on the following model and manufacturer properties.
w_buf
);
* Because these are optional, it is not an error if they are missing.
if
(
report_size
<=
0
)
{
*/
hid_err
(
hsdev
->
hdev
,
"Failed to get real usage info %d
\n
"
,
report_size
);
return
-
ENODEV
;
}
/* convert from wide char to char */
hid_sensor_custom_get_prop
(
hsdev
,
HID_USAGE_SENSOR_PROP_MODEL
,
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
buf
)
-
1
&&
w_buf
[
i
];
i
++
)
HID_CUSTOM_MAX_FEATURE_BYTES
,
buf
[
i
]
=
(
char
)
w_buf
[
i
]
;
prop
->
model
)
;
if
(
strlen
(
buf
)
!=
strlen
(
known_sensor_luid
[
0
])
+
5
)
{
hid_sensor_custom_get_prop
(
hsdev
,
HID_USAGE_SENSOR_PROP_MANUFACTURER
,
hid_err
(
hsdev
->
hdev
,
HID_CUSTOM_MAX_FEATURE_BYTES
,
"%s luid length not match %zu != (%zu + 5)
\n
"
,
__func__
,
prop
->
manufacturer
);
strlen
(
buf
),
strlen
(
known_sensor_luid
[
0
]));
return
-
ENODEV
;
}
/* get table index with luid (not matching 'LUID: ' in luid) */
return
0
;
return
get_luid_table_index
(
&
buf
[
5
]);
}
static
int
hid_sensor_custom_get_known
(
struct
hid_sensor_hub_device
*
hsdev
,
const
struct
hid_sensor_custom_match
**
known
)
{
int
ret
;
const
struct
hid_sensor_custom_match
*
match
=
hid_sensor_custom_known_table
;
struct
hid_sensor_custom_properties
*
prop
;
prop
=
kmalloc
(
sizeof
(
struct
hid_sensor_custom_properties
),
GFP_KERNEL
);
if
(
!
prop
)
return
-
ENOMEM
;
ret
=
hid_sensor_custom_properties_get
(
hsdev
,
prop
);
if
(
ret
<
0
)
goto
out
;
while
(
match
->
tag
)
{
if
(
hid_sensor_custom_do_match
(
hsdev
,
match
,
prop
))
{
*
known
=
match
;
ret
=
0
;
goto
out
;
}
match
++
;
}
ret
=
-
ENODATA
;
out:
kfree
(
prop
);
return
ret
;
}
}
static
struct
platform_device
*
static
struct
platform_device
*
hid_sensor_register_platform_device
(
struct
platform_device
*
pdev
,
hid_sensor_register_platform_device
(
struct
platform_device
*
pdev
,
struct
hid_sensor_hub_device
*
hsdev
,
struct
hid_sensor_hub_device
*
hsdev
,
int
index
)
const
struct
hid_sensor_custom_match
*
match
)
{
{
char
real_usage
[
HID_SENSOR_USAGE_LENGTH
]
=
{
0
}
;
char
real_usage
[
HID_SENSOR_USAGE_LENGTH
];
struct
platform_device
*
custom_pdev
;
struct
platform_device
*
custom_pdev
;
const
char
*
dev_name
;
const
char
*
dev_name
;
char
*
c
;
char
*
c
;
/* copy real usage id */
memcpy
(
real_usage
,
match
->
luid
,
4
);
memcpy
(
real_usage
,
known_sensor_luid
[
index
],
4
);
/* usage id are all lowcase */
/* usage id are all lowcase */
for
(
c
=
real_usage
;
*
c
!=
'\0'
;
c
++
)
for
(
c
=
real_usage
;
*
c
!=
'\0'
;
c
++
)
*
c
=
tolower
(
*
c
);
*
c
=
tolower
(
*
c
);
/* HID-SENSOR-INT-REAL_USAGE_ID */
/* HID-SENSOR-TAG-REAL_USAGE_ID */
dev_name
=
kasprintf
(
GFP_KERNEL
,
"HID-SENSOR-INT-%s"
,
real_usage
);
dev_name
=
kasprintf
(
GFP_KERNEL
,
"HID-SENSOR-%s-%s"
,
match
->
tag
,
real_usage
);
if
(
!
dev_name
)
if
(
!
dev_name
)
return
ERR_PTR
(
-
ENOMEM
);
return
ERR_PTR
(
-
ENOMEM
);
...
@@ -873,7 +969,7 @@ static int hid_sensor_custom_probe(struct platform_device *pdev)
...
@@ -873,7 +969,7 @@ static int hid_sensor_custom_probe(struct platform_device *pdev)
struct
hid_sensor_custom
*
sensor_inst
;
struct
hid_sensor_custom
*
sensor_inst
;
struct
hid_sensor_hub_device
*
hsdev
=
pdev
->
dev
.
platform_data
;
struct
hid_sensor_hub_device
*
hsdev
=
pdev
->
dev
.
platform_data
;
int
ret
;
int
ret
;
int
index
;
const
struct
hid_sensor_custom_match
*
match
;
sensor_inst
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
sensor_inst
),
sensor_inst
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
sensor_inst
),
GFP_KERNEL
);
GFP_KERNEL
);
...
@@ -888,10 +984,10 @@ static int hid_sensor_custom_probe(struct platform_device *pdev)
...
@@ -888,10 +984,10 @@ static int hid_sensor_custom_probe(struct platform_device *pdev)
mutex_init
(
&
sensor_inst
->
mutex
);
mutex_init
(
&
sensor_inst
->
mutex
);
platform_set_drvdata
(
pdev
,
sensor_inst
);
platform_set_drvdata
(
pdev
,
sensor_inst
);
index
=
get_known_custom_sensor_index
(
hsdev
);
ret
=
hid_sensor_custom_get_known
(
hsdev
,
&
match
);
if
(
index
>=
0
&&
index
<
ARRAY_SIZE
(
known_sensor_luid
)
)
{
if
(
!
ret
)
{
sensor_inst
->
custom_pdev
=
sensor_inst
->
custom_pdev
=
hid_sensor_register_platform_device
(
pdev
,
hsdev
,
index
);
hid_sensor_register_platform_device
(
pdev
,
hsdev
,
match
);
ret
=
PTR_ERR_OR_ZERO
(
sensor_inst
->
custom_pdev
);
ret
=
PTR_ERR_OR_ZERO
(
sensor_inst
->
custom_pdev
);
if
(
ret
)
{
if
(
ret
)
{
...
...
drivers/iio/light/hid-sensor-als.c
View file @
2818ccb4
...
@@ -86,6 +86,7 @@ static int als_read_raw(struct iio_dev *indio_dev,
...
@@ -86,6 +86,7 @@ static int als_read_raw(struct iio_dev *indio_dev,
long
mask
)
long
mask
)
{
{
struct
als_state
*
als_state
=
iio_priv
(
indio_dev
);
struct
als_state
*
als_state
=
iio_priv
(
indio_dev
);
struct
hid_sensor_hub_device
*
hsdev
=
als_state
->
common_attributes
.
hsdev
;
int
report_id
=
-
1
;
int
report_id
=
-
1
;
u32
address
;
u32
address
;
int
ret_type
;
int
ret_type
;
...
@@ -110,11 +111,8 @@ static int als_read_raw(struct iio_dev *indio_dev,
...
@@ -110,11 +111,8 @@ static int als_read_raw(struct iio_dev *indio_dev,
hid_sensor_power_state
(
&
als_state
->
common_attributes
,
hid_sensor_power_state
(
&
als_state
->
common_attributes
,
true
);
true
);
*
val
=
sensor_hub_input_attr_get_raw_value
(
*
val
=
sensor_hub_input_attr_get_raw_value
(
als_state
->
common_attributes
.
hsdev
,
hsdev
,
hsdev
->
usage
,
address
,
report_id
,
HID_USAGE_SENSOR_ALS
,
address
,
SENSOR_HUB_SYNC
,
min
<
0
);
report_id
,
SENSOR_HUB_SYNC
,
min
<
0
);
hid_sensor_power_state
(
&
als_state
->
common_attributes
,
hid_sensor_power_state
(
&
als_state
->
common_attributes
,
false
);
false
);
}
else
{
}
else
{
...
@@ -259,9 +257,7 @@ static int als_parse_report(struct platform_device *pdev,
...
@@ -259,9 +257,7 @@ static int als_parse_report(struct platform_device *pdev,
dev_dbg
(
&
pdev
->
dev
,
"als %x:%x
\n
"
,
st
->
als_illum
.
index
,
dev_dbg
(
&
pdev
->
dev
,
"als %x:%x
\n
"
,
st
->
als_illum
.
index
,
st
->
als_illum
.
report_id
);
st
->
als_illum
.
report_id
);
st
->
scale_precision
=
hid_sensor_format_scale
(
st
->
scale_precision
=
hid_sensor_format_scale
(
usage_id
,
&
st
->
als_illum
,
HID_USAGE_SENSOR_ALS
,
&
st
->
als_illum
,
&
st
->
scale_pre_decml
,
&
st
->
scale_post_decml
);
&
st
->
scale_pre_decml
,
&
st
->
scale_post_decml
);
return
ret
;
return
ret
;
...
@@ -285,7 +281,8 @@ static int hid_als_probe(struct platform_device *pdev)
...
@@ -285,7 +281,8 @@ static int hid_als_probe(struct platform_device *pdev)
als_state
->
common_attributes
.
hsdev
=
hsdev
;
als_state
->
common_attributes
.
hsdev
=
hsdev
;
als_state
->
common_attributes
.
pdev
=
pdev
;
als_state
->
common_attributes
.
pdev
=
pdev
;
ret
=
hid_sensor_parse_common_attributes
(
hsdev
,
HID_USAGE_SENSOR_ALS
,
ret
=
hid_sensor_parse_common_attributes
(
hsdev
,
hsdev
->
usage
,
&
als_state
->
common_attributes
,
&
als_state
->
common_attributes
,
als_sensitivity_addresses
,
als_sensitivity_addresses
,
ARRAY_SIZE
(
als_sensitivity_addresses
));
ARRAY_SIZE
(
als_sensitivity_addresses
));
...
@@ -303,7 +300,8 @@ static int hid_als_probe(struct platform_device *pdev)
...
@@ -303,7 +300,8 @@ static int hid_als_probe(struct platform_device *pdev)
ret
=
als_parse_report
(
pdev
,
hsdev
,
ret
=
als_parse_report
(
pdev
,
hsdev
,
(
struct
iio_chan_spec
*
)
indio_dev
->
channels
,
(
struct
iio_chan_spec
*
)
indio_dev
->
channels
,
HID_USAGE_SENSOR_ALS
,
als_state
);
hsdev
->
usage
,
als_state
);
if
(
ret
)
{
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to setup attributes
\n
"
);
dev_err
(
&
pdev
->
dev
,
"failed to setup attributes
\n
"
);
return
ret
;
return
ret
;
...
@@ -333,8 +331,7 @@ static int hid_als_probe(struct platform_device *pdev)
...
@@ -333,8 +331,7 @@ static int hid_als_probe(struct platform_device *pdev)
als_state
->
callbacks
.
send_event
=
als_proc_event
;
als_state
->
callbacks
.
send_event
=
als_proc_event
;
als_state
->
callbacks
.
capture_sample
=
als_capture_sample
;
als_state
->
callbacks
.
capture_sample
=
als_capture_sample
;
als_state
->
callbacks
.
pdev
=
pdev
;
als_state
->
callbacks
.
pdev
=
pdev
;
ret
=
sensor_hub_register_callback
(
hsdev
,
HID_USAGE_SENSOR_ALS
,
ret
=
sensor_hub_register_callback
(
hsdev
,
hsdev
->
usage
,
&
als_state
->
callbacks
);
&
als_state
->
callbacks
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"callback reg failed
\n
"
);
dev_err
(
&
pdev
->
dev
,
"callback reg failed
\n
"
);
goto
error_iio_unreg
;
goto
error_iio_unreg
;
...
@@ -356,7 +353,7 @@ static int hid_als_remove(struct platform_device *pdev)
...
@@ -356,7 +353,7 @@ static int hid_als_remove(struct platform_device *pdev)
struct
iio_dev
*
indio_dev
=
platform_get_drvdata
(
pdev
);
struct
iio_dev
*
indio_dev
=
platform_get_drvdata
(
pdev
);
struct
als_state
*
als_state
=
iio_priv
(
indio_dev
);
struct
als_state
*
als_state
=
iio_priv
(
indio_dev
);
sensor_hub_remove_callback
(
hsdev
,
HID_USAGE_SENSOR_ALS
);
sensor_hub_remove_callback
(
hsdev
,
hsdev
->
usage
);
iio_device_unregister
(
indio_dev
);
iio_device_unregister
(
indio_dev
);
hid_sensor_remove_trigger
(
indio_dev
,
&
als_state
->
common_attributes
);
hid_sensor_remove_trigger
(
indio_dev
,
&
als_state
->
common_attributes
);
...
@@ -368,6 +365,10 @@ static const struct platform_device_id hid_als_ids[] = {
...
@@ -368,6 +365,10 @@ static const struct platform_device_id hid_als_ids[] = {
/* Format: HID-SENSOR-usage_id_in_hex_lowercase */
/* Format: HID-SENSOR-usage_id_in_hex_lowercase */
.
name
=
"HID-SENSOR-200041"
,
.
name
=
"HID-SENSOR-200041"
,
},
},
{
/* Format: HID-SENSOR-custom_sensor_tag-usage_id_in_hex_lowercase */
.
name
=
"HID-SENSOR-LISS-0041"
,
},
{
/* sentinel */
}
{
/* sentinel */
}
};
};
MODULE_DEVICE_TABLE
(
platform
,
hid_als_ids
);
MODULE_DEVICE_TABLE
(
platform
,
hid_als_ids
);
...
...
drivers/iio/light/hid-sensor-prox.c
View file @
2818ccb4
...
@@ -61,6 +61,7 @@ static int prox_read_raw(struct iio_dev *indio_dev,
...
@@ -61,6 +61,7 @@ static int prox_read_raw(struct iio_dev *indio_dev,
long
mask
)
long
mask
)
{
{
struct
prox_state
*
prox_state
=
iio_priv
(
indio_dev
);
struct
prox_state
*
prox_state
=
iio_priv
(
indio_dev
);
struct
hid_sensor_hub_device
*
hsdev
;
int
report_id
=
-
1
;
int
report_id
=
-
1
;
u32
address
;
u32
address
;
int
ret_type
;
int
ret_type
;
...
@@ -75,6 +76,7 @@ static int prox_read_raw(struct iio_dev *indio_dev,
...
@@ -75,6 +76,7 @@ static int prox_read_raw(struct iio_dev *indio_dev,
report_id
=
prox_state
->
prox_attr
.
report_id
;
report_id
=
prox_state
->
prox_attr
.
report_id
;
min
=
prox_state
->
prox_attr
.
logical_minimum
;
min
=
prox_state
->
prox_attr
.
logical_minimum
;
address
=
HID_USAGE_SENSOR_HUMAN_PRESENCE
;
address
=
HID_USAGE_SENSOR_HUMAN_PRESENCE
;
hsdev
=
prox_state
->
common_attributes
.
hsdev
;
break
;
break
;
default:
default:
report_id
=
-
1
;
report_id
=
-
1
;
...
@@ -84,11 +86,8 @@ static int prox_read_raw(struct iio_dev *indio_dev,
...
@@ -84,11 +86,8 @@ static int prox_read_raw(struct iio_dev *indio_dev,
hid_sensor_power_state
(
&
prox_state
->
common_attributes
,
hid_sensor_power_state
(
&
prox_state
->
common_attributes
,
true
);
true
);
*
val
=
sensor_hub_input_attr_get_raw_value
(
*
val
=
sensor_hub_input_attr_get_raw_value
(
prox_state
->
common_attributes
.
hsdev
,
hsdev
,
hsdev
->
usage
,
address
,
report_id
,
HID_USAGE_SENSOR_PROX
,
address
,
SENSOR_HUB_SYNC
,
min
<
0
);
report_id
,
SENSOR_HUB_SYNC
,
min
<
0
);
hid_sensor_power_state
(
&
prox_state
->
common_attributes
,
hid_sensor_power_state
(
&
prox_state
->
common_attributes
,
false
);
false
);
}
else
{
}
else
{
...
@@ -191,10 +190,16 @@ static int prox_capture_sample(struct hid_sensor_hub_device *hsdev,
...
@@ -191,10 +190,16 @@ static int prox_capture_sample(struct hid_sensor_hub_device *hsdev,
switch
(
usage_id
)
{
switch
(
usage_id
)
{
case
HID_USAGE_SENSOR_HUMAN_PRESENCE
:
case
HID_USAGE_SENSOR_HUMAN_PRESENCE
:
prox_state
->
human_presence
=
*
(
u32
*
)
raw_data
;
switch
(
raw_len
)
{
ret
=
0
;
case
1
:
break
;
prox_state
->
human_presence
=
*
(
u8
*
)
raw_data
;
default:
return
0
;
case
4
:
prox_state
->
human_presence
=
*
(
u32
*
)
raw_data
;
return
0
;
default:
break
;
}
break
;
break
;
}
}
...
@@ -244,7 +249,7 @@ static int hid_prox_probe(struct platform_device *pdev)
...
@@ -244,7 +249,7 @@ static int hid_prox_probe(struct platform_device *pdev)
prox_state
->
common_attributes
.
hsdev
=
hsdev
;
prox_state
->
common_attributes
.
hsdev
=
hsdev
;
prox_state
->
common_attributes
.
pdev
=
pdev
;
prox_state
->
common_attributes
.
pdev
=
pdev
;
ret
=
hid_sensor_parse_common_attributes
(
hsdev
,
HID_USAGE_SENSOR_PROX
,
ret
=
hid_sensor_parse_common_attributes
(
hsdev
,
hsdev
->
usage
,
&
prox_state
->
common_attributes
,
&
prox_state
->
common_attributes
,
prox_sensitivity_addresses
,
prox_sensitivity_addresses
,
ARRAY_SIZE
(
prox_sensitivity_addresses
));
ARRAY_SIZE
(
prox_sensitivity_addresses
));
...
@@ -262,7 +267,7 @@ static int hid_prox_probe(struct platform_device *pdev)
...
@@ -262,7 +267,7 @@ static int hid_prox_probe(struct platform_device *pdev)
ret
=
prox_parse_report
(
pdev
,
hsdev
,
ret
=
prox_parse_report
(
pdev
,
hsdev
,
(
struct
iio_chan_spec
*
)
indio_dev
->
channels
,
(
struct
iio_chan_spec
*
)
indio_dev
->
channels
,
HID_USAGE_SENSOR_PROX
,
prox_state
);
hsdev
->
usage
,
prox_state
);
if
(
ret
)
{
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to setup attributes
\n
"
);
dev_err
(
&
pdev
->
dev
,
"failed to setup attributes
\n
"
);
return
ret
;
return
ret
;
...
@@ -291,8 +296,8 @@ static int hid_prox_probe(struct platform_device *pdev)
...
@@ -291,8 +296,8 @@ static int hid_prox_probe(struct platform_device *pdev)
prox_state
->
callbacks
.
send_event
=
prox_proc_event
;
prox_state
->
callbacks
.
send_event
=
prox_proc_event
;
prox_state
->
callbacks
.
capture_sample
=
prox_capture_sample
;
prox_state
->
callbacks
.
capture_sample
=
prox_capture_sample
;
prox_state
->
callbacks
.
pdev
=
pdev
;
prox_state
->
callbacks
.
pdev
=
pdev
;
ret
=
sensor_hub_register_callback
(
hsdev
,
HID_USAGE_SENSOR_PROX
,
ret
=
sensor_hub_register_callback
(
hsdev
,
hsdev
->
usage
,
&
prox_state
->
callbacks
);
&
prox_state
->
callbacks
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"callback reg failed
\n
"
);
dev_err
(
&
pdev
->
dev
,
"callback reg failed
\n
"
);
goto
error_iio_unreg
;
goto
error_iio_unreg
;
...
@@ -314,7 +319,7 @@ static int hid_prox_remove(struct platform_device *pdev)
...
@@ -314,7 +319,7 @@ static int hid_prox_remove(struct platform_device *pdev)
struct
iio_dev
*
indio_dev
=
platform_get_drvdata
(
pdev
);
struct
iio_dev
*
indio_dev
=
platform_get_drvdata
(
pdev
);
struct
prox_state
*
prox_state
=
iio_priv
(
indio_dev
);
struct
prox_state
*
prox_state
=
iio_priv
(
indio_dev
);
sensor_hub_remove_callback
(
hsdev
,
HID_USAGE_SENSOR_PROX
);
sensor_hub_remove_callback
(
hsdev
,
hsdev
->
usage
);
iio_device_unregister
(
indio_dev
);
iio_device_unregister
(
indio_dev
);
hid_sensor_remove_trigger
(
indio_dev
,
&
prox_state
->
common_attributes
);
hid_sensor_remove_trigger
(
indio_dev
,
&
prox_state
->
common_attributes
);
...
@@ -326,6 +331,10 @@ static const struct platform_device_id hid_prox_ids[] = {
...
@@ -326,6 +331,10 @@ static const struct platform_device_id hid_prox_ids[] = {
/* Format: HID-SENSOR-usage_id_in_hex_lowercase */
/* Format: HID-SENSOR-usage_id_in_hex_lowercase */
.
name
=
"HID-SENSOR-200011"
,
.
name
=
"HID-SENSOR-200011"
,
},
},
{
/* Format: HID-SENSOR-tag-usage_id_in_hex_lowercase */
.
name
=
"HID-SENSOR-LISS-0226"
,
},
{
/* sentinel */
}
{
/* sentinel */
}
};
};
MODULE_DEVICE_TABLE
(
platform
,
hid_prox_ids
);
MODULE_DEVICE_TABLE
(
platform
,
hid_prox_ids
);
...
...
include/linux/hid-sensor-ids.h
View file @
2818ccb4
...
@@ -132,6 +132,7 @@
...
@@ -132,6 +132,7 @@
#define HID_USAGE_SENSOR_PROP_FRIENDLY_NAME 0x200301
#define HID_USAGE_SENSOR_PROP_FRIENDLY_NAME 0x200301
#define HID_USAGE_SENSOR_PROP_SERIAL_NUM 0x200307
#define HID_USAGE_SENSOR_PROP_SERIAL_NUM 0x200307
#define HID_USAGE_SENSOR_PROP_MANUFACTURER 0x200305
#define HID_USAGE_SENSOR_PROP_MANUFACTURER 0x200305
#define HID_USAGE_SENSOR_PROP_MODEL 0x200306
#define HID_USAGE_SENSOR_PROP_REPORT_INTERVAL 0x20030E
#define HID_USAGE_SENSOR_PROP_REPORT_INTERVAL 0x20030E
#define HID_USAGE_SENSOR_PROP_SENSITIVITY_ABS 0x20030F
#define HID_USAGE_SENSOR_PROP_SENSITIVITY_ABS 0x20030F
#define HID_USAGE_SENSOR_PROP_SENSITIVITY_RANGE_PCT 0x200310
#define HID_USAGE_SENSOR_PROP_SENSITIVITY_RANGE_PCT 0x200310
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment