First ready to use version (no ref to upstream commit)

This commit is contained in:
tdk-opensource
2021-01-20 18:28:03 +01:00
parent cf087f22ee
commit 52bc9fbde0
50 changed files with 14728 additions and 0 deletions

356
LICENCE Normal file
View File

@@ -0,0 +1,356 @@
NOTE! This copyright does *not* cover user programs that use kernel
services by normal system calls - this is merely considered normal use
of the kernel, and does *not* fall under the heading of "derived work".
Also note that the GPL below is copyrighted by the Free Software
Foundation, but the instance of code that it refers to (the Linux
kernel) is copyrighted by me and others who actually wrote it.
Also note that the only valid version of the GPL as far as the kernel
is concerned is _this_ particular version of the license (ie v2, not
v2.2 or v3.x or whatever), unless explicitly otherwise stated.
Linus Torvalds
----------------------------------------
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@@ -0,0 +1,29 @@
TDK/InvenSense CH101 UltraSonic device
https://invensense.tdk.com/products/ch101/
Required properties:
- compatible : should be one of
"invensense,ch101"
"invensense,ch201"
- reg : the I2C address of the sensor
- rst-gpios: reset pin
- rtc_rst-gpios: rtc reset
- prg-gpios: program pin.
- interrupts: interrupt mapping for IRQ. It should be configured with flags
IRQ_TYPE_EDGE_RISING, or IRQ_TYPE_EDGE_FALLING.
Refer to interrupt-controller/interrupts.txt for generic interrupt client node
bindings.
Example:
ch101_0: ch101_1@45 {
compatible = "invensense,ch101";
reg = <0x45>;
rst-gpios = <&tlmm 140 GPIO_ACTIVE_HIGH>;
rtc_rst-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;
prg-gpios = <0 1 2>;
int-gpios = <&tlmm 122 GPIO_ACTIVE_HIGH>,
<&tlmm 123 GPIO_ACTIVE_HIGH>,
}

View File

@@ -0,0 +1,737 @@
CONFIG_LOCALVERSION="-perf"
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_PREEMPT=y
CONFIG_IRQ_TIME_ACCOUNTING=y
CONFIG_SCHED_WALT=y
CONFIG_TASKSTATS=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_PSI=y
CONFIG_RCU_EXPERT=y
CONFIG_RCU_FAST_NO_HZ=y
CONFIG_RCU_NOCB_CPU=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_IKHEADERS=y
CONFIG_LOG_CPU_MAX_BUF_SHIFT=17
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
CONFIG_BLK_CGROUP=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CPUSETS=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_BPF=y
CONFIG_SCHED_CORE_CTL=y
CONFIG_NAMESPACES=y
# CONFIG_PID_NS is not set
CONFIG_SCHED_AUTOGROUP=y
CONFIG_SCHED_TUNE=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_RD_XZ is not set
# CONFIG_RD_LZO is not set
# CONFIG_RD_LZ4 is not set
# CONFIG_FHANDLE is not set
CONFIG_KALLSYMS_ALL=y
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_JIT_ALWAYS_ON=y
CONFIG_EMBEDDED=y
# CONFIG_SLUB_DEBUG is not set
# CONFIG_COMPAT_BRK is not set
CONFIG_SLAB_FREELIST_RANDOM=y
CONFIG_SLAB_FREELIST_HARDENED=y
CONFIG_PROFILING=y
# CONFIG_ZONE_DMA32 is not set
CONFIG_HOTPLUG_SIZE_BITS=29
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_KONA=y
CONFIG_PCI=y
CONFIG_PCI_MSM=y
CONFIG_PCI_MSM_MSI=y
CONFIG_SCHED_MC=y
CONFIG_NR_CPUS=8
CONFIG_SECCOMP=y
CONFIG_OKL4_GUEST=y
# CONFIG_UNMAP_KERNEL_AT_EL0 is not set
CONFIG_ARM64_SSBD=y
CONFIG_ARMV8_DEPRECATED=y
CONFIG_SWP_EMULATION=y
CONFIG_CP15_BARRIER_EMULATION=y
CONFIG_SETEND_EMULATION=y
CONFIG_ARM64_SW_TTBR0_PAN=y
CONFIG_ARM64_LSE_ATOMICS=y
# CONFIG_ARM64_VHE is not set
CONFIG_RANDOMIZE_BASE=y
# CONFIG_EFI is not set
CONFIG_BUILD_ARM64_UNCOMPRESSED_KERNEL=y
CONFIG_KRYO_PMU_WORKAROUND=y
CONFIG_COMPAT=y
CONFIG_PM_WAKELOCKS=y
CONFIG_PM_WAKELOCKS_LIMIT=0
# CONFIG_PM_WAKELOCKS_GC is not set
CONFIG_ENERGY_MODEL=y
CONFIG_CPU_IDLE=y
CONFIG_ARM_CPUIDLE=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TIMES=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_BOOST=y
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
CONFIG_ARM_QCOM_CPUFREQ_HW=y
CONFIG_MSM_TZ_LOG=y
CONFIG_ARM64_CRYPTO=y
CONFIG_CRYPTO_SHA1_ARM64_CE=y
CONFIG_CRYPTO_SHA2_ARM64_CE=y
CONFIG_CRYPTO_GHASH_ARM64_CE=y
CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
CONFIG_PANIC_ON_REFCOUNT_ERROR=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SIG=y
CONFIG_MODULE_SIG_FORCE=y
CONFIG_MODULE_SIG_SHA512=y
CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_CFQ_GROUP_IOSCHED=y
CONFIG_IOSCHED_BFQ=y
CONFIG_BFQ_GROUP_IOSCHED=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE=y
CONFIG_MEMORY_HOTPLUG_MOVABLE_NODE=y
CONFIG_MEMORY_HOTREMOVE=y
CONFIG_CMA=y
CONFIG_CMA_DEBUGFS=y
CONFIG_CMA_AREAS=16
CONFIG_ZSMALLOC=y
CONFIG_BALANCE_ANON_FILE_RECLAIM=y
CONFIG_HAVE_USERSPACE_LOW_MEMORY_KILLER=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_XFRM_USER=y
CONFIG_XFRM_INTERFACE=y
CONFIG_XFRM_STATISTICS=y
CONFIG_NET_KEY=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_NET_IPGRE_DEMUX=y
CONFIG_SYN_COOKIES=y
CONFIG_NET_IPVTI=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
CONFIG_INET_IPCOMP=y
CONFIG_INET_UDP_DIAG=y
CONFIG_INET_DIAG_DESTROY=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
CONFIG_IPV6_OPTIMISTIC_DAD=y
CONFIG_INET6_AH=y
CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
CONFIG_IPV6_VTI=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_NETFILTER=y
CONFIG_NF_CONNTRACK=y
CONFIG_NF_CONNTRACK_SECMARK=y
CONFIG_NF_CONNTRACK_EVENTS=y
CONFIG_NF_CONNTRACK_AMANDA=y
CONFIG_NF_CONNTRACK_FTP=y
CONFIG_NF_CONNTRACK_H323=y
CONFIG_NF_CONNTRACK_IRC=y
CONFIG_NF_CONNTRACK_NETBIOS_NS=y
CONFIG_NF_CONNTRACK_PPTP=y
CONFIG_NF_CONNTRACK_SANE=y
CONFIG_NF_CONNTRACK_TFTP=y
CONFIG_NF_CT_NETLINK=y
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
CONFIG_NETFILTER_XT_TARGET_DSCP=y
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
CONFIG_NETFILTER_XT_TARGET_HARDIDLETIMER=y
CONFIG_NETFILTER_XT_TARGET_LOG=y
CONFIG_NETFILTER_XT_TARGET_MARK=y
CONFIG_NETFILTER_XT_TARGET_NFLOG=y
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
CONFIG_NETFILTER_XT_TARGET_TEE=y
CONFIG_NETFILTER_XT_TARGET_TPROXY=y
CONFIG_NETFILTER_XT_TARGET_TRACE=y
CONFIG_NETFILTER_XT_TARGET_SECMARK=y
CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
CONFIG_NETFILTER_XT_MATCH_BPF=y
CONFIG_NETFILTER_XT_MATCH_COMMENT=y
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
CONFIG_NETFILTER_XT_MATCH_DSCP=y
CONFIG_NETFILTER_XT_MATCH_ESP=y
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
CONFIG_NETFILTER_XT_MATCH_HELPER=y
CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
# CONFIG_NETFILTER_XT_MATCH_L2TP is not set
CONFIG_NETFILTER_XT_MATCH_LENGTH=y
CONFIG_NETFILTER_XT_MATCH_LIMIT=y
CONFIG_NETFILTER_XT_MATCH_MAC=y
CONFIG_NETFILTER_XT_MATCH_MARK=y
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
CONFIG_NETFILTER_XT_MATCH_OWNER=y
CONFIG_NETFILTER_XT_MATCH_POLICY=y
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
CONFIG_NETFILTER_XT_MATCH_SOCKET=y
CONFIG_NETFILTER_XT_MATCH_STATE=y
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
CONFIG_NETFILTER_XT_MATCH_STRING=y
CONFIG_NETFILTER_XT_MATCH_TIME=y
CONFIG_NETFILTER_XT_MATCH_U32=y
CONFIG_IP_NF_IPTABLES=y
CONFIG_IP_NF_MATCH_AH=y
CONFIG_IP_NF_MATCH_ECN=y
CONFIG_IP_NF_MATCH_RPFILTER=y
CONFIG_IP_NF_MATCH_TTL=y
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_REJECT=y
CONFIG_IP_NF_NAT=y
CONFIG_IP_NF_TARGET_MASQUERADE=y
CONFIG_IP_NF_TARGET_NETMAP=y
CONFIG_IP_NF_TARGET_REDIRECT=y
CONFIG_IP_NF_MANGLE=y
CONFIG_IP_NF_RAW=y
CONFIG_IP_NF_SECURITY=y
CONFIG_IP_NF_ARPTABLES=y
CONFIG_IP_NF_ARPFILTER=y
CONFIG_IP_NF_ARP_MANGLE=y
CONFIG_IP6_NF_IPTABLES=y
CONFIG_IP6_NF_MATCH_RPFILTER=y
CONFIG_IP6_NF_FILTER=y
CONFIG_IP6_NF_TARGET_REJECT=y
CONFIG_IP6_NF_MANGLE=y
CONFIG_IP6_NF_RAW=y
CONFIG_BRIDGE_NF_EBTABLES=y
CONFIG_BRIDGE_EBT_BROUTE=y
CONFIG_IP_SCTP=y
CONFIG_L2TP=y
CONFIG_L2TP_V3=y
CONFIG_L2TP_IP=y
CONFIG_L2TP_ETH=y
CONFIG_BRIDGE=y
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_HTB=y
CONFIG_NET_SCH_PRIO=y
CONFIG_NET_SCH_MULTIQ=y
CONFIG_NET_SCH_NETEM=y
CONFIG_NET_SCH_INGRESS=y
CONFIG_NET_CLS_FW=y
CONFIG_NET_CLS_U32=y
CONFIG_CLS_U32_MARK=y
CONFIG_NET_CLS_FLOW=y
CONFIG_NET_CLS_BPF=y
CONFIG_NET_EMATCH=y
CONFIG_NET_EMATCH_CMP=y
CONFIG_NET_EMATCH_NBYTE=y
CONFIG_NET_EMATCH_U32=y
CONFIG_NET_EMATCH_META=y
CONFIG_NET_EMATCH_TEXT=y
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_GACT=y
CONFIG_NET_ACT_MIRRED=y
CONFIG_NET_ACT_SKBEDIT=y
CONFIG_QRTR=y
CONFIG_QRTR_SMD=y
CONFIG_QRTR_MHI=y
CONFIG_BPF_JIT=y
CONFIG_SOCKEV_NLMCAST=y
CONFIG_BT=y
CONFIG_MSM_BT_POWER=y
CONFIG_BT_SLIM_QCA6390=y
CONFIG_CFG80211=y
CONFIG_CFG80211_INTERNAL_REGDB=y
CONFIG_RFKILL=y
CONFIG_NFC_NQ=y
CONFIG_FW_LOADER_USER_HELPER=y
CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
# CONFIG_FW_CACHE is not set
CONFIG_REGMAP_WCD_IRQ=y
CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y
CONFIG_DMA_CMA=y
CONFIG_MHI_BUS=y
CONFIG_MHI_QCOM=y
CONFIG_MHI_NETDEV=y
CONFIG_MHI_UCI=y
CONFIG_MHI_SATELLITE=y
CONFIG_ZRAM=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=16
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_HDCP_QSEECOM=y
CONFIG_QSEECOM=y
CONFIG_UID_SYS_STATS=y
CONFIG_OKL4_USER_VIRQ=y
CONFIG_WIGIG_SENSING_SPI=m
CONFIG_QTI_XR_SMRTVWR_MISC=y
CONFIG_QTI_MAXIM_FAN_CONTROLLER=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_SG=y
CONFIG_CHR_DEV_SCH=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_SCSI_UFSHCD=y
CONFIG_SCSI_UFSHCD_PLATFORM=y
CONFIG_SCSI_UFS_QCOM=y
CONFIG_SCSI_UFS_CRYPTO=y
CONFIG_SCSI_UFS_CRYPTO_QTI=y
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_DEFAULT_KEY=y
CONFIG_DM_SNAPSHOT=y
CONFIG_DM_UEVENT=y
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_FEC=y
CONFIG_NETDEVICES=y
CONFIG_BONDING=y
CONFIG_DUMMY=y
CONFIG_TUN=y
CONFIG_VETH=y
CONFIG_SKY2=y
CONFIG_RMNET=y
CONFIG_SMSC911X=y
CONFIG_PPP=y
CONFIG_PPP_BSDCOMP=y
CONFIG_PPP_DEFLATE=y
CONFIG_PPP_MPPE=y
CONFIG_PPTP=y
CONFIG_PPPOL2TP=y
CONFIG_USB_RTL8152=y
CONFIG_USB_LAN78XX=y
CONFIG_USB_USBNET=y
CONFIG_WIL6210=m
CONFIG_WCNSS_MEM_PRE_ALLOC=y
CONFIG_CLD_LL_CORE=y
CONFIG_CNSS2=y
CONFIG_CNSS2_QMI=y
CONFIG_CNSS_ASYNC=y
CONFIG_BUS_AUTO_SUSPEND=y
CONFIG_CNSS_GENL=y
CONFIG_NVM=y
CONFIG_NVM_PBLK=y
CONFIG_INPUT_EVDEV=y
CONFIG_KEYBOARD_GPIO=y
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_JOYSTICK=y
CONFIG_JOYSTICK_XPAD=y
CONFIG_JOYSTICK_XPAD_FF=y
CONFIG_JOYSTICK_XPAD_LEDS=y
CONFIG_INPUT_TABLET=y
CONFIG_TABLET_USB_ACECAD=y
CONFIG_TABLET_USB_AIPTEK=y
CONFIG_TABLET_USB_GTCO=y
CONFIG_TABLET_USB_HANWANG=y
CONFIG_TABLET_USB_KBTAB=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_FTS=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_QPNP_POWER_ON=y
CONFIG_INPUT_QTI_HAPTICS=y
CONFIG_INPUT_UINPUT=y
# CONFIG_SERIO_SERPORT is not set
# CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVMEM is not set
CONFIG_SERIAL_MSM_GENI=y
CONFIG_SERIAL_MSM_GENI_HALF_SAMPLING=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_MSM_LEGACY=y
# CONFIG_DEVPORT is not set
CONFIG_DIAG_CHAR=y
CONFIG_MSM_ADSPRPC=y
CONFIG_MSM_RDBG=m
CONFIG_OKL4_PIPE=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_QCOM_GENI=y
CONFIG_I3C=y
CONFIG_I3C_MASTER_QCOM_GENI=y
CONFIG_SPI=y
CONFIG_SPI_QCOM_GENI=y
CONFIG_SPI_SPIDEV=y
CONFIG_SPMI=y
CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=y
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
CONFIG_PINCTRL_KONA=y
CONFIG_GPIO_SYSFS=y
CONFIG_POWER_RESET_QCOM=y
CONFIG_POWER_RESET_XGENE=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_QPNP_SMB5=y
CONFIG_SMB1390_CHARGE_PUMP_PSY=y
CONFIG_SMB1355_SLAVE_CHARGER=y
CONFIG_QPNP_QNOVO5=y
CONFIG_QPNP_FG_GEN4=y
CONFIG_HL6111R=y
CONFIG_THERMAL=y
CONFIG_THERMAL_WRITABLE_TRIPS=y
CONFIG_THERMAL_GOV_USER_SPACE=y
CONFIG_THERMAL_GOV_LOW_LIMITS=y
CONFIG_CPU_THERMAL=y
CONFIG_DEVFREQ_THERMAL=y
CONFIG_QCOM_SPMI_TEMP_ALARM=y
CONFIG_THERMAL_TSENS=y
CONFIG_QTI_ADC_TM=y
CONFIG_QTI_VIRTUAL_SENSOR=y
CONFIG_QTI_QMI_SENSOR=y
CONFIG_QTI_BCL_PMIC5=y
CONFIG_QTI_BCL_SOC_DRIVER=y
CONFIG_QTI_QMI_COOLING_DEVICE=y
CONFIG_QTI_THERMAL_LIMITS_DCVS=y
CONFIG_QTI_CPU_ISOLATE_COOLING_DEVICE=y
CONFIG_QTI_LIMITS_ISENSE_CDSP=y
CONFIG_MFD_I2C_PMIC=y
CONFIG_MFD_SPMI_PMIC=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_PROXY_CONSUMER=y
CONFIG_REGULATOR_QPNP_AMOLED=y
CONFIG_REGULATOR_QPNP_LCDB=y
CONFIG_REGULATOR_REFGEN=y
CONFIG_REGULATOR_RPMH=y
CONFIG_REGULATOR_STUB=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
CONFIG_MEDIA_RADIO_SUPPORT=y
CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_VIDEO_ADV_DEBUG=y
CONFIG_VIDEO_FIXED_MINOR_RANGES=y
CONFIG_MEDIA_USB_SUPPORT=y
CONFIG_USB_VIDEO_CLASS=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_MSM_CVP_V4L2=y
CONFIG_MSM_NPU=y
CONFIG_MSM_GLOBAL_SYNX=y
CONFIG_DVB_MPQ=m
CONFIG_DVB_MPQ_DEMUX=m
CONFIG_DVB_MPQ_SW=y
CONFIG_VIDEO_V4L2_VIDEOBUF2_CORE=y
CONFIG_I2C_RTC6226_QCA=y
CONFIG_DRM=y
CONFIG_DRM_LONTIUM_LT9611UXC=y
CONFIG_FB_ARMCLCD=y
CONFIG_BACKLIGHT_QCOM_SPMI_WLED=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_DYNAMIC_MINORS=y
CONFIG_SND_USB_AUDIO=y
CONFIG_SND_USB_AUDIO_QMI=y
CONFIG_SND_SOC=y
CONFIG_UHID=y
CONFIG_HID_APPLE=y
CONFIG_HID_ELECOM=y
CONFIG_HID_MAGICMOUSE=y
CONFIG_HID_MICROSOFT=y
CONFIG_HID_MULTITOUCH=y
CONFIG_HID_NINTENDO=y
CONFIG_HID_PLANTRONICS=y
CONFIG_HID_SONY=y
CONFIG_HID_QVR=y
CONFIG_USB_HIDDEV=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_HCD_PLATFORM=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PLATFORM=y
CONFIG_USB_ACM=y
CONFIG_USB_STORAGE=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_MSM=y
CONFIG_USB_ISP1760=y
CONFIG_USB_ISP1760_HOST_ROLE=y
CONFIG_USB_SERIAL=y
CONFIG_USB_SERIAL_CP210X=y
CONFIG_USB_SERIAL_FTDI_SIO=y
CONFIG_USB_EHSET_TEST_FIXTURE=y
CONFIG_USB_LINK_LAYER_TEST=y
CONFIG_USB_REDRIVER_NB7VPQ904M=y
CONFIG_NOP_USB_XCEIV=y
CONFIG_USB_MSM_SSPHY_QMP=y
CONFIG_MSM_HSUSB_PHY=y
CONFIG_USB_QCOM_EMU_PHY=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VBUS_DRAW=900
CONFIG_USB_CONFIGFS=y
CONFIG_USB_CONFIGFS_UEVENT=y
CONFIG_USB_CONFIGFS_NCM=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_FS=y
CONFIG_USB_CONFIGFS_F_ACC=y
CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y
CONFIG_USB_CONFIGFS_F_UAC2=y
CONFIG_USB_CONFIGFS_F_MIDI=y
CONFIG_USB_CONFIGFS_F_HID=y
CONFIG_USB_CONFIGFS_F_DIAG=y
CONFIG_USB_CONFIGFS_F_CDEV=y
CONFIG_USB_CONFIGFS_F_CCID=y
CONFIG_USB_CONFIGFS_F_QDSS=y
CONFIG_USB_CONFIGFS_F_GSI=y
CONFIG_USB_CONFIGFS_F_MTP=y
CONFIG_USB_CONFIGFS_F_PTP=y
CONFIG_TYPEC=y
CONFIG_USB_PD_POLICY=y
CONFIG_QPNP_USB_PDPHY=y
CONFIG_MMC=y
CONFIG_MMC_BLOCK_MINORS=32
CONFIG_MMC_BLOCK_DEFERRED_RESUME=y
CONFIG_MMC_TEST=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_MSM=y
CONFIG_MMC_CQHCI_CRYPTO=y
CONFIG_MMC_CQHCI_CRYPTO_QTI=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_QTI_TRI_LED=y
CONFIG_LEDS_QPNP_FLASH_V2=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_EDAC=y
CONFIG_EDAC_KRYO_ARM64=y
CONFIG_EDAC_KRYO_ARM64_PANIC_ON_UE=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_PM8XXX=y
CONFIG_DMADEVICES=y
CONFIG_QCOM_GPI_DMA=y
CONFIG_UIO=y
CONFIG_STAGING=y
CONFIG_ASHMEM=y
CONFIG_ION=y
CONFIG_ION_POOL_AUTO_REFILL=y
CONFIG_QPNP_REVID=y
CONFIG_SPS=y
CONFIG_SPS_SUPPORT_NDP_BAM=y
CONFIG_GSI_REGISTER_VERSION_2=y
CONFIG_IPA3=y
CONFIG_IPA_WDI_UNIFIED_API=y
CONFIG_RMNET_IPA3=y
CONFIG_RNDIS_IPA=y
CONFIG_IPA3_MHI_PRIME_MANAGER=y
CONFIG_IPA_UT=y
CONFIG_MSM_11AD=m
CONFIG_USB_BAM=y
CONFIG_QCOM_GENI_SE=y
CONFIG_IPA3_REGDUMP=y
CONFIG_QCOM_CLK_RPMH=y
CONFIG_SPMI_PMIC_CLKDIV=y
CONFIG_MSM_CLK_AOP_QMP=y
CONFIG_MSM_VIDEOCC_KONA=y
CONFIG_MSM_DISPCC_KONA=y
CONFIG_MSM_CAMCC_KONA=y
CONFIG_MSM_GPUCC_KONA=y
CONFIG_MSM_DEBUGCC_KONA=y
CONFIG_MSM_NPUCC_KONA=y
CONFIG_HWSPINLOCK=y
CONFIG_HWSPINLOCK_QCOM=y
CONFIG_MAILBOX=y
CONFIG_QCOM_APCS_IPC=y
CONFIG_MSM_QMP=y
CONFIG_IOMMU_IO_PGTABLE_FAST=y
CONFIG_ARM_SMMU=y
CONFIG_QCOM_LAZY_MAPPING=y
CONFIG_IOMMU_DEBUG=y
CONFIG_IOMMU_TESTS=y
CONFIG_RPMSG_CHAR=y
CONFIG_RPMSG_QCOM_GLINK_SMEM=y
CONFIG_RPMSG_QCOM_GLINK_SPSS=y
CONFIG_QCOM_COMMAND_DB=y
CONFIG_QCOM_MEM_OFFLINE=y
CONFIG_OVERRIDE_MEMORY_LIMIT=y
CONFIG_QCOM_RUN_QUEUE_STATS=y
CONFIG_MSM_QBT_HANDLER=y
CONFIG_QCOM_IPCC=y
CONFIG_QCOM_LLCC=y
CONFIG_QCOM_KONA_LLCC=y
CONFIG_QCOM_LLCC_PERFMON=m
CONFIG_QCOM_MDT_LOADER=y
CONFIG_QPNP_PBS=y
CONFIG_QCOM_QMI_HELPERS=y
CONFIG_QCOM_QMI_RMNET=y
CONFIG_QCOM_QMI_DFC=y
CONFIG_RMNET_CTL=y
CONFIG_QCOM_QMI_POWER_COLLAPSE=y
CONFIG_QCOM_RPMH=y
CONFIG_QCOM_SMEM=y
CONFIG_QCOM_EARLY_RANDOM=y
CONFIG_QCOM_MEMORY_DUMP_V2=y
CONFIG_QCOM_SMP2P=y
CONFIG_SETUP_SSR_NOTIF_TIMEOUTS=y
CONFIG_SSR_SYSMON_NOTIF_TIMEOUT=20000
CONFIG_SSR_SUBSYS_NOTIF_TIMEOUT=20000
CONFIG_PANIC_ON_SSR_NOTIF_TIMEOUT=y
CONFIG_QCOM_SECURE_BUFFER=y
CONFIG_MSM_SERVICE_LOCATOR=y
CONFIG_MSM_SERVICE_NOTIFIER=y
CONFIG_MSM_SUBSYSTEM_RESTART=y
CONFIG_MSM_PIL=y
CONFIG_MSM_SYSMON_QMI_COMM=y
CONFIG_MSM_PIL_SSR_GENERIC=y
CONFIG_MSM_BOOT_STATS=y
CONFIG_QCOM_DCC_V2=y
CONFIG_QCOM_EUD=y
CONFIG_QCOM_MINIDUMP=y
CONFIG_QCOM_FSA4480_I2C=y
CONFIG_QCOM_WATCHDOG_V2=y
CONFIG_QCOM_INITIAL_LOGBUF=y
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
CONFIG_QCOM_BUS_SCALING=y
CONFIG_QCOM_BUS_CONFIG_RPMH=y
CONFIG_MSM_SPCOM=y
CONFIG_MSM_SPSS_UTILS=y
CONFIG_QSEE_IPC_IRQ_BRIDGE=y
CONFIG_QCOM_GLINK=y
CONFIG_QCOM_GLINK_PKT=y
CONFIG_QCOM_SMP2P_SLEEPSTATE=y
CONFIG_QCOM_QDSS_BRIDGE=y
CONFIG_MSM_CDSP_LOADER=y
CONFIG_QCOM_SMCINVOKE=y
CONFIG_MSM_EVENT_TIMER=y
CONFIG_MSM_PM=y
CONFIG_QTI_RPM_STATS_LOG=y
CONFIG_QTI_DDR_STATS_LOG=y
CONFIG_QTEE_SHM_BRIDGE=y
CONFIG_MSM_PERFORMANCE=y
CONFIG_QMP_DEBUGFS_CLIENT=y
CONFIG_QCOM_CDSP_RM=y
CONFIG_QCOM_QHEE_ENABLE_MEM_PROTECTION=y
CONFIG_QTI_CRYPTO_COMMON=y
CONFIG_QTI_CRYPTO_TZ=y
CONFIG_DEVFREQ_GOV_PASSIVE=y
CONFIG_QCOM_BIMC_BWMON=y
CONFIG_ARM_MEMLAT_MON=y
CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
CONFIG_DEVFREQ_GOV_QCOM_CACHE_HWMON=y
CONFIG_DEVFREQ_GOV_MEMLAT=y
CONFIG_DEVFREQ_GOV_CDSPL3=y
CONFIG_ARM_QCOM_DEVFREQ_FW=y
CONFIG_DEVFREQ_SIMPLE_DEV=y
CONFIG_QCOM_DEVFREQ_DEVBW=y
CONFIG_ARM_QCOM_DEVFREQ_QOSLAT=y
CONFIG_DEVFREQ_GOV_STATICMAP=y
CONFIG_EXTCON_USB_GPIO=y
CONFIG_IIO=y
CONFIG_IIO_KFIFO_BUF=y
CONFIG_IIO_BUFFER=y
CONFIG_IIO_TRIGGERED_BUFFER=m
CONFIG_IIO_TRIGGER=y
CONFIG_I2C_MUX=y
CONFIG_CH101=y
CONFIG_CH101_I2C=y
CONFIG_REGMAP_I2C=y
CONFIG_ADS7052_TDK_THERMISTOR=y
CONFIG_QCOM_SPMI_ADC5=y
CONFIG_PWM=y
CONFIG_PWM_QTI_LPG=y
CONFIG_QCOM_PDC=y
CONFIG_ARM_DSU_PMU=y
CONFIG_QCOM_LLCC_PMU=y
CONFIG_RAS=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
CONFIG_ANDROID_BINDERFS=y
# CONFIG_NVMEM_SYSFS is not set
CONFIG_QCOM_QFPROM=y
CONFIG_NVMEM_SPMI_SDAM=y
CONFIG_SLIMBUS_MSM_NGD=y
CONFIG_ESOC=y
CONFIG_ESOC_DEV=y
CONFIG_ESOC_CLIENT=y
CONFIG_ESOC_MDM_4x=y
CONFIG_ESOC_MDM_DRV=y
CONFIG_SENSORS_SSC=y
CONFIG_QCOM_KGSL=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXT4_ENCRYPTION=y
CONFIG_F2FS_FS=y
CONFIG_F2FS_FS_SECURITY=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y
CONFIG_FS_VERITY=y
CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_QFMT_V2=y
CONFIG_FUSE_FS=y
CONFIG_OVERLAY_FS=y
CONFIG_INCREMENTAL_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_ECRYPT_FS=y
CONFIG_ECRYPT_FS_MESSAGING=y
CONFIG_SDCARD_FS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
CONFIG_SECURITY=y
CONFIG_HARDENED_USERCOPY=y
CONFIG_FORTIFY_SOURCE=y
CONFIG_STATIC_USERMODEHELPER=y
CONFIG_STATIC_USERMODEHELPER_PATH=""
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SMACK=y
CONFIG_SECURITY_APPARMOR=y
CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=0
CONFIG_CRYPTO_CCM=y
CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_ANSI_CPRNG=y
CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
CONFIG_CRYPTO_DEV_QCRYPTO=y
CONFIG_CRYPTO_DEV_QCEDEV=y
CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_FS=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_PANIC_TIMEOUT=-1
CONFIG_SCHEDSTATS=y
# CONFIG_DEBUG_PREEMPT is not set
CONFIG_DEBUG_LIST=y
CONFIG_IPC_LOGGING=y
CONFIG_DEBUG_ALIGN_RODATA=y
CONFIG_CORESIGHT=y
CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
CONFIG_CORESIGHT_DYNAMIC_REPLICATOR=y
CONFIG_CORESIGHT_STM=y
CONFIG_CORESIGHT_CTI=y
CONFIG_CORESIGHT_CTI_SAVE_DISABLE=y
CONFIG_CORESIGHT_TPDA=y
CONFIG_CORESIGHT_TPDM=y
CONFIG_CORESIGHT_HWEVENT=y
CONFIG_CORESIGHT_DUMMY=y
CONFIG_CORESIGHT_REMOTE_ETM=y
CONFIG_CORESIGHT_TGU=y

View File

@@ -0,0 +1,823 @@
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_PREEMPT=y
CONFIG_IRQ_TIME_ACCOUNTING=y
CONFIG_SCHED_WALT=y
CONFIG_TASKSTATS=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_PSI=y
CONFIG_PSI_FTRACE=y
CONFIG_RCU_EXPERT=y
CONFIG_RCU_FAST_NO_HZ=y
CONFIG_RCU_NOCB_CPU=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_IKHEADERS=y
CONFIG_LOG_CPU_MAX_BUF_SHIFT=17
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
CONFIG_BLK_CGROUP=y
CONFIG_DEBUG_BLK_CGROUP=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CPUSETS=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_BPF=y
CONFIG_CGROUP_DEBUG=y
CONFIG_SCHED_CORE_CTL=y
CONFIG_NAMESPACES=y
# CONFIG_PID_NS is not set
CONFIG_SCHED_AUTOGROUP=y
CONFIG_SCHED_TUNE=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_RD_XZ is not set
# CONFIG_RD_LZO is not set
# CONFIG_RD_LZ4 is not set
# CONFIG_FHANDLE is not set
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_JIT_ALWAYS_ON=y
CONFIG_EMBEDDED=y
# CONFIG_COMPAT_BRK is not set
CONFIG_SLAB_FREELIST_RANDOM=y
CONFIG_SLAB_FREELIST_HARDENED=y
CONFIG_PROFILING=y
# CONFIG_ZONE_DMA32 is not set
CONFIG_HOTPLUG_SIZE_BITS=29
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_KONA=y
CONFIG_PCI=y
CONFIG_PCI_MSM=y
CONFIG_PCI_MSM_MSI=y
CONFIG_SCHED_MC=y
CONFIG_NR_CPUS=8
CONFIG_SECCOMP=y
CONFIG_OKL4_GUEST=y
# CONFIG_UNMAP_KERNEL_AT_EL0 is not set
CONFIG_ARM64_SSBD=y
CONFIG_PRINT_VMEMLAYOUT=y
CONFIG_ARMV8_DEPRECATED=y
CONFIG_SWP_EMULATION=y
CONFIG_CP15_BARRIER_EMULATION=y
CONFIG_SETEND_EMULATION=y
CONFIG_ARM64_SW_TTBR0_PAN=y
CONFIG_ARM64_LSE_ATOMICS=y
# CONFIG_ARM64_VHE is not set
CONFIG_RANDOMIZE_BASE=y
CONFIG_BUILD_ARM64_UNCOMPRESSED_KERNEL=y
CONFIG_KRYO_PMU_WORKAROUND=y
CONFIG_COMPAT=y
CONFIG_PM_WAKELOCKS=y
CONFIG_PM_WAKELOCKS_LIMIT=0
# CONFIG_PM_WAKELOCKS_GC is not set
CONFIG_PM_DEBUG=y
CONFIG_ENERGY_MODEL=y
CONFIG_CPU_IDLE=y
CONFIG_ARM_CPUIDLE=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TIMES=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_BOOST=y
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
CONFIG_ARM_QCOM_CPUFREQ_HW=y
CONFIG_MSM_TZ_LOG=y
CONFIG_ARM64_CRYPTO=y
CONFIG_CRYPTO_SHA1_ARM64_CE=y
CONFIG_CRYPTO_SHA2_ARM64_CE=y
CONFIG_CRYPTO_GHASH_ARM64_CE=y
CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
CONFIG_KPROBES=y
CONFIG_PANIC_ON_REFCOUNT_ERROR=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SIG=y
CONFIG_MODULE_SIG_FORCE=y
CONFIG_MODULE_SIG_SHA512=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
CONFIG_PARTITION_ADVANCED=y
# CONFIG_IOSCHED_DEADLINE is not set
CONFIG_CFQ_GROUP_IOSCHED=y
CONFIG_IOSCHED_BFQ=y
CONFIG_BFQ_GROUP_IOSCHED=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE=y
CONFIG_MEMORY_HOTPLUG_MOVABLE_NODE=y
CONFIG_MEMORY_HOTREMOVE=y
CONFIG_CLEANCACHE=y
CONFIG_CMA=y
CONFIG_CMA_DEBUG=y
CONFIG_CMA_DEBUGFS=y
CONFIG_CMA_ALLOW_WRITE_DEBUGFS=y
CONFIG_CMA_AREAS=16
CONFIG_ZSMALLOC=y
CONFIG_BALANCE_ANON_FILE_RECLAIM=y
CONFIG_HAVE_USERSPACE_LOW_MEMORY_KILLER=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_XFRM_USER=y
CONFIG_XFRM_INTERFACE=y
CONFIG_XFRM_STATISTICS=y
CONFIG_NET_KEY=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_NET_IPGRE_DEMUX=y
CONFIG_SYN_COOKIES=y
CONFIG_NET_IPVTI=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
CONFIG_INET_IPCOMP=y
CONFIG_INET_UDP_DIAG=y
CONFIG_INET_DIAG_DESTROY=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
CONFIG_IPV6_OPTIMISTIC_DAD=y
CONFIG_INET6_AH=y
CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
CONFIG_IPV6_VTI=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_NETFILTER=y
CONFIG_NF_CONNTRACK=y
CONFIG_NF_CONNTRACK_SECMARK=y
CONFIG_NF_CONNTRACK_EVENTS=y
CONFIG_NF_CONNTRACK_AMANDA=y
CONFIG_NF_CONNTRACK_FTP=y
CONFIG_NF_CONNTRACK_H323=y
CONFIG_NF_CONNTRACK_IRC=y
CONFIG_NF_CONNTRACK_NETBIOS_NS=y
CONFIG_NF_CONNTRACK_PPTP=y
CONFIG_NF_CONNTRACK_SANE=y
CONFIG_NF_CONNTRACK_TFTP=y
CONFIG_NF_CT_NETLINK=y
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
CONFIG_NETFILTER_XT_TARGET_DSCP=y
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
CONFIG_NETFILTER_XT_TARGET_HARDIDLETIMER=y
CONFIG_NETFILTER_XT_TARGET_LOG=y
CONFIG_NETFILTER_XT_TARGET_MARK=y
CONFIG_NETFILTER_XT_TARGET_NFLOG=y
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
CONFIG_NETFILTER_XT_TARGET_TEE=y
CONFIG_NETFILTER_XT_TARGET_TPROXY=y
CONFIG_NETFILTER_XT_TARGET_TRACE=y
CONFIG_NETFILTER_XT_TARGET_SECMARK=y
CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
CONFIG_NETFILTER_XT_MATCH_BPF=y
CONFIG_NETFILTER_XT_MATCH_COMMENT=y
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
CONFIG_NETFILTER_XT_MATCH_DSCP=y
CONFIG_NETFILTER_XT_MATCH_ESP=y
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
CONFIG_NETFILTER_XT_MATCH_HELPER=y
CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
# CONFIG_NETFILTER_XT_MATCH_L2TP is not set
CONFIG_NETFILTER_XT_MATCH_LENGTH=y
CONFIG_NETFILTER_XT_MATCH_LIMIT=y
CONFIG_NETFILTER_XT_MATCH_MAC=y
CONFIG_NETFILTER_XT_MATCH_MARK=y
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
CONFIG_NETFILTER_XT_MATCH_OWNER=y
CONFIG_NETFILTER_XT_MATCH_POLICY=y
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
CONFIG_NETFILTER_XT_MATCH_SOCKET=y
CONFIG_NETFILTER_XT_MATCH_STATE=y
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
CONFIG_NETFILTER_XT_MATCH_STRING=y
CONFIG_NETFILTER_XT_MATCH_TIME=y
CONFIG_NETFILTER_XT_MATCH_U32=y
CONFIG_IP_NF_IPTABLES=y
CONFIG_IP_NF_MATCH_AH=y
CONFIG_IP_NF_MATCH_ECN=y
CONFIG_IP_NF_MATCH_RPFILTER=y
CONFIG_IP_NF_MATCH_TTL=y
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_REJECT=y
CONFIG_IP_NF_NAT=y
CONFIG_IP_NF_TARGET_MASQUERADE=y
CONFIG_IP_NF_TARGET_NETMAP=y
CONFIG_IP_NF_TARGET_REDIRECT=y
CONFIG_IP_NF_MANGLE=y
CONFIG_IP_NF_RAW=y
CONFIG_IP_NF_SECURITY=y
CONFIG_IP_NF_ARPTABLES=y
CONFIG_IP_NF_ARPFILTER=y
CONFIG_IP_NF_ARP_MANGLE=y
CONFIG_IP6_NF_IPTABLES=y
CONFIG_IP6_NF_MATCH_RPFILTER=y
CONFIG_IP6_NF_FILTER=y
CONFIG_IP6_NF_TARGET_REJECT=y
CONFIG_IP6_NF_MANGLE=y
CONFIG_IP6_NF_RAW=y
CONFIG_BRIDGE_NF_EBTABLES=y
CONFIG_BRIDGE_EBT_BROUTE=y
CONFIG_IP_SCTP=y
CONFIG_L2TP=y
CONFIG_L2TP_DEBUGFS=y
CONFIG_L2TP_V3=y
CONFIG_L2TP_IP=y
CONFIG_L2TP_ETH=y
CONFIG_BRIDGE=y
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_HTB=y
CONFIG_NET_SCH_PRIO=y
CONFIG_NET_SCH_MULTIQ=y
CONFIG_NET_SCH_NETEM=y
CONFIG_NET_SCH_INGRESS=y
CONFIG_NET_CLS_FW=y
CONFIG_NET_CLS_U32=y
CONFIG_CLS_U32_MARK=y
CONFIG_NET_CLS_FLOW=y
CONFIG_NET_CLS_BPF=y
CONFIG_NET_EMATCH=y
CONFIG_NET_EMATCH_CMP=y
CONFIG_NET_EMATCH_NBYTE=y
CONFIG_NET_EMATCH_U32=y
CONFIG_NET_EMATCH_META=y
CONFIG_NET_EMATCH_TEXT=y
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_GACT=y
CONFIG_NET_ACT_MIRRED=y
CONFIG_NET_ACT_SKBEDIT=y
CONFIG_DNS_RESOLVER=y
CONFIG_QRTR=y
CONFIG_QRTR_SMD=y
CONFIG_QRTR_MHI=y
CONFIG_BPF_JIT=y
CONFIG_SOCKEV_NLMCAST=y
CONFIG_CAN=y
CONFIG_CAN_MCP25XXFD=y
CONFIG_BT=y
CONFIG_MSM_BT_POWER=y
CONFIG_BT_SLIM_QCA6390=y
CONFIG_CFG80211=y
CONFIG_CFG80211_CERTIFICATION_ONUS=y
CONFIG_CFG80211_REG_CELLULAR_HINTS=y
CONFIG_CFG80211_INTERNAL_REGDB=y
CONFIG_RFKILL=y
CONFIG_NFC_NQ=y
CONFIG_FW_LOADER_USER_HELPER=y
CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
# CONFIG_FW_CACHE is not set
CONFIG_REGMAP_WCD_IRQ=y
CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y
CONFIG_DMA_CMA=y
CONFIG_MHI_BUS=y
CONFIG_MHI_DEBUG=y
CONFIG_MHI_QCOM=y
CONFIG_MHI_NETDEV=y
CONFIG_MHI_UCI=y
CONFIG_MHI_SATELLITE=y
CONFIG_ZRAM=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=16
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_HDCP_QSEECOM=y
CONFIG_QSEECOM=y
CONFIG_UID_SYS_STATS=y
CONFIG_OKL4_USER_VIRQ=y
CONFIG_WIGIG_SENSING_SPI=m
CONFIG_QTI_XR_SMRTVWR_MISC=y
CONFIG_QTI_MAXIM_FAN_CONTROLLER=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_SG=y
CONFIG_CHR_DEV_SCH=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_SCSI_UFSHCD=y
CONFIG_SCSI_UFSHCD_PLATFORM=y
CONFIG_SCSI_UFS_QCOM=y
CONFIG_SCSI_UFSHCD_CMD_LOGGING=y
CONFIG_SCSI_UFS_CRYPTO=y
CONFIG_SCSI_UFS_CRYPTO_QTI=y
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_DEFAULT_KEY=y
CONFIG_DM_SNAPSHOT=y
CONFIG_DM_UEVENT=y
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_FEC=y
CONFIG_NETDEVICES=y
CONFIG_BONDING=y
CONFIG_DUMMY=y
CONFIG_TUN=y
CONFIG_VETH=y
CONFIG_RMNET=y
CONFIG_PPP=y
CONFIG_PPP_BSDCOMP=y
CONFIG_PPP_DEFLATE=y
CONFIG_PPP_MPPE=y
CONFIG_PPTP=y
CONFIG_PPPOL2TP=y
CONFIG_USB_RTL8152=y
CONFIG_USB_LAN78XX=y
CONFIG_USB_USBNET=y
CONFIG_WIL6210=m
CONFIG_WCNSS_MEM_PRE_ALLOC=y
CONFIG_CLD_LL_CORE=y
CONFIG_CNSS2=y
CONFIG_CNSS2_DEBUG=y
CONFIG_CNSS2_QMI=y
CONFIG_CNSS_ASYNC=y
CONFIG_BUS_AUTO_SUSPEND=y
CONFIG_CNSS_GENL=y
CONFIG_NVM=y
CONFIG_NVM_PBLK=y
CONFIG_INPUT_EVDEV=y
CONFIG_KEYBOARD_GPIO=y
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_JOYSTICK=y
CONFIG_JOYSTICK_XPAD=y
CONFIG_JOYSTICK_XPAD_FF=y
CONFIG_JOYSTICK_XPAD_LEDS=y
CONFIG_INPUT_TABLET=y
CONFIG_TABLET_USB_ACECAD=y
CONFIG_TABLET_USB_AIPTEK=y
CONFIG_TABLET_USB_GTCO=y
CONFIG_TABLET_USB_HANWANG=y
CONFIG_TABLET_USB_KBTAB=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_FTS=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_QPNP_POWER_ON=y
CONFIG_INPUT_QTI_HAPTICS=y
CONFIG_INPUT_UINPUT=y
# CONFIG_SERIO_SERPORT is not set
# CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVMEM is not set
CONFIG_SERIAL_MSM_GENI=y
CONFIG_SERIAL_MSM_GENI_CONSOLE=y
CONFIG_SERIAL_MSM_GENI_HALF_SAMPLING=y
CONFIG_TTY_PRINTK=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_MSM_LEGACY=y
# CONFIG_DEVPORT is not set
CONFIG_DIAG_CHAR=y
CONFIG_MSM_ADSPRPC=y
CONFIG_MSM_RDBG=m
CONFIG_OKL4_PIPE=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_QCOM_GENI=y
CONFIG_I3C=y
CONFIG_I3C_MASTER_QCOM_GENI=y
CONFIG_SPI=y
CONFIG_SPI_QCOM_GENI=y
CONFIG_SPI_SPIDEV=y
CONFIG_SPMI=y
CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=y
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
CONFIG_PINCTRL_KONA=y
CONFIG_PINCTRL_SX150X=y
CONFIG_GPIO_SYSFS=y
CONFIG_POWER_RESET_QCOM=y
CONFIG_POWER_RESET_XGENE=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_QPNP_SMB5=y
CONFIG_SMB1390_CHARGE_PUMP_PSY=y
CONFIG_SMB1355_SLAVE_CHARGER=y
CONFIG_QPNP_QNOVO5=y
CONFIG_QPNP_FG_GEN4=y
CONFIG_HL6111R=y
CONFIG_THERMAL=y
CONFIG_THERMAL_WRITABLE_TRIPS=y
CONFIG_THERMAL_GOV_USER_SPACE=y
CONFIG_THERMAL_GOV_LOW_LIMITS=y
CONFIG_CPU_THERMAL=y
CONFIG_DEVFREQ_THERMAL=y
CONFIG_QCOM_SPMI_TEMP_ALARM=y
CONFIG_THERMAL_TSENS=y
CONFIG_QTI_ADC_TM=y
CONFIG_QTI_VIRTUAL_SENSOR=y
CONFIG_QTI_QMI_SENSOR=y
CONFIG_QTI_BCL_PMIC5=y
CONFIG_QTI_BCL_SOC_DRIVER=y
CONFIG_QTI_QMI_COOLING_DEVICE=y
CONFIG_QTI_THERMAL_LIMITS_DCVS=y
CONFIG_QTI_CPU_ISOLATE_COOLING_DEVICE=y
CONFIG_QTI_LIMITS_ISENSE_CDSP=y
CONFIG_MFD_I2C_PMIC=y
CONFIG_MFD_SPMI_PMIC=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_PROXY_CONSUMER=y
CONFIG_REGULATOR_QPNP_AMOLED=y
CONFIG_REGULATOR_QPNP_LCDB=y
CONFIG_REGULATOR_REFGEN=y
CONFIG_REGULATOR_RPMH=y
CONFIG_REGULATOR_STUB=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
CONFIG_MEDIA_RADIO_SUPPORT=y
CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_VIDEO_ADV_DEBUG=y
CONFIG_VIDEO_FIXED_MINOR_RANGES=y
CONFIG_MEDIA_USB_SUPPORT=y
CONFIG_USB_VIDEO_CLASS=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_MSM_CVP_V4L2=y
CONFIG_MSM_NPU=y
CONFIG_MSM_GLOBAL_SYNX=y
CONFIG_DVB_MPQ=m
CONFIG_DVB_MPQ_DEMUX=m
CONFIG_DVB_MPQ_SW=y
CONFIG_VIDEO_V4L2_VIDEOBUF2_CORE=y
CONFIG_I2C_RTC6226_QCA=y
CONFIG_DRM=y
CONFIG_DRM_LONTIUM_LT9611UXC=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_BACKLIGHT_QCOM_SPMI_WLED=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_DYNAMIC_MINORS=y
CONFIG_SND_USB_AUDIO=y
CONFIG_SND_USB_AUDIO_QMI=y
CONFIG_SND_SOC=y
CONFIG_UHID=y
CONFIG_HID_APPLE=y
CONFIG_HID_ELECOM=y
CONFIG_HID_MAGICMOUSE=y
CONFIG_HID_MICROSOFT=y
CONFIG_HID_MULTITOUCH=y
CONFIG_HID_NINTENDO=y
CONFIG_HID_PLANTRONICS=y
CONFIG_HID_SONY=y
CONFIG_HID_QVR=y
CONFIG_USB_HIDDEV=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_HCD_PLATFORM=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PLATFORM=y
CONFIG_USB_ACM=y
CONFIG_USB_STORAGE=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_MSM=y
CONFIG_USB_ISP1760=y
CONFIG_USB_ISP1760_HOST_ROLE=y
CONFIG_USB_SERIAL=y
CONFIG_USB_SERIAL_CP210X=y
CONFIG_USB_SERIAL_FTDI_SIO=y
CONFIG_USB_EHSET_TEST_FIXTURE=y
CONFIG_USB_LINK_LAYER_TEST=y
CONFIG_USB_REDRIVER_NB7VPQ904M=y
CONFIG_NOP_USB_XCEIV=y
CONFIG_USB_MSM_SSPHY_QMP=y
CONFIG_MSM_HSUSB_PHY=y
CONFIG_USB_QCOM_EMU_PHY=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VBUS_DRAW=900
CONFIG_USB_CONFIGFS=y
CONFIG_USB_CONFIGFS_UEVENT=y
CONFIG_USB_CONFIGFS_NCM=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_FS=y
CONFIG_USB_CONFIGFS_F_ACC=y
CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y
CONFIG_USB_CONFIGFS_F_UAC2=y
CONFIG_USB_CONFIGFS_F_MIDI=y
CONFIG_USB_CONFIGFS_F_HID=y
CONFIG_USB_CONFIGFS_F_DIAG=y
CONFIG_USB_CONFIGFS_F_CDEV=y
CONFIG_USB_CONFIGFS_F_CCID=y
CONFIG_USB_CONFIGFS_F_QDSS=y
CONFIG_USB_CONFIGFS_F_GSI=y
CONFIG_USB_CONFIGFS_F_MTP=y
CONFIG_USB_CONFIGFS_F_PTP=y
CONFIG_TYPEC=y
CONFIG_USB_PD_POLICY=y
CONFIG_QPNP_USB_PDPHY=y
CONFIG_MMC=y
CONFIG_MMC_BLOCK_MINORS=32
CONFIG_MMC_BLOCK_DEFERRED_RESUME=y
CONFIG_MMC_TEST=y
CONFIG_MMC_IPC_LOGGING=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_MSM=y
CONFIG_MMC_CQHCI_CRYPTO=y
CONFIG_MMC_CQHCI_CRYPTO_QTI=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_QTI_TRI_LED=y
CONFIG_LEDS_QPNP_FLASH_V2=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_EDAC=y
CONFIG_EDAC_KRYO_ARM64=y
CONFIG_EDAC_KRYO_ARM64_PANIC_ON_CE=y
CONFIG_EDAC_KRYO_ARM64_PANIC_ON_UE=y
CONFIG_EDAC_QCOM=y
CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE=y
CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_PM8XXX=y
CONFIG_DMADEVICES=y
CONFIG_QCOM_GPI_DMA=y
CONFIG_QCOM_GPI_DMA_DEBUG=y
CONFIG_DEBUG_DMA_BUF_REF=y
CONFIG_UIO=y
CONFIG_STAGING=y
CONFIG_ASHMEM=y
CONFIG_ION=y
CONFIG_ION_POOL_AUTO_REFILL=y
CONFIG_QPNP_REVID=y
CONFIG_SPS=y
CONFIG_SPS_SUPPORT_NDP_BAM=y
CONFIG_GSI_REGISTER_VERSION_2=y
CONFIG_IPA3=y
CONFIG_IPA_WDI_UNIFIED_API=y
CONFIG_RMNET_IPA3=y
CONFIG_RNDIS_IPA=y
CONFIG_IPA3_MHI_PRIME_MANAGER=y
CONFIG_IPA_UT=y
CONFIG_MSM_11AD=m
CONFIG_USB_BAM=y
CONFIG_QCOM_GENI_SE=y
CONFIG_IPA3_REGDUMP=y
CONFIG_QCOM_CLK_RPMH=y
CONFIG_SPMI_PMIC_CLKDIV=y
CONFIG_MSM_CLK_AOP_QMP=y
CONFIG_MSM_VIDEOCC_KONA=y
CONFIG_MSM_DISPCC_KONA=y
CONFIG_MSM_CAMCC_KONA=y
CONFIG_MSM_GPUCC_KONA=y
CONFIG_MSM_DEBUGCC_KONA=y
CONFIG_MSM_NPUCC_KONA=y
CONFIG_HWSPINLOCK=y
CONFIG_HWSPINLOCK_QCOM=y
CONFIG_MAILBOX=y
CONFIG_QCOM_APCS_IPC=y
CONFIG_MSM_QMP=y
CONFIG_IOMMU_IO_PGTABLE_FAST=y
CONFIG_ARM_SMMU=y
CONFIG_IOMMU_TLBSYNC_DEBUG=y
CONFIG_QCOM_LAZY_MAPPING=y
CONFIG_IOMMU_DEBUG=y
CONFIG_IOMMU_TESTS=y
CONFIG_RPMSG_CHAR=y
CONFIG_RPMSG_QCOM_GLINK_SMEM=y
CONFIG_RPMSG_QCOM_GLINK_SPSS=y
CONFIG_QCOM_COMMAND_DB=y
CONFIG_QCOM_MEM_OFFLINE=y
CONFIG_BUG_ON_HW_MEM_ONLINE_FAIL=y
CONFIG_OVERRIDE_MEMORY_LIMIT=y
CONFIG_QCOM_RUN_QUEUE_STATS=y
CONFIG_MSM_QBT_HANDLER=y
CONFIG_QCOM_IPCC=y
CONFIG_QCOM_LLCC=y
CONFIG_QCOM_KONA_LLCC=y
CONFIG_QCOM_LLCC_PERFMON=m
CONFIG_QCOM_MDT_LOADER=y
CONFIG_QPNP_PBS=y
CONFIG_QCOM_QMI_HELPERS=y
CONFIG_QCOM_QMI_RMNET=y
CONFIG_QCOM_QMI_DFC=y
CONFIG_RMNET_CTL=y
CONFIG_RMNET_CTL_DEBUG=y
CONFIG_QCOM_QMI_POWER_COLLAPSE=y
CONFIG_QCOM_RPMH=y
CONFIG_QCOM_SMEM=y
CONFIG_QCOM_EARLY_RANDOM=y
CONFIG_QCOM_MEMORY_DUMP_V2=y
CONFIG_QCOM_SMP2P=y
CONFIG_SETUP_SSR_NOTIF_TIMEOUTS=y
CONFIG_SSR_SYSMON_NOTIF_TIMEOUT=20000
CONFIG_SSR_SUBSYS_NOTIF_TIMEOUT=20000
CONFIG_PANIC_ON_SSR_NOTIF_TIMEOUT=y
CONFIG_QCOM_SECURE_BUFFER=y
CONFIG_MSM_REMOTEQDSS=y
CONFIG_MSM_SERVICE_LOCATOR=y
CONFIG_MSM_SERVICE_NOTIFIER=y
CONFIG_MSM_SUBSYSTEM_RESTART=y
CONFIG_MSM_PIL=y
CONFIG_MSM_SYSMON_QMI_COMM=y
CONFIG_MSM_PIL_SSR_GENERIC=y
CONFIG_MSM_BOOT_STATS=y
CONFIG_QCOM_DCC_V2=y
CONFIG_QCOM_EUD=y
CONFIG_QCOM_MINIDUMP=y
CONFIG_MSM_CORE_HANG_DETECT=y
CONFIG_QCOM_FSA4480_I2C=y
CONFIG_QCOM_WATCHDOG_V2=y
CONFIG_QCOM_INITIAL_LOGBUF=y
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
CONFIG_QCOM_WDOG_IPI_ENABLE=y
CONFIG_QCOM_BUS_SCALING=y
CONFIG_QCOM_BUS_CONFIG_RPMH=y
CONFIG_MSM_SPCOM=y
CONFIG_MSM_SPSS_UTILS=y
CONFIG_QSEE_IPC_IRQ_BRIDGE=y
CONFIG_QCOM_GLINK=y
CONFIG_QCOM_GLINK_PKT=y
CONFIG_QCOM_SMP2P_SLEEPSTATE=y
CONFIG_QCOM_QDSS_BRIDGE=y
CONFIG_MSM_CDSP_LOADER=y
CONFIG_QCOM_SMCINVOKE=y
CONFIG_MSM_EVENT_TIMER=y
CONFIG_MSM_PM=y
CONFIG_QTI_RPM_STATS_LOG=y
CONFIG_QTI_DDR_STATS_LOG=y
CONFIG_QTEE_SHM_BRIDGE=y
CONFIG_MSM_PERFORMANCE=y
CONFIG_QMP_DEBUGFS_CLIENT=y
CONFIG_QCOM_CDSP_RM=y
CONFIG_QCOM_QHEE_ENABLE_MEM_PROTECTION=y
CONFIG_QTI_CRYPTO_COMMON=y
CONFIG_QTI_CRYPTO_TZ=y
CONFIG_DEVFREQ_GOV_PASSIVE=y
CONFIG_QCOM_BIMC_BWMON=y
CONFIG_ARM_MEMLAT_MON=y
CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
CONFIG_DEVFREQ_GOV_QCOM_CACHE_HWMON=y
CONFIG_DEVFREQ_GOV_MEMLAT=y
CONFIG_DEVFREQ_GOV_CDSPL3=y
CONFIG_ARM_QCOM_DEVFREQ_FW=y
CONFIG_DEVFREQ_SIMPLE_DEV=y
CONFIG_QCOM_DEVFREQ_DEVBW=y
CONFIG_ARM_QCOM_DEVFREQ_QOSLAT=y
CONFIG_DEVFREQ_GOV_STATICMAP=y
CONFIG_EXTCON_USB_GPIO=y
CONFIG_IIO=y
CONFIG_IIO_KFIFO_BUF=y
CONFIG_IIO_BUFFER=y
CONFIG_IIO_TRIGGERED_BUFFER=m
CONFIG_IIO_TRIGGER=y
CONFIG_I2C_MUX=y
CONFIG_CH101=y
CONFIG_CH101_I2C=y
CONFIG_REGMAP_I2C=y
CONFIG_ADS7052_TDK_THERMISTOR=y
CONFIG_QCOM_SPMI_ADC5=y
CONFIG_PWM=y
CONFIG_PWM_QTI_LPG=y
CONFIG_QCOM_PDC=y
CONFIG_PHY_XGENE=y
CONFIG_ARM_DSU_PMU=y
CONFIG_QCOM_LLCC_PMU=y
CONFIG_RAS=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
CONFIG_ANDROID_BINDERFS=y
# CONFIG_NVMEM_SYSFS is not set
CONFIG_QCOM_QFPROM=y
CONFIG_NVMEM_SPMI_SDAM=y
CONFIG_SLIMBUS_MSM_NGD=y
CONFIG_ESOC=y
CONFIG_ESOC_DEV=y
CONFIG_ESOC_CLIENT=y
CONFIG_ESOC_DEBUG=y
CONFIG_ESOC_MDM_4x=y
CONFIG_ESOC_MDM_DRV=y
CONFIG_ESOC_MDM_DBG_ENG=y
CONFIG_SENSORS_SSC=y
CONFIG_QCOM_KGSL=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_F2FS_FS=y
CONFIG_F2FS_FS_SECURITY=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y
CONFIG_FS_VERITY=y
CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_QFMT_V2=y
CONFIG_FUSE_FS=y
CONFIG_OVERLAY_FS=y
CONFIG_INCREMENTAL_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_EFIVAR_FS=y
CONFIG_ECRYPT_FS=y
CONFIG_ECRYPT_FS_MESSAGING=y
CONFIG_SDCARD_FS=y
# CONFIG_NETWORK_FILESYSTEMS is not set
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
CONFIG_SECURITY=y
CONFIG_HARDENED_USERCOPY=y
CONFIG_HARDENED_USERCOPY_PAGESPAN=y
CONFIG_FORTIFY_SOURCE=y
CONFIG_STATIC_USERMODEHELPER=y
CONFIG_STATIC_USERMODEHELPER_PATH=""
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SMACK=y
CONFIG_SECURITY_APPARMOR=y
CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=0
CONFIG_CRYPTO_CCM=y
CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_ANSI_CPRNG=y
CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
CONFIG_CRYPTO_DEV_QCRYPTO=y
CONFIG_CRYPTO_DEV_QCEDEV=y
CONFIG_XZ_DEC=y
CONFIG_PRINTK_TIME=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_CONSOLE_UNHASHED_POINTERS=y
CONFIG_DEBUG_MODULE_LOAD_INFO=y
CONFIG_DEBUG_INFO=y
CONFIG_PAGE_OWNER=y
CONFIG_PAGE_OWNER_ENABLE_DEFAULT=y
CONFIG_DEBUG_SECTION_MISMATCH=y
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_PAGEALLOC=y
CONFIG_SLUB_DEBUG_PANIC_ON=y
CONFIG_DEBUG_PANIC_ON_OOM=y
CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y
CONFIG_PAGE_POISONING=y
CONFIG_PAGE_POISONING_ENABLE_DEFAULT=y
CONFIG_SLUB_DEBUG_ON=y
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=4000
CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_SOFTLOCKUP_DETECTOR=y
CONFIG_WQ_WATCHDOG=y
CONFIG_PANIC_TIMEOUT=-1
CONFIG_PANIC_ON_SCHED_BUG=y
CONFIG_PANIC_ON_RT_THROTTLING=y
CONFIG_SCHEDSTATS=y
CONFIG_SCHED_STACK_END_CHECK=y
CONFIG_PROVE_LOCKING=y
CONFIG_LOCK_STAT=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_LOCK_TORTURE_TEST=m
CONFIG_DEBUG_SG=y
CONFIG_DEBUG_NOTIFIERS=y
CONFIG_DEBUG_CREDENTIALS=y
CONFIG_RCU_TORTURE_TEST=m
CONFIG_FAULT_INJECTION=y
CONFIG_FAIL_PAGE_ALLOC=y
CONFIG_FAULT_INJECTION_DEBUG_FS=y
CONFIG_UFS_FAULT_INJECTION=y
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
CONFIG_IPC_LOGGING=y
CONFIG_QCOM_RTB=y
CONFIG_QCOM_RTB_SEPARATE_CPUS=y
CONFIG_FUNCTION_TRACER=y
CONFIG_PREEMPTIRQ_EVENTS=y
CONFIG_IRQSOFF_TRACER=y
CONFIG_PREEMPT_TRACER=y
CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_LKDTM=m
CONFIG_ATOMIC64_SELFTEST=m
CONFIG_TEST_USER_COPY=m
CONFIG_MEMTEST=y
CONFIG_BUG_ON_DATA_CORRUPTION=y
CONFIG_PANIC_ON_DATA_CORRUPTION=y
CONFIG_ARM64_STRICT_BREAK_BEFORE_MAKE=y
CONFIG_CORESIGHT=y
CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
CONFIG_CORESIGHT_SOURCE_ETM4X=y
CONFIG_CORESIGHT_DYNAMIC_REPLICATOR=y
CONFIG_CORESIGHT_STM=y
CONFIG_CORESIGHT_CTI=y
CONFIG_CORESIGHT_TPDA=y
CONFIG_CORESIGHT_TPDM=y
CONFIG_CORESIGHT_HWEVENT=y
CONFIG_CORESIGHT_DUMMY=y
CONFIG_CORESIGHT_REMOTE_ETM=y
CONFIG_CORESIGHT_TGU=y

View File

@@ -0,0 +1,97 @@
#
# Proximity sensors
#
menu "Lightning sensors"
config AS3935
tristate "AS3935 Franklin lightning sensor"
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
depends on SPI
help
Say Y here to build SPI interface support for the Austrian
Microsystems AS3935 lightning detection sensor.
To compile this driver as a module, choose M here: the
module will be called as3935
endmenu
menu "Proximity and distance sensors"
source "drivers/iio/proximity/inv_ch101/Kconfig"
config ISL29501
tristate "Intersil ISL29501 Time Of Flight sensor"
depends on I2C
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
select IIO_KFIFO_BUF
help
Say Y here if you want to build a driver for the Intersil ISL29501
Time of Flight sensor.
To compile this driver as a module, choose M here: the module will be
called isl29501.
config LIDAR_LITE_V2
tristate "PulsedLight LIDAR sensor"
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
depends on I2C
help
Say Y to build a driver for PulsedLight LIDAR range finding
sensor.
To compile this driver as a module, choose M here: the
module will be called pulsedlight-lite-v2
config RFD77402
tristate "RFD77402 ToF sensor"
depends on I2C
help
Say Y to build a driver for the RFD77420 Time-of-Flight (distance)
sensor module with I2C interface.
To compile this driver as a module, choose M here: the
module will be called rfd77402.
config SRF04
tristate "Devantech SRF04 ultrasonic ranger sensor"
depends on GPIOLIB
help
Say Y here to build a driver for Devantech SRF04 ultrasonic
ranger sensor. This driver can be used to measure the distance
of objects. It is using two GPIOs.
To compile this driver as a module, choose M here: the
module will be called srf04.
config SX9500
tristate "SX9500 Semtech proximity sensor"
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
select REGMAP_I2C
depends on I2C
help
Say Y here to build a driver for Semtech's SX9500 capacitive
proximity/button sensor.
To compile this driver as a module, choose M here: the
module will be called sx9500.
config SRF08
tristate "Devantech SRF02/SRF08/SRF10 ultrasonic ranger sensor"
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
depends on I2C
help
Say Y here to build a driver for Devantech SRF02/SRF08/SRF10
ultrasonic ranger sensors with i2c interface.
This driver can be used to measure the distance of objects.
To compile this driver as a module, choose M here: the
module will be called srf08.
endmenu

View File

@@ -0,0 +1,15 @@
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for IIO proximity sensors
#
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_AS3935) += as3935.o
obj-$(CONFIG_ISL29501) += isl29501.o
obj-$(CONFIG_LIDAR_LITE_V2) += pulsedlight-lidar-lite-v2.o
obj-$(CONFIG_RFD77402) += rfd77402.o
obj-$(CONFIG_SRF04) += srf04.o
obj-$(CONFIG_SRF08) += srf08.o
obj-$(CONFIG_SX9500) += sx9500.o
obj-y += inv_ch101/

View File

@@ -0,0 +1,22 @@
#
# ch101 drivers for Invensense CH-101 device
#
# To include ch101 to kernel build add next line to drivers/iio/proximity/Kconfig
# source "drivers/iio/proximity/inv_ch101/Kconfig"
#
config CH101
tristate
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
config CH101_I2C
tristate "Invensense CH-101 devices (I2C)"
depends on I2C_MUX
select CH101
select REGMAP_I2C
help
This driver supports the Invensense CH-101 ultra-low power
ultrasonic Time-of-Flight (ToF) range sensor over I2C.
This driver can be built as a module. The module will be called
ch101-i2c

View File

@@ -0,0 +1,31 @@
#
# Makefile for CH101 proximity sensors
#
# To include ch101 to kernel build add next line to drivers/iio/proximity/Makefile
# obj-y += inv_ch101/
#
obj-$(CONFIG_CH101) += ch101-core.o
ch101-core-objs += ch101_core.o
ch101-core-objs += ch101_sysfs.o
ch101-core-objs += src/init_driver.o
ch101-core-objs += src/chbsp_dummy.o
ch101-core-objs += src/chbsp_init.o
ch101-core-objs += src/chirp_hal.o
ch101-core-objs += src/i2c_hal.o
ch101-core-objs += src/ch101_gpr.o
ch101-core-objs += src/ch101_gpr_fw.o
ch101-core-objs += src/ch101_gpr_open.o
ch101-core-objs += src/ch101_gpr_open_fw.o
ch101-core-objs += src/ch101_gpr_sr_open.o
ch101-core-objs += src/ch101_gpr_sr_open_fw.o
ch101-core-objs += src/ch_api.o
ch101-core-objs += src/ch_common.o
ch101-core-objs += src/ch_driver.o
ch101-core-objs += src/ch201_gprmt_fw.o
obj-$(CONFIG_CH101_I2C) += ch101-i2c.o
ch101-i2c-objs += ch101_i2c.o
# disable some warning flags
ccflags-y += -Wno-format

View File

@@ -0,0 +1,88 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2020 InvenSense, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef DRIVERS_IIO_PROXIMITY_INV_CH101_CH101_CLIENT_H_
#define DRIVERS_IIO_PROXIMITY_INV_CH101_CH101_CLIENT_H_
#include <linux/regmap.h>
#include "src/chbsp_init.h"
#define TAG "ch101: "
#define MAX_SAMPLES 450
#define MAX_DEVICES 3
#define MAX_BUSES 2
#define MAX_DEV_BUSES (MAX_DEVICES * MAX_BUSES)
typedef u32 ioport_pin_t;
enum ioport_direction {
IOPORT_DIR_INPUT, /*!< IOPORT input direction */
IOPORT_DIR_OUTPUT, /*!< IOPORT output direction */
};
enum ioport_value {
IOPORT_PIN_LEVEL_LOW, /*!< IOPORT pin value low */
IOPORT_PIN_LEVEL_HIGH, /*!< IOPORT pin value high */
};
struct ch101_iq_data {
s16 I;
s16 Q;
};
struct ch101_buffer {
u16 distance[MAX_DEV_BUSES];
u16 amplitude[MAX_DEV_BUSES];
u16 nb_samples[MAX_DEV_BUSES];
struct ch101_iq_data iq_data[MAX_DEV_BUSES][MAX_SAMPLES];
u8 mode[MAX_DEV_BUSES];
};
struct ch101_client;
struct ch101_callbacks {
int (*write_reg)(void *cl, u16 i2c_addr, u8 reg, u16 length, u8 *data);
int (*read_reg)(void *cl, u16 i2c_addr, u8 reg, u16 length, u8 *data);
int (*write_sync)(void *cl, u16 i2c_addr, u16 length, u8 *data);
int (*read_sync)(void *cl, u16 i2c_addr, u16 length, u8 *data);
void (*set_pin_level)(ioport_pin_t pin, int value);
void (*set_pin_dir)(ioport_pin_t pin, enum ioport_direction dir);
void (*data_complete)(struct ch101_client *data);
int (*setup_int_gpio)(struct ch101_client *data, uint32_t pin);
int (*free_int_gpio)(struct ch101_client *data, uint32_t pin);
};
struct ch101_i2c_bus {
struct i2c_client *i2c_client;
struct gpio_desc *gpiod_int[MAX_DEVICES];
u32 gpio_exp_prog_pin[MAX_DEVICES];
};
struct ch101_gpios {
struct gpio_desc *gpiod_rst;
struct gpio_desc *gpiod_rst_pulse;
};
struct ch101_client {
struct ch101_i2c_bus bus[MAX_BUSES];
struct ch101_gpios gpios;
struct ch101_callbacks *cbk;
};
int ch101_core_probe(struct i2c_client *client, struct regmap *regmap,
struct ch101_callbacks *cbk, const char *name);
int ch101_core_remove(struct i2c_client *client);
#endif /* DRIVERS_IIO_PROXIMITY_INV_CH101_CH101_CLIENT_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,45 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2020 InvenSense, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef DRIVERS_IIO_PROXIMITY_CH101_DATA_H_
#define DRIVERS_IIO_PROXIMITY_CH101_DATA_H_
#include <linux/hrtimer.h>
#include <linux/mutex.h>
#include <linux/completion.h>
#include <asm-generic/int-ll64.h>
#include "ch101_client.h"
struct ch101_data {
struct device *dev;
struct ch101_client client;
struct ch101_buffer buffer;
struct regmap *regmap;
struct mutex lock;
struct completion ss_completion;
struct completion data_completion;
struct iio_trigger *trig;
struct hrtimer timer;
int irq[CHBSP_MAX_DEVICES];
int irq_set[CHBSP_MAX_DEVICES];
int irq_map[CHBSP_MAX_DEVICES];
int scan_rate;
ktime_t period;
int counter;
int fw_initialized;
};
#endif /* DRIVERS_IIO_PROXIMITY_CH101_DATA_H_ */

View File

@@ -0,0 +1,459 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2020 InvenSense, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/gfp.h>
#include <linux/mutex.h>
#include <linux/interrupt.h>
#include <linux/iio/iio.h>
#include <linux/gpio/driver.h>
#include "ch101_data.h"
#include "ch101_client.h"
#include "ch101_reg.h"
#define SX1508_DEVICE_ID "sx1508q"
// Device tree RP4
//
// ch101@45 {
// compatible = "invensense,ch101";
// reg = <0x45>;
// pinctrl-0 = <&chirp_int_pin>;
// rst-gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
// prg-gpios = <&gpio 27 GPIO_ACTIVE_HIGH>;
// int-gpios = <&gpio 23 GPIO_ACTIVE_HIGH>;
// interrupts = <23 1>;
// interrupt-parent = <&gpio>;
// };
//
// Device tree RB5
//&qupv3_se1_i2c {
// status = "ok";
// qcom,clk-freq-out = <400000>;
// #address-cells = <1>;
// #size-cells = <0>;
//
// /* TDK Chirp IO Expander */
// ch_io_expander@22 {
// #gpio-cells = <2>;
// #interrupt-cells = <2>;
// compatible = "semtech,sx1508q";
// reg = <0x22>;
// gpio-controller;
// };
//};
//
//&qupv3_se4_i2c {
// #address-cells = <1>;
// #size-cells = <0>;
// status = "ok";
// /* TDK Chirp 0, 1, and 2 are connected to QUP4 */
// qcom,clk-freq-out = <400000>;
// ch101_0: ch101_0@45 {
// compatible = "invensense,ch101";
// reg = <0x45>;
// prg-gpios = <0 1 2>;
// rst-gpios = <&tlmm 140 GPIO_ACTIVE_HIGH>;
// rtc_rst-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;
// int-gpios = <&tlmm 129 GPIO_ACTIVE_HIGH>,
// <&tlmm 138 GPIO_ACTIVE_HIGH>,
// <&tlmm 113 GPIO_ACTIVE_HIGH>;
// interrupt-parent = <&tlmm>;
// interrupts = <129 1>,
// <141 1>,
// <113 1>;
// interrupt-names = "ch101_0_irq";
// pinctrl-names = "default";
// pinctrl-0 = <&ch101_rst &ch101_tmr_rst &ch101_0_irq>;
// };
//};
//
//&qupv3_se15_i2c {
// #address-cells = <1>;
// #size-cells = <0>;
// status = "ok";
// /* TDK Chirp 3, 4, and 5 are connected to QUP15 */
// qcom,clk-freq-out = <400000>;
// ch101_1: ch101_1@45 {
// compatible = "invensense,ch101";
// reg = <0x45>;
// prg-gpios = <3 4 5>;
// rst-gpios = <&tlmm 140 GPIO_ACTIVE_HIGH>;
// rtc_rst-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;
// int-gpios = <&tlmm 122 GPIO_ACTIVE_HIGH>,
// <&tlmm 123 GPIO_ACTIVE_HIGH>,
// <&tlmm 66 GPIO_ACTIVE_HIGH>;
// interrupt-parent = <&tlmm>;
// interrupts = <122 1>,
// <123 1>,
// <66 1>;
// interrupt-names = "ch101_1_irq";
// pinctrl-names = "default";
// pinctrl-0 = <&ch101_rst &ch101_tmr_rst &ch101_1_irq>;
// };
static const struct regmap_config ch101_i2c_regmap_config = {
.reg_bits = 8, .val_bits = 8,
};
static int read_reg(void *client, u16 i2c_addr, u8 reg, u16 length, u8 *data)
{
int res;
struct i2c_msg msg[] = {
{ .addr = i2c_addr, .flags = 0, .len = 1, .buf = &reg },
{ .addr = i2c_addr, .flags = I2C_M_RD,
.len = length, .buf = (__u8 *)data }
};
struct i2c_client *i2c_client = (struct i2c_client *)client;
struct i2c_adapter *i2c_adapter = i2c_client->adapter;
// pr_info(TAG "%s: name: %s, addr: %02x, flags: %x\n", __func__,
// i2c_client->name, i2c_client->addr, i2c_client->flags);
// pr_info(TAG "%s: addr: %02x, reg: %02x, len: %d\n", __func__,
// i2c_addr, reg, length);
res = i2c_transfer(i2c_adapter, msg, 2);
// pr_info(TAG "%s: RES: %d\n", __func__, res);
// {
// int i;
// pr_info(TAG "Read Values: ");
// for (i = 0; i < (length < 3 ? length : 3); i++)
// pr_info(TAG " %02x ", *(u8 *)(data + i));
// pr_info(TAG "\n");
// }
if (res <= 0) {
if (res == 0)
res = -EIO;
return res;
} else {
return 0;
}
}
static int write_reg(void *client, u16 i2c_addr, u8 reg, u16 length, u8 *data)
{
int res;
u8 buf[4];
struct i2c_msg msg[] = {
{ .addr = i2c_addr, .flags = I2C_M_STOP,
.len = length + 1, .buf = (__u8 *)buf }
};
struct i2c_client *i2c_client = (struct i2c_client *)client;
struct i2c_adapter *i2c_adapter = i2c_client->adapter;
// pr_info(TAG "%s: name: %s, addr: %02x, flags: %x\n", __func__,
// i2c_client->name, i2c_client->addr, i2c_client->flags);
// pr_info(TAG "%s: addr: %02x, reg: %02x, len: %d\n", __func__,
// i2c_addr, reg, length);
if (length > sizeof(buf))
return -EIO;
// prepend the 'register address' to the buffer
buf[0] = reg;
memcpy(&(buf[1]), data, length);
// {
// int i;
// pr_info(TAG "Write Values: ");
// for (i = 0; i < sizeof(buf); i++)
// pr_info(TAG " %02x ", *(u8 *)(buf + i));
// pr_info(TAG "\n");
// }
res = i2c_transfer(i2c_adapter, msg, 1);
// pr_info(TAG "%s: RES: %d\n", __func__, res);
if (res <= 0) {
if (res == 0)
res = -EIO;
return res;
} else {
return 0;
}
}
static int read_sync(void *client, u16 i2c_addr, u16 length, u8 *data)
{
int res;
struct i2c_msg msg[] = {
{ .addr = i2c_addr, .flags = I2C_M_STOP | I2C_M_RD,
.len = length, .buf = (__u8 *)data }
};
struct i2c_client *i2c_client = (struct i2c_client *)client;
struct i2c_adapter *i2c_adapter = i2c_client->adapter;
// pr_info(TAG "%s: name: %s, addr: %02x, flags: %x\n", __func__,
// i2c_client->name, i2c_client->addr, i2c_client->flags);
// pr_info(TAG "%s: addr: %02x, len: %d\n", __func__,
// i2c_addr, length);
res = i2c_transfer(i2c_adapter, msg, 1);
// pr_info(TAG "%s: RES: %d\n", __func__, res);
if (res <= 0) {
if (res == 0)
res = -EIO;
return res;
} else {
return 0;
}
}
static int write_sync(void *client, u16 i2c_addr, u16 length, u8 *data)
{
int res;
struct i2c_msg msg[] = {
{ .addr = i2c_addr, .flags = I2C_M_STOP,
.len = length, .buf = (__u8 *)data }
};
struct i2c_client *i2c_client = (struct i2c_client *)client;
struct i2c_adapter *i2c_adapter = i2c_client->adapter;
// pr_info(TAG "%s: name: %s, addr: %02x, flags: %x\n", __func__,
// i2c_client->name, i2c_client->addr, i2c_client->flags);
// pr_info(TAG "%s: addr: %02x, len: %d\n", __func__,
// i2c_addr, length);
res = i2c_transfer(i2c_adapter, msg, 1);
// pr_info(TAG "%s: RES: %d\n", __func__, res);
if (res <= 0) {
if (res == 0)
res = -EIO;
return res;
} else {
return 0;
}
}
static int match_gpio_chip_by_label(struct gpio_chip *chip, void *data)
{
return !strcmp(chip->label, data);
}
static struct gpio_chip *get_gpio_exp(void)
{
struct gpio_chip *chip;
chip = gpiochip_find(SX1508_DEVICE_ID,
match_gpio_chip_by_label);
// pr_info(TAG "%s: name: %s gpio: %p\n", __func__,SX1508_DEVICE_ID,chip);
return chip;
}
static void set_pin_level(ioport_pin_t pin, int value)
{
struct gpio_chip *gpio = get_gpio_exp();
if (!gpio)
return;
// pr_info(TAG "%s: pin: %d, value: %d\n", __func__, pin, value);
gpio->set(gpio, pin, value);
}
static void set_pin_dir(ioport_pin_t pin, enum ioport_direction dir)
{
struct gpio_chip *gpio = get_gpio_exp();
if (!gpio)
return;
// pr_info(TAG "%s: pin: %d, dir: %d\n", __func__, pin, dir);
if (dir == IOPORT_DIR_INPUT)
gpio->direction_input(gpio, pin);
else
gpio->direction_output(gpio, pin, 0);
}
static int ch101_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct regmap *regmap;
struct device *dev;
struct gpio_chip *gpio;
int irq;
struct irq_desc *desc;
struct ch101_callbacks *cbk;
int ret = 0;
if (!client)
return -ENOMEM;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_I2C_BLOCK)) {
return -EPERM;
}
dev = &client->dev;
cbk = devm_kmalloc(dev, sizeof(struct ch101_callbacks), GFP_KERNEL);
if (!cbk)
return -ENOMEM;
irq = client->irq;
desc = irq_to_desc(irq);
dev_info(dev, "%s: Start: %p, %s\n", __func__,
dev, dev ? dev->init_name : "");
dev_info(dev, "%s: IRQ: %d\n", __func__, irq);
gpio = get_gpio_exp();
if (!gpio) {
dev_err(dev, "Error initializing expander: %s\n",
SX1508_DEVICE_ID);
}
cbk->read_reg = read_reg;
cbk->write_reg = write_reg;
cbk->read_sync = read_sync;
cbk->write_sync = write_sync;
cbk->set_pin_level = set_pin_level;
cbk->set_pin_dir = set_pin_dir;
regmap = devm_regmap_init_i2c(client, &ch101_i2c_regmap_config);
if (IS_ERR(regmap)) {
dev_err(dev, "Error initializing i2c regmap: %ld\n",
PTR_ERR(regmap));
return PTR_ERR(regmap);
}
pr_info(TAG "%s: client: %p\n", __func__, client);
pr_info(TAG "%s: adapter: %p\n", __func__, client->adapter);
ret = ch101_core_probe(client, regmap, cbk, id ? id->name : NULL);
dev_info(dev, "%s: End\n", __func__);
return ret;
}
static int ch101_i2c_remove(struct i2c_client *client)
{
struct device *dev;
int irq;
struct irq_desc *desc;
int ret = 0;
dev = &client->dev;
irq = client->irq;
desc = irq_to_desc(irq);
dev_info(dev, "%s: Start: %p, %s\n", __func__,
dev, dev ? dev->init_name : "");
dev_info(dev, "%s: IRQ: %d, %s\n", __func__,
irq, ((desc && desc->action) ? desc->action->name : ""));
ret = ch101_core_remove(client);
dev_info(dev, "%s: End: %p, %s\n", __func__,
dev, dev ? dev->init_name : "");
return ret;
}
#ifdef CONFIG_PM_SLEEP
static int ch101_suspend(struct device *dev)
{
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
struct ch101_data *data = iio_priv(indio_dev);
int ret;
dev_info(dev, "%s: Start\n", __func__);
mutex_lock(&data->lock);
ret = regmap_write(data->regmap, CH_PROG_REG_CPU, 0x11);
mutex_unlock(&data->lock);
dev_info(dev, "%s: End\n", __func__);
return ret;
}
static int ch101_resume(struct device *dev)
{
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
struct ch101_data *data = iio_priv(indio_dev);
int ret;
dev_info(dev, "%s: Start\n", __func__);
mutex_lock(&data->lock);
ret = regmap_write(data->regmap, CH_PROG_REG_CPU, 0x02);
mutex_unlock(&data->lock);
dev_info(dev, "%s: End\n", __func__);
return ret;
}
#endif /* CONFIG_PM_SLEEP */
static const struct dev_pm_ops ch101_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(ch101_suspend, ch101_resume)
};
static const struct i2c_device_id ch101_i2c_id[] = {
{ "ch101", 0 },
{ },
};
MODULE_DEVICE_TABLE(i2c, ch101_i2c_id);
static const struct of_device_id ch101_of_match[] = {
{ .compatible = "invensense,ch101" },
{ },
};
MODULE_DEVICE_TABLE(of, ch101_of_match);
static struct i2c_driver ch101_i2c_driver = {
.driver = {
.name = "ch101_i2c",
.of_match_table = ch101_of_match,
.pm = &ch101_pm_ops,
},
.probe = ch101_i2c_probe,
.remove = ch101_i2c_remove,
.id_table = ch101_i2c_id,
};
module_i2c_driver(ch101_i2c_driver);
MODULE_AUTHOR("Invensense Corporation");
MODULE_DESCRIPTION("Invensense CH101 I2C device driver");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,47 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2020 InvenSense, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _CH101REG_H_
#define _CH101REG_H_
/* CH-101 common definitions */
#define CH101_COMMON_REG_OPMODE 0x01
#define CH101_COMMON_REG_TICK_INTERVAL 0x02
#define CH101_COMMON_REG_PERIOD 0x05
#define CH101_COMMON_REG_MAX_RANGE 0x07
#define CH101_COMMON_REG_TIME_PLAN 0x09
#define CH101_COMMON_REG_STAT_RANGE 0x12
#define CH101_COMMON_REG_STAT_COEFF 0x13
#define CH101_COMMON_REG_READY 0x14
#define CH101_COMMON_REG_TOF_SF 0x16
#define CH101_COMMON_REG_TOF 0x18
#define CH101_COMMON_REG_AMPLITUDE 0x1A
#define CH101_COMMON_REG_CAL_TRIG 0x06
#define CH101_COMMON_REG_CAL_RESULT 0x0A
#define CH101_COMMON_REG_DATA 0x1C
/* Programming interface register addresses */
#define CH_PROG_REG_PING 0x00 /*!< Read-only register used for ping device.*/
#define CH_PROG_REG_CPU 0x42 /*!< Processor control register address. */
#define CH_PROG_REG_STAT 0x43 /*!< Processor status register address. */
#define CH_PROG_REG_CTL 0x44 /*!< Data transfer control register address. */
#define CH_PROG_REG_ADDR 0x05 /*!< Data transfer starting register address.*/
#define CH_PROG_REG_CNT 0x07 /*!< Data transfer size register address. */
#define CH_PROG_REG_DATA 0x06 /*!< Data transfer value register address. */
#define CH101_SIG_BYTE_0 (0x0a) /* Signature bytes in sensor */
#define CH101_SIG_BYTE_1 (0x02)
#endif /* _CH101REG_H_ */

View File

@@ -0,0 +1,222 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2020 InvenSense, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/sysfs.h>
#include <linux/types.h>
#include "ch101_sysfs.h"
#include "ch101_data.h"
#include "src/ch101_gpr.h"
#include "src/ch201_gprmt.h"
static int current_part;
static ssize_t ch101_fw_read(char *buf, loff_t off, size_t count,
u8 *addr, u8 *end_addr)
{
int read_count = 0;
int i = 0;
while (count > 0 && addr < end_addr) {
if (count > MAX_DMP_READ_SIZE)
read_count = MAX_DMP_READ_SIZE;
else
read_count = count;
if (read_count > end_addr - addr)
read_count = end_addr - addr;
pr_info(TAG "%s: %d, %p, %p, %d", __func__,
i, &buf[i], addr, read_count);
memcpy((void *)&buf[i], (const void *)addr, read_count);
addr += read_count;
i += read_count;
count -= read_count;
}
pr_info(TAG "%s: %d", __func__, read_count);
return read_count;
}
/*
* ch101_firmware_write() - calling this function will load the firmware.
*/
static ssize_t ch101_firmware_write(struct file *fp, struct kobject *kobj,
struct bin_attribute *attr, char *buf,
loff_t pos, size_t size)
{
struct iio_dev *indio_dev =
dev_get_drvdata(container_of(kobj, struct device, kobj));
struct ch101_data *data = iio_priv(indio_dev);
ssize_t len;
u16 ram_addr;
u8 ram_size;
if (current_part == CH101_PART_NUMBER)
len = sizeof(ch101_gpr_fw);
else
len = sizeof(ch201_gprmt_fw);
data->fw_initialized = 0;
if (size > len - pos) {
pr_err("firmware load failed\n");
return -EFBIG;
}
pr_info(TAG "%s: %d, %d, %d", __func__,
pos, size, len);
if (current_part == CH101_PART_NUMBER) {
pr_info(TAG "write CH101");
memcpy(ch101_gpr_fw + pos, buf, len - pos);
if ((len - pos) == size) {
ram_size = (u8)ch101_gpr_fw[CH101_FW_SIZE];
if (ram_size > 29)
ram_size = 29;
ram_addr = (u8)ch101_gpr_fw[CH101_FW_SIZE + 2];
ram_addr <<= 8;
ram_addr += (u8)ch101_gpr_fw[CH101_FW_SIZE + 1];
set_ch101_gpr_fw_ram_init_addr(ram_addr);
set_ch101_gpr_fw_ram_write_size(ram_size);
memcpy(get_ram_ch101_gpr_init_ptr(),
&ch101_gpr_fw[CH101_FW_SIZE + 3], ram_size);
}
} else {
pr_info(TAG "write CH201");
memcpy(ch201_gprmt_fw + pos, buf, len - pos);
if ((len - pos) == size) {
ram_size = (u8)ch201_gprmt_fw[CH101_FW_SIZE];
if (ram_size > 29)
ram_size = 29;
ram_addr = (u8)ch201_gprmt_fw[CH101_FW_SIZE + 2];
ram_addr <<= 8;
ram_addr += (u8)ch201_gprmt_fw[CH101_FW_SIZE + 1];
set_ch201_gpr_fw_ram_init_addr(ram_addr);
set_ch201_gpr_fw_ram_write_size(ram_size);
memcpy(get_ram_ch201_gprmt_init_ptr(),
&ch201_gprmt_fw[CH201_FW_SIZE + 3], ram_size);
}
}
return len;
}
static ssize_t ch101_firmware_read(struct file *filp,
struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
u8 *addr = (u8 *)ch101_gpr_fw + off;
u8 *end_addr = (u8 *)ch101_gpr_fw + CH101_FW_SIZE;
return ch101_fw_read(buf, off, count, addr, end_addr);
}
/*
* ch101_firmware_write_vers() - calling this function will load the firmware.
*/
static ssize_t ch101_firmware_write_vers(struct file *fp, struct kobject *kobj,
struct bin_attribute *attr, char *buf,
loff_t pos, size_t size)
{
ssize_t len = sizeof(ch101_gpr_version) - 2;
char ch201_fw_name[] = "ch201";
char input_file[] = "ch201";
int res;
if (size > len - pos) {
pr_err("firmware version load failed\n");
return -EFBIG;
}
pr_info(TAG "%s: %d, %d, %d", __func__,
pos, size, len);
memcpy(input_file, buf, sizeof(input_file));
pr_info("size=%d, size2=%d, %s\n",
sizeof(input_file), sizeof(ch201_fw_name), input_file);
res = memcmp(buf, ch201_fw_name, sizeof(ch201_fw_name)-1);
pr_info(TAG "%d, %s\n", res, buf);
if (res) {
memcpy(ch101_gpr_version + pos, buf, len - pos);
current_part = CH101_PART_NUMBER;
} else {
memcpy(ch201_gprmt_version + pos, buf, len - pos);
current_part = CH201_PART_NUMBER;
}
return len;
}
static ssize_t ch101_firmware_read_vers(struct file *filp,
struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
u8 *addr = (u8 *)ch101_gpr_version + off;
u8 *end_addr = (u8 *)ch101_gpr_version + CH101_FW_VERS_SIZE;
ch101_fw_read(buf, off, count, addr, end_addr);
return strlen(buf);
}
static struct bin_attribute dmp_firmware = {
.attr = {
.name = "misc_bin_dmp_firmware",
.mode = 0666},
.read = ch101_firmware_read,
.write = ch101_firmware_write,
};
static struct bin_attribute dmp_firmware_vers = {
.attr = {
.name = "misc_bin_dmp_firmware_vers",
.mode = 0666},
.read = ch101_firmware_read_vers,
.write = ch101_firmware_write_vers,
};
int ch101_create_dmp_sysfs(struct iio_dev *indio_dev)
{
int result = 0;
struct ch101_data *data = iio_priv(indio_dev);
struct device *dev = data->dev;
dev_info(dev, "%s:\n", __func__);
dmp_firmware.size = CH101_FW_SIZE+32;
result = sysfs_create_bin_file(&indio_dev->dev.kobj, &dmp_firmware);
if (result)
return result;
dmp_firmware_vers.size = CH101_FW_VERS_SIZE;
result = sysfs_create_bin_file(&indio_dev->dev.kobj,
&dmp_firmware_vers);
if (result)
return result;
return result;
}

View File

@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2020 InvenSense, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/iio/iio.h>
#define MAX_DMP_READ_SIZE 16
int ch101_create_dmp_sysfs(struct iio_dev *ind);

View File

@@ -0,0 +1,65 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*! \file ch101.h
*
* \brief Internal definitions for the Chirp CH101 ultrasonic sensor.
*
* This file contains various hardware-defined values for the CH101 sensor.
*
* You should not need to edit this file or call the driver functions directly.
* Doing so will reduce your ability to benefit from future enhancements and
* releases from Chirp.
*
*/
/*
* Copyright (c) 2016-2019, Chirp Microsystems. All rights reserved.
*
* Chirp Microsystems CONFIDENTIAL
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL CHIRP MICROSYSTEMS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CH101_H_
#define CH101_H_
typedef signed char s8;
typedef unsigned char u8;
typedef signed short s16;
typedef unsigned short u16;
typedef signed int s32;
typedef unsigned int u32;
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef signed int int32_t;
typedef unsigned int uint32_t;
#define CH101_DATA_MEM_SIZE 0x800
#define CH101_DATA_MEM_ADDR 0x0200
#define CH101_PROG_MEM_SIZE 0x800
#define CH101_PROG_MEM_ADDR 0xF800
#define CH101_FW_SIZE CH101_PROG_MEM_SIZE
#define CH101_FW_VERS_SIZE 32
#define CH101_FREQCOUNTERCYCLES 128
#define CH101_EXTERNAL_FW 1
#define CH101_INIT_RAM_MAX_SIZE 32
void set_ch101_gpr_fw_ram_init_addr(int addr);
void set_ch101_gpr_fw_ram_write_size(int size);
#endif

View File

@@ -0,0 +1,75 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2020 InvenSense, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "soniclib.h"
#include "ch101_gpr.h"
#include "ch_common.h"
u8 ch101_gpr_init(struct ch_dev_t *dev_ptr, struct ch_group_t *grp_ptr,
u8 i2c_addr, u8 io_index, u8 i2c_bus_index)
{
if (io_index < 3)
dev_ptr->part_number = CH101_PART_NUMBER;
else
dev_ptr->part_number = CH201_PART_NUMBER;
dev_ptr->app_i2c_address = i2c_addr;
dev_ptr->io_index = io_index;
dev_ptr->i2c_bus_index = i2c_bus_index;
/* Init firmware-specific function pointers */
if (dev_ptr->part_number == CH101_PART_NUMBER) {
dev_ptr->firmware = ch101_gpr_fw;
dev_ptr->fw_version_string = ch101_gpr_version;
dev_ptr->ram_init = get_ram_ch101_gpr_init_ptr();
dev_ptr->get_fw_ram_init_size = get_ch101_gpr_fw_ram_init_size;
dev_ptr->get_fw_ram_init_addr = get_ch101_gpr_fw_ram_init_addr;
} else {
dev_ptr->firmware = ch201_gprmt_fw;
dev_ptr->fw_version_string = ch201_gprmt_version;
dev_ptr->ram_init = get_ram_ch201_gprmt_init_ptr();
dev_ptr->get_fw_ram_init_size =
get_ch201_gprmt_fw_ram_init_size;
dev_ptr->get_fw_ram_init_addr =
get_ch201_gprmt_fw_ram_init_addr;
}
dev_ptr->prepare_pulse_timer = ch_common_prepare_pulse_timer;
dev_ptr->store_pt_result = ch_common_store_pt_result;
dev_ptr->store_op_freq = ch_common_store_op_freq;
dev_ptr->store_bandwidth = ch_common_store_bandwidth;
dev_ptr->store_scalefactor = ch_common_store_scale_factor;
dev_ptr->get_locked_state = ch_common_get_locked_state;
/* Init API function pointers */
dev_ptr->api_funcs.fw_load = ch_common_fw_load;
dev_ptr->api_funcs.set_mode = ch_common_set_mode;
dev_ptr->api_funcs.set_sample_interval = ch_common_set_sample_interval;
dev_ptr->api_funcs.set_num_samples = ch_common_set_num_samples;
dev_ptr->api_funcs.set_max_range = ch_common_set_max_range;
dev_ptr->api_funcs.set_static_range = ch_common_set_static_range;
dev_ptr->api_funcs.get_range = ch_common_get_range;
dev_ptr->api_funcs.get_amplitude = ch_common_get_amplitude;
dev_ptr->api_funcs.get_iq_data = ch_common_get_iq_data;
dev_ptr->api_funcs.samples_to_mm = ch_common_samples_to_mm;
dev_ptr->api_funcs.mm_to_samples = ch_common_mm_to_samples;
dev_ptr->api_funcs.set_thresholds = NULL; // not supported
dev_ptr->api_funcs.get_thresholds = NULL; // not supported
/* Init device and group descriptor linkage */
dev_ptr->group = grp_ptr; // set parent group pointer
grp_ptr->device[io_index] = dev_ptr; // add to parent group
return 0;
}

View File

@@ -0,0 +1,71 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*! \file ch101_gpr.h
*
* \brief Internal definitions for the Chirp CH101 GPR sensor firmware.
*
* This file contains register offsets and other values for use with the CH101
* GPR sensor firmware. These values are subject to change without notice.
*
* You should not need to edit this file or call the driver functions directly.
* Doing so will reduce your ability to benefit from future enhancements and
* releases from Chirp.
*/
/*
* Copyright (c) 2016-2019, Chirp Microsystems. All rights reserved.
*
* Chirp Microsystems CONFIDENTIAL
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL CHIRP MICROSYSTEMS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CH101_GPR_H_
#define CH101_GPR_H_
#include "ch101.h"
#include "soniclib.h"
/* GPR firmware registers */
#define CH101_GPR_REG_OPMODE 0x01
#define CH101_GPR_REG_TICK_INTERVAL 0x02
#define CH101_GPR_REG_PERIOD 0x05
#define CH101_GPR_REG_CAL_TRIG 0x06
#define CH101_GPR_REG_CAL_TRIG 0x06
#define CH101_GPR_REG_MAX_RANGE 0x07
#define CH101_GPR_REG_CALC 0x08
#define CH101_GPR_REG_ST_RANGE 0x12
#define CH101_GPR_REG_READY 0x14
#define CH101_GPR_REG_TOF_SF 0x16
#define CH101_GPR_REG_TOF 0x18
#define CH101_GPR_REG_AMPLITUDE 0x1A
#define CH101_GPR_REG_CAL_RESULT 0x0A
#define CH101_GPR_REG_DATA 0x1C
/* XXX need more values (?) */
#define CMREG_READY_FREQ_LOCKED_BM (0x02)
#define CH101_GPR_CTR (0x2B368)
extern char ch101_gpr_version[CH101_FW_VERS_SIZE]; // version string
extern u8 ch101_gpr_fw[CH101_FW_SIZE + 32];
uint16_t get_ch101_gpr_fw_ram_init_addr(void);
uint16_t get_ch101_gpr_fw_ram_init_size(void);
unsigned char *get_ram_ch101_gpr_init_ptr(void);
u8 ch101_gpr_init(struct ch_dev_t *dev_ptr, struct ch_group_t *grp_ptr,
u8 i2c_addr, u8 dev_num, u8 i2c_bus_index);
void ch101_gpr_store_pt_result(struct ch_dev_t *dev_ptr);
#endif

View File

@@ -0,0 +1,92 @@
// SPDX-License-Identifier: GPL-2.0
// DEFINE THIS TO USE SPECIAL SENSOR F/W WITH PATTERN I/Q DATA
#define USE_IQ_DEBUG 0
#if !USE_IQ_DEBUG
/* REGULAR FIRMWARE */
//Chirp Microsystems Firmware Header Generator
#include "ch101.h"
char ch101_gpr_version[CH101_FW_VERS_SIZE];
//#define RAM_INIT_ADDRESS 1864
static uint16_t ram_init_addr;
//static uint8_t RAM_INIT_WRITE_SIZE;
static uint8_t ram_init_write_size;
uint16_t get_ch101_gpr_fw_ram_init_addr(void)
{
return (uint16_t)ram_init_addr;
}
uint16_t get_ch101_gpr_fw_ram_init_size(void)
{
return (uint16_t)ram_init_write_size;
}
void set_ch101_gpr_fw_ram_init_addr(int addr)
{
ram_init_addr = addr;
}
void set_ch101_gpr_fw_ram_write_size(int size)
{
ram_init_write_size = size;
}
unsigned char ram_ch101_gpr_init[CH101_INIT_RAM_MAX_SIZE] = {
/*0x06, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x64, 0x00,*/
/* 0x00, 0x0C, 0x00, 0x00, 0x01, 0x00,*/
};
unsigned char *get_ram_ch101_gpr_init_ptr(void)
{
return &ram_ch101_gpr_init[0];
}
unsigned char ch101_gpr_fw[CH101_FW_SIZE + CH101_INIT_RAM_MAX_SIZE];
#else // USE_IQ_DEBUG
/* SPECIAL DEBUG FIRMWARE - Puts out ascending */
/* number sequence instead of real I/Q data */
//Chirp Microsystems Firmware Header Generator
#include "ch101.h"
char ch101_gpr_version[CH101_FW_VERS_SIZE];
#define RAM_INIT_ADDRESS 1864
#define RAM_INIT_WRITE_SIZE 16
uint16_t get_ch101_gpr_fw_ram_init_addr(void)
{
return (uint16_t)RAM_INIT_ADDRESS;
}
uint16_t get_ch101_gpr_fw_ram_init_size(void)
{
return (uint16_t)RAM_INIT_WRITE_SIZE;
}
unsigned char ram_ch101_gpr_init[CH101_INIT_RAM_MAX_SIZE] = {
/*0x06, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x64,*/
/* 0x00, 0x00, 0x0C, 0x00, 0x00, 0x01, 0x00,*/
};
unsigned char *get_ram_ch101_gpr_init_ptr(void)
{
return &ram_ch101_gpr_init[0];
}
unsigned char ch101_gpr_fw[CH101_FW_SIZE + CH101_INIT_RAM_MAX_SIZE];
#endif // USE_IQ_DEBUG

View File

@@ -0,0 +1,90 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2016-2019, Chirp Microsystems. All rights reserved.
*
* Chirp Microsystems CONFIDENTIAL
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL CHIRP MICROSYSTEMS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "soniclib.h"
#include "ch101_gpr_open.h"
#include "ch_common.h"
u8 ch101_gpr_open_init(struct ch_dev_t *dev_ptr, struct ch_group_t *grp_ptr,
u8 i2c_addr, u8 io_index, u8 i2c_bus_index)
{
if (io_index < 3)
dev_ptr->part_number = CH101_PART_NUMBER;
else
dev_ptr->part_number = CH201_PART_NUMBER;
dev_ptr->app_i2c_address = i2c_addr;
dev_ptr->io_index = io_index;
dev_ptr->i2c_bus_index = i2c_bus_index;
/* Init firmware-specific function pointers */
dev_ptr->firmware = ch101_gpr_open_fw;
dev_ptr->fw_version_string = ch101_gpr_open_version;
dev_ptr->ram_init = get_ram_ch101_gpr_open_init_ptr();
dev_ptr->get_fw_ram_init_size = get_ch101_gpr_open_fw_ram_init_size;
dev_ptr->get_fw_ram_init_addr = get_ch101_gpr_open_fw_ram_init_addr;
dev_ptr->prepare_pulse_timer = ch_common_prepare_pulse_timer;
dev_ptr->store_pt_result = ch101_gpr_open_store_pt_result;
dev_ptr->store_op_freq = ch_common_store_op_freq;
dev_ptr->store_bandwidth = ch_common_store_bandwidth;
dev_ptr->store_scalefactor = ch_common_store_scale_factor;
dev_ptr->get_locked_state = ch_common_get_locked_state;
/* Init API function pointers */
dev_ptr->api_funcs.fw_load = ch_common_fw_load;
dev_ptr->api_funcs.set_mode = ch_common_set_mode;
dev_ptr->api_funcs.set_sample_interval = ch_common_set_sample_interval;
dev_ptr->api_funcs.set_num_samples = ch_common_set_num_samples;
dev_ptr->api_funcs.set_max_range = ch_common_set_max_range;
dev_ptr->api_funcs.set_static_range = ch_common_set_static_range;
dev_ptr->api_funcs.get_range = ch_common_get_range;
dev_ptr->api_funcs.get_amplitude = ch_common_get_amplitude;
dev_ptr->api_funcs.get_iq_data = ch_common_get_iq_data;
dev_ptr->api_funcs.samples_to_mm = ch_common_samples_to_mm;
dev_ptr->api_funcs.mm_to_samples = ch_common_mm_to_samples;
dev_ptr->api_funcs.set_thresholds = NULL; // not supported
dev_ptr->api_funcs.get_thresholds = NULL; // not supported
/* Init device and group descriptor linkage */
dev_ptr->group = grp_ptr; // set parent group pointer
grp_ptr->device[io_index] = dev_ptr; // add to parent group
return 0;
}
void ch101_gpr_open_store_pt_result(struct ch_dev_t *dev_ptr)
{
u16 rtc_cal_result;
u16 calc_val;
u32 count;
chdrv_read_word(dev_ptr, CH101_GPR_OPEN_REG_CAL_RESULT,
&rtc_cal_result);
count = (rtc_cal_result * 1000) / dev_ptr->group->rtc_cal_pulse_ms;
calc_val = (u16)((u32)CH101_GPR_OPEN_CTR * 16U
* CH101_FREQCOUNTERCYCLES / count);
chdrv_write_word(dev_ptr, CH101_GPR_OPEN_REG_CALC, calc_val);
dev_ptr->rtc_cal_result = rtc_cal_result;
}

View File

@@ -0,0 +1,71 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*! \file ch101_gpr_open.h
*
* \brief Internal definitions for the Chirp CH101 GPR Open sensor firmware.
*
* This file contains register offsets and other values for use with the CH101
* GPR Open sensor firmware. These values are subject to change without notice.
*
* You should not need to edit this file or call the driver functions directly.
* Doing so will reduce your ability to benefit from future enhancements and
* releases from Chirp.
*/
/*
* Copyright (c) 2016-2019, Chirp Microsystems. All rights reserved.
*
* Chirp Microsystems CONFIDENTIAL
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL CHIRP MICROSYSTEMS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CH101_GPR_OPEN_H_
#define CH101_GPR_OPEN_H_
#include "ch101.h"
#include "soniclib.h"
/* GPR firmware registers */
#define CH101_GPR_OPEN_REG_OPMODE 0x01
#define CH101_GPR_OPEN_REG_TICK_INTERVAL 0x02
#define CH101_GPR_OPEN_REG_PERIOD 0x05
#define CH101_GPR_OPEN_REG_CAL_TRIG 0x06
#define CH101_GPR_OPEN_REG_CAL_TRIG 0x06
#define CH101_GPR_OPEN_REG_MAX_RANGE 0x07
#define CH101_GPR_OPEN_REG_CALC 0x08
#define CH101_GPR_OPEN_REG_ST_RANGE 0x12
#define CH101_GPR_OPEN_REG_READY 0x14
#define CH101_GPR_OPEN_REG_TOF_SF 0x16
#define CH101_GPR_OPEN_REG_TOF 0x18
#define CH101_GPR_OPEN_REG_AMPLITUDE 0x1A
#define CH101_GPR_OPEN_REG_CAL_RESULT 0x0A
#define CH101_GPR_OPEN_REG_DATA 0x1C
/* XXX need more values (?) */
#define CMREG_READY_FREQ_LOCKED_BM (0x02)
#define CH101_GPR_OPEN_CTR (0x2B368)
extern const char *ch101_gpr_open_version; // version string in fw .c file
extern u8 ch101_gpr_open_fw[CH101_FW_SIZE + 32];
uint16_t get_ch101_gpr_open_fw_ram_init_addr(void);
uint16_t get_ch101_gpr_open_fw_ram_init_size(void);
unsigned char *get_ram_ch101_gpr_open_init_ptr(void);
u8 ch101_gpr_open_init(struct ch_dev_t *dev_ptr, struct ch_group_t *grp_ptr,
u8 i2c_addr, u8 dev_num, u8 i2c_bus_index);
void ch101_gpr_open_store_pt_result(struct ch_dev_t *dev_ptr);
#endif

View File

@@ -0,0 +1,33 @@
// SPDX-License-Identifier: GPL-2.0
//Chirp Microsystems Firmware Header Generator
#include "ch101.h"
char *ch101_gpr_open_version;
//#define RAM_INIT_ADDRESS 1864
#define RAM_INIT_ADDRESS 0x974
#define RAM_INIT_WRITE_SIZE 16
u16 get_ch101_gpr_open_fw_ram_init_addr(void)
{
return (u16)RAM_INIT_ADDRESS;
}
u16 get_ch101_gpr_open_fw_ram_init_size(void)
{
return (u16)RAM_INIT_WRITE_SIZE;
}
unsigned char ram_ch101_gpr_open_init[RAM_INIT_WRITE_SIZE] = {
/*0x06, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x00,*/
/*0x64, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x01, 0x00,*/
};
unsigned char *get_ram_ch101_gpr_open_init_ptr(void)
{
return &ram_ch101_gpr_open_init[0];
}
unsigned char ch101_gpr_open_fw[CH101_FW_SIZE + 32];

View File

@@ -0,0 +1,87 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2016-2019, Chirp Microsystems. All rights reserved.
*
* Chirp Microsystems CONFIDENTIAL
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL CHIRP MICROSYSTEMS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "soniclib.h"
#include "ch101_gpr_sr_open.h"
#include "ch_common.h"
u8 ch101_gpr_sr_open_init(struct ch_dev_t *dev_ptr, struct ch_group_t *grp_ptr,
u8 i2c_addr, u8 io_index, u8 i2c_bus_index)
{
dev_ptr->part_number = CH101_PART_NUMBER;
dev_ptr->app_i2c_address = i2c_addr;
dev_ptr->io_index = io_index;
dev_ptr->i2c_bus_index = i2c_bus_index;
/* Init firmware-specific function pointers */
dev_ptr->firmware = ch101_gpr_sr_open_fw;
dev_ptr->fw_version_string = ch101_gpr_sr_open_version;
dev_ptr->ram_init = get_ram_ch101_gpr_sr_open_init_ptr();
dev_ptr->get_fw_ram_init_size = get_ch101_gpr_sr_open_fw_ram_init_size;
dev_ptr->get_fw_ram_init_addr = get_ch101_gpr_sr_open_fw_ram_init_addr;
dev_ptr->prepare_pulse_timer = ch_common_prepare_pulse_timer;
dev_ptr->store_pt_result = ch101_gpr_sr_open_store_pt_result;
dev_ptr->store_op_freq = ch_common_store_op_freq;
dev_ptr->store_bandwidth = ch_common_store_bandwidth;
dev_ptr->store_scalefactor = ch_common_store_scale_factor;
dev_ptr->get_locked_state = ch_common_get_locked_state;
/* Init API function pointers */
dev_ptr->api_funcs.fw_load = ch_common_fw_load;
dev_ptr->api_funcs.set_mode = ch_common_set_mode;
dev_ptr->api_funcs.set_sample_interval = ch_common_set_sample_interval;
dev_ptr->api_funcs.set_num_samples = ch_common_set_num_samples;
dev_ptr->api_funcs.set_max_range = ch_common_set_max_range;
dev_ptr->api_funcs.set_static_range = ch_common_set_static_range;
dev_ptr->api_funcs.get_range = ch_common_get_range;
dev_ptr->api_funcs.get_amplitude = ch_common_get_amplitude;
dev_ptr->api_funcs.get_iq_data = ch_common_get_iq_data;
dev_ptr->api_funcs.samples_to_mm = ch_common_samples_to_mm;
dev_ptr->api_funcs.mm_to_samples = ch_common_mm_to_samples;
dev_ptr->api_funcs.set_thresholds = NULL; // not supported
dev_ptr->api_funcs.get_thresholds = NULL; // not supported
/* This firmware uses oversampling */
dev_ptr->oversample = 2; // 4x oversampling (value is power of 2)
/* Init device and group descriptor linkage */
dev_ptr->group = grp_ptr; // set parent group pointer
grp_ptr->device[io_index] = dev_ptr; // add to parent group
return 0;
}
void ch101_gpr_sr_open_store_pt_result(struct ch_dev_t *dev_ptr)
{
u16 rtc_cal_result;
u16 calc_val;
u32 count;
chdrv_read_word(dev_ptr, CH101_GPR_SR_OPEN_REG_CAL_RESULT,
&rtc_cal_result);
count = (rtc_cal_result * 1000) / dev_ptr->group->rtc_cal_pulse_ms;
calc_val = (u16)((u32)CH101_GPR_SR_OPEN_CTR * 16U
* CH101_FREQCOUNTERCYCLES / count);
chdrv_write_word(dev_ptr, CH101_GPR_SR_OPEN_REG_CALC, calc_val);
dev_ptr->rtc_cal_result = rtc_cal_result;
}

View File

@@ -0,0 +1,72 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*! \file ch101_gpr_sr_open.h
*
* \brief Internal definitions for the Chirp CH101 GPR Short-range Open sensor
* firmware.
*
* This file contains register offsets and other values for use with the CH101
* GPR Short-range Open sensor firmware. These values are subject to change
* without notice.
*
* You should not need to edit this file or call the driver functions directly.
* Doing so will reduce your ability to benefit from future enhancements and
* releases from Chirp.
*/
/*
* Copyright (c) 2016-2019, Chirp Microsystems. All rights reserved.
*
* Chirp Microsystems CONFIDENTIAL
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL CHIRP MICROSYSTEMS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CH101_GPR_SR_OPEN_H_
#define CH101_GPR_SR_OPEN_H_
#include "ch101.h"
#include "soniclib.h"
/* GPR firmware registers */
#define CH101_GPR_SR_OPEN_REG_OPMODE 0x01
#define CH101_GPR_SR_OPEN_REG_TICK_INTERVAL 0x02
#define CH101_GPR_SR_OPEN_REG_PERIOD 0x05
#define CH101_GPR_SR_OPEN_REG_CAL_TRIG 0x06
#define CH101_GPR_SR_OPEN_REG_CAL_TRIG 0x06
#define CH101_GPR_SR_OPEN_REG_MAX_RANGE 0x07
#define CH101_GPR_SR_OPEN_REG_CALC 0x08
#define CH101_GPR_SR_OPEN_REG_ST_RANGE 0x12
#define CH101_GPR_SR_OPEN_REG_READY 0x14
#define CH101_GPR_SR_OPEN_REG_TOF_SF 0x16
#define CH101_GPR_SR_OPEN_REG_TOF 0x18
#define CH101_GPR_SR_OPEN_REG_AMPLITUDE 0x1A
#define CH101_GPR_SR_OPEN_REG_CAL_RESULT 0x0A
#define CH101_GPR_SR_OPEN_REG_DATA 0x1C
/* XXX need more values (?) */
#define CMREG_READY_FREQ_LOCKED_BM (0x02)
#define CH101_GPR_SR_OPEN_CTR (0x2B368)
extern const char *ch101_gpr_sr_open_version; // version string in fw .c file
extern u8 ch101_gpr_sr_open_fw[CH101_FW_SIZE + 32];
uint16_t get_ch101_gpr_sr_open_fw_ram_init_addr(void);
uint16_t get_ch101_gpr_sr_open_fw_ram_init_size(void);
unsigned char *get_ram_ch101_gpr_sr_open_init_ptr(void);
u8 ch101_gpr_sr_open_init(struct ch_dev_t *dev_ptr, struct ch_group_t
*grp_ptr, u8 i2c_addr, u8 dev_num, u8 i2c_bus_index);
void ch101_gpr_sr_open_store_pt_result(struct ch_dev_t *dev_ptr);
#endif

View File

@@ -0,0 +1,32 @@
// SPDX-License-Identifier: GPL-2.0
//Chirp Microsystems Firmware Header Generator
#include "ch101.h"
char *ch101_gpr_sr_open_version;
#define RAM_INIT_ADDRESS 1660
#define RAM_INIT_WRITE_SIZE 18
u16 get_ch101_gpr_sr_open_fw_ram_init_addr(void)
{
return (u16)RAM_INIT_ADDRESS;
}
u16 get_ch101_gpr_sr_open_fw_ram_init_size(void)
{
return (u16)RAM_INIT_WRITE_SIZE;
}
unsigned char ram_ch101_gpr_sr_open_init[RAM_INIT_WRITE_SIZE] = {
/* 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x00,*/
/* 0x00, 0x64, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x01, 0x00,*/
};
unsigned char *get_ram_ch101_gpr_sr_open_init_ptr(void)
{
return &ram_ch101_gpr_sr_open_init[0];
}
unsigned char ch101_gpr_sr_open_fw[CH101_FW_SIZE + 32];

View File

@@ -0,0 +1,46 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*! \file ch201.h
*
* \brief Internal definitions for the Chirp CH201 ultrasonic sensor.
*
* This file contains various hardware-defined values for the CH201 sensor.
*
* You should not need to edit this file or call the driver functions directly.
* Doing so will reduce your ability to benefit from future enhancements and
* releases from Chirp.
*/
/*
* Copyright (c) 2016-2019, Chirp Microsystems. All rights reserved.
*
* Chirp Microsystems CONFIDENTIAL
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL CHIRP MICROSYSTEMS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CH201_H_
#define CH201_H_
#define CH201_DATA_MEM_SIZE 0x800
#define CH201_DATA_MEM_ADDR 0x0200
#define CH201_PROG_MEM_SIZE 0x800
#define CH201_PROG_MEM_ADDR 0xF800
#define CH201_FW_SIZE CH201_PROG_MEM_SIZE
#define CH201_RAM_INIT_WRITE_SIZE 28
#define CH201_FREQCOUNTERCYCLES 128
#define CH201_INIT_RAM_MAX_SIZE 32
void set_ch201_gpr_fw_ram_init_addr(int addr);
void set_ch201_gpr_fw_ram_write_size(int size);
#endif

View File

@@ -0,0 +1,80 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*! \file ch201_gprmt.h
*
* \brief Internal definitions for the Chirp CH201 GPR Multi-threshold sensor
* firmware.
*
* This file contains register offsets and other values for use with the CH201
* GPR Multi-threshold sensor firmware. These values are subject to change
* without notice.
*
* You should not need to edit this file or call the driver functions directly.
* Doing so will reduce your ability to benefit from future enhancements and
* releases from Chirp.
*/
/*
* Copyright (c) 2016-2019, Chirp Microsystems. All rights reserved.
*
* Chirp Microsystems CONFIDENTIAL
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL CHIRP MICROSYSTEMS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CH201_GPRMT_H_
#define CH201_GPRMT_H_
#include "ch201.h"
#include "soniclib.h"
/* GPR with multi thresholds firmware registers */
#define CH201_GPRMT_REG_OPMODE 0x01
#define CH201_GPRMT_REG_TICK_INTERVAL 0x02
#define CH201_GPRMT_REG_PERIOD 0x05
#define CH201_GPRMT_REG_CAL_TRIG 0x06
#define CH201_GPRMT_REG_MAX_RANGE 0x07
#define CH201_GPRMT_REG_THRESH_LEN_0 0x08
#define CH201_GPRMT_REG_THRESH_LEN_1 0x09
#define CH201_GPRMT_REG_CAL_RESULT 0x0A
#define CH201_GPRMT_REG_THRESH_LEN_2 0x0C
#define CH201_GPRMT_REG_THRESH_LEN_3 0x0D
#define CH201_GPRMT_REG_ST_RANGE 0x12
#define CH201_GPRMT_REG_READY 0x14
#define CH201_GPRMT_REG_THRESH_LEN_4 0x15
/* start of array of six 2-byte threshold levels */
#define CH201_GPRMT_REG_THRESHOLDS 0x16
#define CH201_GPRMT_REG_TOF_SF 0x22
#define CH201_GPRMT_REG_TOF 0x24
#define CH201_GPRMT_REG_AMPLITUDE 0x26
#define CH201_GPRMT_REG_DATA 0x28
#define CMREG_READY_FREQ_LOCKED_BM (0x02)
#define CH201_GPRMT_MAX_SAMPLES (450) // max number of samples
/* total number of thresholds */
#define CH201_GPRMT_NUM_THRESHOLDS (6)
#define CH201_FW_VERS_SIZE 32
extern char ch201_gprmt_version[CH201_FW_VERS_SIZE];
// version string in fw .c file
extern u8 ch201_gprmt_fw[CH201_FW_SIZE + 32];
uint16_t get_ch201_gprmt_fw_ram_init_addr(void);
uint16_t get_ch201_gprmt_fw_ram_init_size(void);
unsigned char *get_ram_ch201_gprmt_init_ptr(void);
u8 ch201_gprmt_init(struct ch_dev_t *dev_ptr, struct ch_group_t
*grp_ptr, u8 i2c_addr, u8 dev_num, u8 i2c_bus_index);
#endif

View File

@@ -0,0 +1,57 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2020 InvenSense, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "ch201.h"
#include "ch201_gprmt.h"
char ch201_gprmt_version[CH201_FW_VERS_SIZE] = "gprmt_gprmt-201_v9";
const char *ch201_gprmt_gitsha1 = "7d06f03f0db7165f2e42305143416f7973dedf01";
//#define CH201_RAM_INIT_ADDRESS 2392
static uint16_t ram_init_addr;
static uint8_t ram_init_write_size;
uint16_t get_ch201_gprmt_fw_ram_init_addr(void)
{
return (uint16_t)ram_init_addr;
}
uint16_t get_ch201_gprmt_fw_ram_init_size(void)
{
return (uint16_t)ram_init_write_size;
}
unsigned char ram_ch201_gprmt_init[CH201_INIT_RAM_MAX_SIZE] = {
/* 0x88, 0x13, 0xD0, 0x07, 0x20, 0x03, 0x90, 0x01, 0xFA, 0x00, 0xAF,*/
/* 0x00, 0x06, 0x00, 0x00, 0x00,*/
/*0x00, 0xFA, 0x00, 0x00, 0x64, 0x00, 0x00, 0x0C, 0x00,*/
/* 0x00, 0x01, 0x00, */};
void set_ch201_gpr_fw_ram_init_addr(int addr)
{
ram_init_addr = addr;
}
void set_ch201_gpr_fw_ram_write_size(int size)
{
ram_init_write_size = size;
}
unsigned char *get_ram_ch201_gprmt_init_ptr(void)
{
return &ram_ch201_gprmt_init[0];
}
unsigned char ch201_gprmt_fw[CH201_FW_SIZE + CH201_INIT_RAM_MAX_SIZE];

View File

@@ -0,0 +1,452 @@
// SPDX-License-Identifier: GPL-2.0
/*! \file ch_api.c
* \brief Chirp SonicLib public API functions for using the Chirp ultrasonic
* sensor.
* The user should not need to edit this file. This file relies on hardware
* interface functions declared in ch_bsp.h and supplied in the board support
* package (BSP) for the specific hardware platform being used.
*/
/*
* Copyright (c) 2016-2019, Chirp Microsystems. All rights reserved.
*
* Chirp Microsystems CONFIDENTIAL
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL CHIRP MICROSYSTEMS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "soniclib.h"
#include "ch_driver.h"
#include "chirp_bsp.h"
/*!
* \brief Initialize a Chirp ultrasonic sensor descriptor structure
*
* \param dev_ptr a pointer to the ch_dev_t config structure for a sensor
*
* \return 0 (RET_OK) if successful, non-zero otherwise
*
*/
u8 ch_init(struct ch_dev_t *dev_ptr, struct ch_group_t *grp_ptr, u8 dev_num,
ch_fw_init_func_t fw_init_func)
{
u8 ret_val = RET_ERR;
struct ch_i2c_info_t i2c_info;
if (fw_init_func != NULL) {
/* Get I2C parameters from BSP */
ret_val = chbsp_i2c_get_info(grp_ptr, dev_num, &i2c_info);
if (ret_val == RET_OK) {
/* Save special handling flags for Chirp driver */
grp_ptr->i2c_drv_flags = i2c_info.drv_flags;
/* Call asic f/w init function passed in as parameter */
ret_val = (*fw_init_func)(dev_ptr, grp_ptr,
i2c_info.address, dev_num, i2c_info.bus_num);
}
}
return ret_val;
}
u8 ch_get_config(struct ch_dev_t *dev_ptr, struct ch_config_t *config_ptr)
{
u8 ret_val = 0;
config_ptr->mode = dev_ptr->mode;
config_ptr->max_range = dev_ptr->max_range;
config_ptr->static_range = dev_ptr->static_range;
config_ptr->sample_interval = dev_ptr->sample_interval;
// thresholds not returned here - use ch_get_thresholds()
config_ptr->thresh_ptr = NULL;
return ret_val;
}
u8 ch_set_config(struct ch_dev_t *dev_ptr, struct ch_config_t *config_ptr)
{
u8 ret_val = 0;
ret_val = ch_set_mode(dev_ptr, config_ptr->mode); // set operating mode
printf("ch_set_mode: %d\n", ret_val);
if (!ret_val) {
dev_ptr->mode = config_ptr->mode;
// set max range
ret_val = ch_set_max_range(dev_ptr, config_ptr->max_range);
printf("ch_set_max_range: %d\n", ret_val);
}
if (!ret_val) {
// static rejection only on CH101
if (dev_ptr->part_number == CH101_PART_NUMBER) {
// set static target rejection range
ret_val = ch_set_static_range(dev_ptr,
config_ptr->static_range);
printf("ch_set_static_range: %d\n", ret_val);
if (!ret_val) {
dev_ptr->static_range =
config_ptr->static_range;
}
}
}
if (!ret_val) {
// set sample interval (free-run mode only)
ret_val = ch_set_sample_interval(dev_ptr,
config_ptr->sample_interval);
printf("ch_set_sample_interval: %d\n", ret_val);
}
if (!ret_val) {
dev_ptr->sample_interval = config_ptr->sample_interval;
// multi threshold only on CH201
if (dev_ptr->part_number == CH201_PART_NUMBER) {
// set multiple thresholds
ret_val = ch_set_thresholds(dev_ptr,
config_ptr->thresh_ptr);
printf("ch_set_thresholds: %d\n", ret_val);
}
}
return ret_val;
}
u8 ch_group_start(struct ch_group_t *grp_ptr)
{
u8 ret_val;
ret_val = chdrv_group_start(grp_ptr);
return ret_val;
}
void ch_trigger(struct ch_dev_t *dev_ptr)
{
chdrv_hw_trigger_up(dev_ptr);
chdrv_hw_trigger_down(dev_ptr);
}
void ch_group_trigger(struct ch_group_t *grp_ptr)
{
chdrv_group_hw_trigger(grp_ptr);
}
void ch_reset(struct ch_dev_t *dev_ptr, enum ch_reset_t reset_type)
{
// TODO need single device hard reset
if (reset_type == CH_RESET_HARD)
chdrv_group_hard_reset(dev_ptr->group);
else
chdrv_soft_reset(dev_ptr);
}
void ch_group_reset(struct ch_group_t *grp_ptr, enum ch_reset_t reset_type)
{
if (reset_type == CH_RESET_HARD)
chdrv_group_hard_reset(grp_ptr);
else
chdrv_group_soft_reset(grp_ptr);
}
u8 ch_sensor_is_connected(struct ch_dev_t *dev_ptr)
{
return dev_ptr->sensor_connected;
}
u16 ch_get_part_number(struct ch_dev_t *dev_ptr)
{
return dev_ptr->part_number;
}
u8 ch_get_dev_num(struct ch_dev_t *dev_ptr)
{
return dev_ptr->io_index;
}
struct ch_dev_t *ch_get_dev_ptr(struct ch_group_t *grp_ptr, u8 dev_num)
{
return grp_ptr->device[dev_num];
}
u8 ch_get_i2c_address(struct ch_dev_t *dev_ptr)
{
return dev_ptr->i2c_address;
}
u8 ch_get_i2c_bus(struct ch_dev_t *dev_ptr)
{
return dev_ptr->i2c_bus_index;
}
u8 ch_get_num_ports(struct ch_group_t *grp_ptr)
{
return grp_ptr->num_ports;
}
char *ch_get_fw_version_string(struct ch_dev_t *dev_ptr)
{
return (char *)dev_ptr->fw_version_string;
}
enum ch_mode_t ch_get_mode(struct ch_dev_t *dev_ptr)
{
return dev_ptr->mode;
}
u8 ch_set_mode(struct ch_dev_t *dev_ptr, enum ch_mode_t mode)
{
int ret_val = RET_ERR;
ch_set_mode_func_t func_ptr = dev_ptr->api_funcs.set_mode;
if (func_ptr != NULL)
ret_val = (*func_ptr)(dev_ptr, mode);
return ret_val;
}
u16 ch_get_sample_interval(struct ch_dev_t *dev_ptr)
{
u16 sample_interval = 0;
if (dev_ptr->mode == CH_MODE_FREERUN)
sample_interval = dev_ptr->sample_interval;
return sample_interval;
}
u8 ch_set_sample_interval(struct ch_dev_t *dev_ptr, u16 sample_interval)
{
int ret_val = RET_ERR;
ch_set_sample_interval_func_t func_ptr =
dev_ptr->api_funcs.set_sample_interval;
if (func_ptr != NULL)
ret_val = (*func_ptr)(dev_ptr, sample_interval);
return ret_val;
}
u16 ch_get_num_samples(struct ch_dev_t *dev_ptr)
{
return dev_ptr->num_rx_samples;
}
u8 ch_set_num_samples(struct ch_dev_t *dev_ptr, u16 num_samples)
{
u8 ret_val = RET_ERR;
ch_set_num_samples_func_t func_ptr = dev_ptr->api_funcs.set_num_samples;
if (func_ptr != NULL)
ret_val = (*func_ptr)(dev_ptr, num_samples);
// store corresponding range in mm
dev_ptr->max_range = ch_samples_to_mm(dev_ptr, num_samples);
return ret_val;
}
u16 ch_get_max_range(struct ch_dev_t *dev_ptr)
{
return dev_ptr->max_range;
}
u8 ch_set_max_range(struct ch_dev_t *dev_ptr, u16 max_range)
{
u8 ret_val = RET_ERR;
ch_set_max_range_func_t func_ptr = dev_ptr->api_funcs.set_max_range;
if (func_ptr != NULL)
ret_val = (*func_ptr)(dev_ptr, max_range);
return ret_val;
}
u16 ch_get_static_range(struct ch_dev_t *dev_ptr)
{
return dev_ptr->static_range;
}
u8 ch_set_static_range(struct ch_dev_t *dev_ptr, u16 num_samples)
{
u8 ret_val = RET_ERR;
ch_set_static_range_func_t func_ptr =
dev_ptr->api_funcs.set_static_range;
if (func_ptr != NULL)
ret_val = (*func_ptr)(dev_ptr, num_samples);
return ret_val;
}
u8 ch_get_range(struct ch_dev_t *dev_ptr, enum ch_range_t range_type,
u32 *range)
{
u8 err = RET_ERR;
ch_get_range_func_t func_ptr = dev_ptr->api_funcs.get_range;
if (func_ptr != NULL)
err = (*func_ptr)(dev_ptr, range_type, range);
return err;
}
u8 ch_get_amplitude(struct ch_dev_t *dev_ptr, u16 *amplitude)
{
u8 err = RET_ERR;
ch_get_amplitude_func_t func_ptr = dev_ptr->api_funcs.get_amplitude;
if (func_ptr != NULL)
err = (*func_ptr)(dev_ptr, amplitude);
return err;
}
u32 ch_get_frequency(struct ch_dev_t *dev_ptr)
{
return dev_ptr->op_frequency;
}
u16 ch_get_rtc_cal_pulselength(struct ch_dev_t *dev_ptr)
{
return dev_ptr->group->rtc_cal_pulse_ms;
}
u16 ch_get_rtc_cal_result(struct ch_dev_t *dev_ptr)
{
return dev_ptr->rtc_cal_result;
}
u8 ch_get_iq_data(struct ch_dev_t *dev_ptr, struct ch_iq_sample_t *buf_ptr,
u16 start_sample, u16 num_samples, enum ch_io_mode_t mode)
{
int ret_val = 0;
ch_get_iq_data_func_t func_ptr = dev_ptr->api_funcs.get_iq_data;
if (func_ptr != NULL)
ret_val = (*func_ptr)(dev_ptr, buf_ptr, start_sample,
num_samples, mode);
return ret_val;
}
u16 ch_samples_to_mm(struct ch_dev_t *dev_ptr, u16 num_samples)
{
int num_mm = 0;
ch_samples_to_mm_func_t func_ptr = dev_ptr->api_funcs.samples_to_mm;
if (func_ptr != NULL)
num_mm = (*func_ptr)(dev_ptr, num_samples);
return num_mm;
}
u16 ch_mm_to_samples(struct ch_dev_t *dev_ptr, u16 num_mm)
{
int num_samples = 0;
ch_mm_to_samples_func_t func_ptr = dev_ptr->api_funcs.mm_to_samples;
if (func_ptr != NULL)
num_samples = (*func_ptr)(dev_ptr, num_mm);
return num_samples;
}
u8 ch_set_thresholds(struct ch_dev_t *dev_ptr,
struct ch_thresholds_t *thresh_ptr)
{
int ret_val = RET_ERR;
ch_set_thresholds_func_t func_ptr = dev_ptr->api_funcs.set_thresholds;
if (func_ptr != NULL && thresh_ptr != NULL)
ret_val = (*func_ptr)(dev_ptr, thresh_ptr);
return ret_val;
}
u8 ch_get_thresholds(struct ch_dev_t *dev_ptr,
struct ch_thresholds_t *thresh_ptr)
{
int ret_val = RET_ERR;
ch_get_thresholds_func_t func_ptr = dev_ptr->api_funcs.get_thresholds;
if (func_ptr != NULL && thresh_ptr != NULL)
ret_val = (*func_ptr)(dev_ptr, thresh_ptr);
return ret_val;
}
/*!
* \brief Start a non-blocking sensor readout
*
* \param grp_ptr pointer to the ch_group_t descriptor structure for
* a group of sensors
*
* This function starts a non-blocking I/O operation on the specified group
* of sensors.
*/
u8 ch_io_start_nb(struct ch_group_t *grp_ptr)
{
u8 ret_val = 1;
// only start I/O if there is a callback function
if (grp_ptr->io_complete_callback != NULL) {
chdrv_group_i2c_start_nb(grp_ptr);
ret_val = 0;
}
return ret_val;
}
/*!
* \brief Set callback function for Chirp sensor I/O interrupt
*
* \note
*/
void ch_io_int_callback_set(struct ch_group_t *grp_ptr,
ch_io_int_callback_t callback_func_ptr)
{
grp_ptr->io_int_callback = callback_func_ptr;
}
/*!
* \brief Set callback function for Chirp sensor I/O operation complete
*
* \note
*/
void ch_io_complete_callback_set(struct ch_group_t *grp_ptr,
ch_io_complete_callback_t callback_func_ptr)
{
grp_ptr->io_complete_callback = callback_func_ptr;
}
/*!
* \brief Continue a non-blocking readout
*
* \param grp_ptr pointer to the ch_group_t config structure for
* a group of sensors
* \param i2c_bus_index index value identifying I2C bus within group
*
* Call this function once from your I2C interrupt handler each time it
* completes an I/O operation. It will call the function previously specified
* during ch_io_complete_callback_set() when all group transactions are complete
*/
void ch_io_notify(struct ch_group_t *grp_ptr, u8 i2c_bus_index)
{
chdrv_group_i2c_irq_handler(grp_ptr, i2c_bus_index);
}

View File

@@ -0,0 +1,797 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2016-2019, Chirp Microsystems. All rights reserved.
*
* Chirp Microsystems CONFIDENTIAL
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL CHIRP MICROSYSTEMS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "soniclib.h"
#include "ch_common.h"
#include "chirp_bsp.h"
static u16 chirp_rx_samples = {0};
void set_output_samples(int ind, int val)
{
chirp_rx_samples = val;
}
u8 ch_common_set_mode(struct ch_dev_t *dev_ptr, enum ch_mode_t mode)
{
u8 ret_val = 0;
u8 opmode_reg;
u8 period_reg;
u8 tick_interval_reg;
if (dev_ptr->part_number == CH101_PART_NUMBER) {
opmode_reg = CH101_COMMON_REG_OPMODE;
period_reg = CH101_COMMON_REG_PERIOD;
tick_interval_reg = CH101_COMMON_REG_TICK_INTERVAL;
} else {
opmode_reg = CH201_COMMON_REG_OPMODE;
period_reg = CH201_COMMON_REG_PERIOD;
tick_interval_reg = CH201_COMMON_REG_TICK_INTERVAL;
}
printf("API: %s: mode: %02x dev_num: %d\n",
__func__, mode, ch_get_dev_num(dev_ptr));
if (dev_ptr->sensor_connected) {
switch (mode) {
case CH_MODE_IDLE:
chdrv_write_byte(dev_ptr, opmode_reg, CH_MODE_IDLE);
chdrv_write_byte(dev_ptr, period_reg, 0);
// XXX need define
chdrv_write_word(dev_ptr, tick_interval_reg, 2048);
break;
case CH_MODE_FREERUN:
chdrv_write_byte(dev_ptr, opmode_reg, CH_MODE_FREERUN);
// XXX need to set period / tick interval (?)
break;
case CH_MODE_TRIGGERED_TX_RX:
chdrv_write_byte(dev_ptr, opmode_reg,
CH_MODE_TRIGGERED_TX_RX);
break;
case CH_MODE_TRIGGERED_RX_ONLY:
chdrv_write_byte(dev_ptr, opmode_reg,
CH_MODE_TRIGGERED_RX_ONLY);
break;
default:
ret_val = RET_ERR; // return non-zero to indicate error
break;
}
}
return ret_val;
}
u8 ch_common_fw_load(struct ch_dev_t *dev_ptr)
{
u8 ch_err = 0;
u16 prog_mem_addr;
u16 fw_size;
if (dev_ptr->part_number == CH101_PART_NUMBER) {
prog_mem_addr = CH101_PROG_MEM_ADDR;
fw_size = CH101_FW_SIZE;
} else {
prog_mem_addr = CH201_PROG_MEM_ADDR;
fw_size = CH201_FW_SIZE;
}
printf("API: %s: addr: %02x\n", __func__, prog_mem_addr);
ch_err = chdrv_prog_mem_write(dev_ptr, prog_mem_addr,
(u8 *)dev_ptr->firmware, fw_size);
return ch_err;
}
u8 ch_common_set_sample_interval(struct ch_dev_t *dev_ptr, u16 interval_ms)
{
u8 period_reg;
u8 tick_interval_reg;
u8 ret_val = 0;
if (dev_ptr->part_number == CH101_PART_NUMBER) {
period_reg = CH101_COMMON_REG_PERIOD;
tick_interval_reg = CH101_COMMON_REG_TICK_INTERVAL;
} else {
period_reg = CH201_COMMON_REG_PERIOD;
tick_interval_reg = CH201_COMMON_REG_TICK_INTERVAL;
}
printf("API: %s: interval_ms: %u\n", __func__, interval_ms);
if (dev_ptr->sensor_connected) {
u32 sample_interval = dev_ptr->rtc_cal_result * interval_ms
/ dev_ptr->group->rtc_cal_pulse_ms;
u32 period = (sample_interval / 2048) + 1; // XXX need define
if (period > UINT8_MAX) { /* check if result fits in register */
ret_val = 1;
}
if (ret_val == 0) {
u32 tick_interval = sample_interval / period;
#ifdef CHDRV_DEBUG
printf("Set period=%u, tick_interval=%u\n",
period, tick_interval);
#endif
printf("API: %s: tick_interval: %u dev_num: %d\n",
__func__, tick_interval,
ch_get_dev_num(dev_ptr));
chdrv_write_byte(dev_ptr, period_reg, (u8)period);
chdrv_write_word(dev_ptr, tick_interval_reg,
(u16)tick_interval);
}
}
return ret_val;
}
// XXX need comment block
// XXX note uses actual num_samples, even for CH201
u8 ch_common_set_num_samples(struct ch_dev_t *dev_ptr, u16 num_samples)
{
u8 max_range_reg;
// default is error (not connected or num_samples too big)
u8 ret_val = 1;
printf("API: %s: num_samples: %u dev_num: %d\n",
__func__, num_samples, ch_get_dev_num(dev_ptr));
if (dev_ptr->part_number == CH101_PART_NUMBER) {
max_range_reg = CH101_COMMON_REG_MAX_RANGE;
} else {
max_range_reg = CH201_COMMON_REG_MAX_RANGE;
// each internal count for CH201 represents 2 physical samples
num_samples /= 2;
}
if (dev_ptr->sensor_connected && num_samples <= UINT8_MAX) {
ret_val = chdrv_write_byte(dev_ptr, max_range_reg,
(u8)num_samples);
}
return ret_val;
}
u8 ch_common_set_max_range(struct ch_dev_t *dev_ptr, u16 max_range_mm)
{
u8 ret_val;
u16 num_samples = 0;
u16 max_num_samples = 0;
printf("API: %s: max_range_mm: %u dev_num: %d\n",
__func__, max_range_mm, ch_get_dev_num(dev_ptr));
if (dev_ptr->part_number == CH101_PART_NUMBER)
max_num_samples = CH101_COMMON_NUM_SAMPLES;
else
max_num_samples = CH201_COMMON_NUM_SAMPLES;
ret_val = (!dev_ptr->sensor_connected);
printf("part_number=%u sensor_connected=%u\n",
dev_ptr->part_number, dev_ptr->sensor_connected);
printf("max_num_samples=%u\n", max_num_samples);
if (!ret_val) {
num_samples = ch_common_mm_to_samples(dev_ptr, max_range_mm);
if (chirp_rx_samples != 0)
num_samples = chirp_rx_samples;
printf("num_samples=%u max_range_mm=%u\n",
num_samples, max_range_mm);
if (num_samples > max_num_samples) {
num_samples = max_num_samples;
dev_ptr->max_range = ch_samples_to_mm(dev_ptr,
num_samples); // store reduced max range
printf("max_range=%u num_samples=%u\n",
dev_ptr->max_range, num_samples);
} else {
// store user-specified max range
dev_ptr->max_range = max_range_mm;
}
#ifdef CHDRV_DEBUG
printf("num_samples=%u\n", num_samples);
#endif
}
if (dev_ptr->part_number == CH201_PART_NUMBER)
num_samples *= 2;
if (!ret_val)
ret_val = ch_common_set_num_samples(dev_ptr, num_samples);
if (!ret_val)
dev_ptr->num_rx_samples = num_samples;
else
dev_ptr->num_rx_samples = 0;
#ifdef CHDRV_DEBUG
printf("Set samples: ret_val: %u dev_ptr->num_rx_samples: %u\n",
ret_val, dev_ptr->num_rx_samples);
#endif
return ret_val;
}
u16 ch_common_mm_to_samples(struct ch_dev_t *dev_ptr, u16 num_mm)
{
u8 err;
u16 scale_factor;
u32 num_samples = 0;
u32 divisor1;
u32 divisor2;
err = (!dev_ptr) || (!dev_ptr->sensor_connected);
printf("dev_ptr->rtc_cal_result=%u\n", dev_ptr->rtc_cal_result);
printf("dev_ptr->group->rtc_cal_pulse_ms=%u\n",
dev_ptr->group->rtc_cal_pulse_ms);
if (!err) {
if (dev_ptr->part_number == CH101_PART_NUMBER)
divisor1 = 0x2000;// (4*16*128) XXX need define(s)
else
divisor1 = 0x4000;// (4*16*128*2) XXX need define(s)
printf("dev_ptr->scale_factor=%u\n", dev_ptr->scale_factor);
if (dev_ptr->scale_factor == 0)
ch_common_store_scale_factor(dev_ptr);
printf("dev_ptr->scale_factor=%u\n", dev_ptr->scale_factor);
scale_factor = dev_ptr->scale_factor;
}
if (!err) {
divisor2 = (dev_ptr->group->rtc_cal_pulse_ms
* CH_SPEEDOFSOUND_MPS);
// Two steps of division to avoid needing a type larger
// than 32 bits
// Ceiling division to ensure result is at least enough samples
// to meet specified range
num_samples = ((dev_ptr->rtc_cal_result * scale_factor)
+ (divisor1 - 1)) / divisor1;
num_samples = ((num_samples * num_mm) + (divisor2 - 1))
/ divisor2;
err = (num_samples > UINT16_MAX);
printf("scale_factor=%u\n", scale_factor);
}
if (!err) {
// each internal count for CH201 represents 2 physical samples
if (dev_ptr->part_number == CH201_PART_NUMBER)
num_samples *= 2;
/* Adjust for oversampling, if used */
num_samples <<= dev_ptr->oversample;
}
if (err)
num_samples = 0; // return zero if error
return (u16)num_samples;
}
u16 ch_common_samples_to_mm(struct ch_dev_t *dev_ptr, u16 num_samples)
{
u32 num_mm = 0;
u32 op_freq = dev_ptr->op_frequency;
if (op_freq != 0) {
num_mm = ((u32)num_samples * CH_SPEEDOFSOUND_MPS * 8
* 1000) / (op_freq * 2);
}
/* Adjust for oversampling, if used */
num_mm >>= dev_ptr->oversample;
return (u16)num_mm;
}
u8 ch_common_set_static_range(struct ch_dev_t *dev_ptr, u16 samples)
{
u8 ret_val = 1; // default is error return
printf("API: %s: samples: %u dev_num: %d\n",
__func__, samples, ch_get_dev_num(dev_ptr));
if (dev_ptr->part_number == CH101_PART_NUMBER) { // CH101 only
if (dev_ptr->sensor_connected) {
ret_val = chdrv_write_byte(dev_ptr,
CH101_COMMON_REG_STAT_RANGE, (u8)samples);
if (!ret_val)
dev_ptr->static_range = samples;
}
}
return ret_val;
}
u8 ch_common_get_range(struct ch_dev_t *dev_ptr, enum ch_range_t range_type,
u32 *range)
{
u8 tof_reg;
u16 time_of_flight;
u16 scale_factor;
u8 err = 1;
*range = CH_NO_TARGET;
if (dev_ptr->sensor_connected) {
if (dev_ptr->part_number == CH101_PART_NUMBER)
tof_reg = CH101_COMMON_REG_TOF;
else
tof_reg = CH201_COMMON_REG_TOF;
err = chdrv_read_word(dev_ptr, tof_reg, &time_of_flight);
// If object detected
if (!err && time_of_flight != UINT16_MAX) {
if (dev_ptr->scale_factor == 0)
ch_common_store_scale_factor(dev_ptr);
scale_factor = dev_ptr->scale_factor;
if (scale_factor != 0) {
u32 tmp_range;
u32 num = (CH_SPEEDOFSOUND_MPS
* dev_ptr->group->rtc_cal_pulse_ms
* (u32)time_of_flight);
u32 den = ((u32)dev_ptr->rtc_cal_result
* (u32)scale_factor)
>> 11; // XXX need define
tmp_range = (num / den);
if (dev_ptr->part_number == CH201_PART_NUMBER)
tmp_range *= 2;
if (range_type == CH_RANGE_ECHO_ONE_WAY)
tmp_range /= 2;
/* Adjust for oversampling, if used */
tmp_range >>= dev_ptr->oversample;
*range = tmp_range;
}
}
}
printf("API: %s: range: %u dev_num: %d\n",
__func__, *range, ch_get_dev_num(dev_ptr));
return err;
}
u8 ch_common_get_amplitude(struct ch_dev_t *dev_ptr, u16 *amplitude)
{
u8 amplitude_reg;
u8 err = 1;
if (dev_ptr->sensor_connected) {
if (dev_ptr->part_number == CH101_PART_NUMBER)
amplitude_reg = CH101_COMMON_REG_AMPLITUDE;
else
amplitude_reg = CH201_COMMON_REG_AMPLITUDE;
err = chdrv_read_word(dev_ptr, amplitude_reg, amplitude);
}
printf("API: %s: amplitude: %u dev_num: %d\n",
__func__, *amplitude, ch_get_dev_num(dev_ptr));
return err;
}
u8 ch_common_get_locked_state(struct ch_dev_t *dev_ptr)
{
u8 ready_reg;
u8 lock_mask;
u8 ret_val = 0;
if (dev_ptr->part_number == CH101_PART_NUMBER) {
ready_reg = CH101_COMMON_REG_READY;
lock_mask = CH101_COMMON_READY_FREQ_LOCKED;
} else {
ready_reg = CH201_COMMON_REG_READY;
lock_mask = CH201_COMMON_READY_FREQ_LOCKED;
}
if (dev_ptr->sensor_connected) {
u8 ready_value = 0;
chdrv_read_byte(dev_ptr, ready_reg, &ready_value);
if (ready_value & lock_mask)
ret_val = 1;
}
printf("API: %s: lock_mask: %u dev_num: %d\n",
__func__, lock_mask, ch_get_dev_num(dev_ptr));
return ret_val;
}
void ch_common_prepare_pulse_timer(struct ch_dev_t *dev_ptr)
{
u8 cal_trig_reg;
printf("API: %s: dev_num: %d\n", __func__, ch_get_dev_num(dev_ptr));
if (dev_ptr->part_number == CH101_PART_NUMBER)
cal_trig_reg = CH101_COMMON_REG_CAL_TRIG;
else
cal_trig_reg = CH201_COMMON_REG_CAL_TRIG;
chdrv_write_byte(dev_ptr, cal_trig_reg, 0);
}
void ch_common_store_pt_result(struct ch_dev_t *dev_ptr)
{
u8 pt_result_reg;
u16 rtc_cal_result;
printf("API: %s: dev_num: %d\n", __func__, ch_get_dev_num(dev_ptr));
if (dev_ptr->part_number == CH101_PART_NUMBER)
pt_result_reg = CH101_COMMON_REG_CAL_RESULT;
else
pt_result_reg = CH201_COMMON_REG_CAL_RESULT;
chdrv_read_word(dev_ptr, pt_result_reg, &rtc_cal_result);
dev_ptr->rtc_cal_result = rtc_cal_result;
}
void ch_common_store_op_freq(struct ch_dev_t *dev_ptr)
{
u8 tof_sf_reg;
u16 raw_freq; // aka scale factor
u32 freq_counter_cycles;
u32 num;
u32 den;
u32 op_freq;
printf("API: %s: dev_num: %d\n", __func__, ch_get_dev_num(dev_ptr));
if (dev_ptr->part_number == CH101_PART_NUMBER) {
tof_sf_reg = CH101_COMMON_REG_TOF_SF;
freq_counter_cycles = CH101_FREQCOUNTERCYCLES;
} else {
tof_sf_reg = CH201_COMMON_REG_TOF_SF;
freq_counter_cycles = CH201_FREQCOUNTERCYCLES;
}
chdrv_read_word(dev_ptr, tof_sf_reg, &raw_freq);
num = (u32)(((dev_ptr->rtc_cal_result) * 1000U)
/ (16U * freq_counter_cycles)) * (u32)(raw_freq);
den = (u32)(dev_ptr->group->rtc_cal_pulse_ms);
op_freq = (num / den);
dev_ptr->op_frequency = op_freq;
}
void ch_common_store_bandwidth(struct ch_dev_t *dev_ptr)
{
/*
* Not supported in current GPR firmware
*/
}
void ch_common_store_scale_factor(struct ch_dev_t *dev_ptr)
{
u8 err;
u8 tof_sf_reg;
u16 scale_factor;
printf("API: %s: dev_num: %d\n", __func__, ch_get_dev_num(dev_ptr));
if (dev_ptr->part_number == CH101_PART_NUMBER)
tof_sf_reg = CH101_COMMON_REG_TOF_SF;
else
tof_sf_reg = CH201_COMMON_REG_TOF_SF;
err = chdrv_read_word(dev_ptr, tof_sf_reg, &scale_factor);
printf("tof_sf_reg=%02x scale_factor=%u err=%u\n",
tof_sf_reg, scale_factor, err);
if (!err)
dev_ptr->scale_factor = scale_factor;
else
dev_ptr->scale_factor = 0;
}
// XXX Need comment block
u8 ch_common_set_thresholds(struct ch_dev_t *dev_ptr,
struct ch_thresholds_t *thresholds_ptr)
{
u8 thresh_len_reg = 0;// offset of register for this threshold's length
u8 thresh_level_reg; // threshold level reg (first in array)
u8 max_num_thresholds;
int ret_val = 1; // default return = error
u8 thresh_num;
u8 thresh_len;
u16 thresh_level;
u16 start_sample = 0;
printf("API: %s: dev_num: %d\n", __func__, ch_get_dev_num(dev_ptr));
if (dev_ptr->sensor_connected) {
if (dev_ptr->part_number == CH101_PART_NUMBER) {
return ret_val; // NOT SUPPORTED in CH101
} else {
thresh_level_reg = CH201_COMMON_REG_THRESHOLDS;
max_num_thresholds = CH201_COMMON_NUM_THRESHOLDS;
}
for (thresh_num = 0; thresh_num < max_num_thresholds;
thresh_num++) {
if (thresh_num < (max_num_thresholds - 1)) {
u16 next_start_sample =
thresholds_ptr->threshold
[thresh_num + 1].start_sample;
thresh_len = (next_start_sample - start_sample);
start_sample = next_start_sample;
} else {
thresh_len = 0;
}
if (dev_ptr->part_number == CH201_PART_NUMBER) {
if (thresh_num == 0) {
thresh_len_reg =
CH201_COMMON_REG_THRESH_LEN_0;
} else if (thresh_num == 1) {
thresh_len_reg =
CH201_COMMON_REG_THRESH_LEN_1;
} else if (thresh_num == 2) {
thresh_len_reg =
CH201_COMMON_REG_THRESH_LEN_2;
} else if (thresh_num == 3) {
thresh_len_reg =
CH201_COMMON_REG_THRESH_LEN_3;
} else if (thresh_num == 4) {
thresh_len_reg =
CH201_COMMON_REG_THRESH_LEN_4;
} else if (thresh_num == 5) {
// last threshold does not have length
// field - assumed to extend to end
// of data
thresh_len_reg = 0;
}
}
// set the length field (if any) for this threshold
if (thresh_len_reg != 0) {
chdrv_write_byte(dev_ptr, thresh_len_reg,
thresh_len);
}
// write level to this threshold's entry in
// register array
thresh_level =
thresholds_ptr->threshold[thresh_num].level;
chdrv_write_word(dev_ptr,
(thresh_level_reg
+ (thresh_num * sizeof(u16))),
thresh_level);
}
ret_val = 0; // return OK
}
return ret_val;
}
// XXX Need comment block
u8 ch_common_get_thresholds(struct ch_dev_t *dev_ptr,
struct ch_thresholds_t *thresholds_ptr)
{
u8 thresh_len_reg = 0; // offset of register for this threshold length
u8 thresh_level_reg; // threshold level reg (first in array)
u8 max_num_thresholds;
u8 ret_val = 1; // default = error return
u8 thresh_num;
u8 thresh_len = 0; // number of samples described by each threshold
u16 start_sample = 0; // calculated start sample for each threshold
printf("API: %s: dev_num: %d\n", __func__, ch_get_dev_num(dev_ptr));
if (dev_ptr->sensor_connected && thresholds_ptr != NULL) {
if (dev_ptr->part_number == CH101_PART_NUMBER)
return ret_val; // NOT SUPPORTED in CH101
thresh_level_reg = CH201_COMMON_REG_THRESHOLDS;
max_num_thresholds = CH201_COMMON_NUM_THRESHOLDS;
for (thresh_num = 0; thresh_num < max_num_thresholds;
thresh_num++) {
if (dev_ptr->part_number == CH201_PART_NUMBER) {
if (thresh_num == 0) {
thresh_len_reg =
CH201_COMMON_REG_THRESH_LEN_0;
} else if (thresh_num == 1) {
thresh_len_reg =
CH201_COMMON_REG_THRESH_LEN_1;
} else if (thresh_num == 2) {
thresh_len_reg =
CH201_COMMON_REG_THRESH_LEN_2;
} else if (thresh_num == 3) {
thresh_len_reg =
CH201_COMMON_REG_THRESH_LEN_3;
} else if (thresh_num == 4) {
thresh_len_reg =
CH201_COMMON_REG_THRESH_LEN_4;
} else if (thresh_num == 5) {
// last threshold does not have length
// field - assumed to extend to end
// of data
thresh_len_reg = 0;
}
}
// read the length field register for this threshold
if (thresh_len_reg != 0) {
chdrv_read_byte(dev_ptr, thresh_len_reg,
&thresh_len);
} else {
thresh_len = 0;
}
thresholds_ptr->threshold[thresh_num].start_sample =
start_sample;
// increment start sample for next threshold
start_sample += thresh_len;
// get level from this threshold's entry in
// register array
chdrv_read_word(dev_ptr,
(thresh_level_reg + (thresh_num * sizeof(u16))),
&thresholds_ptr->threshold[thresh_num].level);
}
ret_val = 0; // return OK
}
return ret_val;
}
// XXX need comment block
u8 ch_common_get_iq_data(struct ch_dev_t *dev_ptr,
struct ch_iq_sample_t *buf_ptr, u16 start_sample, u16 num_samples,
enum ch_io_mode_t mode)
{
u16 iq_data_addr;
u16 max_samples;
struct ch_group_t *grp_ptr = dev_ptr->group;
int error = 1;
printf("API: %s: dev_num: %d\n", __func__, ch_get_dev_num(dev_ptr));
if (dev_ptr->part_number == CH101_PART_NUMBER) {
iq_data_addr = CH101_COMMON_REG_DATA;
max_samples = CH101_COMMON_NUM_SAMPLES;
} else {
iq_data_addr = CH201_COMMON_REG_DATA;
max_samples = CH201_COMMON_NUM_SAMPLES;
}
iq_data_addr += (start_sample * sizeof(struct ch_iq_sample_t));
if (num_samples != 0 && (start_sample + num_samples) <= max_samples) {
u16 num_bytes = (num_samples * sizeof(struct ch_iq_sample_t));
if (mode == CH_IO_MODE_BLOCK) {
#ifdef USE_STD_I2C_FOR_IQ
/* blocking transfer - use standard I2C interface */
error = chdrv_burst_read(dev_ptr, iq_data_addr,
(u8 *)buf_ptr, num_bytes);
#else
/* blocking transfer - use low-level programming
* interface for speed
*/
int num_transfers = (num_bytes + CH_PROG_XFER_SIZE - 1)
/ CH_PROG_XFER_SIZE;
int bytes_left = num_bytes; // remaining bytes to read
/* Convert register offsets to full memory addresses */
if (dev_ptr->part_number == CH101_PART_NUMBER)
iq_data_addr += CH101_DATA_MEM_ADDR +
CH101_COMMON_I2CREGS_OFFSET;
else
iq_data_addr += CH201_DATA_MEM_ADDR +
CH201_COMMON_I2CREGS_OFFSET;
// assert PROG pin
chbsp_program_enable(dev_ptr);
for (int xfer = 0; xfer < num_transfers; xfer++) {
int bytes_to_read;
// read burst command
u8 message[] = {(0x80 | CH_PROG_REG_CTL), 0x09};
if (bytes_left > CH_PROG_XFER_SIZE)
bytes_to_read = CH_PROG_XFER_SIZE;
else
bytes_to_read = bytes_left;
chdrv_prog_write(dev_ptr, CH_PROG_REG_ADDR,
(iq_data_addr +
(xfer * CH_PROG_XFER_SIZE)));
chdrv_prog_write(dev_ptr, CH_PROG_REG_CNT,
bytes_to_read - 1);
error = chdrv_prog_i2c_write(dev_ptr, message,
sizeof(message));
error |= chdrv_prog_i2c_read(dev_ptr,
(u8 *)(buf_ptr) +
(xfer * CH_PROG_XFER_SIZE),
bytes_to_read);
bytes_left -= bytes_to_read;
}
// de-assert PROG pin
chbsp_program_disable(dev_ptr);
#endif // USE_STD_I2C_FOR_IQ
} else {
/* non-blocking transfer - queue a read transaction
* (must be started using ch_io_start_nb() )
*/
if (grp_ptr->i2c_drv_flags & I2C_DRV_FLAG_USE_PROG_NB) {
/* Use low-level programming interface
* to read data
*/
/* Convert register offsets to full memory
* addresses
*/
if (dev_ptr->part_number == CH101_PART_NUMBER) {
iq_data_addr += (CH101_DATA_MEM_ADDR
+ CH101_COMMON_I2CREGS_OFFSET);
} else {
iq_data_addr += (CH201_DATA_MEM_ADDR
+ CH201_COMMON_I2CREGS_OFFSET);
}
error = chdrv_group_i2c_queue(grp_ptr, dev_ptr,
1, CHDRV_NB_TRANS_TYPE_PROG,
iq_data_addr, num_bytes,
(u8 *)buf_ptr);
} else {
/* Use regular I2C register interface
* to read data
*/
error = chdrv_group_i2c_queue(grp_ptr, dev_ptr,
1, CHDRV_NB_TRANS_TYPE_STD,
iq_data_addr, num_bytes,
(u8 *)buf_ptr);
}
}
}
return error;
}

View File

@@ -0,0 +1,149 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*! \file ch_common.h
*
* \brief Internal driver functions for operation with the Chirp ultrasonic
* sensor.
*
* This file contains common implementations of sensor support routines.
* These are suitable for use with most standard sensor firmware images.
* The firmware-specific init function will set up various function pointers to
* either the common implementations in this file, or corresponding
* firmware-specific implementations.
*
* You should not need to edit this file or call the driver functions directly.
* Doing so will reduce your ability to benefit from future enhancements and
* releases from Chirp.
*/
/*
* Copyright (c) 2016-2019, Chirp Microsystems. All rights reserved.
*
* Chirp Microsystems CONFIDENTIAL
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL CHIRP MICROSYSTEMS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CH_COMMON_H_
#define CH_COMMON_H_
#include "soniclib.h"
/* CH-101 common definitions */
#define CH101_COMMON_REG_OPMODE 0x01
#define CH101_COMMON_REG_TICK_INTERVAL 0x02
#define CH101_COMMON_REG_PERIOD 0x05
#define CH101_COMMON_REG_MAX_RANGE 0x07
#define CH101_COMMON_REG_TIME_PLAN 0x09
#define CH101_COMMON_REG_STAT_RANGE 0x12
#define CH101_COMMON_REG_STAT_COEFF 0x13
#define CH101_COMMON_REG_READY 0x14
#define CH101_COMMON_REG_TOF_SF 0x16
#define CH101_COMMON_REG_TOF 0x18
#define CH101_COMMON_REG_AMPLITUDE 0x1A
#define CH101_COMMON_REG_CAL_TRIG 0x06
#define CH101_COMMON_REG_CAL_RESULT 0x0A
#define CH101_COMMON_REG_DATA 0x1C
#define CH101_COMMON_I2CREGS_OFFSET 0
/* XXX need more values (?) */
#define CH101_COMMON_READY_FREQ_LOCKED (0x02)
/* max number of I/Q samples */
#define CH101_COMMON_NUM_SAMPLES (450)
/* default value for stationary target coefficient */
#define CH101_COMMON_STAT_COEFF_DEFAULT (6)
/* total number of thresholds */
#define CH101_COMMON_NUM_THRESHOLDS (6)
/* CH-201 common definitions */
#define CH201_COMMON_REG_OPMODE 0x01
#define CH201_COMMON_REG_TICK_INTERVAL 0x02
#define CH201_COMMON_REG_PERIOD 0x05
#define CH201_COMMON_REG_CAL_TRIG 0x06
#define CH201_COMMON_REG_MAX_RANGE 0x07
#define CH201_COMMON_REG_THRESH_LEN_0 0x08
#define CH201_COMMON_REG_THRESH_LEN_1 0x09
#define CH201_COMMON_REG_CAL_RESULT 0x0A
#define CH201_COMMON_REG_THRESH_LEN_2 0x0C
#define CH201_COMMON_REG_THRESH_LEN_3 0x0D
#define CH201_COMMON_REG_ST_RANGE 0x12
#define CH201_COMMON_REG_READY 0x14
#define CH201_COMMON_REG_THRESH_LEN_4 0x15
// start of array of six 2-byte threshold levels
#define CH201_COMMON_REG_THRESHOLDS 0x16
#define CH201_COMMON_REG_TOF_SF 0x22
#define CH201_COMMON_REG_TOF 0x24
#define CH201_COMMON_REG_AMPLITUDE 0x26
#define CH201_COMMON_REG_DATA 0x28
#define CH201_COMMON_I2CREGS_OFFSET 0
#define CH201_COMMON_READY_FREQ_LOCKED (0x02) // XXX need more values (?)
#define CH201_COMMON_NUM_SAMPLES (450) // max number of I/Q samples
#define CH201_COMMON_NUM_THRESHOLDS (6) // total number of thresholds
#define USE_STD_I2C_FOR_IQ
/* Function prototypes */
uint8_t ch_common_set_mode(struct ch_dev_t *dev_ptr, enum ch_mode_t mode);
uint8_t ch_common_fw_load(struct ch_dev_t *dev_ptr);
uint8_t ch_common_set_sample_interval(struct ch_dev_t *dev_ptr,
u16 interval_ms);
uint8_t ch_common_set_num_samples(struct ch_dev_t *dev_ptr, u16 num_samples);
uint8_t ch_common_set_max_range(struct ch_dev_t *dev_ptr, u16 max_range_mm);
uint8_t ch_common_set_static_range(struct ch_dev_t *dev_ptr, u16 samples);
uint8_t ch_common_get_range(struct ch_dev_t *dev_ptr,
enum ch_range_t range_type, uint32_t *range);
uint8_t ch_common_get_amplitude(struct ch_dev_t *dev_ptr, u16 *amplitude);
uint8_t ch_common_get_locked_state(struct ch_dev_t *dev_ptr);
uint32_t ch_common_get_op_freq(struct ch_dev_t *dev_ptr);
void ch_common_prepare_pulse_timer(struct ch_dev_t *dev_ptr);
void ch_common_store_pt_result(struct ch_dev_t *dev_ptr);
void ch_common_store_op_freq(struct ch_dev_t *dev_ptr);
void ch_common_store_bandwidth(struct ch_dev_t *dev_ptr);
void ch_common_store_scale_factor(struct ch_dev_t *dev_ptr);
uint8_t ch_common_set_thresholds(struct ch_dev_t *dev_ptr,
struct ch_thresholds_t *thresholds_ptr);
uint8_t ch_common_get_thresholds(struct ch_dev_t *dev_ptr,
struct ch_thresholds_t *thresholds_ptr);
u16 ch_common_mm_to_samples(struct ch_dev_t *dev_ptr, u16 num_mm);
u16 ch_common_samples_to_mm(struct ch_dev_t *dev_ptr, u16 num_samples);
uint8_t ch_common_get_iq_data(struct ch_dev_t *dev_ptr,
struct ch_iq_sample_t *buf_ptr, u16 start_sample, u16 num_samples,
enum ch_io_mode_t io_mode);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,668 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*! \file ch_driver.h
*
* \brief Internal driver functions for operation with the Chirp ultrasonic
* sensor.
*
* This file contains definitions for the internal Chirp sensor driver functions
* and structures within SonicLib. These functions are provided in source code
* form to simplify integration with an embedded application and for reference
* only.
*
* The Chirp driver functions provide an interface between the SonicLib public
* API layer and the actual sensor devices. The driver manages all software
* defined aspects of the Chirp sensor, including the register set.
*
* You should not need to edit this file or call the driver functions directly.
* Doing so will reduce your ability to benefit from future enhancements and
* releases from Chirp.
*/
/*
* Copyright (c) 2016-2019, Chirp Microsystems. All rights reserved.
*
* Chirp Microsystems CONFIDENTIAL
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL CHIRP MICROSYSTEMS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CH_DRIVER_H_
#define CH_DRIVER_H_
#define CHDRV_DEBUG
#include "chirp_board_config.h"
#include "soniclib.h"
#ifndef NULL
#define NULL 0
#endif
/* Chirp SonicLib API/driver version number */
#define CH_DRIVER_VERSION "2.0.0"
/* I2C address of sensor programming interface */
#define CH_I2C_ADDR_PROG 0x45
/* maximum number of bytes in a single I2C write */
#define CHDRV_I2C_MAX_WRITE_BYTES 256
/* standard non-blocking I/O transaction */
#define CHDRV_NB_TRANS_TYPE_STD (0)
/* non-blocking I/O via low-level programming interface */
#define CHDRV_NB_TRANS_TYPE_PROG (1)
/* externally requested non-blocking I/O transaction */
#define CHDRV_NB_TRANS_TYPE_EXTERNAL (2)
/* Programming interface register addresses */
/* Read-only register used during device discovery. */
#define CH_PROG_REG_PING 0x00
/* Processor control register address. */
#define CH_PROG_REG_CPU 0x42
/* Processor status register address. */
#define CH_PROG_REG_STAT 0x43
/* Data transfer control register address. */
#define CH_PROG_REG_CTL 0x44
/* Data transfer starting address register address. */
#define CH_PROG_REG_ADDR 0x05
/* Data transfer size register address. */
#define CH_PROG_REG_CNT 0x07
/* Data transfer value register address. */
#define CH_PROG_REG_DATA 0x06
/* Macro to determine programming register size. */
#define CH_PROG_SIZEOF(R) ((R) & 0x40 ? 1 : 2)
/* max size of a read operation via programming interface */
#define CH_PROG_XFER_SIZE (256)
/* debug pin number (index) to use for debug indication */
#define CHDRV_DEBUG_PIN_NUM (0)
/* Max queued non-blocking I2C transactions - value from chirp_board_config.h */
#define CHDRV_MAX_I2C_QUEUE_LENGTH CHIRP_MAX_NUM_SENSORS
/* Time to wait in chdrv_group_start() for sensor initialization, in millisec.*/
#define CHDRV_FREQLOCK_TIMEOUT_MS 100
/* Index of first sample to use for calculating bandwidth. */
#define CHDRV_BANDWIDTH_INDEX_1 6
/* Index of second sample to use for calculating bandwidth. */
#define CHDRV_BANDWIDTH_INDEX_2 (CHDRV_BANDWIDTH_INDEX_1 + 1)
/* Index for calculating scale factor. */
#define CHDRV_SCALEFACTOR_INDEX 4
/* Incomplete definitions of structs in ch_api.h, to resolve include order */
struct ch_dev_t;
struct ch_group_t;
//! Hook routine pointer typedefs
typedef u8 (*chdrv_discovery_hook_t)(struct ch_dev_t *dev_ptr);
//! I2C transaction control structure
struct chdrv_i2c_transaction_t {
/* I2C transaction type: 0 = std, 1 = prog interface, 2 = external */
u8 type;
/* Read/write indicator: 0 if write operation, 1 if read operation */
u8 rd_wrb;
/* current transfer within this transaction */
u8 xfer_num;
/* I2C address */
u16 addr;
/* Number of bytes to transfer */
u16 nbytes;
/* Pointer to ch_dev_t descriptor structure for individual sensor */
struct ch_dev_t *dev_ptr;
/* Pointer to buffer to receive data or containing data to send */
u8 *databuf;
};
//! I2C queue structure, for non-blocking access
struct chdrv_i2c_queue_t {
/* Read transaction status: non-zero if read operation is pending */
u8 read_pending;
/* I2C transaction status: non-zero if I/O operation in progress */
u8 running;
/* Number of transactions in queue */
u8 len;
/* Index of current transaction within queue */
u8 idx;
/* List of transactions in queue */
struct chdrv_i2c_transaction_t transaction[CHDRV_MAX_I2C_QUEUE_LENGTH];
};
/*!
* \brief Calibrate the sensor real-time clock against the host microcontroller
* clock.
*
* \param grp_ptr pointer to the ch_group_t descriptor structure for a group
* of sensors
*
* This function sends a pulse (timed by the host MCU) on the INT line to each
* device in the group, then reads back the count of sensor RTC cycles that
* elapsed during that pulse on each individual device. The result is stored in
* the ch_dev_t descriptor structure for each device and is subsequently used
* during range calculations.
*
* The length of the pulse is grp_ptr->rtc_cal_pulse_ms milliseconds
* (typically 100ms).
*
* \note The calibration pulse is sent to all devices in the group at the same
* time. Therefore all connected devices will see the same reference pulse
* length.
*
*/
void chdrv_group_measure_rtc(struct ch_group_t *grp_ptr);
/*!
* \brief Convert the sensor register values to a range using the calibration
* data in the ch_dev_t struct.
*
* \param dev_ptr pointer to the ch_dev_t descriptor structure
* \param tof value of TOF register
* \param tof_sf value of TOF_SF register
*
* \return range in millimeters, or \a CH_NO_TARGET (0xFFFFFFFF) if no object is
* detected. The range result format is fixed point with 5 binary fractional
* digits (divide by 32 to convert to mm).
*
* This function takes the time-of-flight and scale factor values from the
* sensor, and computes the actual one-way range based on the formulas given in
* the sensor datasheet.
*/
uint32_t chdrv_one_way_range(struct ch_dev_t *dev_ptr, u16 tof, u16 tof_sf);
/*!
* \brief Convert the sensor register values to a round-trip range using
* the calibration data in the ch_dev_t struct.
*
* \param dev_ptr pointer to the ch_dev_t descriptor structure
* \param tof value of TOF register
* \param tof_sf value of TOF_SF register
*
* \return range in millimeters, or \a CH_NO_TARGET (0xFFFFFFFF) if no object is
* detected. The range result format is fixed point with 5 binary fractional
* digits (divide by 32 to convert to mm).
*
* This function takes the time-of-flight and scale factor values from the
* sensor, and computes the actual round-trip range based on the formulas given
* in the sensor datasheet.
*/
uint32_t chdrv_round_trip_range(struct ch_dev_t *dev_ptr, u16 tof,
u16 tof_sf);
/*!
* \brief Add an I2C transaction to the non-blocking queue
*
* \param grp_ptr pointer to the ch_group_t descriptor structure for
* a group of sensors
* \param instance pointer to the ch_dev_t descriptor structure
* \param rd_wrb read/write indicator:
* 0 if write operation, 1 if read operation
* \param type I2C transaction type:
* 0 = std, 1 = prog interface, 2 = external
* \param addr I2C address for transfer
* \param nbytes number of bytes to read/write
* \param data pointer to buffer to receive data or containing
* data to send
*
* \return 0 if successful, non-zero otherwise
*/
int chdrv_group_i2c_queue(struct ch_group_t *grp_ptr, struct ch_dev_t *instance,
u8 rd_wrb, u8 type, u16 addr, u16 nbytes,
u8 *data);
/*!
* \brief Add an I2C transaction for an external device to the non-blocking
* queue
*
* \param grp_ptr pointer to the ch_group_t descriptor structure for
* a group of sensors
* \param instance pointer to the ch_dev_t descriptor structure
* \param rd_wrb read/write indicator:
* 0 if write operation, 1 if read operation
* \param addr I2C address for transfer
* \param nbytes number of bytes to read/write
* \param data pointer to buffer to receive data or containing
* data to send
*
* \return 0 if successful, non-zero otherwise
*
* This function queues an I2C transaction for an "external" device (i.e. not
* a Chirp sensor). It is used when the I2C bus is shared between the Chirp
* sensor(s) and other devices.
*
* The transaction is flagged for special handling when the I/O operation
* completes. Specifically, the \a chbsp_external_i2c_irq_handler() will be
* called by the driver to allow the board support packate (BSP) to perform any
* necessary operations.
*/
int chdrv_external_i2c_queue(struct ch_group_t *grp_ptr,
struct ch_dev_t *instance, u8 rd_wrb, u16 addr, u16 nbytes, u8 *data);
/*!
* \brief Start a non-blocking sensor readout
*
* \param grp_ptr pointer to the ch_group_t descriptor structure for
* a group of sensors
*
* This function starts a non-blocking I/O operation on the specified group
* of sensors.
*/
void chdrv_group_i2c_start_nb(struct ch_group_t *grp_ptr);
/*!
* \brief Continue a non-blocking readout
*
* \param grp_ptr pointer to the ch_group_t descriptor structure for
* a group of sensors
* \param i2c_bus_index index value identifying I2C bus within group
*
* Call this function once from your I2C interrupt handler each time it
* executes. It will call \a chdrv_group_i2c_complete_callback() when all
* transactions are complete.
*/
void chdrv_group_i2c_irq_handler(struct ch_group_t *grp_ptr, u8 i2c_bus_index);
/*!
* \brief Wait for an individual sensor to finish start-up procedure.
*
* \param dev_ptr pointer to the ch_dev_t descriptor structure
* \param timeout_ms number of milliseconds to wait for sensor to finish
* start-up before returning failure
*
* \return 0 if startup sequence finished, non-zero if startup sequence timed
* out or sensor is not connected
*
* After the sensor is programmed, it executes an internal start-up and
* self-test sequence. This function waits the specified time in milliseconds
* for the sensor to finish this sequence.
*/
int chdrv_wait_for_lock(struct ch_dev_t *dev_ptr, u16 timeout_ms);
/*!
* \brief Wait for all sensors to finish start-up procedure.
*
* \param grp_ptr pointer to the ch_group_t descriptor structure for
* a group of sensors
*
* \return 0 if startup sequence finished on all detected sensors, non-zero if
* startup sequence timed out on any sensor(s).
*
* After each sensor is programmed, it executes an internal start-up and
* self-test sequence. This function waits for all sensor devices to finish this
* sequence. For each device, the maximum time to wait is
* \a CHDRV_FREQLOCK_TIMEOUT_MS milliseconds.
*/
int chdrv_group_wait_for_lock(struct ch_group_t *grp_ptr);
/*!
* \brief Start a measurement in hardware triggered mode.
*
* \param grp_ptr pointer to the ch_group_t descriptor structure for
* a group of sensors
*
* \return 0 if success, non-zero if \a grp_ptr pointer is invalid
*
* This function starts a triggered measurement on each sensor in a group, by
* briefly asserting the INT line to each device. Each sensor must have already
* been placed in hardware triggered mode before this function is called.
*/
int chdrv_group_hw_trigger(struct ch_group_t *grp_ptr);
/*!
* \brief Start a measurement in hardware triggered mode on one sensor.
*
* \param dev_ptr pointer to the ch_dev_t descriptor structure
*
* \return 0 if success, non-zero if \a dev_ptr pointer is invalid
*
* This function starts a triggered measurement on a single sensor, by briefly
* asserting the INT line to the device. The sensor must have already been
* placed in hardware triggered mode before this function is called.
*
* \note This function requires implementing the optional chirp_bsp.h functions
* to control the INT pin direction and level for individual sensors
* (\a chbsp_set_io_dir_in(), \a chbsp_set_io_dir_out(), \a chbsp_io_set(),
* and \a chbsp_io_clear()).
*/
int chdrv_hw_trigger_up(struct ch_dev_t *dev_ptr);
int chdrv_hw_trigger_down(struct ch_dev_t *dev_ptr);
/*!
* \brief Detect a connected sensor.
*
* \param dev_ptr pointer to the ch_dev_t descriptor structure
*
* \return 1 if sensor is found, 0 if no sensor is found
*
* This function checks for a sensor on the I2C bus by attempting to reset,
* halt, and read from the device using the programming interface
* I2C address (0x45).
*
* In order for the device to respond, the PROG pin for the device must be
* asserted before this function is called. If there are multiple sensors in
* an application, only one device's PROG pin should be active at any time.
*/
int chdrv_prog_ping(struct ch_dev_t *dev_ptr);
/*!
* \brief Detect, program, and start a sensor.
*
* \param dev_ptr pointer to the ch_dev_t descriptor structure
*
* \return 0 if write to sensor succeeded, non-zero otherwise
*
* This function probes the I2C bus for the device. If it is found, the sensor
* firmware is programmed into the device, and the application I2C address is
* set. Then the sensor is reset and execution starts.
*
* Once started, the sensor device will begin an internal initialization and
* self-test sequence. The \a chdrv_wait_for_lock() function may be used to wait
* for this sequence to complete.
*
* \note This routine will leave the PROG pin de-asserted when it completes.
*/
int chdrv_detect_and_program(struct ch_dev_t *dev_ptr);
/*!
* \brief Detect, program, and start all sensors in a group.
*
* \param grp_ptr pointer to the ch_group_t descriptor structure for
* a group of sensors
*
* \return 0 for success, non-zero if write(s) failed to any sensor initially
* detected as present
*
* This function probes the I2C bus for each device in the group. For each
* detected sensor, the firmware is programmed into the device, and the
* application I2C address is set. Then the sensor is reset and execution starts
*
* Once started, each device will begin an internal initialization and self-test
* sequence. The \a chdrv_group_wait_for_lock() function may be used to wait for
* this sequence to complete on all devices in the group.
*
* \note This routine will leave the PROG pin de-asserted for all devices in
* the group when it completes.
*/
int chdrv_group_detect_and_program(struct ch_group_t *grp_ptr);
/*!
* \brief Initialize the sensor device configuration.
*
* \param dev_ptr pointer to the ch_dev_t descriptor structure to
* be initialized
* \param i2c_addr I2C address to assign to this device. This will be the
* "application I2C address" used to access the device
* after it is initialized. Each sensor on an I2C interface
* must use a unique application I2C address.
* \param io_index index identifying this device. Each sensor in a group
* must have a unique \a io_index value.
* \param i2c_bus_index index identifying the I2C interface (bus) to use with
* this device
* \param part_number integer part number for sensor (e.g. 101 for CH101
* device, or 201 for CH201))
*
* \return 0 (always)
*
* This function initializes the ch_dev_t descriptor structure for the device
* with the specified values.
*/
int chdrv_init(struct ch_dev_t *dev_ptr, u8 i2c_addr, u8 io_index,
u8 i2c_bus_index, u16 part_number);
/*!
* \brief Initialize data structures and hardware for sensor interaction and
* reset sensors.
*
* \param grp_ptr pointer to the ch_group_t descriptor structure for
* a group of sensors
*
* \return 0 if hardware initialization is successful, non-zero otherwise
*
* This function is called internally by \a chdrv_group_start().
*/
int chdrv_group_prepare(struct ch_group_t *grp_ptr);
/*!
* \brief Initialize and start a group of sensors.
*
* \param grp_ptr pointer to the ch_group_t descriptor structure for
* a group of sensors
*
* \return 0 if successful, 1 if device doesn't respond
*
* This function resets each sensor in programming mode, transfers the firmware
* image to the sensor's on-chip memory, changes the sensor's application I2C
* address from the default, then starts the sensor and sends a timed pulse on
* the INT line for real-time clock calibration.
*
* This function assumes firmware-specific initialization has already been
* performed for each ch_dev_t descriptor in the sensor group.
* (See \a ch_init()).
*/
int chdrv_group_start(struct ch_group_t *grp_ptr);
/*!
* \brief Write byte to a sensor application register.
*
* \param dev_ptr pointer to the ch_dev_t descriptor structure
* \param reg_addr register address
* \param data data value to transmit
*
* \return 0 if successful, non-zero otherwise
*/
int chdrv_write_byte(struct ch_dev_t *dev_ptr, u16 mem_addr, u8 data);
/*!
* \brief Write 16 bits to a sensor application register.
*
* \param dev_ptr pointer to the ch_dev_t descriptor structure
* \param mem_addr sensor memory/register address
* \param data data value to transmit
*
* \return 0 if successful, non-zero otherwise
*/
int chdrv_write_word(struct ch_dev_t *dev_ptr, u16 mem_addr, u16 data);
/*!
* \brief Read byte from a sensor application register.
*
* \param dev_ptr pointer to the ch_dev_t descriptor structure
* \param mem_addr sensor memory/register address
* \param data pointer to receive buffer
*
* \return 0 if successful, non-zero otherwise
*/
int chdrv_read_byte(struct ch_dev_t *dev_ptr, u16 mem_addr, u8 *data);
/*!
* \brief Read 16 bits from a sensor application register.
*
* \param dev_ptr pointer to the ch_dev_t descriptor structure
* \param mem_addr sensor memory/register address
* \param data pointer to receive buffer
*
* \return 0 if successful, non-zero otherwise
*/
int chdrv_read_word(struct ch_dev_t *dev_ptr, u16 mem_addr, u16 *data);
/*!
* \brief Read multiple bytes from a sensor application register location.
*
* \param dev_ptr pointer to the ch_dev_t descriptor structure
* \param mem_addr sensor memory/register address
* \param data pointer to receive buffer
* \param len number of bytes to read
*
* \return 0 if successful, non-zero otherwise
*
*/
int chdrv_burst_read(struct ch_dev_t *dev_ptr, u16 mem_addr, u8 *data,
u16 len);
/*!
* \brief Write multiple bytes to a sensor application register location.
*
* \param dev_ptr pointer to the ch_dev_t descriptor structure
* \param mem_addr sensor memory/register address
* \param data pointer to transmit buffer containing data to send
* \param len number of bytes to write
*
* \return 0 if successful, non-zero otherwise
*
*/
int chdrv_burst_write(struct ch_dev_t *dev_ptr, u16 mem_addr, u8 *data,
u8 len);
/*!
* \brief Perform a soft reset on a sensor.
*
* \param dev_ptr pointer to the ch_dev_t descriptor structure
* \param mem_addr sensor memory/register address
*
* \return 0 if successful, non-zero otherwise
*
* This function performs a soft reset on an individual sensor by writing to
* a special control register.
*/
int chdrv_soft_reset(struct ch_dev_t *dev_ptr);
/*!
* \brief Perform a hard reset on a group of sensors.
*
* \param grp_ptr pointer to the ch_group_t descriptor structure for
* a group of sensors
*
* \return 0 if successful, non-zero otherwise
*
* This function performs a hardware reset on each device in a group of sensors
* by asserting each device's RESET_N pin.
*/
int chdrv_group_hard_reset(struct ch_group_t *grp_ptr);
/*!
* \brief Perform a soft reset on a group of sensors.
*
* \param grp_ptr pointer to the ch_group_t descriptor structure for
* a group of sensors
*
* \return 0 if successful, non-zero otherwise
*
* This function performs a soft reset on each device in a group of sensors by
* writing to a special control register.
*/
int chdrv_group_soft_reset(struct ch_group_t *grp_ptr);
/*!
* \brief Put sensor(s) in idle state
*
* \param dev_ptr pointer to the ch_dev_t descriptor structure
*
* \return 0 if successful, non-zero otherwise
*
* This function places the sensor in an idle state by loading an idle loop
* instruction sequence. This is used only during early initialization of
* the device. This is NOT the same as putting a running device into
* "idle mode" by using the \a ch_set_mode() function.
*/
int chdrv_set_idle(struct ch_dev_t *dev_ptr);
/*!
* \brief Write to a sensor programming register.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
* \param reg_addr sensor programming register address.
* \param data 8-bit or 16-bit data to transmit.
*
* \return 0 if write to sensor succeeded, non-zero otherwise
*
* This function writes a value to a sensor programming register.
*/
int chdrv_prog_write(struct ch_dev_t *dev_ptr, u8 reg_addr, u16 data);
/*!
* \brief Write bytes to a sensor device in programming mode.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
* \param message pointer to a buffer containing the bytes to write
* \param len number of bytes to write
*
* \return 0 if successful, non-zero otherwise
*
* This function writes bytes to the device using the programming I2C address.
* The PROG line for the device must have been asserted before this function
* is called.
*/
int chdrv_prog_i2c_write(struct ch_dev_t *dev_ptr, u8 *message, u16 len);
/*!
* \brief Read bytes from a sensor device in programming mode.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
* \param message pointer to a buffer where read bytes will be placed
* \param len number of bytes to read
*
* \return 0 if successful, non-zero otherwise
*
* This function reads bytes from the device using the programming I2C address.
* The PROG line for the device must have been asserted before this function
* is called.
*/
int chdrv_prog_i2c_read(struct ch_dev_t *dev_ptr, u8 *message, u16 len);
/*!
* \brief Read bytes from a sensor device in programming mode, non-blocking.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
* \param message pointer to a buffer where read bytes will be placed
* \param len number of bytes to read
*
* \return 0 if successful, non-zero otherwise
*
* This function temporarily changes the device I2C address to the low-level
* programming interface, and issues a non-blocking read request. The PROG line
* for the device must have been asserted before this function is called.
*/
int chdrv_prog_i2c_read_nb(struct ch_dev_t *dev_ptr, u8 *message, u16 len);
/*!
* \brief Write to sensor memory.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
* \param addr sensor programming register start address
* \param message pointer to data to transmit
* \param nbytes number of bytes to write
*
* \return 0 if write to sensor succeeded, non-zero otherwise
*
* This function writes to sensor memory using the low-level programming
* interface. The type of write is automatically determined based on data
* length and target address alignment.
*/
int chdrv_prog_mem_write(struct ch_dev_t *dev_ptr, u16 addr, u8 *message,
u16 nbytes);
/*!
* \brief Register a hook routine to be called after device discovery.
*
* \param grp_ptr pointer to the ch_group_t config structure for
* a group of sensors
* \param hook_func_ptr address of hook routine to be called
*
* This function sets a pointer to a hook routine, which will be called from the
* Chirp driver when each device is discovered on the I2C bus, before the device
* is initialized.
*
* This function should be called between \a ch_init() and \a ch_group_start().
*/
void chdrv_discovery_hook_set(struct ch_group_t *grp_ptr,
chdrv_discovery_hook_t hook_func_ptr);
#endif /* CH_DRIVER_H_ */

View File

@@ -0,0 +1,53 @@
// SPDX-License-Identifier: GPL-2.0
/*!
* \file chbsp_dummy.c
*
* \brief Dummy implementations of optional board support package IO functions
* allowing platforms to selectively support only needed functionality.
* These are placeholder routines that will satisfy references from other code
* to avoid link errors, but they do not peform any actual operations.
*
* See chirp_bsp.h for descriptions of all board support package interfaces,
* including details on these optional functions.
*/
/*
* Copyright (c) 2017-2019 Chirp Microsystems. All rights reserved.
*/
#include "chirp_bsp.h"
/* Functions supporting debugging */
WEAK void chbsp_debug_toggle(u8 dbg_pin_num)
{
}
WEAK void chbsp_debug_on(u8 dbg_pin_num)
{
}
WEAK void chbsp_debug_off(u8 dbg_pin_num)
{
}
WEAK void chbsp_external_i2c_irq_handler(struct chdrv_i2c_transaction_t *trans)
{
(void)(trans);
}
/* Other BSP functions */
WEAK void chbsp_proc_sleep(u16 ms)
{
msleep(ms);
}
WEAK void chbsp_critical_section_enter(void)
{
}
WEAK void chbsp_critical_section_leave(void)
{
}

View File

@@ -0,0 +1,864 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2016-2019, Chirp Microsystems. All rights reserved.
*
* Chirp Microsystems CONFIDENTIAL
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL CHIRP MICROSYSTEMS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "soniclib.h" // Chirp SonicLib API definitions
#include "chirp_hal.h"
#include "chbsp_init.h" // header with board-specific defines
#include "chirp_bsp.h"
#include "i2c_hal.h"
u8 chirp_i2c_addrs[] = CHIRP_I2C_ADDRS;
u8 chirp_i2c_buses[] = CHIRP_I2C_BUSES;
/*
* Here you set the pin masks for each of the prog pins
*/
u32 chirp_pin_enabled[] = { 1, 1, 1, 1, 1, 1};
u32 chirp_pin_prog[] = {
CHIRP0_PROG_0, CHIRP0_PROG_1, CHIRP0_PROG_2,
CHIRP1_PROG_0, CHIRP1_PROG_1, CHIRP1_PROG_2
};
u32 chirp_pin_io[] = {
CHIRP0_INT_0, CHIRP0_INT_1, CHIRP0_INT_2,
CHIRP1_INT_0, CHIRP1_INT_1, CHIRP1_INT_2
};
u32 chirp_pin_io_irq[] = {
CHIRP0_INT_0, CHIRP0_INT_1, CHIRP0_INT_2,
CHIRP1_INT_0, CHIRP1_INT_1, CHIRP1_INT_2
};
/* Callback function pointers */
static ch_timer_callback_t periodic_timer_callback_ptr;
static u16 periodic_timer_interval_ms;
/*!
* \brief Initialize board hardware
*
* \note This function performs all necessary initialization on the board.
*/
void chbsp_board_init(struct ch_group_t *grp_ptr)
{
/* Initialize group descriptor */
grp_ptr->num_ports = CHBSP_MAX_DEVICES;
grp_ptr->num_i2c_buses = CHBSP_NUM_I2C_BUSES;
grp_ptr->rtc_cal_pulse_ms = CHBSP_RTC_CAL_PULSE_MS;
ext_int_init();
}
/*!
* \brief Assert the reset pin
*
* This function drives the sensor reset pin low.
*/
void chbsp_reset_assert(void)
{
ioport_set_pin_level(CHIRP_RST, IOPORT_PIN_LEVEL_LOW); //reset low
}
/*!
* \brief De-assert the reset pin
*
* This function drives the sensor reset pin high.
*/
void chbsp_reset_release(void)
{
ioport_set_pin_level(CHIRP_RST, IOPORT_PIN_LEVEL_HIGH); //reset high
}
void chbsp_reset_ps_assert(void)
{
ioport_set_pin_level(CHIRP_RST_PS, IOPORT_PIN_LEVEL_LOW); //reset low
}
/*!
* \brief De-assert the pulse reset pin
*
* This function drives the pulse reset pin high.
*/
void chbsp_reset_ps_release(void)
{
ioport_set_pin_level(CHIRP_RST_PS, IOPORT_PIN_LEVEL_HIGH); //reset high
}
/*!
* \brief Assert the PROG pin
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
*
* This function drives the sensor PROG pin high on the specified port.
*/
void chbsp_program_enable(struct ch_dev_t *dev_ptr)
{
u8 dev_num = ch_get_dev_num(dev_ptr);
// select Chirp chip PROG line according to chip number
ioport_set_pin_level(chirp_pin_prog[dev_num], IOPORT_PIN_LEVEL_HIGH);
}
/*!
* \brief De-assert the PROG pin
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
*
* This function drives the sensor PROG pin low on the specified port.
*/
void chbsp_program_disable(struct ch_dev_t *dev_ptr)
{
u8 dev_num = ch_get_dev_num(dev_ptr);
// select Chirp chip PROGRAM line according to chip number
ioport_set_pin_level(chirp_pin_prog[dev_num], IOPORT_PIN_LEVEL_LOW);
}
/*!
* \brief Configure the Chirp sensor INT pin as an output for one sensor.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
*
* This function configures the Chirp sensor INT pin as an output
* (from the perspective of the host system).
*/
void chbsp_set_io_dir_out(struct ch_dev_t *dev_ptr)
{
u8 dev_num = ch_get_dev_num(dev_ptr);
if (ch_sensor_is_connected(dev_ptr)) {
ioport_set_pin_dir(chirp_pin_io[dev_num],
IOPORT_DIR_OUTPUT);
}
}
/*!
* \brief Configure the Chirp sensor INT pin as an input for one sensor.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
*
* This function configures the Chirp sensor INT pin as an input
* (from the perspective of the host system).
*/
void chbsp_set_io_dir_in(struct ch_dev_t *dev_ptr)
{
u8 dev_num = ch_get_dev_num(dev_ptr);
if (ch_sensor_is_connected(dev_ptr)) {
ioport_set_pin_dir(chirp_pin_io[dev_num],
IOPORT_DIR_INPUT);
}
}
/* Functions supporting controlling int pins of individual sensors
* (originally only controllable in a group)
*/
void chbsp_io_set(struct ch_dev_t *dev_ptr)
{
u8 dev_num = ch_get_dev_num(dev_ptr);
if (ch_sensor_is_connected(dev_ptr)) {
ioport_set_pin_level(chirp_pin_io[dev_num],
IOPORT_PIN_LEVEL_HIGH);
}
}
void chbsp_io_clear(struct ch_dev_t *dev_ptr)
{
u8 dev_num = ch_get_dev_num(dev_ptr);
if (ch_sensor_is_connected(dev_ptr)) {
ioport_set_pin_level(chirp_pin_io[dev_num],
IOPORT_PIN_LEVEL_LOW);
}
}
/*!
* \brief Configure the Chirp sensor INT pins as outputs for a group of sensors
*
* \param grp_ptr pointer to the ch_group_t config structure for
* a group of sensors
*
* This function configures each Chirp sensor's INT pin as an output
* (from the perspective of the host system).
*/
void chbsp_group_set_io_dir_out(struct ch_group_t *grp_ptr)
{
u8 dev_num;
for (dev_num = 0; dev_num < ch_get_num_ports(grp_ptr); dev_num++) {
struct ch_dev_t *dev_ptr = ch_get_dev_ptr(grp_ptr, dev_num);
if (ch_sensor_is_connected(dev_ptr)) {
ioport_set_pin_dir(chirp_pin_io[dev_num],
IOPORT_DIR_OUTPUT); //output pin
}
}
}
/*!
* \brief Configure the Chirp sensor INT pins as inputs for a group of sensors
*
* \param dev_ptr pointer to the ch_group_t config structure for
* a group of sensors
*
* \note This function assumes a bidirectional level shifter is interfacing
*/
void chbsp_group_set_io_dir_in(struct ch_group_t *grp_ptr)
{
u8 dev_num;
for (dev_num = 0; dev_num < ch_get_num_ports(grp_ptr); dev_num++) {
struct ch_dev_t *dev_ptr = ch_get_dev_ptr(grp_ptr, dev_num);
if (ch_sensor_is_connected(dev_ptr)) {
ioport_set_pin_dir(chirp_pin_io[dev_num],
IOPORT_DIR_INPUT); //input pin
}
}
}
/*!
* \brief Initialize the I/O pins.
*
* \param dev_ptr pointer to the ch_group_t config structure for
* a group of sensors
*
* Configure reset and program pins as outputs. Assert reset and program.
* Configure sensor INT pin as input.
*/
void chbsp_group_pin_init(struct ch_group_t *grp_ptr)
{
u8 dev_num;
int i;
for (i = 0; i < ARRAY_SIZE(chirp_pin_prog); i++) {
if (!chirp_pin_enabled[i])
continue;
ioport_set_pin_dir(chirp_pin_prog[i], IOPORT_DIR_OUTPUT);
ioport_set_pin_level(chirp_pin_prog[i], IOPORT_PIN_LEVEL_LOW);
}
ioport_set_pin_dir(CHIRP_RST, IOPORT_DIR_OUTPUT); //reset=output
chbsp_reset_assert();
for (dev_num = 0; dev_num < grp_ptr->num_ports; dev_num++) {
struct ch_dev_t *dev_ptr = ch_get_dev_ptr(grp_ptr, dev_num);
chbsp_program_enable(dev_ptr);
}
/* Initialize IO pins */
chbsp_group_set_io_dir_in(grp_ptr);
}
/*!
* \brief Set the INT pins low for a group of sensors.
*
* \param dev_ptr pointer to the ch_group_t config structure for
* a group of sensors
*
* This function drives the INT line low for each sensor in the group.
*/
void chbsp_group_io_clear(struct ch_group_t *grp_ptr)
{
u8 dev_num;
for (dev_num = 0; dev_num < ch_get_num_ports(grp_ptr); dev_num++) {
struct ch_dev_t *dev_ptr = ch_get_dev_ptr(grp_ptr, dev_num);
if (ch_sensor_is_connected(dev_ptr)) {
ioport_set_pin_level(chirp_pin_io[dev_num],
IOPORT_PIN_LEVEL_LOW);
}
}
}
/*!
* \brief Set the INT pins high for a group of sensors.
*
* \param dev_ptr pointer to the ch_group_t config structure for
* a group of sensors
*
* This function drives the INT line high for each sensor in the group.
*/
void chbsp_group_io_set(struct ch_group_t *grp_ptr)
{
u8 dev_num;
for (dev_num = 0; dev_num < ch_get_num_ports(grp_ptr); dev_num++) {
struct ch_dev_t *dev_ptr = ch_get_dev_ptr(grp_ptr, dev_num);
if (ch_sensor_is_connected(dev_ptr)) {
ioport_set_pin_level(chirp_pin_io[dev_num],
IOPORT_PIN_LEVEL_HIGH);
}
}
}
/*!
* \brief Disable interrupts for a group of sensors
*
* \param dev_ptr pointer to the ch_group_t config structure for
* a group of sensors
*
* For each sensor in the group, this function disables the host interrupt
* associated with the Chirp sensor device's INT line.
*/
void chbsp_group_io_interrupt_enable(struct ch_group_t *grp_ptr)
{
u8 dev_num;
for (dev_num = 0; dev_num < ch_get_num_ports(grp_ptr); dev_num++) {
struct ch_dev_t *dev_ptr = ch_get_dev_ptr(grp_ptr, dev_num);
chbsp_io_interrupt_enable(dev_ptr);
}
}
/*!
* \brief Enable the interrupt for one sensor
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
*
* This function enables the host interrupt associated with the Chirp sensor
* device's INT line.
*/
void chbsp_io_interrupt_enable(struct ch_dev_t *dev_ptr)
{
u8 dev_num = ch_get_dev_num(dev_ptr);
if (ch_sensor_is_connected(dev_ptr)) {
os_clear_interrupt(chirp_pin_io_irq[dev_num]);
os_enable_interrupt(chirp_pin_io_irq[dev_num]);
}
}
/*!
* \brief Disable interrupts for a group of sensors
*
* \param dev_ptr pointer to the ch_group_t config structure for
* a group of sensors
*
* For each sensor in the group, this function disables the host interrupt
* associated with the Chirp sensor device's INT line.
*/
void chbsp_group_io_interrupt_disable(struct ch_group_t *grp_ptr)
{
u8 dev_num;
for (dev_num = 0; dev_num < ch_get_num_ports(grp_ptr); dev_num++) {
struct ch_dev_t *dev_ptr = ch_get_dev_ptr(grp_ptr, dev_num);
chbsp_io_interrupt_disable(dev_ptr);
}
}
/*!
* \brief Disable the interrupt for one sensor
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
*
* This function disables the host interrupt associated with the Chirp sensor
* device's INT line.
*/
void chbsp_io_interrupt_disable(struct ch_dev_t *dev_ptr)
{
u8 dev_num = ch_get_dev_num(dev_ptr);
if (dev_ptr->sensor_connected)
os_disable_interrupt(chirp_pin_io_irq[dev_num]);
}
/*!
* \brief Set callback routine for Chirp sensor I/O interrupt
*
* \param callback_func_ptr pointer to application function to be called
* when interrupt occurs
*
* This function sets up the specified callback routine to be called whenever
* the interrupt associated with the sensor's INT line occurs.
* The callback routine address in stored in a pointer variable that will later
* be accessed from within the interrupt handler to call the function.
*
* The callback function will be called at interrupt level from the interrupt
* service routine.
*/
void chbsp_io_callback_set(ch_io_int_callback_t callback_func_ptr)
{
}
/*!
* \brief Delay for specified number of microseconds
*
* \param us number of microseconds to delay before returning
*
* This function waits for the specified number of microseconds before
* returning to the caller.
*/
void chbsp_delay_us(u32 us)
{
os_delay_us(us);
}
/*!
* \brief Delay for specified number of milliseconds.
*
* \param ms number of milliseconds to delay before returning
*
* This function waits for the specified number of milliseconds before
* returning to the caller.
*/
void chbsp_delay_ms(u32 ms)
{
os_delay_ms(ms);
}
/*!
* \brief Initialize the host's I2C hardware.
*
* \return 0 if successful, 1 on error
*
* This function performs general I2C initialization on the host system.
*/
int chbsp_i2c_init(void)
{
i2c_master_init();
return 0;
}
int chbsp_i2c_deinit(void)
{
return 0;
}
/*!
* \brief Return I2C information for a sensor port on the board.
*
* \param dev_ptr pointer to the ch_group_t config structure for
* a group of sensors
* \param dev_num device number within sensor group
* \param info_ptr pointer to structure to be filled with I2C config values
*
* \return 0 if successful, 1 if error
*
* This function returns I2C values in the ch_i2c_info_t structure specified by
* \a info_ptr.
* The structure includes three fields.
* - The \a address field contains the I2C address for the sensor.
* - The \a bus_num field contains the I2C bus number (index).
* - The \a drv_flags field contains various bit flags through which the BSP
* can inform
* SonicLib driver functions to perform specific actions during
* I2C I/O operations.
*/
u8 chbsp_i2c_get_info(struct ch_group_t *grp_ptr, u8 io_index,
struct ch_i2c_info_t *info_ptr)
{
u8 ret_val = 1;
if (io_index < CHBSP_MAX_DEVICES) {
info_ptr->address = chirp_i2c_addrs[io_index];
info_ptr->bus_num = chirp_i2c_buses[io_index];
// no special I2C handling by SonicLib driver is needed
info_ptr->drv_flags = 0;
ret_val = 0;
}
return ret_val;
}
/*!
* \brief Write bytes to an I2C slave.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
* \param data data to be transmitted
* \param num_bytes length of data to be transmitted
*
* \return 0 if successful, 1 on error or NACK
*
* This function writes one or more bytes of data to an I2C slave device.
* The I2C interface must have already been initialized using chbsp_i2c_init().
*/
int chbsp_i2c_write(struct ch_dev_t *dev_ptr, u8 *data, u16 num_bytes)
{
int bytes = 0;
if (dev_ptr->i2c_bus_index == 0) {
bytes = i2c_master_write_register0_sync(dev_ptr->i2c_address,
num_bytes, data); //I2C bus 0
} else if (dev_ptr->i2c_bus_index == 1) {
bytes = i2c_master_write_register1_sync(dev_ptr->i2c_address,
num_bytes, data); //I2C bus 1
} else if (dev_ptr->i2c_bus_index == 2) {
bytes = i2c_master_write_register2_sync(dev_ptr->i2c_address,
num_bytes, data); //I2C bus 2
}
return (bytes != num_bytes);
}
/*!
* \brief Write bytes to an I2C slave using memory addressing.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
* \param mem_addr internal memory or register address within device
* \param data data to be transmitted
* \param num_bytes length of data to be transmitted
*
* \return 0 if successful, 1 on error or NACK
*
* This function writes one or more bytes of data to an I2C slave device using
* an internal memory or register address. The remote device will write
* \a num_bytes bytes of data starting at internal memory/register address
* \a mem_addr.
* The I2C interface must have already been initialized using chbsp_i2c_init().
*/
int chbsp_i2c_mem_write(struct ch_dev_t *dev_ptr, u16 mem_addr, u8 *data,
u16 num_bytes)
{
int error = 0;
if (dev_ptr->i2c_bus_index == 0) {
// I2C bus 0
error = i2c_master_write_register0(dev_ptr->i2c_address,
(unsigned char)mem_addr, num_bytes, data);
} else if (dev_ptr->i2c_bus_index == 1) {
// I2C bus 1
error = i2c_master_write_register1(dev_ptr->i2c_address,
(unsigned char)mem_addr, num_bytes, data);
} else if (dev_ptr->i2c_bus_index == 2) {
// I2C bus 2
error = i2c_master_write_register2(dev_ptr->i2c_address,
(unsigned char)mem_addr, num_bytes, data);
}
return error;
}
/*!
* \brief Write bytes to an I2C slave, non-blocking.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
* \param data pointer to the start of data to be transmitted
* \param num_bytes length of data to be transmitted
*
* \return 0 if successful, 1 on error or NACK
*
* This function initiates a non-blocking write of the specified number
* of bytes to an I2C slave device.
*
* The I2C interface must have already been initialized using chbsp_i2c_init().
*/
int chbsp_i2c_write_nb(struct ch_dev_t *dev_ptr, u8 *data, u16 num_bytes)
{
// XXX not implemented
return 1;
}
/*!
* \brief Write bytes to an I2C slave using memory addressing, non-blocking.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
* \param mem_addr internal memory or register address within device
* \param data pointer to the start of data to be transmitted
* \param num_bytes length of data to be transmitted
*
* \return 0 if successful, 1 on error or NACK
*
* This function initiates a non-blocking write of the specified number of bytes
* to an I2C slave device, using an internal memory or register address.
* The remote device will write \a num_bytes bytes of data starting at internal
* memory/register address \a mem_addr.
*
* The I2C interface must have already been initialized using chbsp_i2c_init().
*/
int chbsp_i2c_mem_write_nb(struct ch_dev_t *dev_ptr, u16 mem_addr, u8 *data,
u16 num_bytes)
{
// XXX not implemented
return 1;
}
/*!
* \brief Read bytes from an I2C slave.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
* \param data pointer to receive data buffer
* \param num_bytes number of bytes to read
*
* \return 0 if successful, 1 on error or NACK
*
* This function reads the specified number of bytes from an I2C slave device.
* The I2C interface must have already been initialized using chbsp_i2c_init().
*/
int chbsp_i2c_read(struct ch_dev_t *dev_ptr, u8 *data, u16 num_bytes)
{
int bytes = 0;
u8 i2c_addr = ch_get_i2c_address(dev_ptr);
u8 bus_num = ch_get_i2c_bus(dev_ptr);
if (bus_num == 0) {
// I2C bus 0
bytes = i2c_master_read_register0_sync(i2c_addr, num_bytes,
data);
} else if (bus_num == 1) {
// I2C bus 1
bytes = i2c_master_read_register1_sync(i2c_addr, num_bytes,
data);
} else if (bus_num == 2) {
// I2C bus 2
bytes = i2c_master_read_register2_sync(i2c_addr, num_bytes,
data);
}
return (bytes != num_bytes);
}
/*!
* \brief Read bytes from an I2C slave using memory addressing.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
* \param mem_addr internal memory or register address within device
* \param data pointer to receive data buffer
* \param num_bytes number of bytes to read
*
* \return 0 if successful, 1 on error or NACK
*
* This function reads the specified number of bytes from an I2C slave device,
* using an internal memory or register address. The remote device will return
* \a num_bytes bytes starting at internal memory/register address \a mem_addr.
*
* The I2C interface must have already been initialized using chbsp_i2c_init().
*/
int chbsp_i2c_mem_read(struct ch_dev_t *dev_ptr, u16 mem_addr, u8 *data,
u16 num_bytes)
{
int error = 1; // default is error return
u8 i2c_addr = ch_get_i2c_address(dev_ptr);
u8 bus_num = ch_get_i2c_bus(dev_ptr);
if (bus_num == 0) {
// I2C bus 0
error = i2c_master_read_register0(i2c_addr,
(unsigned char)mem_addr, num_bytes, data);
} else if (bus_num == 1) {
// I2C bus 1
error = i2c_master_read_register1(i2c_addr,
(unsigned char)mem_addr, num_bytes, data);
} else if (bus_num == 2) {
// I2C bus 2
error = i2c_master_read_register2(i2c_addr,
(unsigned char)mem_addr, num_bytes, data);
}
return error;
}
/*!
* \brief Read bytes from an I2C slave, non-blocking.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
* \param data pointer to receive data buffer
* \param num_bytes number of bytes to read
*
* \return 0 if successful, 1 on error or NACK
*
* This function initiates a non-blocking read of the specified number of bytes
* from an I2C slave.
*
* The I2C interface must have already been initialized using chbsp_i2c_init().
*/
int chbsp_i2c_read_nb(struct ch_dev_t *dev_ptr, u8 *data, u16 num_bytes)
{
int error = 0;
error = chbsp_i2c_read(dev_ptr, data, num_bytes);
return error;
}
/*!
* \brief Read bytes from an I2C slave using memory addressing, non-blocking.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
* \param mem_addr internal memory or register address within device
* \param data pointer to receive data buffer
* \param num_bytes number of bytes to read
*
* \return 0 if successful, 1 on error or NACK
*
* This function initiates a non-blocking read of the specified number of bytes
* from an I2C slave.
*
* The I2C interface must have already been initialized using chbsp_i2c_init().
*/
int chbsp_i2c_mem_read_nb(struct ch_dev_t *dev_ptr, u16 mem_addr, u8 *data,
u16 num_bytes)
{
int bytes = 0;
u8 i2c_addr = ch_get_i2c_address(dev_ptr);
u8 bus_num = ch_get_i2c_bus(dev_ptr);
if (bus_num == 0) {
// I2C bus 0
bytes = i2c_master_read_register0_nb(i2c_addr, num_bytes, data);
} else if (bus_num == 1) {
// I2C bus 1
bytes = i2c_master_read_register1_nb(i2c_addr, num_bytes, data);
} else if (bus_num == 2) {
// I2C bus 2
bytes = i2c_master_read_register2_nb(i2c_addr, num_bytes, data);
}
return (bytes != num_bytes);
}
/*!
* \brief Reset I2C bus associated with device.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
*
* This function performs a reset of the I2C interface for the specified device.
*/
void chbsp_i2c_reset(struct ch_dev_t *dev_ptr)
{
u8 bus_num = ch_get_i2c_bus(dev_ptr);
if (bus_num == 0) // I2C bus 0
i2c_master_initialize0();
else if (bus_num == 1) // I2C bus 1
i2c_master_initialize1();
else if (bus_num == 2) // I2C bus 2
i2c_master_initialize2();
}
/*!
* \brief Initialize periodic timer.
*
* \param interval_ms timer interval, in milliseconds
* \param callback_func_ptr address of routine to be called every time the
* timer expires
*
* \return 0 if successful, 1 if error
*
* This function initializes a periodic timer on the board. The timer is
* programmed to generate an interrupt after every \a interval_ms milliseconds.
*
* The \a callback_func_ptr parameter specifies a callback routine that will be
* called when the timer expires (and interrupt occurs).
* The \a chbsp_periodic_timer_handler function will call this function.
*/
u8 chbsp_periodic_timer_init(u16 interval_ms,
ch_timer_callback_t callback_func_ptr)
{
/* Save timer interval and callback function */
periodic_timer_interval_ms = interval_ms;
periodic_timer_callback_ptr = callback_func_ptr;
return 0;
}
/*!
* \brief Enable periodic timer interrupt.
*
* This function enables the interrupt associated with the periodic timer
* initialized by \a chbsp_periodic_timer_init().
*/
void chbsp_periodic_timer_irq_enable(void)
{
}
/*!
* \brief Disable periodic timer interrupt.
*
* This function enables the interrupt associated with the periodic timer
* initialized by \a chbsp_periodic_timer_init().
*/
void chbsp_periodic_timer_irq_disable(void)
{
}
/*!
* \brief Start periodic timer.
*
* \return 0 if successful, 1 if error
*
* This function starts the periodic timer initialized by
* \a chbsp_periodic_timer_init().
*/
u8 chbsp_periodic_timer_start(void)
{
return 0;
}
/*!
* \brief Periodic timer handler.
*
* \return 0 if successful, 1 if error
*
* This function handles the expiration of the periodic timer, re-arms it and
* any associated interrupts for the next interval, and calls the callback
* routine that was registered using \a chbsp_periodic_timer_init().
*/
void chbsp_periodic_timer_handler(void)
{
ch_timer_callback_t func_ptr = periodic_timer_callback_ptr;
chbsp_periodic_timer_start();
if (func_ptr != NULL)
(*func_ptr)(); // call application timer callback routine
chbsp_periodic_timer_irq_enable();
}
/*!
* \brief Turn on an LED on the board.
*
* This function turns on an LED on the board.
*
* The \a dev_num parameter contains the device number of a specific sensor.
* This routine will turn on the LED on the Chirp sensor daughterboard that
* is next to the specified sensor.
*/
void chbsp_led_on(u8 led_num)
{
}
/*!
* \brief Turn off an LED on the board.
*
* This function turns off an LED on the board.
*
* The \a dev_num parameter contains the device number of a specific sensor.
* This routine will turn off the LED on the Chirp sensor daughterboard that
* is next to the specified sensor.
*/
void chbsp_led_off(u8 led_num)
{
}
u32 chbsp_timestamp_ms(void)
{
return (u32)os_timestamp_ms();
}
void chbsp_print_str(char *str)
{
os_print_str(str);
}

View File

@@ -0,0 +1,70 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2020 InvenSense, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef CHBSPINIT_H_
#define CHBSPINIT_H_
#include "system.h"
#include "chirp_board_config.h"
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif
#define CHIRP_RST 1
#define CHIRP_RST_PS 2
#define CHIRP0_PROG_0 10
#define CHIRP0_PROG_1 11
#define CHIRP0_PROG_2 12
#define CHIRP1_PROG_0 13
#define CHIRP1_PROG_1 14
#define CHIRP1_PROG_2 15
#define CHIRP2_PROG_0 16
#define CHIRP2_PROG_1 17
#define CHIRP2_PROG_2 18
#define CHIRP0_INT_0 20
#define CHIRP0_INT_1 21
#define CHIRP0_INT_2 22
#define CHIRP1_INT_0 23
#define CHIRP1_INT_1 24
#define CHIRP1_INT_2 25
#define CHIRP2_INT_0 26
#define CHIRP2_INT_1 27
#define CHIRP2_INT_2 28
/* Standard symbols used in BSP - use values from config header */
#define CHBSP_MAX_DEVICES CHIRP_MAX_NUM_SENSORS
#define CHBSP_NUM_I2C_BUSES CHIRP_NUM_I2C_BUSES
/* RTC hardware pulse pin */
#define CHBSP_RTC_CAL_PULSE_PIN 1
/* Length of real-time clock calibration pulse, in milliseconds */
/* Length of pulse applied to sensor INT line during clock cal */
#define CHBSP_RTC_CAL_PULSE_MS 63
/* I2C Address assignments for each possible device */
#define CHIRP_I2C_ADDRS {45, 43, 44, 52, 53, 54} //, 62, 63, 64}
#define CHIRP_I2C_BUSES {0, 0, 0, 1, 1, 1} //, 2, 2, 2}
extern u8 chirp_i2c_addrs[CHBSP_MAX_DEVICES];
extern u8 chirp_i2c_buses[CHBSP_MAX_DEVICES];
extern u32 chirp_pin_enabled[CHBSP_MAX_DEVICES];
extern u32 chirp_pin_prog[CHBSP_MAX_DEVICES];
extern u32 chirp_pin_io[CHBSP_MAX_DEVICES];
extern u32 chirp_pin_io_irq[CHBSP_MAX_DEVICES];
#endif /* CHBSPINIT_H_ */

View File

@@ -0,0 +1,34 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* chirp_board_config.h
*
* This file defines required symbols used to build an application with the
* Chirp SonicLib API and driver. These symbols are used for static array
* allocations and counters in SonicLib (and often applications), and are based
* on the number of specific resources on the target board.
*
* Two symbols must be defined:
* CHIRP_MAX_NUM_SENSORS - the number of possible sensor devices
* (i.e. the number of sensor ports)
* CHIRP_NUM_I2C_BUSES - the number of I2C buses on the board that are
* used for those sensor ports
*
* This file must be in the C pre-processor include path when the application
* is built with SonicLib and this board support package.
*/
#ifndef CHIRP_BOARD_CONFIG_H_
#define CHIRP_BOARD_CONFIG_H_
/* Settings for the Chirp RB5 board */
/* maximum possible number of sensor devices */
#define CHIRP_MAX_NUM_SENSORS 6
/* number of I2C buses used by sensors */
#define CHIRP_NUM_I2C_BUSES 2
#define CH101_MAX_PORTS CHIRP_MAX_NUM_SENSORS
#define CH101_I2C_BUSES CHIRP_NUM_I2C_BUSES
#define CH101_PORTS_PER_BUSES 3
#define CH101_MAX_I2C_QUEUE_LENGTH 12
#endif /* CHIRP_BOARD_CONFIG_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,272 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2020 InvenSense, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/gpio/driver.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/gpio/consumer.h>
#include <linux/export.h>
#include <linux/timekeeping.h>
#include <linux/delay.h>
#include <linux/printk.h>
#include <linux/time.h>
#include <asm/div64.h>
#include "chirp_hal.h"
#include "chbsp_init.h"
static struct ch101_client *_ch101_client;
void set_chirp_gpios(struct ch101_client *client)
{
_ch101_client = client;
printf("%s: data: %p\n", __func__, _ch101_client);
}
struct ch101_client *get_chirp_gpios(void)
{
return _ch101_client;
}
struct gpio_desc *os_get_pin_desc(ioport_pin_t pin)
{
if (!_ch101_client)
return 0;
if (pin == CHIRP_RST)
return _ch101_client->gpios.gpiod_rst;
if (pin == CHIRP_RST_PS)
return _ch101_client->gpios.gpiod_rst_pulse;
if (pin == CHIRP0_INT_0)
return _ch101_client->bus[0].gpiod_int[0];
if (pin == CHIRP0_INT_1)
return _ch101_client->bus[0].gpiod_int[1];
if (pin == CHIRP0_INT_2)
return _ch101_client->bus[0].gpiod_int[2];
if (pin == CHIRP1_INT_0)
return _ch101_client->bus[1].gpiod_int[0];
if (pin == CHIRP1_INT_1)
return _ch101_client->bus[1].gpiod_int[1];
if (pin == CHIRP1_INT_2)
return _ch101_client->bus[1].gpiod_int[2];
if (pin >= CHIRP0_PROG_0 && pin <= CHIRP2_PROG_2)
return 0;
printf("%s: pin: %d undefined\n", __func__, (u32)pin);
return 0;
}
u32 os_get_pin_prog(ioport_pin_t pin)
{
if (!_ch101_client)
return 0;
if (pin == CHIRP0_PROG_0)
return _ch101_client->bus[0].gpio_exp_prog_pin[0];
if (pin == CHIRP0_PROG_1)
return _ch101_client->bus[0].gpio_exp_prog_pin[1];
if (pin == CHIRP0_PROG_2)
return _ch101_client->bus[0].gpio_exp_prog_pin[2];
if (pin == CHIRP1_PROG_0)
return _ch101_client->bus[1].gpio_exp_prog_pin[0];
if (pin == CHIRP1_PROG_1)
return _ch101_client->bus[1].gpio_exp_prog_pin[1];
if (pin == CHIRP1_PROG_2)
return _ch101_client->bus[1].gpio_exp_prog_pin[2];
printf("%s: pin: %d undefined\n", __func__, (u32)pin);
return 0;
}
void prog_set_dir(ioport_pin_t pin, enum ioport_direction dir)
{
struct ch101_client *data = get_chirp_data();
if (data && data->cbk->set_pin_dir)
data->cbk->set_pin_dir(pin, dir);
}
void prog_set_level(ioport_pin_t pin, bool level)
{
struct ch101_client *data = get_chirp_data();
if (data && data->cbk->set_pin_level)
data->cbk->set_pin_level(pin, level);
}
void ioport_set_pin_dir(ioport_pin_t pin, enum ioport_direction dir)
{
if (pin >= CHIRP0_PROG_0 && pin <= CHIRP2_PROG_2) {
u32 prog_pin;
prog_pin = os_get_pin_prog(pin);
// printf("%s: prog_pin: %d dir: %d\n",
// __func__, prog_pin, dir);
prog_set_dir(prog_pin, dir);
} else {
struct gpio_desc *desc;
desc = os_get_pin_desc(pin);
// printf("%s: pin: %d(%p) dir: %d\n",
// __func__, pin, desc, dir);
if (!desc) {
printf("%s: pin: %d(%p) NULL\n",
__func__, pin, desc);
return;
}
if (dir == IOPORT_DIR_INPUT)
gpiod_direction_input(desc);
else
gpiod_direction_output(desc, 0);
}
}
void ioport_set_pin_level(ioport_pin_t pin, bool level)
{
if (pin >= CHIRP0_PROG_0 && pin <= CHIRP2_PROG_2) {
u32 prog_pin;
prog_pin = os_get_pin_prog(pin);
// printf("%s: prog_pin: %d level: %d\n",
// __func__, prog_pin, level);
prog_set_level(prog_pin, level);
} else {
struct gpio_desc *desc;
desc = os_get_pin_desc(pin);
// printf("%s: pin: %d(%p) level: %d\n",
// __func__, pin, desc, level);
if (!desc) {
printf("%s: pin: %d(%p) NULL\n",
__func__, pin, desc);
return;
}
gpiod_set_value_cansleep(desc, level);
}
// ioport_get_pin_level(pin);
}
enum ioport_direction ioport_get_pin_dir(ioport_pin_t pin)
{
enum ioport_direction dir = IOPORT_DIR_INPUT;
if (pin >= CHIRP0_PROG_0 && pin <= CHIRP2_PROG_2) {
//u32 prog_pin;
//prog_pin = os_get_pin_prog(pin);
//dir = prog_get_dir(prog_pin);
} else {
struct gpio_desc *desc;
desc = os_get_pin_desc(pin);
if (!desc) {
printf("%s: pin: %d(%p) NULL\n",
__func__, pin, desc);
return dir;
}
dir = gpiod_get_direction(desc);
// printf("%s: pin: %d(%p) dir: %d\n", __func__, pin, desc, dir);
}
return dir;
}
bool ioport_get_pin_level(ioport_pin_t pin)
{
bool level = false;
if (pin >= CHIRP0_PROG_0 && pin <= CHIRP2_PROG_2) {
//u32 prog_pin;
//prog_pin = os_get_pin_prog(pin);
//level = prog_set_level(prog_pin, level);
} else {
struct gpio_desc *desc;
desc = os_get_pin_desc(pin);
if (!desc) {
printf("%s: pin: %d(%p) NULL\n",
__func__, pin, desc);
return level;
}
level = gpiod_get_value_cansleep(desc);
}
return level;
}
int32_t os_enable_interrupt(const uint32_t pin)
{
struct gpio_desc *desc = os_get_pin_desc(pin);
unsigned int irq = gpiod_to_irq(desc);
struct ch101_client *data = get_chirp_data();
printf("%s: irq: %d\n", __func__, irq);
if (data && data->cbk->setup_int_gpio)
data->cbk->setup_int_gpio(data, pin);
return 0;
}
int32_t os_disable_interrupt(const uint32_t pin)
{
struct gpio_desc *desc = os_get_pin_desc(pin);
unsigned int irq = gpiod_to_irq(desc);
struct ch101_client *data = get_chirp_data();
printf("%s: irq: %d\n", __func__, irq);
if (data && data->cbk->free_int_gpio)
data->cbk->free_int_gpio(data, pin);
return 0;
}
void os_clear_interrupt(const uint32_t pin)
{
}
// delay in microseconds
void os_delay_us(const uint16_t us)
{
usleep_range(us, us + 1);
}
// delay in miliseconds
void os_delay_ms(const uint16_t ms)
{
msleep(ms);
}
u64 os_timestamp_ns(void)
{
struct timespec ts;
get_monotonic_boottime(&ts);
return timespec_to_ns(&ts);
}
u64 os_timestamp_ms(void)
{
u64 ns = os_timestamp_ns();
u32 div = 1e6;
return div64_ul(ns, div);
}
void os_print_str(char *str)
{
printf("%s", str);
}

View File

@@ -0,0 +1,43 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2020 InvenSense, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef CHIRPHAL_H
#define CHIRPHAL_H
#include "system.h"
#include "init_driver.h"
#include "chirp_hal.h"
#include "../ch101_client.h"
void ioport_set_pin_dir(ioport_pin_t pin, enum ioport_direction dir);
void ioport_set_pin_level(ioport_pin_t pin, bool level);
enum ioport_direction ioport_get_pin_dir(ioport_pin_t pin);
bool ioport_get_pin_level(ioport_pin_t pin);
int32_t os_enable_interrupt(const u32 pin);
int32_t os_disable_interrupt(const u32 pin);
void os_clear_interrupt(const u32 pin);
void os_delay_us(const u16 us);
void os_delay_ms(const u16 ms);
uint64_t os_timestamp_ms(void);
void set_chirp_gpios(struct ch101_client *client);
void os_print_str(char *str);
#endif /* CHIRPHAL_H */

View File

@@ -0,0 +1,258 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2020 InvenSense, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/i2c.h>
#include "i2c_hal.h"
#include "chirp_hal.h"
#include "init_driver.h"
#include "../ch101_client.h"
unsigned long i2c_master_read_register(int bus_index, unsigned char Address,
unsigned char RegAddr, unsigned short RegLen,
unsigned char *RegValue)
{
int res = 0;
struct ch101_client *data = get_chirp_data();
const void *client = data->bus[bus_index].i2c_client;
// printf("%s: Address: %02x, RegAddr: %02x, RegLen: %d\n",
// __func__, (u16)Address, (u8)RegAddr, (u16)RegLen);
res = data->cbk->read_reg((void *)client, (u16)Address, (u8)RegAddr,
(u16)RegLen, (u8 *)RegValue);
if (res)
printf("%s: res: %d", __func__, res);
// {
// int i;
// printf("Read Values: ");
// for (i = 0; i < (RegLen < 3 ? RegLen : 3); i++)
// printf(" %02x ", *(u8 *)(RegValue + i));
// printf("\n");
// }
return res;
}
unsigned long i2c_master_write_register(int bus_index, unsigned char Address,
unsigned char RegAddr, unsigned short RegLen,
unsigned char *RegValue)
{
int res = 0;
struct ch101_client *data = get_chirp_data();
const void *client = data->bus[bus_index].i2c_client;
// printf("%s: Address: %02x, RegAddr: %02x, RegLen: %d\n",
// __func__, (u16)Address, (u8)RegAddr, (u16)RegLen);
//
// {
// int i;
// printf("Write Values: ");
// for (i = 0; i < (RegLen < 3 ? RegLen : 3); i++)
// printf(" %02x ", *(u8 *)(RegValue + i));
// printf("\n");
// }
res = data->cbk->write_reg((void *)client, (u16)Address, (u8)RegAddr,
(u16)RegLen, (u8 *)RegValue);
if (res)
printf("%s: res: %d", __func__, res);
return res;
}
unsigned long i2c_master_read_sync(int bus_index, unsigned char Address,
unsigned short RegLen, unsigned char *RegValue)
{
int res = 0;
struct ch101_client *data = get_chirp_data();
const void *client = data->bus[bus_index].i2c_client;
// printf("%s: start\n", __func__);
//
// printf("%s: Address: %02x, RegAddr: %02x, RegLen: %d\n",
// __func__, (u16)Address, (u16)RegLen);
res = data->cbk->read_sync((void *)client, (u16)Address,
(u16)RegLen, (u8 *)RegValue);
if (res)
printf("%s: res: %d", __func__, res);
// {
// int i;
// printf("Read Values: ");
// for (i = 0; i < (RegLen < 3 ? RegLen : 3); i++)
// printf(" %02x ", *(u8 *)(RegValue + i));
// printf("\n");
// }
return (res == 0 ? RegLen : res);
}
unsigned long i2c_master_write_sync(int bus_index, unsigned char Address,
unsigned short RegLen, unsigned char *RegValue)
{
int res = 0;
struct ch101_client *data = get_chirp_data();
const void *client = data->bus[bus_index].i2c_client;
// printf("%s: Address: %02x, RegLen: %d\n",
// __func__, (u16)Address, (u16)RegLen);
//
// {
// int i;
// printf("Write Values: ");
// for (i = 0; i < (RegLen < 3 ? RegLen : 3); i++)
// printf(" %02x ", *(u8 *)(RegValue + i));
// printf("\n");
// }
res = data->cbk->write_sync((void *)client, (u16)Address,
(u16)RegLen, (u8 *)RegValue);
if (res)
printf("%s: res: %d", __func__, res);
return (res == 0 ? RegLen : res);
}
////////////////////////////////////////////////////////////////////////////////
unsigned long i2c_master_read_register0(unsigned char Address,
unsigned char RegAddr, unsigned short RegLen,
unsigned char *RegValue)
{
return i2c_master_read_register(0, Address, RegAddr, RegLen, RegValue);
}
unsigned long i2c_master_read_register1(unsigned char Address,
unsigned char RegAddr, unsigned short RegLen,
unsigned char *RegValue)
{
return i2c_master_read_register(1, Address, RegAddr, RegLen, RegValue);
}
unsigned long i2c_master_read_register2(unsigned char Address,
unsigned char RegAddr, unsigned short RegLen,
unsigned char *RegValue)
{
return i2c_master_read_register(2, Address, RegAddr, RegLen, RegValue);
}
////////////////////////////////////////////////////////////////////////////////
unsigned long i2c_master_write_register0(unsigned char Address,
unsigned char RegAddr, unsigned short RegLen,
unsigned char *RegValue)
{
return i2c_master_write_register(0, Address, RegAddr, RegLen, RegValue);
}
unsigned long i2c_master_write_register1(unsigned char Address,
unsigned char RegAddr, unsigned short RegLen,
unsigned char *RegValue)
{
return i2c_master_write_register(1, Address, RegAddr, RegLen, RegValue);
}
unsigned long i2c_master_write_register2(unsigned char Address,
unsigned char RegAddr, unsigned short RegLen,
unsigned char *RegValue)
{
return i2c_master_write_register(2, Address, RegAddr, RegLen, RegValue);
}
////////////////////////////////////////////////////////////////////////////////
unsigned long i2c_master_read_register0_sync(unsigned char Address,
unsigned short RegLen, unsigned char *RegValue)
{
return i2c_master_read_sync(0, Address, RegLen, RegValue);
}
unsigned long i2c_master_read_register1_sync(unsigned char Address,
unsigned short RegLen, unsigned char *RegValue)
{
return i2c_master_read_sync(1, Address, RegLen, RegValue);
}
unsigned long i2c_master_read_register2_sync(unsigned char Address,
unsigned short RegLen, unsigned char *RegValue)
{
return i2c_master_read_sync(2, Address, RegLen, RegValue);
}
////////////////////////////////////////////////////////////////////////////////
unsigned long i2c_master_read_register0_nb(unsigned char Address,
unsigned short RegLen, unsigned char *RegValue)
{
return i2c_master_read_sync(0, Address, RegLen, RegValue);
}
unsigned long i2c_master_read_register1_nb(unsigned char Address,
unsigned short RegLen, unsigned char *RegValue)
{
return i2c_master_read_sync(1, Address, RegLen, RegValue);
}
unsigned long i2c_master_read_register2_nb(unsigned char Address,
unsigned short RegLen, unsigned char *RegValue)
{
return i2c_master_read_sync(2, Address, RegLen, RegValue);
}
////////////////////////////////////////////////////////////////////////////////
unsigned long i2c_master_write_register0_sync(unsigned char Address,
unsigned short RegLen, unsigned char *RegValue)
{
return i2c_master_write_sync(0, Address, RegLen, RegValue);
}
unsigned long i2c_master_write_register1_sync(unsigned char Address,
unsigned short RegLen, unsigned char *RegValue)
{
return i2c_master_write_sync(1, Address, RegLen, RegValue);
}
unsigned long i2c_master_write_register2_sync(unsigned char Address,
unsigned short RegLen, unsigned char *RegValue)
{
return i2c_master_write_sync(2, Address, RegLen, RegValue);
}
void i2c_master_initialize0(void)
{
}
void i2c_master_initialize1(void)
{
}
void i2c_master_initialize2(void)
{
}
void i2c_master_init(void)
{
i2c_master_initialize0();
i2c_master_initialize1();
i2c_master_initialize2();
}
void ext_int_init(void)
{
}

View File

@@ -0,0 +1,66 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2020 InvenSense, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef I2CHAL_H
#define I2CHAL_H
unsigned long i2c_master_read_register0(unsigned char Address,
unsigned char RegisterAddr, unsigned short RegisterLen,
unsigned char *RegisterValue);
unsigned long i2c_master_read_register1(unsigned char Address,
unsigned char RegisterAddr, unsigned short RegisterLen,
unsigned char *RegisterValue);
unsigned long i2c_master_read_register2(unsigned char Address,
unsigned char RegisterAddr, unsigned short RegisterLen,
unsigned char *RegisterValue);
unsigned long i2c_master_read_register0_sync(unsigned char Address,
unsigned short RegisterLen, unsigned char *RegisterValue);
unsigned long i2c_master_read_register1_sync(unsigned char Address,
unsigned short RegisterLen, unsigned char *RegisterValue);
unsigned long i2c_master_read_register2_sync(unsigned char Address,
unsigned short RegisterLen, unsigned char *RegisterValue);
unsigned long i2c_master_read_register0_nb(unsigned char Address,
unsigned short RegisterLen, unsigned char *RegisterValue);
unsigned long i2c_master_read_register1_nb(unsigned char Address,
unsigned short RegisterLen, unsigned char *RegisterValue);
unsigned long i2c_master_read_register2_nb(unsigned char Address,
unsigned short RegisterLen, unsigned char *RegisterValue);
unsigned long i2c_master_write_register0(unsigned char Address,
unsigned char RegisterAddr, unsigned short RegisterLen,
unsigned char *RegisterValue);
unsigned long i2c_master_write_register1(unsigned char Address,
unsigned char RegisterAddr, unsigned short RegisterLen,
unsigned char *RegisterValue);
unsigned long i2c_master_write_register2(unsigned char Address,
unsigned char RegisterAddr, unsigned short RegisterLen,
unsigned char *RegisterValue);
unsigned long i2c_master_write_register0_sync(unsigned char Address,
unsigned short RegisterLen, unsigned char *RegisterValue);
unsigned long i2c_master_write_register1_sync(unsigned char Address,
unsigned short RegisterLen, unsigned char *RegisterValue);
unsigned long i2c_master_write_register2_sync(unsigned char Address,
unsigned short RegisterLen, unsigned char *RegisterValue);
void i2c_master_initialize0(void);
void i2c_master_initialize1(void);
void i2c_master_initialize2(void);
void i2c_master_init(void);
void ext_int_init(void);
#endif /* I2CHAL_H */

View File

@@ -0,0 +1,259 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2016-2019, Chirp Microsystems. All rights reserved.
*
* Chirp Microsystems CONFIDENTIAL
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL CHIRP MICROSYSTEMS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef IDLPROTOCOL_H_
#define IDLPROTOCOL_H_
#include <stdint.h>
#define IDL_PACKET_DEFAULTDATASIZE 1
#define IDL_PACKET_INVALID 0x00
#define IDL_PACKET_FWVERSION 0x01
#define IDL_PACKET_SINGLEREGREAD 0x02
#define IDL_PACKET_SINGLEREGWRITE 0x03
#define IDL_PACKET_MULREGREAD 0x04
#define IDL_PACKET_MULREGWRITE 0x05
#define IDL_PACKET_RESET 0x06
#define IDL_PACKET_OPENSENSOR 0x07
#define IDL_PACKET_CLOSESENSOR 0x08
#define IDL_PACKET_ENABLEDATABUF 0x09
#define IDL_PACKET_GETDATABUF 0x0A
#define IDL_PACKET_DISABLEDATABUF 0x0B
#define IDL_PACKET_RAWREAD 0x0C
#define IDL_PACKET_RAWWRITE 0x0D
#define IDL_PACKET_OPENSENSORSEC 0x0E
#define IDL_PACKET_CUSTOMSENSINIT 0x0F
#define IDL_SENSORID_ERROR 0x00
#define IDL_SENSORID_OK 0x01
#define IDL_INTERFACEID_I2C 0
#define IDL_INTERFACEID_SPI1 1
#define IDL_INTERFACEID_SPI2 2
#define IDL_PACKET_RESULT_ERROR 0x00
#define IDL_PACKET_RAWREADSIZE 9 //max size
#define IDL_PACKET_RAWWRITESIZE 5 //max size
/* HEADER */
struct IDLP_HEADER {
u8 size;
u8 size1;
u8 packetid;
};
/* FWVERSION */
struct IDLPREQ_FWVERSION {
struct IDLP_HEADER header;
};
struct IDLPRSP_FWVERSION {
struct IDLP_HEADER header;
u8 major;
u8 minor;
u8 build;
};
/* ** RESET * */
struct IDLPREQ_RESET {
struct IDLP_HEADER header;
};
struct IDLPRSP_RESET {
struct IDLP_HEADER header;
};
/* REGREAD */
struct IDLPREQ_REGREAD {
struct IDLP_HEADER header;
u8 sensorid;
u8 addr;
};
struct IDLPRSP_REGREAD {
struct IDLP_HEADER header;
u8 sensorid;
u8 addr;
u8 value;
};
/* REGWRITE */
struct IDLPREQ_REGWRITE {
struct IDLP_HEADER header;
u8 sensorid;
u8 addr;
u8 value;
};
struct IDLPRSP_REGWRITE {
struct IDLP_HEADER header;
u8 sensorid;
u8 addr;
u8 result;
};
/* OPENSENSOR */
struct IDLPREQ_OPENSENSOR {
struct IDLP_HEADER header;
u8 interfaceid;
u8 intopt;
u8 options;
};
struct IDLPREQ_OPENSENSORSEC {
struct IDLP_HEADER header;
u8 interfaceid;
u8 intopt;
u8 options;
u8 options1; //press
};
struct IDLPRSP_OPENSENSOR {
struct IDLP_HEADER header;
u8 sensorid;
};
/* CLOSESENSOR */
struct IDLPREQ_CLOSESENSOR {
struct IDLP_HEADER header;
u8 sensorid;
};
struct tag_idlpacket_rsp_closesensor {
struct IDLP_HEADER header;
u8 result;
} IDLPRSP_CLOSESENSOR;
/* ENABLEDATABUF */
struct IDLPREQ_ENABLEDATABUF {
struct IDLP_HEADER header;
u8 sensorid;
u8 intregaddr;
u8 intregdata;
u8 buffersize0;
u8 buffersize1;
u8 regscount;
// u8 regs[248];
};
struct IDLPRSP_ENABLEDATABUF {
struct IDLP_HEADER header;
u8 sensorid;
u8 result;
};
/* GETDATABUF */
struct IDLPREQ_GETDATABUF {
struct IDLP_HEADER header;
u8 sensorid;
};
#define MAXDATABUF 16002//3600//250//1008 //250
struct IDLPRSP_GETDATABUF {
struct IDLP_HEADER header;
u8 sensorid;
u8 eom;
u8 data[MAXDATABUF];
};
/* DISABLEDATABUF */
struct IDLPREQ_DISABLEDATABUF {
struct IDLP_HEADER header;
u8 sensorid;
};
struct tag_idlpacket_rsp_disabledatabuf {
struct IDLP_HEADER header;
u8 sensorid;
u8 result;
};
/* MULREGREAD */
struct IDLPREQ_MULREGREAD {
struct IDLP_HEADER header;
u8 sensorid;
u8 addr;
u8 stride;
u8 size;
};
struct IDLPRSP_MULREGREAD {
struct IDLP_HEADER header;
u8 sensorid;
u8 addr;
u8 stride;
u8 size;
u8 values[250];
};
/* MULREGWRITE */
struct IDLPREQ_MULREGWRITE {
struct IDLP_HEADER header;
u8 sensorid;
u8 addr;
u8 stride;
u8 size;
// u8 values[250];
};
struct IDLPRSP_MULREGWRITE {
struct IDLP_HEADER header;
u8 sensorid;
u8 addr;
u8 stride;
u8 size;
};
struct IDLPREQ_RAWWRITE {
struct IDLP_HEADER header;
u8 sensorid;
u8 addr;
u8 stride;
u8 size;
u8 values[IDL_PACKET_RAWWRITESIZE];
};
struct IDLPRSP_RAWWRITE {
struct IDLP_HEADER header;
u8 sensorid;
u8 addr;
u8 stride;
u8 size;
u8 result;
};
struct IDLPREQ_RAWREAD {
struct IDLP_HEADER header;
u8 sensorid;
u8 addr;
u8 stride;
u8 size;
};
struct IDLPRSP_RAWREAD {
struct IDLP_HEADER header;
u8 sensorid;
u8 addr;
u8 stride;
u8 size;
u8 values[IDL_PACKET_RAWREADSIZE];
};
#endif /* IDLPROTOCOL_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,69 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2020 InvenSense, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef INITDRIVER_H_
#define INITDRIVER_H_
#include "soniclib.h"
#include "../ch101_client.h"
#define READ_IQ_DATA_BLOCKING
#define IQ_DATA_MAX_NUM_SAMPLES CH101_MAX_NUM_SAMPLES // use CH201 I/Q size
/* Bit flags used in main loop to check for completion of sensor I/O. */
#define DATA_READY_FLAG (1 << 0)
#define IQ_READY_FLAG (1 << 1)
#define MAX_RX_SAMPLES 450
#define MAX_NB_SAMPLES 450
/* Define configuration settings for the Chirp sensors.
* The following symbols define configuration values that are used to
* initialize the ch_config_t structure passed during the ch_set_config() call.
*/
/* maximum range, in mm */
#define CHIRP_SENSOR_MAX_RANGE_MM 1000
/* static target rejection sample range, in samples (0=disabled) */
#define CHIRP_SENSOR_STATIC_RANGE 0
/* internal sample interval -NOT USED IF TRIGGERED */
#define CHIRP_SENSOR_SAMPLE_INTERVAL 0
struct chirp_data_t {
// from ch_get_range()
u32 range;
// from ch_get_amplitude()
u16 amplitude;
// from ch_get_num_samples()
u16 num_samples;
// from ch_get_iq_data()
struct ch_iq_sample_t iq_data[IQ_DATA_MAX_NUM_SAMPLES];
};
void set_chirp_data(struct ch101_client *data);
struct ch101_client *get_chirp_data(void);
void set_chirp_buffer(struct ch101_buffer *buffer);
int find_sensors(void);
void init_driver(void);
void config_driver(void);
void start_driver(int period_ms, int time_ms);
void stop_driver(void);
void ext_ChirpINT0_handler(int index);
void single_shot_driver(void);
void test_detect(void);
void test_write_read(void);
#endif /* INITDRIVER_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef SYSTEM_H_
#define SYSTEM_H_
#if defined(__KERNEL__)
#include <linux/string.h>
#include <linux/printk.h>
#include "../ch101_client.h"
#define printf(...) pr_info(TAG __VA_ARGS__)
#define UINT8_MAX 0xFF
#define UINT16_MAX 0xFFFF
#else
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#define printf(...)
typedef signed char s8;
typedef unsigned char u8;
typedef signed short s16;
typedef unsigned short u16;
typedef signed int s32;
typedef unsigned int u32;
typedef signed long long s64;
typedef unsigned long long u64;
#endif
#endif

View File

@@ -0,0 +1,115 @@
#
# Temperature sensor drivers
#
menu "Temperature sensors"
config ADS7052_TDK_THERMISTOR
tristate "TI ADS7052 coupled with B57861S0103A039"
depends on SPI
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
If you say yes here you get support for the B57861S0103A039
thermistor coupled with an external ADC converter ADS7052 via SPI.
Supported sensors:
* B57861S0103A039
This driver can also be built as a module. If so, the module will
be called tdk_thermistor.
config MAXIM_THERMOCOUPLE
tristate "Maxim thermocouple sensors"
depends on SPI
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
If you say yes here you get support for the Maxim series of
thermocouple sensors connected via SPI.
Supported sensors:
* MAX6675
* MAX31855
This driver can also be built as a module. If so, the module will
be called maxim_thermocouple.
config HID_SENSOR_TEMP
tristate "HID Environmental temperature sensor"
depends on HID_SENSOR_HUB
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
select HID_SENSOR_IIO_COMMON
select HID_SENSOR_IIO_TRIGGER
help
Say yes here to build support for the HID SENSOR
temperature driver
To compile this driver as a module, choose M here: the module
will be called hid-sensor-temperature.
config MLX90614
tristate "MLX90614 contact-less infrared sensor"
depends on I2C
help
If you say yes here you get support for the Melexis
MLX90614 contact-less infrared sensor connected with I2C.
This driver can also be built as a module. If so, the module will
be called mlx90614.
config MLX90632
tristate "MLX90632 contact-less infrared sensor with medical accuracy"
depends on I2C
select REGMAP_I2C
help
If you say yes here you get support for the Melexis
MLX90632 contact-less infrared sensor with medical accuracy
connected with I2C.
This driver can also be built as a module. If so, the module will
be called mlx90632.
config TMP006
tristate "TMP006 infrared thermopile sensor"
depends on I2C
help
If you say yes here you get support for the Texas Instruments
TMP006 infrared thermopile sensor.
This driver can also be built as a module. If so, the module will
be called tmp006.
config TMP007
tristate "TMP007 infrared thermopile sensor with Integrated Math Engine"
depends on I2C
help
If you say yes here you get support for the Texas Instruments
TMP007 infrared thermopile sensor with Integrated Math Engine.
This driver can also be built as a module. If so, the module will
be called tmp007.
config TSYS01
tristate "Measurement Specialties TSYS01 temperature sensor using I2C bus connection"
depends on I2C
select IIO_MS_SENSORS_I2C
help
If you say yes here you get support for the Measurement Specialties
TSYS01 I2C temperature sensor.
This driver can also be built as a module. If so, the module will
be called tsys01.
config TSYS02D
tristate "Measurement Specialties TSYS02D temperature sensor"
depends on I2C
select IIO_MS_SENSORS_I2C
help
If you say yes here you get support for the Measurement Specialties
TSYS02D temperature sensor.
This driver can also be built as a module. If so, the module will
be called tsys02d.
endmenu

View File

@@ -0,0 +1,14 @@
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for industrial I/O temperature drivers
#
obj-$(CONFIG_HID_SENSOR_TEMP) += hid-sensor-temperature.o
obj-$(CONFIG_MAXIM_THERMOCOUPLE) += maxim_thermocouple.o
obj-$(CONFIG_ADS7052_TDK_THERMISTOR) += tdk_thermistor.o
obj-$(CONFIG_MLX90614) += mlx90614.o
obj-$(CONFIG_MLX90632) += mlx90632.o
obj-$(CONFIG_TMP006) += tmp006.o
obj-$(CONFIG_TMP007) += tmp007.o
obj-$(CONFIG_TSYS01) += tsys01.o
obj-$(CONFIG_TSYS02D) += tsys02d.o

View File

@@ -0,0 +1,457 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2020 InvenSense, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mutex.h>
#include <linux/err.h>
#include <linux/spi/spi.h>
#include <linux/iio/iio.h>
#include <linux/iio/trigger.h>
#include <linux/iio/buffer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/kthread.h>
#include <linux/delay.h>
#include <linux/hrtimer.h>
#include <linux/iio/kfifo_buf.h>
#define TAG "tdk-therm: "
#define TDK_THERMISTOR_DRV_NAME "tdk_thermistor"
enum {
TDK_THERM
};
static bool ss_request;
static const struct iio_chan_spec tdk_therm_channels[] = {
{
.type = IIO_TEMP,
.info_mask_separate =
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
.scan_index = 0,
.scan_type = {
.sign = 's',
.realbits = 14,
.storagebits = 16,
.shift = 3,
.endianness = IIO_BE,
},
},
IIO_CHAN_SOFT_TIMESTAMP(1),
};
struct tdk_thermistor_chip {
const struct iio_chan_spec *channels;
const unsigned long *scan_masks;
u8 num_channels;
};
static const struct tdk_thermistor_chip tdk_thermistor_chips[] = {
[TDK_THERM] = {
.channels = tdk_therm_channels,
.num_channels = ARRAY_SIZE(tdk_therm_channels),
},
};
struct tdk_thermistor_data {
struct spi_device *spi;
struct device *dev;
const struct tdk_thermistor_chip *chip;
struct iio_trigger *trig;
struct hrtimer timer;
ktime_t period;
u8 buffer[16] ____cacheline_aligned;
};
static bool current_state;
static int tdk_thermistor_calibrate(struct tdk_thermistor_data *data);
static int tdk_thermistor_read(struct tdk_thermistor_data *data,
struct iio_chan_spec const *chan, int *val);
#ifdef TEST_DRIVER
static struct task_struct *thread_st;
#endif
static int temp_trig_set_state(struct iio_trigger *trig, bool state)
{
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
struct tdk_thermistor_data *data = iio_priv(indio_dev);
struct device *dev = data->dev;
dev_info(dev, "%s: state: %d\n", __func__, state);
current_state = state;
if (state)
hrtimer_start(&data->timer, data->period, HRTIMER_MODE_REL);
else
hrtimer_cancel(&data->timer);
return 0;
}
static const struct iio_trigger_ops temp_trigger_ops = {
.set_trigger_state = temp_trig_set_state,
};
/*HR Timer callback function*/
static enum hrtimer_restart tdk_thermistor_hrtimer_handler(struct hrtimer *t)
{
struct tdk_thermistor_data *data =
container_of(t, struct tdk_thermistor_data, timer);
struct device *dev = data->dev;
if (!data)
return HRTIMER_NORESTART;
pr_info(TAG "%s: t: %lld\n",
__func__, ktime_get_boot_ns());
if (data->trig != NULL)
iio_trigger_poll(data->trig);
else
pr_info(TAG "%s: Trigger is NULL\n", __func__);
hrtimer_forward_now(t, data->period);
return HRTIMER_RESTART;
}
#ifdef TEST_DRIVER /*Test thread function to read and display sensor data*/
static int test_thread_fn(void *input_data)
{
int cycle_cnt = 0;
int value = 0;
struct tdk_thermistor_data *data =
(struct tdk_thermistor_data *)input_data;
struct device *dev = data->dev;
struct iio_dev *indio_dev = dev_get_drvdata(dev);
if (indio_dev == NULL || dev == NULL)
pr_info(TAG "%s: indio_dev or dev NULL\n", __func__);
pr_info(TAG "%s: Starting test thread\n", __func__);
pr_info(TAG "%s: input data: %p spidev: %p\n",
__func__, input_data, data->spi);
msleep(10000);
pr_info(TAG "%s: Triggered calibration of TDK thermistor\n", __func__);
tdk_thermistor_calibrate(data);
msleep(500);
while (1) {
int temp_data = 0;
int temp_voltage;
int temp_resistance;
cycle_cnt++;
msleep(1000);
pr_info(TAG "%s: Reading TDK thermistor\n", __func__);
tdk_thermistor_read(data, NULL, &temp_data);
pr_info(TAG "%s: Read TDK thermistor: %i\n",
__func__, temp_data);
/* multiply by 100*/
temp_voltage = ((temp_data) * 330) / 16368;
temp_resistance = (3300000 / temp_voltage) - 10000;
pr_info(
TAG "%s: Read TDK thermistor voltage %i resistance: %i\n",
__func__, temp_voltage, temp_resistance);
}
do_exit(0);
return 0;
}
#endif
static int tdk_thermistor_calibrate(struct tdk_thermistor_data *data)
{
int ret;
u8 buf[8];
pr_info(TAG "%s: Triggered calibration of TDK thermistor\n", __func__);
ret = spi_read(data->spi, (void *)buf, 8);
if (ret) {
pr_info(TAG "%s: Failed SPI read: %i\n", __func__, ret);
return ret;
}
return 0;
}
static int tdk_thermistor_read(struct tdk_thermistor_data *data,
struct iio_chan_spec const *chan, int *val)
{
u8 raw_data[3];
int ret;
pr_info(TAG "%s: Reading thermistor\n", __func__);
/* Requires 18 clock cycles to get ADC data. First falling edge
* is zero, then 14 bits of data, followed by 3 additional zeroes.
* Use of 3 bytes provide 24 clock cycles.
*/
ret = spi_read(data->spi, (void *)raw_data, 3);
if (ret) {
pr_info(TAG "%s: Failed SPI read: %i\n", __func__, ret);
return ret;
}
pr_info(TAG "%s: Read SPI: 0x%x 0x%x 0x%x\n", __func__,
raw_data[0], raw_data[1], raw_data[2]);
/* check to be sure this is a valid reading */
if (raw_data[0] == 0 && raw_data[1] == 0 && raw_data[2] == 0)
return -EINVAL;
*val = ((raw_data[0] & 0x7F) << 7) | (raw_data[1] >> 1);
pr_info(TAG "%s: Read temp: %i\n", __func__, *val);
return 0;
}
static int tdk_thermistor_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct tdk_thermistor_data *data = iio_priv(indio_dev);
int ret = -EINVAL;
pr_info(TAG "%s: Read raw TDK thermistor, mask: %li\n", __func__, mask);
switch (mask) {
case IIO_CHAN_INFO_RAW:
ret = iio_device_claim_direct_mode(indio_dev);
if (ret)
return ret;
ret = tdk_thermistor_read(data, chan, val);
iio_device_release_direct_mode(indio_dev);
if (!ret)
return IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SCALE:
pr_info(TAG "%s: Read TDK thermistor scale chan: val: %i %i\n",
__func__, *val, chan->channel2);
switch (chan->channel2) {
case IIO_MOD_TEMP_AMBIENT:
*val = 62;
*val2 = 500000; /* 1000 * 0.0625 */
ret = IIO_VAL_INT_PLUS_MICRO;
break;
default:
*val = 250; /* 1000 * 0.25 */
ret = IIO_VAL_INT;
};
break;
}
return ret;
}
static const struct iio_info tdk_thermistor_info = {
.read_raw = tdk_thermistor_read_raw,
};
/*IIO trigger callback function, top half*/
static irqreturn_t tdk_thermistor_store_time(int irq, void *p)
{
struct iio_poll_func *pf = p;
pf->timestamp = ktime_get_boot_ns();
pr_info(TAG "%s: t: %llx\n", __func__, pf->timestamp);
return IRQ_WAKE_THREAD;
}
/*IIO trigger callback function(bottom half), */
/*reads data over SPI and pushes to buffer*/
static irqreturn_t tdk_thermistor_trigger_handler(int irq, void *private)
{
struct iio_poll_func *pf = private;
struct iio_dev *indio_dev = pf->indio_dev;
struct tdk_thermistor_data *data = iio_priv(indio_dev);
int ret;
int val;
pr_info(TAG "%s: Triggered read TDK thermistor\n", __func__);
ret = spi_read(data->spi, data->buffer, 3);
if (!ret) {
iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
iio_get_time_ns(indio_dev));
}
pr_info(TAG "%s: Read SPI: 0x%x 0x%x 0x%x\n", __func__,
data->buffer[0], data->buffer[1], data->buffer[2]);
#ifdef TEST_DRIVER
/* check to be sure this is a valid reading */
if (data->buffer[0] == 0 && data->buffer[1] == 0 &&
data->buffer[2] == 0)
pr_info(TAG "%s: Invalid reading\n", __func__);//return -EINVAL;
val = ((data->buffer[0] & 0x7F) << 7) | (data->buffer[1] >> 1);
pr_info(TAG "%s: Read temp: %i\n", __func__, val);
#endif
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static int tdk_thermistor_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
struct iio_dev *indio_dev;
struct tdk_thermistor_data *data;
const struct tdk_thermistor_chip *chip =
&tdk_thermistor_chips[id->driver_data];
struct iio_buffer *buffer;
int ret = 0;
pr_info(TAG "%s: Probing call for TDK thermistor\n", __func__);
pr_info(TAG "%s: SPI Device detected: %s offset: %lu\n",
__func__, id->name, id->driver_data);
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
if (!indio_dev) {
pr_info(
TAG "%s: Failed to alloc memory TDK thermistor\n", __func__);
return -ENOMEM;
}
buffer = devm_iio_kfifo_allocate(&spi->dev);
if (!buffer) {
pr_info(
TAG "%s: Failed to alloc memory TDK thermistor\n", __func__);
return -ENOMEM;
}
iio_device_attach_buffer(indio_dev, buffer);
indio_dev->info = &tdk_thermistor_info;
indio_dev->name = TDK_THERMISTOR_DRV_NAME;
indio_dev->channels = chip->channels;
indio_dev->available_scan_masks = chip->scan_masks;
indio_dev->num_channels = chip->num_channels;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->dev.parent = &spi->dev;
data = iio_priv(indio_dev);
data->spi = spi;
data->dev = &spi->dev;
data->chip = chip;
/*IIO Triggered buffer setting*/
ret = iio_triggered_buffer_setup(indio_dev, tdk_thermistor_store_time,
tdk_thermistor_trigger_handler, NULL);
if (ret)
return ret;
data->trig = iio_trigger_alloc("%s-hrtimer%d", indio_dev->name,
indio_dev->id);
if (data->trig == NULL) {
ret = -ENOMEM;
dev_err(&spi->dev, "iio trigger alloc error\n");
goto error_unreg_buffer;
}
data->trig->dev.parent = &spi->dev;
data->trig->ops = &temp_trigger_ops;
iio_trigger_set_drvdata(data->trig, indio_dev);
ret = iio_trigger_register(data->trig);
if (ret) {
dev_err(&spi->dev, "iio trigger register error %d\n", ret);
goto error_unreg_buffer;
}
iio_trigger_get(data->trig);
indio_dev->trig = data->trig;
ret = iio_device_register(indio_dev);
if (ret)
goto error_unreg_buffer;
/*Initialize timer for iio buffer updating */
hrtimer_init(&data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
data->period = ns_to_ktime((NSEC_PER_SEC / 1));
/*TBD: test and set appropriate period for timer interrupt*/
data->timer.function = tdk_thermistor_hrtimer_handler;
#ifdef TEST_DRIVER
pr_info(
TAG "%s: Creating test thread for thermistor with data: %p spidev: %p\n",
__func__, data, data->spi);
thread_st = kthread_run(test_thread_fn, data,
"TDK Thermistor Test Thread");
if (thread_st)
pr_info(TAG "%s: Thread Created successfully\n", __func__);
else
pr_info(TAG "%s: Thread creation failed\n", __func__);
#endif
return 0;
error_unreg_buffer:
iio_triggered_buffer_cleanup(indio_dev);
return ret;
}
static int tdk_thermistor_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
return 0;
}
static const struct spi_device_id tdk_thermistor_id[] = {
{"tdktherm", TDK_THERM},
{},
};
MODULE_DEVICE_TABLE(spi, tdk_thermistor_id);
static struct spi_driver tdk_thermistor_driver = {
.driver = {
.name = TDK_THERMISTOR_DRV_NAME,
},
.probe = tdk_thermistor_probe,
.remove = tdk_thermistor_remove,
.id_table = tdk_thermistor_id,
};
module_spi_driver(tdk_thermistor_driver);
MODULE_AUTHOR("Invensense Corporation");
MODULE_DESCRIPTION("Invensense thermistor driver");
MODULE_LICENSE("GPL");