From 530c01b2ae47a0ee796e6a3b8d16af7c62a4e042 Mon Sep 17 00:00:00 2001 From: Jeff Vander Stoep Date: Wed, 29 Jul 2015 20:21:12 -0700 Subject: [PATCH 001/320] Revert "SELinux: ss: Fix policy write for ioctl operations" This reverts commit 8cdfb356b51e29494ca0b9e4e86727d6f841a52d. Bug: 22846070 Change-Id: I4dd2fd5a1d7fb3ae8f74a5decdf8fb9d5cd43def Signed-off-by: Jeff Vander Stoep Signed-off-by: Bharat Pawar --- security/selinux/ss/avtab.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c index dd7466cb2021d..2e4ff003abcdc 100644 --- a/security/selinux/ss/avtab.c +++ b/security/selinux/ss/avtab.c @@ -565,9 +565,6 @@ int avtab_write_item(struct policydb *p, struct avtab_node *cur, void *fp) return rc; if (cur->key.specified & AVTAB_OP) { - rc = put_entry(&cur->datum.u.ops->type, sizeof(u8), 1, fp); - if (rc) - return rc; for (i = 0; i < ARRAY_SIZE(cur->datum.u.ops->op.perms); i++) buf32[i] = cpu_to_le32(cur->datum.u.ops->op.perms[i]); rc = put_entry(buf32, sizeof(u32), From a6cd5b2cd1ed50afc0b68fc7c9b559f07a78cc44 Mon Sep 17 00:00:00 2001 From: Aravind Asam Date: Tue, 23 Feb 2016 17:40:40 -0800 Subject: [PATCH 002/320] Revert "SELinux: use deletion-safe iterator to free list" This reverts commit e623b152f30f6f1204919315df37244d69e5d55e. Change-Id: I8e8903786da86cbe4206c18f817fbb54db229472 Signed-off-by: Aravind Asam --- security/selinux/avc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/security/selinux/avc.c b/security/selinux/avc.c index f3dbbc0f15dd5..5c8e7cfa9de39 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -298,15 +298,13 @@ static void avc_operation_decision_free( static void avc_operation_free(struct avc_operation_node *ops_node) { - struct avc_operation_decision_node *od_node, *tmp; + struct avc_operation_decision_node *od_node; if (!ops_node) return; - list_for_each_entry_safe(od_node, tmp, &ops_node->od_head, od_list) { - list_del(&od_node->od_list); + list_for_each_entry(od_node, &ops_node->od_head, od_list) avc_operation_decision_free(od_node); - } kmem_cache_free(avc_operation_node_cachep, ops_node); } From 8dc5e8040395b27452e978db989e47c10548d1ba Mon Sep 17 00:00:00 2001 From: Aravind Asam Date: Tue, 23 Feb 2016 17:45:11 -0800 Subject: [PATCH 003/320] Revert "SELinux: per-command whitelisting of ioctls" This reverts commit ba733f9857b966459316d0cd33b8da2e22f62d7d. Change-Id: Ie4d3e904160195dafd93a59a25d56b1449e8fc86 Signed-off-by: Aravind Asam --- security/selinux/avc.c | 428 ++-------------------------- security/selinux/hooks.c | 40 +-- security/selinux/include/avc.h | 5 - security/selinux/include/security.h | 34 +-- security/selinux/ss/avtab.c | 91 +----- security/selinux/ss/avtab.h | 25 +- security/selinux/ss/conditional.c | 32 +-- security/selinux/ss/conditional.h | 6 +- security/selinux/ss/policydb.c | 5 - security/selinux/ss/services.c | 202 ++----------- security/selinux/ss/services.h | 6 - 11 files changed, 64 insertions(+), 810 deletions(-) diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 5c8e7cfa9de39..c223a32c0bb32 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -49,7 +48,6 @@ struct avc_entry { u32 tsid; u16 tclass; struct av_decision avd; - struct avc_operation_node *ops_node; }; struct avc_node { @@ -66,16 +64,6 @@ struct avc_cache { u32 latest_notif; /* latest revocation notification */ }; -struct avc_operation_decision_node { - struct operation_decision od; - struct list_head od_list; -}; - -struct avc_operation_node { - struct operation ops; - struct list_head od_head; /* list of operation_decision_node */ -}; - struct avc_callback_node { int (*callback) (u32 event); u32 events; @@ -92,9 +80,6 @@ DEFINE_PER_CPU(struct avc_cache_stats, avc_cache_stats) = { 0 }; static struct avc_cache avc_cache; static struct avc_callback_node *avc_callbacks; static struct kmem_cache *avc_node_cachep; -static struct kmem_cache *avc_operation_decision_node_cachep; -static struct kmem_cache *avc_operation_node_cachep; -static struct kmem_cache *avc_operation_perm_cachep; static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass) { @@ -186,16 +171,6 @@ void __init avc_init(void) avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node), 0, SLAB_PANIC, NULL); - avc_operation_node_cachep = kmem_cache_create("avc_operation_node", - sizeof(struct avc_operation_node), - 0, SLAB_PANIC, NULL); - avc_operation_decision_node_cachep = kmem_cache_create( - "avc_operation_decision_node", - sizeof(struct avc_operation_decision_node), - 0, SLAB_PANIC, NULL); - avc_operation_perm_cachep = kmem_cache_create("avc_operation_perm", - sizeof(struct operation_perm), - 0, SLAB_PANIC, NULL); audit_log(current->audit_context, GFP_KERNEL, AUDIT_KERNEL, "AVC INITIALIZED\n"); } @@ -230,269 +205,9 @@ int avc_get_hash_stats(char *page) slots_used, AVC_CACHE_SLOTS, max_chain_len); } -/* - * using a linked list for operation_decision lookup because the list is - * always small. i.e. less than 5, typically 1 - */ -static struct operation_decision *avc_operation_lookup(u8 type, - struct avc_operation_node *ops_node) -{ - struct avc_operation_decision_node *od_node; - struct operation_decision *od = NULL; - - list_for_each_entry(od_node, &ops_node->od_head, od_list) { - if (od_node->od.type != type) - continue; - od = &od_node->od; - break; - } - return od; -} - -static inline unsigned int avc_operation_has_perm(struct operation_decision *od, - u16 cmd, u8 specified) -{ - unsigned int rc = 0; - u8 num = cmd & 0xff; - - if ((specified == OPERATION_ALLOWED) && - (od->specified & OPERATION_ALLOWED)) - rc = security_operation_test(od->allowed->perms, num); - else if ((specified == OPERATION_AUDITALLOW) && - (od->specified & OPERATION_AUDITALLOW)) - rc = security_operation_test(od->auditallow->perms, num); - else if ((specified == OPERATION_DONTAUDIT) && - (od->specified & OPERATION_DONTAUDIT)) - rc = security_operation_test(od->dontaudit->perms, num); - return rc; -} - -static void avc_operation_allow_perm(struct avc_operation_node *node, u16 cmd) -{ - struct operation_decision *od; - u8 type; - u8 num; - - type = cmd >> 8; - num = cmd & 0xff; - security_operation_set(node->ops.type, type); - od = avc_operation_lookup(type, node); - if (od && od->allowed) - security_operation_set(od->allowed->perms, num); -} - -static void avc_operation_decision_free( - struct avc_operation_decision_node *od_node) -{ - struct operation_decision *od; - - od = &od_node->od; - if (od->allowed) - kmem_cache_free(avc_operation_perm_cachep, od->allowed); - if (od->auditallow) - kmem_cache_free(avc_operation_perm_cachep, od->auditallow); - if (od->dontaudit) - kmem_cache_free(avc_operation_perm_cachep, od->dontaudit); - kmem_cache_free(avc_operation_decision_node_cachep, od_node); -} - -static void avc_operation_free(struct avc_operation_node *ops_node) -{ - struct avc_operation_decision_node *od_node; - - if (!ops_node) - return; - - list_for_each_entry(od_node, &ops_node->od_head, od_list) - avc_operation_decision_free(od_node); - kmem_cache_free(avc_operation_node_cachep, ops_node); -} - -static void avc_copy_operation_decision(struct operation_decision *dest, - struct operation_decision *src) -{ - dest->type = src->type; - dest->specified = src->specified; - if (dest->specified & OPERATION_ALLOWED) - memcpy(dest->allowed->perms, src->allowed->perms, - sizeof(src->allowed->perms)); - if (dest->specified & OPERATION_AUDITALLOW) - memcpy(dest->auditallow->perms, src->auditallow->perms, - sizeof(src->auditallow->perms)); - if (dest->specified & OPERATION_DONTAUDIT) - memcpy(dest->dontaudit->perms, src->dontaudit->perms, - sizeof(src->dontaudit->perms)); -} - -/* - * similar to avc_copy_operation_decision, but only copy decision - * information relevant to this command - */ -static inline void avc_quick_copy_operation_decision(u16 cmd, - struct operation_decision *dest, - struct operation_decision *src) -{ - /* - * compute index of the u32 of the 256 bits (8 u32s) that contain this - * command permission - */ - u8 i = (0xff & cmd) >> 5; - - dest->specified = src->specified; - if (dest->specified & OPERATION_ALLOWED) - dest->allowed->perms[i] = src->allowed->perms[i]; - if (dest->specified & OPERATION_AUDITALLOW) - dest->auditallow->perms[i] = src->auditallow->perms[i]; - if (dest->specified & OPERATION_DONTAUDIT) - dest->dontaudit->perms[i] = src->dontaudit->perms[i]; -} - -static struct avc_operation_decision_node - *avc_operation_decision_alloc(u8 specified) -{ - struct avc_operation_decision_node *node; - struct operation_decision *od; - - node = kmem_cache_zalloc(avc_operation_decision_node_cachep, - GFP_ATOMIC | __GFP_NOMEMALLOC); - if (!node) - return NULL; - - od = &node->od; - if (specified & OPERATION_ALLOWED) { - od->allowed = kmem_cache_zalloc(avc_operation_perm_cachep, - GFP_ATOMIC | __GFP_NOMEMALLOC); - if (!od->allowed) - goto error; - } - if (specified & OPERATION_AUDITALLOW) { - od->auditallow = kmem_cache_zalloc(avc_operation_perm_cachep, - GFP_ATOMIC | __GFP_NOMEMALLOC); - if (!od->auditallow) - goto error; - } - if (specified & OPERATION_DONTAUDIT) { - od->dontaudit = kmem_cache_zalloc(avc_operation_perm_cachep, - GFP_ATOMIC | __GFP_NOMEMALLOC); - if (!od->dontaudit) - goto error; - } - return node; -error: - avc_operation_decision_free(node); - return NULL; -} - -static int avc_add_operation(struct avc_node *node, - struct operation_decision *od) -{ - struct avc_operation_decision_node *dest_od; - - node->ae.ops_node->ops.len++; - dest_od = avc_operation_decision_alloc(od->specified); - if (!dest_od) - return -ENOMEM; - avc_copy_operation_decision(&dest_od->od, od); - list_add(&dest_od->od_list, &node->ae.ops_node->od_head); - return 0; -} - -static struct avc_operation_node *avc_operation_alloc(void) -{ - struct avc_operation_node *ops; - - ops = kmem_cache_zalloc(avc_operation_node_cachep, - GFP_ATOMIC|__GFP_NOMEMALLOC); - if (!ops) - return ops; - INIT_LIST_HEAD(&ops->od_head); - return ops; -} - -static int avc_operation_populate(struct avc_node *node, - struct avc_operation_node *src) -{ - struct avc_operation_node *dest; - struct avc_operation_decision_node *dest_od; - struct avc_operation_decision_node *src_od; - - if (src->ops.len == 0) - return 0; - dest = avc_operation_alloc(); - if (!dest) - return -ENOMEM; - - memcpy(dest->ops.type, &src->ops.type, sizeof(dest->ops.type)); - dest->ops.len = src->ops.len; - - /* for each source od allocate a destination od and copy */ - list_for_each_entry(src_od, &src->od_head, od_list) { - dest_od = avc_operation_decision_alloc(src_od->od.specified); - if (!dest_od) - goto error; - avc_copy_operation_decision(&dest_od->od, &src_od->od); - list_add(&dest_od->od_list, &dest->od_head); - } - node->ae.ops_node = dest; - return 0; -error: - avc_operation_free(dest); - return -ENOMEM; - -} - -static inline u32 avc_operation_audit_required(u32 requested, - struct av_decision *avd, - struct operation_decision *od, - u16 cmd, - int result, - u32 *deniedp) -{ - u32 denied, audited; - - denied = requested & ~avd->allowed; - if (unlikely(denied)) { - audited = denied & avd->auditdeny; - if (audited && od) { - if (avc_operation_has_perm(od, cmd, - OPERATION_DONTAUDIT)) - audited &= ~requested; - } - } else if (result) { - audited = denied = requested; - } else { - audited = requested & avd->auditallow; - if (audited && od) { - if (!avc_operation_has_perm(od, cmd, - OPERATION_AUDITALLOW)) - audited &= ~requested; - } - } - - *deniedp = denied; - return audited; -} - -static inline int avc_operation_audit(u32 ssid, u32 tsid, u16 tclass, - u32 requested, struct av_decision *avd, - struct operation_decision *od, - u16 cmd, int result, - struct common_audit_data *ad) -{ - u32 audited, denied; - - audited = avc_operation_audit_required( - requested, avd, od, cmd, result, &denied); - if (likely(!audited)) - return 0; - return slow_avc_audit(ssid, tsid, tclass, requested, - audited, denied, result, ad, 0); -} - static void avc_node_free(struct rcu_head *rhead) { struct avc_node *node = container_of(rhead, struct avc_node, rhead); - avc_operation_free(node->ae.ops_node); kmem_cache_free(avc_node_cachep, node); avc_cache_stats_incr(frees); } @@ -506,7 +221,6 @@ static void avc_node_delete(struct avc_node *node) static void avc_node_kill(struct avc_node *node) { - avc_operation_free(node->ae.ops_node); kmem_cache_free(avc_node_cachep, node); avc_cache_stats_incr(frees); atomic_dec(&avc_cache.active_nodes); @@ -653,7 +367,6 @@ static int avc_latest_notif_update(int seqno, int is_insert) * @tsid: target security identifier * @tclass: target security class * @avd: resulting av decision - * @ops: resulting operation decisions * * Insert an AVC entry for the SID pair * (@ssid, @tsid) and class @tclass. @@ -665,9 +378,7 @@ static int avc_latest_notif_update(int seqno, int is_insert) * the access vectors into a cache entry, returns * avc_node inserted. Otherwise, this function returns NULL. */ -static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, - struct av_decision *avd, - struct avc_operation_node *ops_node) +static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd) { struct avc_node *pos, *node = NULL; int hvalue; @@ -680,15 +391,10 @@ static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, if (node) { struct hlist_head *head; spinlock_t *lock; - int rc = 0; hvalue = avc_hash(ssid, tsid, tclass); avc_node_populate(node, ssid, tsid, tclass, avd); - rc = avc_operation_populate(node, ops_node); - if (rc) { - kmem_cache_free(avc_node_cachep, node); - return NULL; - } + head = &avc_cache.slots[hvalue]; lock = &avc_cache.slots_lock[hvalue]; @@ -822,17 +528,14 @@ static inline int avc_sidcmp(u32 x, u32 y) * @perms : Permission mask bits * @ssid,@tsid,@tclass : identifier of an AVC entry * @seqno : sequence number when decision was made - * @od: operation_decision to be added to the node * * if a valid AVC entry doesn't exist,this function returns -ENOENT. * if kmalloc() called internal returns NULL, this function returns -ENOMEM. * otherwise, this function updates the AVC entry. The original AVC-entry object * will release later by RCU. */ -static int avc_update_node(u32 event, u32 perms, u16 cmd, u32 ssid, u32 tsid, - u16 tclass, u32 seqno, - struct operation_decision *od, - u32 flags) +static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass, + u32 seqno) { int hvalue, rc = 0; unsigned long flag; @@ -876,19 +579,9 @@ static int avc_update_node(u32 event, u32 perms, u16 cmd, u32 ssid, u32 tsid, avc_node_populate(node, ssid, tsid, tclass, &orig->ae.avd); - if (orig->ae.ops_node) { - rc = avc_operation_populate(node, orig->ae.ops_node); - if (rc) { - kmem_cache_free(avc_node_cachep, node); - goto out_unlock; - } - } - switch (event) { case AVC_CALLBACK_GRANT: node->ae.avd.allowed |= perms; - if (node->ae.ops_node && (flags & AVC_OPERATION_CMD)) - avc_operation_allow_perm(node->ae.ops_node, cmd); break; case AVC_CALLBACK_TRY_REVOKE: case AVC_CALLBACK_REVOKE: @@ -906,9 +599,6 @@ static int avc_update_node(u32 event, u32 perms, u16 cmd, u32 ssid, u32 tsid, case AVC_CALLBACK_AUDITDENY_DISABLE: node->ae.avd.auditdeny &= ~perms; break; - case AVC_CALLBACK_ADD_OPERATION: - avc_add_operation(node, od); - break; } avc_node_replace(node, orig); out_unlock: @@ -980,20 +670,18 @@ int avc_ss_reset(u32 seqno) * results in a bigger stack frame. */ static noinline struct avc_node *avc_compute_av(u32 ssid, u32 tsid, - u16 tclass, struct av_decision *avd, - struct avc_operation_node *ops_node) + u16 tclass, struct av_decision *avd) { rcu_read_unlock(); - INIT_LIST_HEAD(&ops_node->od_head); - security_compute_av(ssid, tsid, tclass, avd, &ops_node->ops); + security_compute_av(ssid, tsid, tclass, avd); rcu_read_lock(); - return avc_insert(ssid, tsid, tclass, avd, ops_node); + return avc_insert(ssid, tsid, tclass, avd); } static noinline int avc_denied(u32 ssid, u32 tsid, - u16 tclass, u32 requested, - u16 cmd, unsigned flags, - struct av_decision *avd) + u16 tclass, u32 requested, + unsigned flags, + struct av_decision *avd) { if (flags & AVC_STRICT) return -EACCES; @@ -1001,92 +689,11 @@ static noinline int avc_denied(u32 ssid, u32 tsid, if (selinux_enforcing && !(avd->flags & AVD_FLAGS_PERMISSIVE)) return -EACCES; - avc_update_node(AVC_CALLBACK_GRANT, requested, cmd, ssid, - tsid, tclass, avd->seqno, NULL, flags); + avc_update_node(AVC_CALLBACK_GRANT, requested, ssid, + tsid, tclass, avd->seqno); return 0; } -/* - * ioctl commands are comprised of four fields, direction, size, type, and - * number. The avc operation logic filters based on two of them: - * - * type: or code, typically unique to each driver - * number: or function - * - * For example, 0x89 is a socket type, and number 0x27 is the get hardware - * address function. - */ -int avc_has_operation(u32 ssid, u32 tsid, u16 tclass, u32 requested, - u16 cmd, struct common_audit_data *ad) -{ - struct avc_node *node; - struct av_decision avd; - u32 denied; - struct operation_decision *od = NULL; - struct operation_decision od_local; - struct operation_perm allowed; - struct operation_perm auditallow; - struct operation_perm dontaudit; - struct avc_operation_node local_ops_node; - struct avc_operation_node *ops_node; - u8 type = cmd >> 8; - int rc = 0, rc2; - - ops_node = &local_ops_node; - BUG_ON(!requested); - - rcu_read_lock(); - - node = avc_lookup(ssid, tsid, tclass); - if (unlikely(!node)) { - node = avc_compute_av(ssid, tsid, tclass, &avd, ops_node); - } else { - memcpy(&avd, &node->ae.avd, sizeof(avd)); - ops_node = node->ae.ops_node; - } - /* if operations are not defined, only consider av_decision */ - if (!ops_node || !ops_node->ops.len) - goto decision; - - od_local.allowed = &allowed; - od_local.auditallow = &auditallow; - od_local.dontaudit = &dontaudit; - - /* lookup operation decision */ - od = avc_operation_lookup(type, ops_node); - if (unlikely(!od)) { - /* Compute operation decision if type is flagged */ - if (!security_operation_test(ops_node->ops.type, type)) { - avd.allowed &= ~requested; - goto decision; - } - rcu_read_unlock(); - security_compute_operation(ssid, tsid, tclass, type, &od_local); - rcu_read_lock(); - avc_update_node(AVC_CALLBACK_ADD_OPERATION, requested, cmd, - ssid, tsid, tclass, avd.seqno, &od_local, 0); - } else { - avc_quick_copy_operation_decision(cmd, &od_local, od); - } - od = &od_local; - - if (!avc_operation_has_perm(od, cmd, OPERATION_ALLOWED)) - avd.allowed &= ~requested; - -decision: - denied = requested & ~(avd.allowed); - if (unlikely(denied)) - rc = avc_denied(ssid, tsid, tclass, requested, cmd, - AVC_OPERATION_CMD, &avd); - - rcu_read_unlock(); - - rc2 = avc_operation_audit(ssid, tsid, tclass, requested, - &avd, od, cmd, rc, ad); - if (rc2) - return rc2; - return rc; -} /** * avc_has_perm_noaudit - Check permissions but perform no auditing. @@ -1114,7 +721,6 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid, struct av_decision *avd) { struct avc_node *node; - struct avc_operation_node ops_node; int rc = 0; u32 denied; @@ -1123,14 +729,16 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid, rcu_read_lock(); node = avc_lookup(ssid, tsid, tclass); - if (unlikely(!node)) - node = avc_compute_av(ssid, tsid, tclass, avd, &ops_node); - else + if (unlikely(!node)) { + node = avc_compute_av(ssid, tsid, tclass, avd); + } else { memcpy(avd, &node->ae.avd, sizeof(*avd)); + avd = &node->ae.avd; + } denied = requested & ~(avd->allowed); if (unlikely(denied)) - rc = avc_denied(ssid, tsid, tclass, requested, 0, flags, avd); + rc = avc_denied(ssid, tsid, tclass, requested, flags, avd); rcu_read_unlock(); return rc; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 0089fea50249a..c5c46039f76a3 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3158,44 +3158,6 @@ static void selinux_file_free_security(struct file *file) file_free_security(file); } -/* - * Check whether a task has the ioctl permission and cmd - * operation to an inode. - */ -int ioctl_has_perm(const struct cred *cred, struct file *file, - u32 requested, u16 cmd) -{ - struct common_audit_data ad; - struct file_security_struct *fsec = file->f_security; - struct inode *inode = file_inode(file); - struct inode_security_struct *isec = inode->i_security; - struct lsm_ioctlop_audit ioctl; - u32 ssid = cred_sid(cred); - int rc; - - ad.type = LSM_AUDIT_DATA_IOCTL_OP; - ad.u.op = &ioctl; - ad.u.op->cmd = cmd; - ad.u.op->path = file->f_path; - - if (ssid != fsec->sid) { - rc = avc_has_perm(ssid, fsec->sid, - SECCLASS_FD, - FD__USE, - &ad); - if (rc) - goto out; - } - - if (unlikely(IS_PRIVATE(inode))) - return 0; - - rc = avc_has_operation(ssid, isec->sid, isec->sclass, - requested, cmd, &ad); -out: - return rc; -} - static int selinux_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -3238,7 +3200,7 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, * to the file's ioctl() function. */ default: - error = ioctl_has_perm(cred, file, FILE__IOCTL, (u16) cmd); + error = file_has_perm(cred, file, FILE__IOCTL); } return error; } diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index 8109ad846e996..28a08a891704a 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h @@ -142,15 +142,11 @@ static inline int avc_audit(u32 ssid, u32 tsid, } #define AVC_STRICT 1 /* Ignore permissive mode. */ -#define AVC_OPERATION_CMD 2 /* ignore command when updating operations */ int avc_has_perm_noaudit(u32 ssid, u32 tsid, u16 tclass, u32 requested, unsigned flags, struct av_decision *avd); -int avc_has_operation(u32 ssid, u32 tsid, u16 tclass, u32 requested, - u16 cmd, struct common_audit_data *ad); - int avc_has_perm_flags(u32 ssid, u32 tsid, u16 tclass, u32 requested, struct common_audit_data *auditdata, @@ -173,7 +169,6 @@ u32 avc_policy_seqno(void); #define AVC_CALLBACK_AUDITALLOW_DISABLE 32 #define AVC_CALLBACK_AUDITDENY_ENABLE 64 #define AVC_CALLBACK_AUDITDENY_DISABLE 128 -#define AVC_CALLBACK_ADD_OPERATION 256 int avc_add_callback(int (*callback)(u32 event), u32 events); diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index e72d8de93725a..b214ef5f86e10 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -34,14 +34,13 @@ #define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27 #define POLICYDB_VERSION_DEFAULT_TYPE 28 #define POLICYDB_VERSION_CONSTRAINT_NAMES 29 -#define POLICYDB_VERSION_IOCTL_OPERATIONS 30 /* Range of policy versions we understand*/ #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX #define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE #else -#define POLICYDB_VERSION_MAX POLICYDB_VERSION_IOCTL_OPERATIONS +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_CONSTRAINT_NAMES #endif /* Mask for just the mount related flags */ @@ -104,40 +103,11 @@ struct av_decision { u32 flags; }; -#define security_operation_set(perms, x) (perms[x >> 5] |= 1 << (x & 0x1f)) -#define security_operation_test(perms, x) (1 & (perms[x >> 5] >> (x & 0x1f))) - -struct operation_perm { - u32 perms[8]; -}; - -struct operation_decision { - u8 type; - u8 specified; - struct operation_perm *allowed; - struct operation_perm *auditallow; - struct operation_perm *dontaudit; -}; - -#define OPERATION_ALLOWED 1 -#define OPERATION_AUDITALLOW 2 -#define OPERATION_DONTAUDIT 4 -#define OPERATION_ALL (OPERATION_ALLOWED | OPERATION_AUDITALLOW |\ - OPERATION_DONTAUDIT) -struct operation { - u16 len; /* length of operation decision chain */ - u32 type[8]; /* 256 types */ -}; - /* definitions of av_decision.flags */ #define AVD_FLAGS_PERMISSIVE 0x0001 void security_compute_av(u32 ssid, u32 tsid, - u16 tclass, struct av_decision *avd, - struct operation *ops); - -void security_compute_operation(u32 ssid, u32 tsid, u16 tclass, - u8 type, struct operation_decision *od); + u16 tclass, struct av_decision *avd); void security_compute_av_user(u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd); diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c index 2e4ff003abcdc..a3dd9faa19c01 100644 --- a/security/selinux/ss/avtab.c +++ b/security/selinux/ss/avtab.c @@ -24,7 +24,6 @@ #include "policydb.h" static struct kmem_cache *avtab_node_cachep; -static struct kmem_cache *avtab_operation_cachep; static inline int avtab_hash(struct avtab_key *keyp, u16 mask) { @@ -38,24 +37,11 @@ avtab_insert_node(struct avtab *h, int hvalue, struct avtab_key *key, struct avtab_datum *datum) { struct avtab_node *newnode; - struct avtab_operation *ops; newnode = kmem_cache_zalloc(avtab_node_cachep, GFP_KERNEL); if (newnode == NULL) return NULL; newnode->key = *key; - - if (key->specified & AVTAB_OP) { - ops = kmem_cache_zalloc(avtab_operation_cachep, GFP_KERNEL); - if (ops == NULL) { - kmem_cache_free(avtab_node_cachep, newnode); - return NULL; - } - *ops = *(datum->u.ops); - newnode->datum.u.ops = ops; - } else { - newnode->datum.u.data = datum->u.data; - } - + newnode->datum = *datum; if (prev) { newnode->next = prev->next; prev->next = newnode; @@ -84,11 +70,8 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat if (key->source_type == cur->key.source_type && key->target_type == cur->key.target_type && key->target_class == cur->key.target_class && - (specified & cur->key.specified)) { - if (specified & AVTAB_OPNUM) - break; + (specified & cur->key.specified)) return -EEXIST; - } if (key->source_type < cur->key.source_type) break; if (key->source_type == cur->key.source_type && @@ -249,9 +232,6 @@ void avtab_destroy(struct avtab *h) while (cur) { temp = cur; cur = cur->next; - if (temp->key.specified & AVTAB_OP) - kmem_cache_free(avtab_operation_cachep, - temp->datum.u.ops); kmem_cache_free(avtab_node_cachep, temp); } h->htable[i] = NULL; @@ -340,13 +320,7 @@ static uint16_t spec_order[] = { AVTAB_AUDITALLOW, AVTAB_TRANSITION, AVTAB_CHANGE, - AVTAB_MEMBER, - AVTAB_OPNUM_ALLOWED, - AVTAB_OPNUM_AUDITALLOW, - AVTAB_OPNUM_DONTAUDIT, - AVTAB_OPTYPE_ALLOWED, - AVTAB_OPTYPE_AUDITALLOW, - AVTAB_OPTYPE_DONTAUDIT + AVTAB_MEMBER }; int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, @@ -356,11 +330,10 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, { __le16 buf16[4]; u16 enabled; + __le32 buf32[7]; u32 items, items2, val, vers = pol->policyvers; struct avtab_key key; struct avtab_datum datum; - struct avtab_operation ops; - __le32 buf32[ARRAY_SIZE(ops.op.perms)]; int i, rc; unsigned set; @@ -417,15 +390,11 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, printk(KERN_ERR "SELinux: avtab: entry has both access vectors and types\n"); return -EINVAL; } - if (val & AVTAB_OP) { - printk(KERN_ERR "SELinux: avtab: entry has operations\n"); - return -EINVAL; - } for (i = 0; i < ARRAY_SIZE(spec_order); i++) { if (val & spec_order[i]) { key.specified = spec_order[i] | enabled; - datum.u.data = le32_to_cpu(buf32[items++]); + datum.data = le32_to_cpu(buf32[items++]); rc = insertf(a, &key, &datum, p); if (rc) return rc; @@ -444,6 +413,7 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, printk(KERN_ERR "SELinux: avtab: truncated entry\n"); return rc; } + items = 0; key.source_type = le16_to_cpu(buf16[items++]); key.target_type = le16_to_cpu(buf16[items++]); @@ -467,32 +437,14 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, return -EINVAL; } - if ((vers < POLICYDB_VERSION_IOCTL_OPERATIONS) - || !(key.specified & AVTAB_OP)) { - rc = next_entry(buf32, fp, sizeof(u32)); - if (rc) { - printk(KERN_ERR "SELinux: avtab: truncated entry\n"); - return rc; - } - datum.u.data = le32_to_cpu(*buf32); - } else { - memset(&ops, 0, sizeof(struct avtab_operation)); - rc = next_entry(&ops.type, fp, sizeof(u8)); - if (rc) { - printk(KERN_ERR "SELinux: avtab: truncated entry\n"); - return rc; - } - rc = next_entry(buf32, fp, sizeof(u32)*ARRAY_SIZE(ops.op.perms)); - if (rc) { - printk(KERN_ERR "SELinux: avtab: truncated entry\n"); - return rc; - } - for (i = 0; i < ARRAY_SIZE(ops.op.perms); i++) - ops.op.perms[i] = le32_to_cpu(buf32[i]); - datum.u.ops = &ops; + rc = next_entry(buf32, fp, sizeof(u32)); + if (rc) { + printk(KERN_ERR "SELinux: avtab: truncated entry\n"); + return rc; } + datum.data = le32_to_cpu(*buf32); if ((key.specified & AVTAB_TYPE) && - !policydb_type_isvalid(pol, datum.u.data)) { + !policydb_type_isvalid(pol, datum.data)) { printk(KERN_ERR "SELinux: avtab: invalid type\n"); return -EINVAL; } @@ -552,9 +504,8 @@ int avtab_read(struct avtab *a, void *fp, struct policydb *pol) int avtab_write_item(struct policydb *p, struct avtab_node *cur, void *fp) { __le16 buf16[4]; - __le32 buf32[ARRAY_SIZE(cur->datum.u.ops->op.perms)]; + __le32 buf32[1]; int rc; - unsigned int i; buf16[0] = cpu_to_le16(cur->key.source_type); buf16[1] = cpu_to_le16(cur->key.target_type); @@ -563,16 +514,8 @@ int avtab_write_item(struct policydb *p, struct avtab_node *cur, void *fp) rc = put_entry(buf16, sizeof(u16), 4, fp); if (rc) return rc; - - if (cur->key.specified & AVTAB_OP) { - for (i = 0; i < ARRAY_SIZE(cur->datum.u.ops->op.perms); i++) - buf32[i] = cpu_to_le32(cur->datum.u.ops->op.perms[i]); - rc = put_entry(buf32, sizeof(u32), - ARRAY_SIZE(cur->datum.u.ops->op.perms), fp); - } else { - buf32[0] = cpu_to_le32(cur->datum.u.data); - rc = put_entry(buf32, sizeof(u32), 1, fp); - } + buf32[0] = cpu_to_le32(cur->datum.data); + rc = put_entry(buf32, sizeof(u32), 1, fp); if (rc) return rc; return 0; @@ -605,13 +548,9 @@ void avtab_cache_init(void) avtab_node_cachep = kmem_cache_create("avtab_node", sizeof(struct avtab_node), 0, SLAB_PANIC, NULL); - avtab_operation_cachep = kmem_cache_create("avtab_operation", - sizeof(struct avtab_operation), - 0, SLAB_PANIC, NULL); } void avtab_cache_destroy(void) { kmem_cache_destroy(avtab_node_cachep); - kmem_cache_destroy(avtab_operation_cachep); } diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h index 97acd6fa705e7..63ce2f9e441da 100644 --- a/security/selinux/ss/avtab.h +++ b/security/selinux/ss/avtab.h @@ -23,8 +23,6 @@ #ifndef _SS_AVTAB_H_ #define _SS_AVTAB_H_ -#include "security.h" - struct avtab_key { u16 source_type; /* source type */ u16 target_type; /* target type */ @@ -37,34 +35,13 @@ struct avtab_key { #define AVTAB_MEMBER 0x0020 #define AVTAB_CHANGE 0x0040 #define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE) -#define AVTAB_OPNUM_ALLOWED 0x0100 -#define AVTAB_OPNUM_AUDITALLOW 0x0200 -#define AVTAB_OPNUM_DONTAUDIT 0x0400 -#define AVTAB_OPNUM (AVTAB_OPNUM_ALLOWED | \ - AVTAB_OPNUM_AUDITALLOW | \ - AVTAB_OPNUM_DONTAUDIT) -#define AVTAB_OPTYPE_ALLOWED 0x1000 -#define AVTAB_OPTYPE_AUDITALLOW 0x2000 -#define AVTAB_OPTYPE_DONTAUDIT 0x4000 -#define AVTAB_OPTYPE (AVTAB_OPTYPE_ALLOWED | \ - AVTAB_OPTYPE_AUDITALLOW | \ - AVTAB_OPTYPE_DONTAUDIT) -#define AVTAB_OP (AVTAB_OPNUM | AVTAB_OPTYPE) #define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */ #define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */ u16 specified; /* what field is specified */ }; -struct avtab_operation { - u8 type; - struct operation_perm op; -}; - struct avtab_datum { - union { - u32 data; /* access vector or type value */ - struct avtab_operation *ops; /* ioctl operations */ - } u; + u32 data; /* access vector or type value */ }; struct avtab_node { diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c index 16651c7a15419..377d148e71574 100644 --- a/security/selinux/ss/conditional.c +++ b/security/selinux/ss/conditional.c @@ -15,7 +15,6 @@ #include "security.h" #include "conditional.h" -#include "services.h" /* * cond_evaluate_expr evaluates a conditional expr @@ -618,39 +617,21 @@ int cond_write_list(struct policydb *p, struct cond_node *list, void *fp) return 0; } - -void cond_compute_operation(struct avtab *ctab, struct avtab_key *key, - struct operation_decision *od) -{ - struct avtab_node *node; - - if (!ctab || !key || !od) - return; - - for (node = avtab_search_node(ctab, key); node; - node = avtab_search_node_next(node, key->specified)) { - if (node->key.specified & AVTAB_ENABLED) - services_compute_operation_num(od, node); - } - return; - -} /* Determine whether additional permissions are granted by the conditional * av table, and if so, add them to the result */ -void cond_compute_av(struct avtab *ctab, struct avtab_key *key, - struct av_decision *avd, struct operation *ops) +void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decision *avd) { struct avtab_node *node; - if (!ctab || !key || !avd || !ops) + if (!ctab || !key || !avd) return; for (node = avtab_search_node(ctab, key); node; node = avtab_search_node_next(node, key->specified)) { if ((u16)(AVTAB_ALLOWED|AVTAB_ENABLED) == (node->key.specified & (AVTAB_ALLOWED|AVTAB_ENABLED))) - avd->allowed |= node->datum.u.data; + avd->allowed |= node->datum.data; if ((u16)(AVTAB_AUDITDENY|AVTAB_ENABLED) == (node->key.specified & (AVTAB_AUDITDENY|AVTAB_ENABLED))) /* Since a '0' in an auditdeny mask represents a @@ -658,13 +639,10 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key, * the '&' operand to ensure that all '0's in the mask * are retained (much unlike the allow and auditallow cases). */ - avd->auditdeny &= node->datum.u.data; + avd->auditdeny &= node->datum.data; if ((u16)(AVTAB_AUDITALLOW|AVTAB_ENABLED) == (node->key.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED))) - avd->auditallow |= node->datum.u.data; - if ((node->key.specified & AVTAB_ENABLED) && - (node->key.specified & AVTAB_OP)) - services_compute_operation_type(ops, node); + avd->auditallow |= node->datum.data; } return; } diff --git a/security/selinux/ss/conditional.h b/security/selinux/ss/conditional.h index 80ee2bb20eee4..4d1f87466508f 100644 --- a/security/selinux/ss/conditional.h +++ b/security/selinux/ss/conditional.h @@ -73,10 +73,8 @@ int cond_read_list(struct policydb *p, void *fp); int cond_write_bool(void *key, void *datum, void *ptr); int cond_write_list(struct policydb *p, struct cond_node *list, void *fp); -void cond_compute_av(struct avtab *ctab, struct avtab_key *key, - struct av_decision *avd, struct operation *ops); -void cond_compute_operation(struct avtab *ctab, struct avtab_key *key, - struct operation_decision *od); +void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decision *avd); + int evaluate_cond_node(struct policydb *p, struct cond_node *node); #endif /* _CONDITIONAL_H_ */ diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index a683475e16359..fc6950b8ec99d 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -148,11 +148,6 @@ static struct policydb_compat_info policydb_compat[] = { .sym_num = SYM_NUM, .ocon_num = OCON_NUM, }, - { - .version = POLICYDB_VERSION_IOCTL_OPERATIONS, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM, - }, }; static struct policydb_compat_info *policydb_lookup_compat(int version) diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 88178da2b834e..18caa16de27b6 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -92,10 +92,9 @@ static int context_struct_to_string(struct context *context, char **scontext, u32 *scontext_len); static void context_struct_compute_av(struct context *scontext, - struct context *tcontext, - u16 tclass, - struct av_decision *avd, - struct operation *ops); + struct context *tcontext, + u16 tclass, + struct av_decision *avd); struct selinux_mapping { u16 value; /* policy value */ @@ -565,8 +564,7 @@ static void type_attribute_bounds_av(struct context *scontext, context_struct_compute_av(&lo_scontext, tcontext, tclass, - &lo_avd, - NULL); + &lo_avd); if ((lo_avd.allowed & avd->allowed) == avd->allowed) return; /* no masked permission */ masked = ~lo_avd.allowed & avd->allowed; @@ -581,8 +579,7 @@ static void type_attribute_bounds_av(struct context *scontext, context_struct_compute_av(scontext, &lo_tcontext, tclass, - &lo_avd, - NULL); + &lo_avd); if ((lo_avd.allowed & avd->allowed) == avd->allowed) return; /* no masked permission */ masked = ~lo_avd.allowed & avd->allowed; @@ -598,8 +595,7 @@ static void type_attribute_bounds_av(struct context *scontext, context_struct_compute_av(&lo_scontext, &lo_tcontext, tclass, - &lo_avd, - NULL); + &lo_avd); if ((lo_avd.allowed & avd->allowed) == avd->allowed) return; /* no masked permission */ masked = ~lo_avd.allowed & avd->allowed; @@ -615,39 +611,14 @@ static void type_attribute_bounds_av(struct context *scontext, } } -/* flag ioctl types that have operation permissions */ -void services_compute_operation_type( - struct operation *ops, - struct avtab_node *node) -{ - u8 type; - unsigned int i; - - if (node->key.specified & AVTAB_OPTYPE) { - /* if allowing one or more complete types */ - for (i = 0; i < ARRAY_SIZE(ops->type); i++) - ops->type[i] |= node->datum.u.ops->op.perms[i]; - } else { - /* if allowing operations within a type */ - type = node->datum.u.ops->type; - security_operation_set(ops->type, type); - } - - /* If no ioctl commands are allowed, ignore auditallow and auditdeny */ - if (node->key.specified & AVTAB_OPTYPE_ALLOWED || - node->key.specified & AVTAB_OPNUM_ALLOWED) - ops->len = 1; -} - /* - * Compute access vectors and operations ranges based on a context - * structure pair for the permissions in a particular class. + * Compute access vectors based on a context structure pair for + * the permissions in a particular class. */ static void context_struct_compute_av(struct context *scontext, - struct context *tcontext, - u16 tclass, - struct av_decision *avd, - struct operation *ops) + struct context *tcontext, + u16 tclass, + struct av_decision *avd) { struct constraint_node *constraint; struct role_allow *ra; @@ -661,10 +632,6 @@ static void context_struct_compute_av(struct context *scontext, avd->allowed = 0; avd->auditallow = 0; avd->auditdeny = 0xffffffff; - if (ops) { - memset(&ops->type, 0, sizeof(ops->type)); - ops->len = 0; - } if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) { if (printk_ratelimit()) @@ -679,7 +646,7 @@ static void context_struct_compute_av(struct context *scontext, * this permission check, then use it. */ avkey.target_class = tclass; - avkey.specified = AVTAB_AV | AVTAB_OP; + avkey.specified = AVTAB_AV; sattr = flex_array_get(policydb.type_attr_map_array, scontext->type - 1); BUG_ON(!sattr); tattr = flex_array_get(policydb.type_attr_map_array, tcontext->type - 1); @@ -692,17 +659,15 @@ static void context_struct_compute_av(struct context *scontext, node; node = avtab_search_node_next(node, avkey.specified)) { if (node->key.specified == AVTAB_ALLOWED) - avd->allowed |= node->datum.u.data; + avd->allowed |= node->datum.data; else if (node->key.specified == AVTAB_AUDITALLOW) - avd->auditallow |= node->datum.u.data; + avd->auditallow |= node->datum.data; else if (node->key.specified == AVTAB_AUDITDENY) - avd->auditdeny &= node->datum.u.data; - else if (ops && (node->key.specified & AVTAB_OP)) - services_compute_operation_type(ops, node); + avd->auditdeny &= node->datum.data; } /* Check conditional av table for additional permissions */ - cond_compute_av(&policydb.te_cond_avtab, &avkey, avd, ops); + cond_compute_av(&policydb.te_cond_avtab, &avkey, avd); } } @@ -933,138 +898,13 @@ static void avd_init(struct av_decision *avd) avd->flags = 0; } -void services_compute_operation_num(struct operation_decision *od, - struct avtab_node *node) -{ - unsigned int i; - if (node->key.specified & AVTAB_OPNUM) { - if (od->type != node->datum.u.ops->type) - return; - } else { - if (!security_operation_test(node->datum.u.ops->op.perms, - od->type)) - return; - } - - if (node->key.specified == AVTAB_OPTYPE_ALLOWED) { - od->specified |= OPERATION_ALLOWED; - memset(od->allowed->perms, 0xff, - sizeof(od->allowed->perms)); - } else if (node->key.specified == AVTAB_OPTYPE_AUDITALLOW) { - od->specified |= OPERATION_AUDITALLOW; - memset(od->auditallow->perms, 0xff, - sizeof(od->auditallow->perms)); - } else if (node->key.specified == AVTAB_OPTYPE_DONTAUDIT) { - od->specified |= OPERATION_DONTAUDIT; - memset(od->dontaudit->perms, 0xff, - sizeof(od->dontaudit->perms)); - } else if (node->key.specified == AVTAB_OPNUM_ALLOWED) { - od->specified |= OPERATION_ALLOWED; - for (i = 0; i < ARRAY_SIZE(od->allowed->perms); i++) - od->allowed->perms[i] |= - node->datum.u.ops->op.perms[i]; - } else if (node->key.specified == AVTAB_OPNUM_AUDITALLOW) { - od->specified |= OPERATION_AUDITALLOW; - for (i = 0; i < ARRAY_SIZE(od->auditallow->perms); i++) - od->auditallow->perms[i] |= - node->datum.u.ops->op.perms[i]; - } else if (node->key.specified == AVTAB_OPNUM_DONTAUDIT) { - od->specified |= OPERATION_DONTAUDIT; - for (i = 0; i < ARRAY_SIZE(od->dontaudit->perms); i++) - od->dontaudit->perms[i] |= - node->datum.u.ops->op.perms[i]; - } else { - BUG(); - } -} - -void security_compute_operation(u32 ssid, - u32 tsid, - u16 orig_tclass, - u8 type, - struct operation_decision *od) -{ - u16 tclass; - struct context *scontext, *tcontext; - struct avtab_key avkey; - struct avtab_node *node; - struct ebitmap *sattr, *tattr; - struct ebitmap_node *snode, *tnode; - unsigned int i, j; - - od->type = type; - od->specified = 0; - memset(od->allowed->perms, 0, sizeof(od->allowed->perms)); - memset(od->auditallow->perms, 0, sizeof(od->auditallow->perms)); - memset(od->dontaudit->perms, 0, sizeof(od->dontaudit->perms)); - - read_lock(&policy_rwlock); - if (!ss_initialized) - goto allow; - - scontext = sidtab_search(&sidtab, ssid); - if (!scontext) { - printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", - __func__, ssid); - goto out; - } - - tcontext = sidtab_search(&sidtab, tsid); - if (!tcontext) { - printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", - __func__, tsid); - goto out; - } - - tclass = unmap_class(orig_tclass); - if (unlikely(orig_tclass && !tclass)) { - if (policydb.allow_unknown) - goto allow; - goto out; - } - - - if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) { - pr_warn_ratelimited("SELinux: Invalid class %hu\n", tclass); - goto out; - } - - avkey.target_class = tclass; - avkey.specified = AVTAB_OP; - sattr = flex_array_get(policydb.type_attr_map_array, - scontext->type - 1); - BUG_ON(!sattr); - tattr = flex_array_get(policydb.type_attr_map_array, - tcontext->type - 1); - BUG_ON(!tattr); - ebitmap_for_each_positive_bit(sattr, snode, i) { - ebitmap_for_each_positive_bit(tattr, tnode, j) { - avkey.source_type = i + 1; - avkey.target_type = j + 1; - for (node = avtab_search_node(&policydb.te_avtab, &avkey); - node; - node = avtab_search_node_next(node, avkey.specified)) - services_compute_operation_num(od, node); - - cond_compute_operation(&policydb.te_cond_avtab, - &avkey, od); - } - } -out: - read_unlock(&policy_rwlock); - return; -allow: - memset(od->allowed->perms, 0xff, sizeof(od->allowed->perms)); - goto out; -} /** * security_compute_av - Compute access vector decisions. * @ssid: source security identifier * @tsid: target security identifier * @tclass: target security class * @avd: access vector decisions - * @od: operation decisions * * Compute a set of access vector decisions based on the * SID pair (@ssid, @tsid) for the permissions in @tclass. @@ -1072,15 +912,13 @@ void security_compute_operation(u32 ssid, void security_compute_av(u32 ssid, u32 tsid, u16 orig_tclass, - struct av_decision *avd, - struct operation *ops) + struct av_decision *avd) { u16 tclass; struct context *scontext = NULL, *tcontext = NULL; read_lock(&policy_rwlock); avd_init(avd); - ops->len = 0; if (!ss_initialized) goto allow; @@ -1108,7 +946,7 @@ void security_compute_av(u32 ssid, goto allow; goto out; } - context_struct_compute_av(scontext, tcontext, tclass, avd, ops); + context_struct_compute_av(scontext, tcontext, tclass, avd); map_decision(orig_tclass, avd, policydb.allow_unknown); out: read_unlock(&policy_rwlock); @@ -1154,7 +992,7 @@ void security_compute_av_user(u32 ssid, goto out; } - context_struct_compute_av(scontext, tcontext, tclass, avd, NULL); + context_struct_compute_av(scontext, tcontext, tclass, avd); out: read_unlock(&policy_rwlock); return; @@ -1674,7 +1512,7 @@ static int security_compute_sid(u32 ssid, if (avdatum) { /* Use the type from the type transition/member/change rule. */ - newcontext.type = avdatum->u.data; + newcontext.type = avdatum->data; } /* if we have a objname this is a file trans check so check those rules */ diff --git a/security/selinux/ss/services.h b/security/selinux/ss/services.h index 569757484d052..e8d907e903cdb 100644 --- a/security/selinux/ss/services.h +++ b/security/selinux/ss/services.h @@ -11,11 +11,5 @@ extern struct policydb policydb; -void services_compute_operation_type(struct operation *ops, - struct avtab_node *node); - -void services_compute_operation_num(struct operation_decision *od, - struct avtab_node *node); - #endif /* _SS_SERVICES_H_ */ From f101ada17295203bd91e4889a28cf81a85d6247b Mon Sep 17 00:00:00 2001 From: Jeff Vander Stoep Date: Thu, 26 Feb 2015 13:54:17 -0800 Subject: [PATCH 004/320] selinux: remove unnecessary pointer reassignment (cherry pick from commit 83d4a806ae46397f606de7376b831524bd3a21e5) Commit f01e1af445fa ("selinux: don't pass in NULL avd to avc_has_perm_noaudit") made this pointer reassignment unnecessary. Avd should continue to reference the stack-based copy. Signed-off-by: Jeff Vander Stoep Acked-by: Stephen Smalley [PM: tweaked subject line] Signed-off-by: Paul Moore Bug: 22846070 Change-Id: I8fcba45a5acc4de862bd5b3f07bf4980f67133c4 Git-commit: b1b3844449d596e5f25f591d89611c7e57d32610 Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: David Ng --- security/selinux/avc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/security/selinux/avc.c b/security/selinux/avc.c index c223a32c0bb32..21e48baf0bbb5 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -729,12 +729,10 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid, rcu_read_lock(); node = avc_lookup(ssid, tsid, tclass); - if (unlikely(!node)) { + if (unlikely(!node)) node = avc_compute_av(ssid, tsid, tclass, avd); - } else { + else memcpy(avd, &node->ae.avd, sizeof(*avd)); - avd = &node->ae.avd; - } denied = requested & ~(avd->allowed); if (unlikely(denied)) From 7fd3daa33a003d28e4210365f7a5336fe3e69ea8 Mon Sep 17 00:00:00 2001 From: Jeff Vander Stoep Date: Fri, 10 Jul 2015 17:19:56 -0400 Subject: [PATCH 005/320] selinux: extended permissions for ioctls (cherry picked from commit fa1aa143ac4a682c7f5fd52a3cf05f5a6fe44a0a) Add extended permissions logic to selinux. Extended permissions provides additional permissions in 256 bit increments. Extend the generic ioctl permission check to use the extended permissions for per-command filtering. Source/target/class sets including the ioctl permission may additionally include a set of commands. Example: allowxperm : ioctl unpriv_app_socket_cmds auditallowxperm : ioctl priv_gpu_cmds Where unpriv_app_socket_cmds and priv_gpu_cmds are macros representing commonly granted sets of ioctl commands. When ioctl commands are omitted only the permissions are checked. This feature is intended to provide finer granularity for the ioctl permission that may be too imprecise. For example, the same driver may use ioctls to provide important and benign functionality such as driver version or socket type as well as dangerous capabilities such as debugging features, read/write/execute to physical memory or access to sensitive data. Per-command filtering provides a mechanism to reduce the attack surface of the kernel, and limit applications to the subset of commands required. The format of the policy binary has been modified to include ioctl commands, and the policy version number has been incremented to POLICYDB_VERSION_XPERMS_IOCTL=30 to account for the format change. The extended permissions logic is deliberately generic to allow components to be reused e.g. netlink filters Signed-off-by: Jeff Vander Stoep Acked-by: Nick Kralevich Signed-off-by: Paul Moore Bug: 22846070 Change-Id: I7c6bdc0362657b47aa1388936c5a1300bc5c0b42 Git-commit: 05b7da58527ef14001fe2b6e8de6b01d895d4429 Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: David Ng --- security/selinux/avc.c | 415 +++++++++++++++++++++++++++- security/selinux/hooks.c | 42 ++- security/selinux/include/avc.h | 5 + security/selinux/include/security.h | 32 ++- security/selinux/ss/avtab.c | 104 ++++++- security/selinux/ss/avtab.h | 34 ++- security/selinux/ss/conditional.c | 32 ++- security/selinux/ss/conditional.h | 6 +- security/selinux/ss/policydb.c | 5 + security/selinux/ss/services.c | 213 ++++++++++++-- security/selinux/ss/services.h | 6 + 11 files changed, 834 insertions(+), 60 deletions(-) diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 21e48baf0bbb5..386aafb2e69b1 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,7 @@ struct avc_entry { u32 tsid; u16 tclass; struct av_decision avd; + struct avc_xperms_node *xp_node; }; struct avc_node { @@ -56,6 +58,16 @@ struct avc_node { struct rcu_head rhead; }; +struct avc_xperms_decision_node { + struct extended_perms_decision xpd; + struct list_head xpd_list; /* list of extended_perms_decision */ +}; + +struct avc_xperms_node { + struct extended_perms xp; + struct list_head xpd_head; /* list head of extended_perms_decision */ +}; + struct avc_cache { struct hlist_head slots[AVC_CACHE_SLOTS]; /* head for avc_node->list */ spinlock_t slots_lock[AVC_CACHE_SLOTS]; /* lock for writes */ @@ -80,6 +92,9 @@ DEFINE_PER_CPU(struct avc_cache_stats, avc_cache_stats) = { 0 }; static struct avc_cache avc_cache; static struct avc_callback_node *avc_callbacks; static struct kmem_cache *avc_node_cachep; +static struct kmem_cache *avc_xperms_data_cachep; +static struct kmem_cache *avc_xperms_decision_cachep; +static struct kmem_cache *avc_xperms_cachep; static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass) { @@ -170,7 +185,17 @@ void __init avc_init(void) atomic_set(&avc_cache.lru_hint, 0); avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node), - 0, SLAB_PANIC, NULL); + 0, SLAB_PANIC, NULL); + avc_xperms_cachep = kmem_cache_create("avc_xperms_node", + sizeof(struct avc_xperms_node), + 0, SLAB_PANIC, NULL); + avc_xperms_decision_cachep = kmem_cache_create( + "avc_xperms_decision_node", + sizeof(struct avc_xperms_decision_node), + 0, SLAB_PANIC, NULL); + avc_xperms_data_cachep = kmem_cache_create("avc_xperms_data", + sizeof(struct extended_perms_data), + 0, SLAB_PANIC, NULL); audit_log(current->audit_context, GFP_KERNEL, AUDIT_KERNEL, "AVC INITIALIZED\n"); } @@ -205,9 +230,261 @@ int avc_get_hash_stats(char *page) slots_used, AVC_CACHE_SLOTS, max_chain_len); } +/* + * using a linked list for extended_perms_decision lookup because the list is + * always small. i.e. less than 5, typically 1 + */ +static struct extended_perms_decision *avc_xperms_decision_lookup(u8 driver, + struct avc_xperms_node *xp_node) +{ + struct avc_xperms_decision_node *xpd_node; + + list_for_each_entry(xpd_node, &xp_node->xpd_head, xpd_list) { + if (xpd_node->xpd.driver == driver) + return &xpd_node->xpd; + } + return NULL; +} + +static inline unsigned int +avc_xperms_has_perm(struct extended_perms_decision *xpd, + u8 perm, u8 which) +{ + unsigned int rc = 0; + + if ((which == XPERMS_ALLOWED) && + (xpd->used & XPERMS_ALLOWED)) + rc = security_xperm_test(xpd->allowed->p, perm); + else if ((which == XPERMS_AUDITALLOW) && + (xpd->used & XPERMS_AUDITALLOW)) + rc = security_xperm_test(xpd->auditallow->p, perm); + else if ((which == XPERMS_DONTAUDIT) && + (xpd->used & XPERMS_DONTAUDIT)) + rc = security_xperm_test(xpd->dontaudit->p, perm); + return rc; +} + +static void avc_xperms_allow_perm(struct avc_xperms_node *xp_node, + u8 driver, u8 perm) +{ + struct extended_perms_decision *xpd; + security_xperm_set(xp_node->xp.drivers.p, driver); + xpd = avc_xperms_decision_lookup(driver, xp_node); + if (xpd && xpd->allowed) + security_xperm_set(xpd->allowed->p, perm); +} + +static void avc_xperms_decision_free(struct avc_xperms_decision_node *xpd_node) +{ + struct extended_perms_decision *xpd; + + xpd = &xpd_node->xpd; + if (xpd->allowed) + kmem_cache_free(avc_xperms_data_cachep, xpd->allowed); + if (xpd->auditallow) + kmem_cache_free(avc_xperms_data_cachep, xpd->auditallow); + if (xpd->dontaudit) + kmem_cache_free(avc_xperms_data_cachep, xpd->dontaudit); + kmem_cache_free(avc_xperms_decision_cachep, xpd_node); +} + +static void avc_xperms_free(struct avc_xperms_node *xp_node) +{ + struct avc_xperms_decision_node *xpd_node, *tmp; + + if (!xp_node) + return; + + list_for_each_entry_safe(xpd_node, tmp, &xp_node->xpd_head, xpd_list) { + list_del(&xpd_node->xpd_list); + avc_xperms_decision_free(xpd_node); + } + kmem_cache_free(avc_xperms_cachep, xp_node); +} + +static void avc_copy_xperms_decision(struct extended_perms_decision *dest, + struct extended_perms_decision *src) +{ + dest->driver = src->driver; + dest->used = src->used; + if (dest->used & XPERMS_ALLOWED) + memcpy(dest->allowed->p, src->allowed->p, + sizeof(src->allowed->p)); + if (dest->used & XPERMS_AUDITALLOW) + memcpy(dest->auditallow->p, src->auditallow->p, + sizeof(src->auditallow->p)); + if (dest->used & XPERMS_DONTAUDIT) + memcpy(dest->dontaudit->p, src->dontaudit->p, + sizeof(src->dontaudit->p)); +} + +/* + * similar to avc_copy_xperms_decision, but only copy decision + * information relevant to this perm + */ +static inline void avc_quick_copy_xperms_decision(u8 perm, + struct extended_perms_decision *dest, + struct extended_perms_decision *src) +{ + /* + * compute index of the u32 of the 256 bits (8 u32s) that contain this + * command permission + */ + u8 i = perm >> 5; + + dest->used = src->used; + if (dest->used & XPERMS_ALLOWED) + dest->allowed->p[i] = src->allowed->p[i]; + if (dest->used & XPERMS_AUDITALLOW) + dest->auditallow->p[i] = src->auditallow->p[i]; + if (dest->used & XPERMS_DONTAUDIT) + dest->dontaudit->p[i] = src->dontaudit->p[i]; +} + +static struct avc_xperms_decision_node + *avc_xperms_decision_alloc(u8 which) +{ + struct avc_xperms_decision_node *xpd_node; + struct extended_perms_decision *xpd; + + xpd_node = kmem_cache_zalloc(avc_xperms_decision_cachep, + GFP_ATOMIC | __GFP_NOMEMALLOC); + if (!xpd_node) + return NULL; + + xpd = &xpd_node->xpd; + if (which & XPERMS_ALLOWED) { + xpd->allowed = kmem_cache_zalloc(avc_xperms_data_cachep, + GFP_ATOMIC | __GFP_NOMEMALLOC); + if (!xpd->allowed) + goto error; + } + if (which & XPERMS_AUDITALLOW) { + xpd->auditallow = kmem_cache_zalloc(avc_xperms_data_cachep, + GFP_ATOMIC | __GFP_NOMEMALLOC); + if (!xpd->auditallow) + goto error; + } + if (which & XPERMS_DONTAUDIT) { + xpd->dontaudit = kmem_cache_zalloc(avc_xperms_data_cachep, + GFP_ATOMIC | __GFP_NOMEMALLOC); + if (!xpd->dontaudit) + goto error; + } + return xpd_node; +error: + avc_xperms_decision_free(xpd_node); + return NULL; +} + +static int avc_add_xperms_decision(struct avc_node *node, + struct extended_perms_decision *src) +{ + struct avc_xperms_decision_node *dest_xpd; + + node->ae.xp_node->xp.len++; + dest_xpd = avc_xperms_decision_alloc(src->used); + if (!dest_xpd) + return -ENOMEM; + avc_copy_xperms_decision(&dest_xpd->xpd, src); + list_add(&dest_xpd->xpd_list, &node->ae.xp_node->xpd_head); + return 0; +} + +static struct avc_xperms_node *avc_xperms_alloc(void) +{ + struct avc_xperms_node *xp_node; + + xp_node = kmem_cache_zalloc(avc_xperms_cachep, + GFP_ATOMIC|__GFP_NOMEMALLOC); + if (!xp_node) + return xp_node; + INIT_LIST_HEAD(&xp_node->xpd_head); + return xp_node; +} + +static int avc_xperms_populate(struct avc_node *node, + struct avc_xperms_node *src) +{ + struct avc_xperms_node *dest; + struct avc_xperms_decision_node *dest_xpd; + struct avc_xperms_decision_node *src_xpd; + + if (src->xp.len == 0) + return 0; + dest = avc_xperms_alloc(); + if (!dest) + return -ENOMEM; + + memcpy(dest->xp.drivers.p, src->xp.drivers.p, sizeof(dest->xp.drivers.p)); + dest->xp.len = src->xp.len; + + /* for each source xpd allocate a destination xpd and copy */ + list_for_each_entry(src_xpd, &src->xpd_head, xpd_list) { + dest_xpd = avc_xperms_decision_alloc(src_xpd->xpd.used); + if (!dest_xpd) + goto error; + avc_copy_xperms_decision(&dest_xpd->xpd, &src_xpd->xpd); + list_add(&dest_xpd->xpd_list, &dest->xpd_head); + } + node->ae.xp_node = dest; + return 0; +error: + avc_xperms_free(dest); + return -ENOMEM; + +} + +static inline u32 avc_xperms_audit_required(u32 requested, + struct av_decision *avd, + struct extended_perms_decision *xpd, + u8 perm, + int result, + u32 *deniedp) +{ + u32 denied, audited; + + denied = requested & ~avd->allowed; + if (unlikely(denied)) { + audited = denied & avd->auditdeny; + if (audited && xpd) { + if (avc_xperms_has_perm(xpd, perm, XPERMS_DONTAUDIT)) + audited &= ~requested; + } + } else if (result) { + audited = denied = requested; + } else { + audited = requested & avd->auditallow; + if (audited && xpd) { + if (!avc_xperms_has_perm(xpd, perm, XPERMS_AUDITALLOW)) + audited &= ~requested; + } + } + + *deniedp = denied; + return audited; +} + +static inline int avc_xperms_audit(u32 ssid, u32 tsid, u16 tclass, + u32 requested, struct av_decision *avd, + struct extended_perms_decision *xpd, + u8 perm, int result, + struct common_audit_data *ad) +{ + u32 audited, denied; + + audited = avc_xperms_audit_required( + requested, avd, xpd, perm, result, &denied); + if (likely(!audited)) + return 0; + return slow_avc_audit(ssid, tsid, tclass, requested, + audited, denied, result, ad, 0); +} + static void avc_node_free(struct rcu_head *rhead) { struct avc_node *node = container_of(rhead, struct avc_node, rhead); + avc_xperms_free(node->ae.xp_node); kmem_cache_free(avc_node_cachep, node); avc_cache_stats_incr(frees); } @@ -221,6 +498,7 @@ static void avc_node_delete(struct avc_node *node) static void avc_node_kill(struct avc_node *node) { + avc_xperms_free(node->ae.xp_node); kmem_cache_free(avc_node_cachep, node); avc_cache_stats_incr(frees); atomic_dec(&avc_cache.active_nodes); @@ -367,6 +645,7 @@ static int avc_latest_notif_update(int seqno, int is_insert) * @tsid: target security identifier * @tclass: target security class * @avd: resulting av decision + * @xp_node: resulting extended permissions * * Insert an AVC entry for the SID pair * (@ssid, @tsid) and class @tclass. @@ -378,7 +657,9 @@ static int avc_latest_notif_update(int seqno, int is_insert) * the access vectors into a cache entry, returns * avc_node inserted. Otherwise, this function returns NULL. */ -static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd) +static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, + struct av_decision *avd, + struct avc_xperms_node *xp_node) { struct avc_node *pos, *node = NULL; int hvalue; @@ -391,10 +672,15 @@ static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, struct av_dec if (node) { struct hlist_head *head; spinlock_t *lock; + int rc = 0; hvalue = avc_hash(ssid, tsid, tclass); avc_node_populate(node, ssid, tsid, tclass, avd); - + rc = avc_xperms_populate(node, xp_node); + if (rc) { + kmem_cache_free(avc_node_cachep, node); + return NULL; + } head = &avc_cache.slots[hvalue]; lock = &avc_cache.slots_lock[hvalue]; @@ -528,14 +814,17 @@ static inline int avc_sidcmp(u32 x, u32 y) * @perms : Permission mask bits * @ssid,@tsid,@tclass : identifier of an AVC entry * @seqno : sequence number when decision was made + * @xpd: extended_perms_decision to be added to the node * * if a valid AVC entry doesn't exist,this function returns -ENOENT. * if kmalloc() called internal returns NULL, this function returns -ENOMEM. * otherwise, this function updates the AVC entry. The original AVC-entry object * will release later by RCU. */ -static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass, - u32 seqno) +static int avc_update_node(u32 event, u32 perms, u8 driver, u8 xperm, u32 ssid, + u32 tsid, u16 tclass, u32 seqno, + struct extended_perms_decision *xpd, + u32 flags) { int hvalue, rc = 0; unsigned long flag; @@ -579,9 +868,19 @@ static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass, avc_node_populate(node, ssid, tsid, tclass, &orig->ae.avd); + if (orig->ae.xp_node) { + rc = avc_xperms_populate(node, orig->ae.xp_node); + if (rc) { + kmem_cache_free(avc_node_cachep, node); + goto out_unlock; + } + } + switch (event) { case AVC_CALLBACK_GRANT: node->ae.avd.allowed |= perms; + if (node->ae.xp_node && (flags & AVC_EXTENDED_PERMS)) + avc_xperms_allow_perm(node->ae.xp_node, driver, xperm); break; case AVC_CALLBACK_TRY_REVOKE: case AVC_CALLBACK_REVOKE: @@ -599,6 +898,9 @@ static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass, case AVC_CALLBACK_AUDITDENY_DISABLE: node->ae.avd.auditdeny &= ~perms; break; + case AVC_CALLBACK_ADD_XPERMS: + avc_add_xperms_decision(node, xpd); + break; } avc_node_replace(node, orig); out_unlock: @@ -670,18 +972,20 @@ int avc_ss_reset(u32 seqno) * results in a bigger stack frame. */ static noinline struct avc_node *avc_compute_av(u32 ssid, u32 tsid, - u16 tclass, struct av_decision *avd) + u16 tclass, struct av_decision *avd, + struct avc_xperms_node *xp_node) { rcu_read_unlock(); - security_compute_av(ssid, tsid, tclass, avd); + INIT_LIST_HEAD(&xp_node->xpd_head); + security_compute_av(ssid, tsid, tclass, avd, &xp_node->xp); rcu_read_lock(); - return avc_insert(ssid, tsid, tclass, avd); + return avc_insert(ssid, tsid, tclass, avd, xp_node); } static noinline int avc_denied(u32 ssid, u32 tsid, - u16 tclass, u32 requested, - unsigned flags, - struct av_decision *avd) + u16 tclass, u32 requested, + u8 driver, u8 xperm, unsigned flags, + struct av_decision *avd) { if (flags & AVC_STRICT) return -EACCES; @@ -689,11 +993,91 @@ static noinline int avc_denied(u32 ssid, u32 tsid, if (selinux_enforcing && !(avd->flags & AVD_FLAGS_PERMISSIVE)) return -EACCES; - avc_update_node(AVC_CALLBACK_GRANT, requested, ssid, - tsid, tclass, avd->seqno); + avc_update_node(AVC_CALLBACK_GRANT, requested, driver, xperm, ssid, + tsid, tclass, avd->seqno, NULL, flags); return 0; } +/* + * The avc extended permissions logic adds an additional 256 bits of + * permissions to an avc node when extended permissions for that node are + * specified in the avtab. If the additional 256 permissions is not adequate, + * as-is the case with ioctls, then multiple may be chained together and the + * driver field is used to specify which set contains the permission. + */ +int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested, + u8 driver, u8 xperm, struct common_audit_data *ad) +{ + struct avc_node *node; + struct av_decision avd; + u32 denied; + struct extended_perms_decision local_xpd; + struct extended_perms_decision *xpd = NULL; + struct extended_perms_data allowed; + struct extended_perms_data auditallow; + struct extended_perms_data dontaudit; + struct avc_xperms_node local_xp_node; + struct avc_xperms_node *xp_node; + int rc = 0, rc2; + + xp_node = &local_xp_node; + BUG_ON(!requested); + + rcu_read_lock(); + + node = avc_lookup(ssid, tsid, tclass); + if (unlikely(!node)) { + node = avc_compute_av(ssid, tsid, tclass, &avd, xp_node); + } else { + memcpy(&avd, &node->ae.avd, sizeof(avd)); + xp_node = node->ae.xp_node; + } + /* if extended permissions are not defined, only consider av_decision */ + if (!xp_node || !xp_node->xp.len) + goto decision; + + local_xpd.allowed = &allowed; + local_xpd.auditallow = &auditallow; + local_xpd.dontaudit = &dontaudit; + + xpd = avc_xperms_decision_lookup(driver, xp_node); + if (unlikely(!xpd)) { + /* + * Compute the extended_perms_decision only if the driver + * is flagged + */ + if (!security_xperm_test(xp_node->xp.drivers.p, driver)) { + avd.allowed &= ~requested; + goto decision; + } + rcu_read_unlock(); + security_compute_xperms_decision(ssid, tsid, tclass, driver, + &local_xpd); + rcu_read_lock(); + avc_update_node(AVC_CALLBACK_ADD_XPERMS, requested, driver, xperm, + ssid, tsid, tclass, avd.seqno, &local_xpd, 0); + } else { + avc_quick_copy_xperms_decision(xperm, &local_xpd, xpd); + } + xpd = &local_xpd; + + if (!avc_xperms_has_perm(xpd, xperm, XPERMS_ALLOWED)) + avd.allowed &= ~requested; + +decision: + denied = requested & ~(avd.allowed); + if (unlikely(denied)) + rc = avc_denied(ssid, tsid, tclass, requested, driver, xperm, + AVC_EXTENDED_PERMS, &avd); + + rcu_read_unlock(); + + rc2 = avc_xperms_audit(ssid, tsid, tclass, requested, + &avd, xpd, xperm, rc, ad); + if (rc2) + return rc2; + return rc; +} /** * avc_has_perm_noaudit - Check permissions but perform no auditing. @@ -721,6 +1105,7 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid, struct av_decision *avd) { struct avc_node *node; + struct avc_xperms_node xp_node; int rc = 0; u32 denied; @@ -730,13 +1115,13 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid, node = avc_lookup(ssid, tsid, tclass); if (unlikely(!node)) - node = avc_compute_av(ssid, tsid, tclass, avd); + node = avc_compute_av(ssid, tsid, tclass, avd, &xp_node); else memcpy(avd, &node->ae.avd, sizeof(*avd)); denied = requested & ~(avd->allowed); if (unlikely(denied)) - rc = avc_denied(ssid, tsid, tclass, requested, flags, avd); + rc = avc_denied(ssid, tsid, tclass, requested, 0, 0, flags, avd); rcu_read_unlock(); return rc; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index c5c46039f76a3..47aa35d2dcbd5 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3158,6 +3158,46 @@ static void selinux_file_free_security(struct file *file) file_free_security(file); } +/* + * Check whether a task has the ioctl permission and cmd + * operation to an inode. + */ +int ioctl_has_perm(const struct cred *cred, struct file *file, + u32 requested, u16 cmd) +{ + struct common_audit_data ad; + struct file_security_struct *fsec = file->f_security; + struct inode *inode = file_inode(file); + struct inode_security_struct *isec = inode->i_security; + struct lsm_ioctlop_audit ioctl; + u32 ssid = cred_sid(cred); + int rc; + u8 driver = cmd >> 8; + u8 xperm = cmd & 0xff; + + ad.type = LSM_AUDIT_DATA_IOCTL_OP; + ad.u.op = &ioctl; + ad.u.op->cmd = cmd; + ad.u.op->path = file->f_path; + + if (ssid != fsec->sid) { + rc = avc_has_perm(ssid, fsec->sid, + SECCLASS_FD, + FD__USE, + &ad); + if (rc) + goto out; + } + + if (unlikely(IS_PRIVATE(inode))) + return 0; + + rc = avc_has_extended_perms(ssid, isec->sid, isec->sclass, + requested, driver, xperm, &ad); +out: + return rc; +} + static int selinux_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -3200,7 +3240,7 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, * to the file's ioctl() function. */ default: - error = file_has_perm(cred, file, FILE__IOCTL); + error = ioctl_has_perm(cred, file, FILE__IOCTL, (u16) cmd); } return error; } diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index 28a08a891704a..6d65f77fd8008 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h @@ -142,6 +142,7 @@ static inline int avc_audit(u32 ssid, u32 tsid, } #define AVC_STRICT 1 /* Ignore permissive mode. */ +#define AVC_EXTENDED_PERMS 2 /* update extended permissions */ int avc_has_perm_noaudit(u32 ssid, u32 tsid, u16 tclass, u32 requested, unsigned flags, @@ -159,6 +160,9 @@ static inline int avc_has_perm(u32 ssid, u32 tsid, return avc_has_perm_flags(ssid, tsid, tclass, requested, auditdata, 0); } +int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested, + u8 driver, u8 perm, struct common_audit_data *ad); + u32 avc_policy_seqno(void); #define AVC_CALLBACK_GRANT 1 @@ -169,6 +173,7 @@ u32 avc_policy_seqno(void); #define AVC_CALLBACK_AUDITALLOW_DISABLE 32 #define AVC_CALLBACK_AUDITDENY_ENABLE 64 #define AVC_CALLBACK_AUDITDENY_DISABLE 128 +#define AVC_CALLBACK_ADD_XPERMS 256 int avc_add_callback(int (*callback)(u32 event), u32 events); diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index b214ef5f86e10..eb25aa9fb3135 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -34,13 +34,14 @@ #define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27 #define POLICYDB_VERSION_DEFAULT_TYPE 28 #define POLICYDB_VERSION_CONSTRAINT_NAMES 29 +#define POLICYDB_VERSION_XPERMS_IOCTL 30 /* Range of policy versions we understand*/ #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX #define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE #else -#define POLICYDB_VERSION_MAX POLICYDB_VERSION_CONSTRAINT_NAMES +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_XPERMS_IOCTL #endif /* Mask for just the mount related flags */ @@ -103,11 +104,38 @@ struct av_decision { u32 flags; }; +#define XPERMS_ALLOWED 1 +#define XPERMS_AUDITALLOW 2 +#define XPERMS_DONTAUDIT 4 + +#define security_xperm_set(perms, x) (perms[x >> 5] |= 1 << (x & 0x1f)) +#define security_xperm_test(perms, x) (1 & (perms[x >> 5] >> (x & 0x1f))) +struct extended_perms_data { + u32 p[8]; +}; + +struct extended_perms_decision { + u8 used; + u8 driver; + struct extended_perms_data *allowed; + struct extended_perms_data *auditallow; + struct extended_perms_data *dontaudit; +}; + +struct extended_perms { + u16 len; /* length associated decision chain */ + struct extended_perms_data drivers; /* flag drivers that are used */ +}; + /* definitions of av_decision.flags */ #define AVD_FLAGS_PERMISSIVE 0x0001 void security_compute_av(u32 ssid, u32 tsid, - u16 tclass, struct av_decision *avd); + u16 tclass, struct av_decision *avd, + struct extended_perms *xperms); + +void security_compute_xperms_decision(u32 ssid, u32 tsid, u16 tclass, + u8 driver, struct extended_perms_decision *xpermd); void security_compute_av_user(u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd); diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c index a3dd9faa19c01..a6bef631b74e8 100644 --- a/security/selinux/ss/avtab.c +++ b/security/selinux/ss/avtab.c @@ -24,6 +24,7 @@ #include "policydb.h" static struct kmem_cache *avtab_node_cachep; +static struct kmem_cache *avtab_xperms_cachep; static inline int avtab_hash(struct avtab_key *keyp, u16 mask) { @@ -37,11 +38,24 @@ avtab_insert_node(struct avtab *h, int hvalue, struct avtab_key *key, struct avtab_datum *datum) { struct avtab_node *newnode; + struct avtab_extended_perms *xperms; newnode = kmem_cache_zalloc(avtab_node_cachep, GFP_KERNEL); if (newnode == NULL) return NULL; newnode->key = *key; - newnode->datum = *datum; + + if (key->specified & AVTAB_XPERMS) { + xperms = kmem_cache_zalloc(avtab_xperms_cachep, GFP_KERNEL); + if (xperms == NULL) { + kmem_cache_free(avtab_node_cachep, newnode); + return NULL; + } + *xperms = *(datum->u.xperms); + newnode->datum.u.xperms = xperms; + } else { + newnode->datum.u.data = datum->u.data; + } + if (prev) { newnode->next = prev->next; prev->next = newnode; @@ -70,8 +84,12 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat if (key->source_type == cur->key.source_type && key->target_type == cur->key.target_type && key->target_class == cur->key.target_class && - (specified & cur->key.specified)) + (specified & cur->key.specified)) { + /* extended perms may not be unique */ + if (specified & AVTAB_XPERMS) + break; return -EEXIST; + } if (key->source_type < cur->key.source_type) break; if (key->source_type == cur->key.source_type && @@ -232,6 +250,9 @@ void avtab_destroy(struct avtab *h) while (cur) { temp = cur; cur = cur->next; + if (temp->key.specified & AVTAB_XPERMS) + kmem_cache_free(avtab_xperms_cachep, + temp->datum.u.xperms); kmem_cache_free(avtab_node_cachep, temp); } h->htable[i] = NULL; @@ -320,7 +341,10 @@ static uint16_t spec_order[] = { AVTAB_AUDITALLOW, AVTAB_TRANSITION, AVTAB_CHANGE, - AVTAB_MEMBER + AVTAB_MEMBER, + AVTAB_XPERMS_ALLOWED, + AVTAB_XPERMS_AUDITALLOW, + AVTAB_XPERMS_DONTAUDIT }; int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, @@ -330,10 +354,11 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, { __le16 buf16[4]; u16 enabled; - __le32 buf32[7]; u32 items, items2, val, vers = pol->policyvers; struct avtab_key key; struct avtab_datum datum; + struct avtab_extended_perms xperms; + __le32 buf32[ARRAY_SIZE(xperms.perms.p)]; int i, rc; unsigned set; @@ -390,11 +415,15 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, printk(KERN_ERR "SELinux: avtab: entry has both access vectors and types\n"); return -EINVAL; } + if (val & AVTAB_XPERMS) { + printk(KERN_ERR "SELinux: avtab: entry has extended permissions\n"); + return -EINVAL; + } for (i = 0; i < ARRAY_SIZE(spec_order); i++) { if (val & spec_order[i]) { key.specified = spec_order[i] | enabled; - datum.data = le32_to_cpu(buf32[items++]); + datum.u.data = le32_to_cpu(buf32[items++]); rc = insertf(a, &key, &datum, p); if (rc) return rc; @@ -437,14 +466,42 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, return -EINVAL; } - rc = next_entry(buf32, fp, sizeof(u32)); - if (rc) { - printk(KERN_ERR "SELinux: avtab: truncated entry\n"); - return rc; + if ((vers < POLICYDB_VERSION_XPERMS_IOCTL) && + (key.specified & AVTAB_XPERMS)) { + printk(KERN_ERR "SELinux: avtab: policy version %u does not " + "support extended permissions rules and one " + "was specified\n", vers); + return -EINVAL; + } else if (key.specified & AVTAB_XPERMS) { + memset(&xperms, 0, sizeof(struct avtab_extended_perms)); + rc = next_entry(&xperms.specified, fp, sizeof(u8)); + if (rc) { + printk(KERN_ERR "SELinux: avtab: truncated entry\n"); + return rc; + } + rc = next_entry(&xperms.driver, fp, sizeof(u8)); + if (rc) { + printk(KERN_ERR "SELinux: avtab: truncated entry\n"); + return rc; + } + rc = next_entry(buf32, fp, sizeof(u32)*ARRAY_SIZE(xperms.perms.p)); + if (rc) { + printk(KERN_ERR "SELinux: avtab: truncated entry\n"); + return rc; + } + for (i = 0; i < ARRAY_SIZE(xperms.perms.p); i++) + xperms.perms.p[i] = le32_to_cpu(buf32[i]); + datum.u.xperms = &xperms; + } else { + rc = next_entry(buf32, fp, sizeof(u32)); + if (rc) { + printk(KERN_ERR "SELinux: avtab: truncated entry\n"); + return rc; + } + datum.u.data = le32_to_cpu(*buf32); } - datum.data = le32_to_cpu(*buf32); if ((key.specified & AVTAB_TYPE) && - !policydb_type_isvalid(pol, datum.data)) { + !policydb_type_isvalid(pol, datum.u.data)) { printk(KERN_ERR "SELinux: avtab: invalid type\n"); return -EINVAL; } @@ -504,8 +561,9 @@ int avtab_read(struct avtab *a, void *fp, struct policydb *pol) int avtab_write_item(struct policydb *p, struct avtab_node *cur, void *fp) { __le16 buf16[4]; - __le32 buf32[1]; + __le32 buf32[ARRAY_SIZE(cur->datum.u.xperms->perms.p)]; int rc; + unsigned int i; buf16[0] = cpu_to_le16(cur->key.source_type); buf16[1] = cpu_to_le16(cur->key.target_type); @@ -514,8 +572,22 @@ int avtab_write_item(struct policydb *p, struct avtab_node *cur, void *fp) rc = put_entry(buf16, sizeof(u16), 4, fp); if (rc) return rc; - buf32[0] = cpu_to_le32(cur->datum.data); - rc = put_entry(buf32, sizeof(u32), 1, fp); + + if (cur->key.specified & AVTAB_XPERMS) { + rc = put_entry(&cur->datum.u.xperms->specified, sizeof(u8), 1, fp); + if (rc) + return rc; + rc = put_entry(&cur->datum.u.xperms->driver, sizeof(u8), 1, fp); + if (rc) + return rc; + for (i = 0; i < ARRAY_SIZE(cur->datum.u.xperms->perms.p); i++) + buf32[i] = cpu_to_le32(cur->datum.u.xperms->perms.p[i]); + rc = put_entry(buf32, sizeof(u32), + ARRAY_SIZE(cur->datum.u.xperms->perms.p), fp); + } else { + buf32[0] = cpu_to_le32(cur->datum.u.data); + rc = put_entry(buf32, sizeof(u32), 1, fp); + } if (rc) return rc; return 0; @@ -548,9 +620,13 @@ void avtab_cache_init(void) avtab_node_cachep = kmem_cache_create("avtab_node", sizeof(struct avtab_node), 0, SLAB_PANIC, NULL); + avtab_xperms_cachep = kmem_cache_create("avtab_extended_perms", + sizeof(struct avtab_extended_perms), + 0, SLAB_PANIC, NULL); } void avtab_cache_destroy(void) { kmem_cache_destroy(avtab_node_cachep); + kmem_cache_destroy(avtab_xperms_cachep); } diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h index 63ce2f9e441da..8133523ca679b 100644 --- a/security/selinux/ss/avtab.h +++ b/security/selinux/ss/avtab.h @@ -23,6 +23,8 @@ #ifndef _SS_AVTAB_H_ #define _SS_AVTAB_H_ +#include "security.h" + struct avtab_key { u16 source_type; /* source type */ u16 target_type; /* target type */ @@ -35,13 +37,43 @@ struct avtab_key { #define AVTAB_MEMBER 0x0020 #define AVTAB_CHANGE 0x0040 #define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE) +/* extended permissions */ +#define AVTAB_XPERMS_ALLOWED 0x0100 +#define AVTAB_XPERMS_AUDITALLOW 0x0200 +#define AVTAB_XPERMS_DONTAUDIT 0x0400 +#define AVTAB_XPERMS (AVTAB_XPERMS_ALLOWED | \ + AVTAB_XPERMS_AUDITALLOW | \ + AVTAB_XPERMS_DONTAUDIT) #define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */ #define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */ u16 specified; /* what field is specified */ }; +/* + * For operations that require more than the 32 permissions provided by the avc + * extended permissions may be used to provide 256 bits of permissions. + */ +struct avtab_extended_perms { +/* These are not flags. All 256 values may be used */ +#define AVTAB_XPERMS_IOCTLFUNCTION 0x01 +#define AVTAB_XPERMS_IOCTLDRIVER 0x02 + /* extension of the avtab_key specified */ + u8 specified; /* ioctl, netfilter, ... */ + /* + * if 256 bits is not adequate as is often the case with ioctls, then + * multiple extended perms may be used and the driver field + * specifies which permissions are included. + */ + u8 driver; + /* 256 bits of permissions */ + struct extended_perms_data perms; +}; + struct avtab_datum { - u32 data; /* access vector or type value */ + union { + u32 data; /* access vector or type value */ + struct avtab_extended_perms *xperms; + } u; }; struct avtab_node { diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c index 377d148e71574..6618fb45cca00 100644 --- a/security/selinux/ss/conditional.c +++ b/security/selinux/ss/conditional.c @@ -15,6 +15,7 @@ #include "security.h" #include "conditional.h" +#include "services.h" /* * cond_evaluate_expr evaluates a conditional expr @@ -617,21 +618,39 @@ int cond_write_list(struct policydb *p, struct cond_node *list, void *fp) return 0; } + +void cond_compute_xperms(struct avtab *ctab, struct avtab_key *key, + struct extended_perms_decision *xpermd) +{ + struct avtab_node *node; + + if (!ctab || !key || !xpermd) + return; + + for (node = avtab_search_node(ctab, key); node; + node = avtab_search_node_next(node, key->specified)) { + if (node->key.specified & AVTAB_ENABLED) + services_compute_xperms_decision(xpermd, node); + } + return; + +} /* Determine whether additional permissions are granted by the conditional * av table, and if so, add them to the result */ -void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decision *avd) +void cond_compute_av(struct avtab *ctab, struct avtab_key *key, + struct av_decision *avd, struct extended_perms *xperms) { struct avtab_node *node; - if (!ctab || !key || !avd) + if (!ctab || !key || !avd || !xperms) return; for (node = avtab_search_node(ctab, key); node; node = avtab_search_node_next(node, key->specified)) { if ((u16)(AVTAB_ALLOWED|AVTAB_ENABLED) == (node->key.specified & (AVTAB_ALLOWED|AVTAB_ENABLED))) - avd->allowed |= node->datum.data; + avd->allowed |= node->datum.u.data; if ((u16)(AVTAB_AUDITDENY|AVTAB_ENABLED) == (node->key.specified & (AVTAB_AUDITDENY|AVTAB_ENABLED))) /* Since a '0' in an auditdeny mask represents a @@ -639,10 +658,13 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decisi * the '&' operand to ensure that all '0's in the mask * are retained (much unlike the allow and auditallow cases). */ - avd->auditdeny &= node->datum.data; + avd->auditdeny &= node->datum.u.data; if ((u16)(AVTAB_AUDITALLOW|AVTAB_ENABLED) == (node->key.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED))) - avd->auditallow |= node->datum.data; + avd->auditallow |= node->datum.u.data; + if ((node->key.specified & AVTAB_ENABLED) && + (node->key.specified & AVTAB_XPERMS)) + services_compute_xperms_drivers(xperms, node); } return; } diff --git a/security/selinux/ss/conditional.h b/security/selinux/ss/conditional.h index 4d1f87466508f..ddb43e7e1c756 100644 --- a/security/selinux/ss/conditional.h +++ b/security/selinux/ss/conditional.h @@ -73,8 +73,10 @@ int cond_read_list(struct policydb *p, void *fp); int cond_write_bool(void *key, void *datum, void *ptr); int cond_write_list(struct policydb *p, struct cond_node *list, void *fp); -void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decision *avd); - +void cond_compute_av(struct avtab *ctab, struct avtab_key *key, + struct av_decision *avd, struct extended_perms *xperms); +void cond_compute_xperms(struct avtab *ctab, struct avtab_key *key, + struct extended_perms_decision *xpermd); int evaluate_cond_node(struct policydb *p, struct cond_node *node); #endif /* _CONDITIONAL_H_ */ diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index fc6950b8ec99d..ca2c6f47d9054 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -148,6 +148,11 @@ static struct policydb_compat_info policydb_compat[] = { .sym_num = SYM_NUM, .ocon_num = OCON_NUM, }, + { + .version = POLICYDB_VERSION_XPERMS_IOCTL, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM, + }, }; static struct policydb_compat_info *policydb_lookup_compat(int version) diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 18caa16de27b6..cf905cdce93f2 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -92,9 +92,10 @@ static int context_struct_to_string(struct context *context, char **scontext, u32 *scontext_len); static void context_struct_compute_av(struct context *scontext, - struct context *tcontext, - u16 tclass, - struct av_decision *avd); + struct context *tcontext, + u16 tclass, + struct av_decision *avd, + struct extended_perms *xperms); struct selinux_mapping { u16 value; /* policy value */ @@ -564,7 +565,8 @@ static void type_attribute_bounds_av(struct context *scontext, context_struct_compute_av(&lo_scontext, tcontext, tclass, - &lo_avd); + &lo_avd, + NULL); if ((lo_avd.allowed & avd->allowed) == avd->allowed) return; /* no masked permission */ masked = ~lo_avd.allowed & avd->allowed; @@ -579,7 +581,8 @@ static void type_attribute_bounds_av(struct context *scontext, context_struct_compute_av(scontext, &lo_tcontext, tclass, - &lo_avd); + &lo_avd, + NULL); if ((lo_avd.allowed & avd->allowed) == avd->allowed) return; /* no masked permission */ masked = ~lo_avd.allowed & avd->allowed; @@ -595,7 +598,8 @@ static void type_attribute_bounds_av(struct context *scontext, context_struct_compute_av(&lo_scontext, &lo_tcontext, tclass, - &lo_avd); + &lo_avd, + NULL); if ((lo_avd.allowed & avd->allowed) == avd->allowed) return; /* no masked permission */ masked = ~lo_avd.allowed & avd->allowed; @@ -612,13 +616,39 @@ static void type_attribute_bounds_av(struct context *scontext, } /* - * Compute access vectors based on a context structure pair for - * the permissions in a particular class. + * flag which drivers have permissions + * only looking for ioctl based extended permssions + */ +void services_compute_xperms_drivers( + struct extended_perms *xperms, + struct avtab_node *node) +{ + unsigned int i; + + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { + /* if one or more driver has all permissions allowed */ + for (i = 0; i < ARRAY_SIZE(xperms->drivers.p); i++) + xperms->drivers.p[i] |= node->datum.u.xperms->perms.p[i]; + } else if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { + /* if allowing permissions within a driver */ + security_xperm_set(xperms->drivers.p, + node->datum.u.xperms->driver); + } + + /* If no ioctl commands are allowed, ignore auditallow and auditdeny */ + if (node->key.specified & AVTAB_XPERMS_ALLOWED) + xperms->len = 1; +} + +/* + * Compute access vectors and extended permissions based on a context + * structure pair for the permissions in a particular class. */ static void context_struct_compute_av(struct context *scontext, - struct context *tcontext, - u16 tclass, - struct av_decision *avd) + struct context *tcontext, + u16 tclass, + struct av_decision *avd, + struct extended_perms *xperms) { struct constraint_node *constraint; struct role_allow *ra; @@ -632,6 +662,10 @@ static void context_struct_compute_av(struct context *scontext, avd->allowed = 0; avd->auditallow = 0; avd->auditdeny = 0xffffffff; + if (xperms) { + memset(&xperms->drivers, 0, sizeof(xperms->drivers)); + xperms->len = 0; + } if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) { if (printk_ratelimit()) @@ -646,7 +680,7 @@ static void context_struct_compute_av(struct context *scontext, * this permission check, then use it. */ avkey.target_class = tclass; - avkey.specified = AVTAB_AV; + avkey.specified = AVTAB_AV | AVTAB_XPERMS; sattr = flex_array_get(policydb.type_attr_map_array, scontext->type - 1); BUG_ON(!sattr); tattr = flex_array_get(policydb.type_attr_map_array, tcontext->type - 1); @@ -659,15 +693,18 @@ static void context_struct_compute_av(struct context *scontext, node; node = avtab_search_node_next(node, avkey.specified)) { if (node->key.specified == AVTAB_ALLOWED) - avd->allowed |= node->datum.data; + avd->allowed |= node->datum.u.data; else if (node->key.specified == AVTAB_AUDITALLOW) - avd->auditallow |= node->datum.data; + avd->auditallow |= node->datum.u.data; else if (node->key.specified == AVTAB_AUDITDENY) - avd->auditdeny &= node->datum.data; + avd->auditdeny &= node->datum.u.data; + else if (xperms && (node->key.specified & AVTAB_XPERMS)) + services_compute_xperms_drivers(xperms, node); } /* Check conditional av table for additional permissions */ - cond_compute_av(&policydb.te_cond_avtab, &avkey, avd); + cond_compute_av(&policydb.te_cond_avtab, &avkey, + avd, xperms); } } @@ -898,6 +935,139 @@ static void avd_init(struct av_decision *avd) avd->flags = 0; } +void services_compute_xperms_decision(struct extended_perms_decision *xpermd, + struct avtab_node *node) +{ + unsigned int i; + + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { + if (xpermd->driver != node->datum.u.xperms->driver) + return; + } else if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { + if (!security_xperm_test(node->datum.u.xperms->perms.p, + xpermd->driver)) + return; + } else { + BUG(); + } + + if (node->key.specified == AVTAB_XPERMS_ALLOWED) { + xpermd->used |= XPERMS_ALLOWED; + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { + memset(xpermd->allowed->p, 0xff, + sizeof(xpermd->allowed->p)); + } + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { + for (i = 0; i < ARRAY_SIZE(xpermd->allowed->p); i++) + xpermd->allowed->p[i] |= + node->datum.u.xperms->perms.p[i]; + } + } else if (node->key.specified == AVTAB_XPERMS_AUDITALLOW) { + xpermd->used |= XPERMS_AUDITALLOW; + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { + memset(xpermd->auditallow->p, 0xff, + sizeof(xpermd->auditallow->p)); + } + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { + for (i = 0; i < ARRAY_SIZE(xpermd->auditallow->p); i++) + xpermd->auditallow->p[i] |= + node->datum.u.xperms->perms.p[i]; + } + } else if (node->key.specified == AVTAB_XPERMS_DONTAUDIT) { + xpermd->used |= XPERMS_DONTAUDIT; + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { + memset(xpermd->dontaudit->p, 0xff, + sizeof(xpermd->dontaudit->p)); + } + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { + for (i = 0; i < ARRAY_SIZE(xpermd->dontaudit->p); i++) + xpermd->dontaudit->p[i] |= + node->datum.u.xperms->perms.p[i]; + } + } else { + BUG(); + } +} + +void security_compute_xperms_decision(u32 ssid, + u32 tsid, + u16 orig_tclass, + u8 driver, + struct extended_perms_decision *xpermd) +{ + u16 tclass; + struct context *scontext, *tcontext; + struct avtab_key avkey; + struct avtab_node *node; + struct ebitmap *sattr, *tattr; + struct ebitmap_node *snode, *tnode; + unsigned int i, j; + + xpermd->driver = driver; + xpermd->used = 0; + memset(xpermd->allowed->p, 0, sizeof(xpermd->allowed->p)); + memset(xpermd->auditallow->p, 0, sizeof(xpermd->auditallow->p)); + memset(xpermd->dontaudit->p, 0, sizeof(xpermd->dontaudit->p)); + + read_lock(&policy_rwlock); + if (!ss_initialized) + goto allow; + + scontext = sidtab_search(&sidtab, ssid); + if (!scontext) { + printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", + __func__, ssid); + goto out; + } + + tcontext = sidtab_search(&sidtab, tsid); + if (!tcontext) { + printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", + __func__, tsid); + goto out; + } + + tclass = unmap_class(orig_tclass); + if (unlikely(orig_tclass && !tclass)) { + if (policydb.allow_unknown) + goto allow; + goto out; + } + + + if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) { + pr_warn_ratelimited("SELinux: Invalid class %hu\n", tclass); + goto out; + } + + avkey.target_class = tclass; + avkey.specified = AVTAB_XPERMS; + sattr = flex_array_get(policydb.type_attr_map_array, + scontext->type - 1); + BUG_ON(!sattr); + tattr = flex_array_get(policydb.type_attr_map_array, + tcontext->type - 1); + BUG_ON(!tattr); + ebitmap_for_each_positive_bit(sattr, snode, i) { + ebitmap_for_each_positive_bit(tattr, tnode, j) { + avkey.source_type = i + 1; + avkey.target_type = j + 1; + for (node = avtab_search_node(&policydb.te_avtab, &avkey); + node; + node = avtab_search_node_next(node, avkey.specified)) + services_compute_xperms_decision(xpermd, node); + + cond_compute_xperms(&policydb.te_cond_avtab, + &avkey, xpermd); + } + } +out: + read_unlock(&policy_rwlock); + return; +allow: + memset(xpermd->allowed->p, 0xff, sizeof(xpermd->allowed->p)); + goto out; +} /** * security_compute_av - Compute access vector decisions. @@ -905,6 +1075,7 @@ static void avd_init(struct av_decision *avd) * @tsid: target security identifier * @tclass: target security class * @avd: access vector decisions + * @xperms: extended permissions * * Compute a set of access vector decisions based on the * SID pair (@ssid, @tsid) for the permissions in @tclass. @@ -912,13 +1083,15 @@ static void avd_init(struct av_decision *avd) void security_compute_av(u32 ssid, u32 tsid, u16 orig_tclass, - struct av_decision *avd) + struct av_decision *avd, + struct extended_perms *xperms) { u16 tclass; struct context *scontext = NULL, *tcontext = NULL; read_lock(&policy_rwlock); avd_init(avd); + xperms->len = 0; if (!ss_initialized) goto allow; @@ -946,7 +1119,7 @@ void security_compute_av(u32 ssid, goto allow; goto out; } - context_struct_compute_av(scontext, tcontext, tclass, avd); + context_struct_compute_av(scontext, tcontext, tclass, avd, xperms); map_decision(orig_tclass, avd, policydb.allow_unknown); out: read_unlock(&policy_rwlock); @@ -992,7 +1165,7 @@ void security_compute_av_user(u32 ssid, goto out; } - context_struct_compute_av(scontext, tcontext, tclass, avd); + context_struct_compute_av(scontext, tcontext, tclass, avd, NULL); out: read_unlock(&policy_rwlock); return; @@ -1512,7 +1685,7 @@ static int security_compute_sid(u32 ssid, if (avdatum) { /* Use the type from the type transition/member/change rule. */ - newcontext.type = avdatum->data; + newcontext.type = avdatum->u.data; } /* if we have a objname this is a file trans check so check those rules */ diff --git a/security/selinux/ss/services.h b/security/selinux/ss/services.h index e8d907e903cdb..6abcd8729ec3a 100644 --- a/security/selinux/ss/services.h +++ b/security/selinux/ss/services.h @@ -11,5 +11,11 @@ extern struct policydb policydb; +void services_compute_xperms_drivers(struct extended_perms *xperms, + struct avtab_node *node); + +void services_compute_xperms_decision(struct extended_perms_decision *xpermd, + struct avtab_node *node); + #endif /* _SS_SERVICES_H_ */ From a80f15e11b3d1d75097ef62f22d0350423359c6f Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Wed, 7 Jan 2015 09:27:15 -0800 Subject: [PATCH 006/320] pstore: selinux: add security in-core xattr support for pstore and debugfs - add "pstore" and "debugfs" to list of in-core exceptions - change fstype checks to boolean equation - change from strncmp to strcmp for checking (Cherry Pick from commit 2294d499b7969df3838becf5e58bf16b0e3c86c8) Signed-off-by: Mark Salyzyn Signed-off-by: Bharat Pawar Bug: 18917345 Bug: 18935184 Change-Id: Ib648f30ce4b5d6c96f11465836d6fee89bec1c72 --- security/selinux/hooks.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 47aa35d2dcbd5..1a39d9e9a1430 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -432,8 +432,11 @@ static int sb_finish_set_opts(struct super_block *sb) sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) sbsec->flags &= ~SE_SBLABELSUPP; - /* Special handling for sysfs. Is genfs but also has setxattr handler*/ - if (strncmp(sb->s_type->name, "sysfs", sizeof("sysfs")) == 0) + /* Special handling. Is genfs but also has in-core setxattr handler*/ + if (!strcmp(sb->s_type->name, "sysfs") || + !strcmp(sb->s_type->name, "pstore") || + !strcmp(sb->s_type->name, "debugfs") || + !strcmp(sb->s_type->name, "rootfs")) sbsec->flags |= SE_SBLABELSUPP; /* From 11d80e6cbf595a0ab6403b3eb55273ea6cf55206 Mon Sep 17 00:00:00 2001 From: Jeff Vander Stoep Date: Thu, 22 Oct 2015 09:30:40 -0700 Subject: [PATCH 007/320] selinux: Android kernel compatibility with M userspace NOT intended for new Android devices - this commit is unnecessary for a target device that does not have a previous M variant. DO NOT upstream. Android only. Motivation: This commit mitigates a mismatch between selinux kernel and selinux userspace. The selinux ioctl white-listing binary policy format that was accepted into Android M differs slightly from what was later accepted into the upstream kernel. This leaves Android master branch kernels incompatible with Android M releases. This patch restores backwards compatibility. This is important because: 1. kernels may be updated on a different cycle than the rest of the OS e.g. security patching. 2. Android M bringup may still be ongoing for some devices. The same kernel should work for both M and master. Backwards compatibility is achieved by checking for an Android M policy characteristic during initial policy read and converting to upstream policy format. The inverse conversion is done for policy write as required for CTS testing Bug: 22846070 Change-Id: I2f1ee2eee402f37cf3c9df9f9e03c1b9ddec1929 Signed-off-by: Jeff Vander Stoep Signed-off-by: Bharat Pawar --- security/selinux/ss/avtab.c | 69 ++++++++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 8 deletions(-) diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c index a6bef631b74e8..640c16b9d3fb7 100644 --- a/security/selinux/ss/avtab.c +++ b/security/selinux/ss/avtab.c @@ -335,6 +335,32 @@ void avtab_hash_eval(struct avtab *h, char *tag) chain2_len_sum); } +/* + * extended permissions compatibility. Make ToT Android kernels compatible + * with Android M releases + */ +#define AVTAB_OPTYPE_ALLOWED 0x1000 +#define AVTAB_OPTYPE_AUDITALLOW 0x2000 +#define AVTAB_OPTYPE_DONTAUDIT 0x4000 +#define AVTAB_OPTYPE (AVTAB_OPTYPE_ALLOWED | \ + AVTAB_OPTYPE_AUDITALLOW | \ + AVTAB_OPTYPE_DONTAUDIT) +#define AVTAB_XPERMS_OPTYPE 4 + +#define avtab_xperms_to_optype(x) (x << AVTAB_XPERMS_OPTYPE) +#define avtab_optype_to_xperms(x) (x >> AVTAB_XPERMS_OPTYPE) + +static unsigned int avtab_android_m_compat; + +static void avtab_android_m_compat_set(void) +{ + if (!avtab_android_m_compat) { + pr_info("SELinux: Android master kernel running Android" + " M policy in compatibility mode.\n"); + avtab_android_m_compat = 1; + } +} + static uint16_t spec_order[] = { AVTAB_ALLOWED, AVTAB_AUDITDENY, @@ -359,6 +385,7 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, struct avtab_datum datum; struct avtab_extended_perms xperms; __le32 buf32[ARRAY_SIZE(xperms.perms.p)]; + unsigned int android_m_compat_optype = 0; int i, rc; unsigned set; @@ -449,6 +476,13 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, key.target_class = le16_to_cpu(buf16[items++]); key.specified = le16_to_cpu(buf16[items++]); + if ((key.specified & AVTAB_OPTYPE) && + (vers == POLICYDB_VERSION_XPERMS_IOCTL)) { + key.specified = avtab_optype_to_xperms(key.specified); + android_m_compat_optype = 1; + avtab_android_m_compat_set(); + } + if (!policydb_type_isvalid(pol, key.source_type) || !policydb_type_isvalid(pol, key.target_type) || !policydb_class_isvalid(pol, key.target_class)) { @@ -479,10 +513,22 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, printk(KERN_ERR "SELinux: avtab: truncated entry\n"); return rc; } - rc = next_entry(&xperms.driver, fp, sizeof(u8)); - if (rc) { - printk(KERN_ERR "SELinux: avtab: truncated entry\n"); - return rc; + if (avtab_android_m_compat || + ((xperms.specified != AVTAB_XPERMS_IOCTLFUNCTION) && + (xperms.specified != AVTAB_XPERMS_IOCTLDRIVER) && + (vers == POLICYDB_VERSION_XPERMS_IOCTL))) { + xperms.driver = xperms.specified; + if (android_m_compat_optype) + xperms.specified = AVTAB_XPERMS_IOCTLDRIVER; + else + xperms.specified = AVTAB_XPERMS_IOCTLFUNCTION; + avtab_android_m_compat_set(); + } else { + rc = next_entry(&xperms.driver, fp, sizeof(u8)); + if (rc) { + printk(KERN_ERR "SELinux: avtab: truncated entry\n"); + return rc; + } } rc = next_entry(buf32, fp, sizeof(u32)*ARRAY_SIZE(xperms.perms.p)); if (rc) { @@ -568,15 +614,22 @@ int avtab_write_item(struct policydb *p, struct avtab_node *cur, void *fp) buf16[0] = cpu_to_le16(cur->key.source_type); buf16[1] = cpu_to_le16(cur->key.target_type); buf16[2] = cpu_to_le16(cur->key.target_class); - buf16[3] = cpu_to_le16(cur->key.specified); + if (avtab_android_m_compat && (cur->key.specified & AVTAB_XPERMS) && + (cur->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER)) + buf16[3] = cpu_to_le16(avtab_xperms_to_optype(cur->key.specified)); + else + buf16[3] = cpu_to_le16(cur->key.specified); rc = put_entry(buf16, sizeof(u16), 4, fp); if (rc) return rc; if (cur->key.specified & AVTAB_XPERMS) { - rc = put_entry(&cur->datum.u.xperms->specified, sizeof(u8), 1, fp); - if (rc) - return rc; + if (avtab_android_m_compat == 0) { + rc = put_entry(&cur->datum.u.xperms->specified, + sizeof(u8), 1, fp); + if (rc) + return rc; + } rc = put_entry(&cur->datum.u.xperms->driver, sizeof(u8), 1, fp); if (rc) return rc; From 8807ad32392d4a9ed0a66a337f66421921779de8 Mon Sep 17 00:00:00 2001 From: Aravind Asam Date: Fri, 18 Sep 2015 12:39:46 -0700 Subject: [PATCH 008/320] selinux: do not check open perm on ftruncate call Use the ATTR_FILE attribute to distinguish between truncate() and ftruncate() system calls. The two other cases where do_truncate is called with a filp (and therefore ATTR_FILE is set) are for coredump files and for open(O_TRUNC). In both of those cases the open permission has already been checked during file open and therefore does not need to be repeated. Commit 95dbf739313f ("SELinux: check OPEN on truncate calls") fixed a major issue where domains were allowed to truncate files without the open permission. However, it introduced a new bug where a domain with the write permission can no longer ftruncate files without the open permission, even when they receive an already open file. (cherry picked from commit b21800f304392ee5d20f411c37470183cc779f11) Bug: 22567870 Change-Id: I2525a0e244c8d635b2d0c1f966071edbb365a43a Signed-off-by: Jeff Vander Stoep Acked-by: Stephen Smalley Signed-off-by: Paul Moore Git-commit: e9e500827b871459306974c32a0b6398375ce7d5 Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: David Ng Signed-off-by: Aravind Asam Signed-off-by: Bharat Pawar --- security/selinux/hooks.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 1a39d9e9a1430..14ca80cb0ec15 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2866,7 +2866,8 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) return dentry_has_perm(cred, dentry, FILE__SETATTR); - if (selinux_policycap_openperm && (ia_valid & ATTR_SIZE)) + if (selinux_policycap_openperm && (ia_valid & ATTR_SIZE) + && !(ia_valid & ATTR_FILE)) av |= FILE__OPEN; return dentry_has_perm(cred, dentry, av); From 54114c228181f69fcd3f009275f70034259d0ebe Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Mon, 23 Nov 2015 16:07:41 -0500 Subject: [PATCH 009/320] UPSTREAM: selinux: fix bug in conditional rules handling (cherry picked from commit commit f3bef67992e8698897b584616535803887c4a73e). commit fa1aa143ac4a ("selinux: extended permissions for ioctls") introduced a bug into the handling of conditional rules, skipping the processing entirely when the caller does not provide an extended permissions (xperms) structure. Access checks from userspace using /sys/fs/selinux/access do not include such a structure since that interface does not presently expose extended permission information. As a result, conditional rules were being ignored entirely on userspace access requests, producing denials when access was allowed by conditional rules in the policy. Fix the bug by only skipping computation of extended permissions in this situation, not the entire conditional rules processing. Change-Id: I24f39e3907d0b00a4194e15a4472e8d859508fa9 Reported-by: Laurent Bigonville Signed-off-by: Stephen Smalley [PM: fixed long lines in patch description] Cc: stable@vger.kernel.org # 4.3 Signed-off-by: Paul Moore Git-commit: bd8d3dd3ae35f283f3b76e47b9762225c9f7d46c Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: David Ng Signed-off-by: Bharat Pawar --- security/selinux/ss/conditional.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c index 6618fb45cca00..ba7dd93661040 100644 --- a/security/selinux/ss/conditional.c +++ b/security/selinux/ss/conditional.c @@ -643,7 +643,7 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key, { struct avtab_node *node; - if (!ctab || !key || !avd || !xperms) + if (!ctab || !key || !avd) return; for (node = avtab_search_node(ctab, key); node; @@ -662,7 +662,7 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key, if ((u16)(AVTAB_AUDITALLOW|AVTAB_ENABLED) == (node->key.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED))) avd->auditallow |= node->datum.u.data; - if ((node->key.specified & AVTAB_ENABLED) && + if (xperms && (node->key.specified & AVTAB_ENABLED) && (node->key.specified & AVTAB_XPERMS)) services_compute_xperms_drivers(xperms, node); } From a1bd77c4885dcf6047d50a9f16c26da9dfdcb2b7 Mon Sep 17 00:00:00 2001 From: "Se Wang (Patrick) Oh" Date: Thu, 30 Jul 2015 15:48:39 -0700 Subject: [PATCH 010/320] qcom: scm: Support register x6 to pass the session id Non-atomic scm call which could be interrupted, trustzone will store the session id in a register(x6) which will be used when trustzone resumes the call. To avoid x6 being used by compiler, HLOS now uses it to send a zero before making scm call. This is the same change as in the 32bit scm call. Change-Id: If7a3ee28bdbf22acf447531603819a6f4f1603ca Signed-off-by: Se Wang (Patrick) Oh --- drivers/soc/qcom/scm.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/soc/qcom/scm.c b/drivers/soc/qcom/scm.c index c806f110ad1ff..795f33da63aad 100644 --- a/drivers/soc/qcom/scm.c +++ b/drivers/soc/qcom/scm.c @@ -101,6 +101,7 @@ struct scm_response { #define R3_STR "x3" #define R4_STR "x4" #define R5_STR "x5" +#define R6_STR "x6" /* Outer caches unsupported on ARM64 platforms */ #define outer_inv_range(x, y) @@ -370,6 +371,7 @@ static int __scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5, register u64 r3 asm("r3") = x3; register u64 r4 asm("r4") = x4; register u64 r5 asm("r5") = x5; + register u64 r6 asm("r6") = 0; do { asm volatile( @@ -383,14 +385,15 @@ static int __scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5, __asmeq("%7", R3_STR) __asmeq("%8", R4_STR) __asmeq("%9", R5_STR) + __asmeq("%10", R6_STR) #ifdef REQUIRES_SEC ".arch_extension sec\n" #endif "smc #0\n" : "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3) : "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4), - "r" (r5) - : "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", + "r" (r5), "r" (r6) + : "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17"); } while (r0 == SCM_INTERRUPTED); @@ -413,6 +416,7 @@ static int __scm_call_armv8_32(u32 w0, u32 w1, u32 w2, u32 w3, u32 w4, u32 w5, register u32 r3 asm("r3") = w3; register u32 r4 asm("r4") = w4; register u32 r5 asm("r5") = w5; + register u32 r6 asm("r6") = 0; do { asm volatile( @@ -426,14 +430,15 @@ static int __scm_call_armv8_32(u32 w0, u32 w1, u32 w2, u32 w3, u32 w4, u32 w5, __asmeq("%7", R3_STR) __asmeq("%8", R4_STR) __asmeq("%9", R5_STR) + __asmeq("%10", R6_STR) #ifdef REQUIRES_SEC ".arch_extension sec\n" #endif "smc #0\n" : "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3) : "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4), - "r" (r5) - : "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", + "r" (r5), "r" (r6) + : "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17"); } while (r0 == SCM_INTERRUPTED); From 6547abe0405080cb2452b58d9a224cc2c4d76a0c Mon Sep 17 00:00:00 2001 From: Ravinder Konka Date: Mon, 26 Oct 2015 13:15:33 +0530 Subject: [PATCH 011/320] rmnet_data : Changes to support Scatter Gather and GSO. This patch enables hardware device features such as NETIF_F_SG NETIF_F_GSO NETIF_F_GSO_UDP_TUNNEL NETIF_F_GSO_UDP_TUNNEL_CSUM. This patch also ensures to skip padding(to align length to word boundaries) for outgoing non linear skbs. This patch also adds a new ioctl interface RMNET_IOCTL_GET_SG_SUPPORT to query the physical network devices for Scatter Gather support. Change-Id: I9788d75c249ab2dac5b598dad131c0692ed84e4d Acked-by: Abhishek Chauhan Signed-off-by: Ravinder Konka --- include/uapi/linux/msm_rmnet.h | 3 ++- net/rmnet_data/rmnet_map_data.c | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/msm_rmnet.h b/include/uapi/linux/msm_rmnet.h index 936b4373d09f6..4892602c2b94f 100644 --- a/include/uapi/linux/msm_rmnet.h +++ b/include/uapi/linux/msm_rmnet.h @@ -59,7 +59,8 @@ enum rmnet_ioctl_extended_cmds_e { RMNET_IOCTL_SET_SLEEP_STATE = 0x0014, /* Set sleep state */ RMNET_IOCTL_SET_XLAT_DEV_INFO = 0x0015, /* xlat dev name */ RMNET_IOCTL_DEREGISTER_DEV = 0x0016, /* Dereg a net dev */ - RMNET_IOCTL_EXTENDED_MAX = 0x0017 + RMNET_IOCTL_GET_SG_SUPPORT = 0x0017, /* Query sg support*/ + RMNET_IOCTL_EXTENDED_MAX = 0x0018 }; /* Return values for the RMNET_IOCTL_GET_SUPPORTED_FEATURES IOCTL */ diff --git a/net/rmnet_data/rmnet_map_data.c b/net/rmnet_data/rmnet_map_data.c index 4a00b775c0997..18f239a17b7b8 100644 --- a/net/rmnet_data/rmnet_map_data.c +++ b/net/rmnet_data/rmnet_map_data.c @@ -79,6 +79,15 @@ struct rmnet_map_header_s *rmnet_map_add_map_header(struct sk_buff *skb, padding = ALIGN(map_datalen, 4) - map_datalen; + if (padding == 0) + goto done; + + if ((skb->dev->features & NETIF_F_GSO) && + skb_is_nonlinear(skb) && unlikely((padding != 0))) { + LOGE("pad:%d required for non linear skb", padding); + BUG(); + } + if (skb_tailroom(skb) < padding) return 0; @@ -86,6 +95,7 @@ struct rmnet_map_header_s *rmnet_map_add_map_header(struct sk_buff *skb, LOGD("pad: %d", padding); memset(padbytes, 0, padding); +done: map_header->pkt_len = htons(map_datalen + padding); map_header->pad_len = padding&0x3F; From 766ff9ddd9f73192483a4dc6c33f18ce91cef287 Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Wed, 30 Mar 2016 17:12:16 +0530 Subject: [PATCH 012/320] msm: limits: Check user buffer size before copying to local buffer User input data is passed in from userspace through debugfs interface of supply lm core to validate supply lm core functionality. Ensure user buffer size is not greater than expected stack buffer size to avoid out of bounds array accesses. Change-Id: I5a93774855241b50895c5e2b3ff939e4c33a0185 Signed-off-by: Manaf Meethalavalappu Pallikunhi --- drivers/thermal/supply_lm_core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/supply_lm_core.c b/drivers/thermal/supply_lm_core.c index fc8e807317f7c..a4d137f8b3f0f 100644 --- a/drivers/thermal/supply_lm_core.c +++ b/drivers/thermal/supply_lm_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -303,6 +303,11 @@ static ssize_t supply_lm_input_write(struct file *fp, enum corner_state gpu; enum corner_state modem; + if (count > (MODE_MAX - 1)) { + pr_err("Invalid user input\n"); + return -EINVAL; + } + if (copy_from_user(&buf, user_buffer, count)) return -EFAULT; From 07201b733d0facb9d57872280886e99891573285 Mon Sep 17 00:00:00 2001 From: Tarun Karra Date: Thu, 17 Mar 2016 21:10:36 -0700 Subject: [PATCH 013/320] msm: kgsl: verify user memory permissions before mapping to GPU driver For user memory of type KGSL_USER_MEM_TYPE_ADDR mapped to GPU driver verify permissions and map GPU permissions same as CPU permissions. If elevated permissions are requested return an error to prevent privilege escalation. Without this check user could map readonly memory into GPU driver as readwrite and gain elevated privilege. Write permissions check is currently inverted causing readonly user pages to be mapped as readwrite in GPU driver. Fix this check to map readonly pages as readonly. CRs-Fixed: 988993 Change-Id: I0e097d7e4e4c414c0849e33bcc61a26fb94291ad Signed-off-by: Tarun Karra Signed-off-by: Sunil Khatri --- drivers/gpu/msm/kgsl.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index f14208b6b5ca1..5f06af5858a07 100755 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -2762,6 +2762,20 @@ static int kgsl_setup_phys_file(struct kgsl_mem_entry *entry, } #endif +static int check_vma_flags(struct vm_area_struct *vma, + unsigned int flags) +{ + unsigned long flags_requested = (VM_READ | VM_WRITE); + + if (flags & KGSL_MEMFLAGS_GPUREADONLY) + flags_requested &= ~VM_WRITE; + + if ((vma->vm_flags & flags_requested) == flags_requested) + return 0; + + return -EFAULT; +} + static int check_vma(struct vm_area_struct *vma, struct file *vmfile, struct kgsl_memdesc *memdesc) { @@ -2775,7 +2789,7 @@ static int check_vma(struct vm_area_struct *vma, struct file *vmfile, if (vma->vm_start != memdesc->useraddr || (memdesc->useraddr + memdesc->size) != vma->vm_end) return -EINVAL; - return 0; + return check_vma_flags(vma, memdesc->flags); } static int memdesc_sg_virt(struct kgsl_memdesc *memdesc, struct file *vmfile) @@ -2784,7 +2798,7 @@ static int memdesc_sg_virt(struct kgsl_memdesc *memdesc, struct file *vmfile) long npages = 0, i; unsigned long sglen = memdesc->size / PAGE_SIZE; struct page **pages = NULL; - int write = (memdesc->flags & KGSL_MEMFLAGS_GPUREADONLY) != 0; + int write = ((memdesc->flags & KGSL_MEMFLAGS_GPUREADONLY) ? 0 : 1); if (sglen == 0 || sglen >= LONG_MAX) return -EINVAL; @@ -2870,6 +2884,7 @@ static int kgsl_setup_useraddr(struct kgsl_mem_entry *entry, struct kgsl_map_user_mem *param = data; struct dma_buf *dmabuf = NULL; struct vm_area_struct *vma = NULL; + int ret; if (param->offset != 0 || param->hostptr == 0 || !KGSL_IS_PAGE_ALIGNED(param->hostptr) @@ -2886,6 +2901,12 @@ static int kgsl_setup_useraddr(struct kgsl_mem_entry *entry, if (vma && vma->vm_file) { int fd; + ret = check_vma_flags(vma, entry->memdesc.flags); + if (ret) { + up_read(¤t->mm->mmap_sem); + return ret; + } + /* * Check to see that this isn't our own memory that we have * already mapped @@ -2904,7 +2925,7 @@ static int kgsl_setup_useraddr(struct kgsl_mem_entry *entry, up_read(¤t->mm->mmap_sem); if (!IS_ERR_OR_NULL(dmabuf)) { - int ret = kgsl_setup_dma_buf(entry, pagetable, device, dmabuf); + ret = kgsl_setup_dma_buf(entry, pagetable, device, dmabuf); if (ret) dma_buf_put(dmabuf); else { From d5422b95ffdac87ad73c7765e35300fa748f6b1f Mon Sep 17 00:00:00 2001 From: Patrick Daly Date: Thu, 28 May 2015 18:05:54 -0700 Subject: [PATCH 014/320] ASoC: msm: qdsp6v2: DAP: Fix unprotected userspace access Use get_user() & friends to access userspace addresses. Change-Id: I9741a60e53f6253da27913175e9b8c4abbf50db9 Signed-off-by: Patrick Daly Signed-off-by: Pradnya Chaphekar --- sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c index 67a94006c54d5..7761b9c725789 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c @@ -1354,11 +1354,13 @@ static int msm_ds2_dap_commit_params(struct dolby_param_data *dolby_data, static int msm_ds2_dap_handle_commands(u32 cmd, void *arg) { int ret = 0, port_id = 0; + int32_t data; struct dolby_param_data *dolby_data = (struct dolby_param_data *)arg; + get_user(data, &dolby_data->data[0]); pr_debug("%s: param_id %d,be_id %d,device_id 0x%x,length %d,data %d\n", __func__, dolby_data->param_id, dolby_data->be_id, - dolby_data->device_id, dolby_data->length, dolby_data->data[0]); + dolby_data->device_id, dolby_data->length, data); switch (dolby_data->param_id) { case DAP_CMD_COMMIT_ALL: @@ -1370,18 +1372,18 @@ static int msm_ds2_dap_handle_commands(u32 cmd, void *arg) break; case DAP_CMD_USE_CACHE_FOR_INIT: - ds2_dap_params_states.use_cache = dolby_data->data[0]; + ds2_dap_params_states.use_cache = data; break; case DAP_CMD_SET_BYPASS: pr_debug("%s: bypass %d bypass type %d, data %d\n", __func__, ds2_dap_params_states.dap_bypass, ds2_dap_params_states.dap_bypass_type, - dolby_data->data[0]); + data); /* Do not perform bypass operation if bypass state is same*/ - if (ds2_dap_params_states.dap_bypass == dolby_data->data[0]) + if (ds2_dap_params_states.dap_bypass == data) break; - ds2_dap_params_states.dap_bypass = dolby_data->data[0]; + ds2_dap_params_states.dap_bypass = data; /* hard bypass */ if (ds2_dap_params_states.dap_bypass_type == DAP_HARD_BYPASS) msm_ds2_dap_handle_bypass(dolby_data); @@ -1390,7 +1392,7 @@ static int msm_ds2_dap_handle_commands(u32 cmd, void *arg) break; case DAP_CMD_SET_BYPASS_TYPE: - if (dolby_data->data[0] == true) + if (data == true) ds2_dap_params_states.dap_bypass_type = DAP_HARD_BYPASS; else @@ -1429,6 +1431,7 @@ static int msm_ds2_dap_set_param(u32 cmd, void *arg) { int rc = 0, idx, i, j, off, port_id = 0, cdev = 0; int32_t num_device = 0; + int32_t data = 0; int32_t dev_arr[DS2_DSP_SUPPORTED_ENDP_DEVICE] = {0}; struct dolby_param_data *dolby_data = (struct dolby_param_data *)arg; @@ -1472,10 +1475,10 @@ static int msm_ds2_dap_set_param(u32 cmd, void *arg) ds2_dap_params[cdev].dap_params_modified[idx] += 1; for (j = 0; j < dolby_data->length; j++) { off = ds2_dap_params_offset[idx]; - ds2_dap_params[cdev].params_val[off + j] = - dolby_data->data[j]; + get_user(data, &dolby_data->data[j]); + ds2_dap_params[cdev].params_val[off + j] = data; pr_debug("%s:off %d,val[i/p:o/p]-[%d / %d]\n", - __func__, off, dolby_data->data[j], + __func__, off, data, ds2_dap_params[cdev]. params_val[off + j]); } From 231725b18952f93c933c13d08e74dfc08bf2efa7 Mon Sep 17 00:00:00 2001 From: Manu Gautam Date: Tue, 5 Apr 2016 15:20:47 +0530 Subject: [PATCH 015/320] usb: f_serial: Check for SMD data length in GSER_IOCTL If user tries to send SMD data more than the driver buffer can handle then fail the same and print error message. This smd_write is exposed to userspace through ioctl using a misc device. Change-Id: Ie8a1c1c0799cd10cef512ad6b1e1e95001dd43b2 Signed-off-by: Manu Gautam --- drivers/usb/gadget/f_serial.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c index 7190194adf012..c51c5b8eb09fb 100644 --- a/drivers/usb/gadget/f_serial.c +++ b/drivers/usb/gadget/f_serial.c @@ -1358,6 +1358,13 @@ static long gser_ioctl(struct file *fp, unsigned cmd, unsigned long arg) smd_port_num = gserial_ports[gser->port_num].client_port_num; + if (smd_write_arg.size > GSERIAL_BUF_LEN) { + pr_err("%s: Invalid size:%u, max: %u", __func__, + smd_write_arg.size, GSERIAL_BUF_LEN); + ret = -EINVAL; + break; + } + pr_debug("%s: Copying %d bytes from user buffer to local\n", __func__, smd_write_arg.size); From 6659219256b61b5517adc784fcfd8199d38b0429 Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Tue, 15 Mar 2016 18:42:27 -0700 Subject: [PATCH 016/320] msm: mdss: fix possible out-of-bounds and overflow issue in mdp debugfs There are few cases where the count argument passed by the user space is not validated, which can potentially lead to out of bounds or overflow issues. In some cases, kernel might copy more data than what is requested. Add necessary checks to avoid such cases. Change-Id: Ifa42fbd475665a0ca581c907ce5432584ea0e7ed Signed-off-by: Veera Sundaram Sankaran --- drivers/video/msm/mdss/mdss_debug.c | 42 ++++++++++++++++------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c index ed1bd0ed6b406..389125e603de5 100644 --- a/drivers/video/msm/mdss/mdss_debug.c +++ b/drivers/video/msm/mdss/mdss_debug.c @@ -111,10 +111,10 @@ static ssize_t panel_debug_base_offset_read(struct file *file, return 0; /* the end */ len = snprintf(buf, sizeof(buf), "0x%02zx %zx\n", dbg->off, dbg->cnt); - if (len < 0) + if (len < 0 || len >= sizeof(buf)) return 0; - if (copy_to_user(buff, buf, len)) + if ((count < sizeof(buf)) || copy_to_user(buff, buf, len)) return -EFAULT; *ppos += len; /* increase offset */ @@ -249,10 +249,11 @@ static ssize_t panel_debug_base_reg_read(struct file *file, if (mdata->debug_inf.debug_enable_clock) mdata->debug_inf.debug_enable_clock(0); - if (len < 0) + if (len < 0 || len >= sizeof(to_user_buf)) return 0; - if (copy_to_user(user_buf, to_user_buf, len)) + if ((count < sizeof(to_user_buf)) + || copy_to_user(user_buf, to_user_buf, len)) return -EFAULT; *ppos += len; /* increase offset */ @@ -386,7 +387,7 @@ static ssize_t mdss_debug_base_offset_read(struct file *file, { struct mdss_debug_base *dbg = file->private_data; int len = 0; - char buf[24]; + char buf[24] = {'\0'}; if (!dbg) return -ENODEV; @@ -395,10 +396,10 @@ static ssize_t mdss_debug_base_offset_read(struct file *file, return 0; /* the end */ len = snprintf(buf, sizeof(buf), "0x%08zx %zx\n", dbg->off, dbg->cnt); - if (len < 0) + if (len < 0 || len >= sizeof(buf)) return 0; - if (copy_to_user(buff, buf, len)) + if ((count < sizeof(buf)) || copy_to_user(buff, buf, len)) return -EFAULT; *ppos += len; /* increase offset */ @@ -629,7 +630,7 @@ static ssize_t mdss_debug_factor_read(struct file *file, { struct mdss_fudge_factor *factor = file->private_data; int len = 0; - char buf[32]; + char buf[32] = {'\0'}; if (!factor) return -ENODEV; @@ -639,10 +640,10 @@ static ssize_t mdss_debug_factor_read(struct file *file, len = snprintf(buf, sizeof(buf), "%d/%d\n", factor->numer, factor->denom); - if (len < 0) + if (len < 0 || len >= sizeof(buf)) return 0; - if (copy_to_user(buff, buf, len)) + if ((count < sizeof(buf)) || copy_to_user(buff, buf, len)) return -EFAULT; *ppos += len; /* increase offset */ @@ -673,6 +674,8 @@ static ssize_t mdss_debug_perf_mode_write(struct file *file, if (copy_from_user(buf, user_buf, count)) return -EFAULT; + buf[count] = 0; /* end of string */ + if (sscanf(buf, "%d", &perf_mode) != 1) return -EFAULT; @@ -693,7 +696,7 @@ static ssize_t mdss_debug_perf_mode_read(struct file *file, { struct mdss_perf_tune *perf_tune = file->private_data; int len = 0; - char buf[40]; + char buf[40] = {'\0'}; if (!perf_tune) return -ENODEV; @@ -701,14 +704,12 @@ static ssize_t mdss_debug_perf_mode_read(struct file *file, if (*ppos) return 0; /* the end */ - buf[count] = 0; - len = snprintf(buf, sizeof(buf), "min_mdp_clk %lu min_bus_vote %llu\n", perf_tune->min_mdp_clk, perf_tune->min_bus_vote); - if (len < 0) + if (len < 0 || len >= sizeof(buf)) return 0; - if (copy_to_user(buff, buf, len)) + if ((count < sizeof(buf)) || copy_to_user(buff, buf, len)) return -EFAULT; *ppos += len; /* increase offset */ @@ -728,7 +729,7 @@ static ssize_t mdss_debug_perf_panic_read(struct file *file, { struct mdss_data_type *mdata = file->private_data; int len = 0; - char buf[40]; + char buf[40] = {'\0'}; if (!mdata) return -ENODEV; @@ -738,10 +739,10 @@ static ssize_t mdss_debug_perf_panic_read(struct file *file, len = snprintf(buf, sizeof(buf), "%d\n", !mdata->has_panic_ctrl); - if (len < 0) + if (len < 0 || len >= sizeof(buf)) return 0; - if (copy_to_user(buff, buf, len)) + if ((count < sizeof(buf)) || copy_to_user(buff, buf, len)) return -EFAULT; *ppos += len; /* increase offset */ @@ -804,9 +805,14 @@ static ssize_t mdss_debug_perf_panic_write(struct file *file, if (!mdata) return -EFAULT; + if (count >= sizeof(buf)) + return -EFAULT; + if (copy_from_user(buf, user_buf, count)) return -EFAULT; + buf[count] = 0; /* end of string */ + if (sscanf(buf, "%d", &disable_panic) != 1) return -EFAULT; From d88726a8e51b8d58dc7cc1a17fe623f5f0c21bb3 Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Wed, 30 Mar 2016 17:12:16 +0530 Subject: [PATCH 017/320] msm: limits: Check user buffer size before copying to local buffer User input data is passed in from userspace through debugfs interface of supply lm core to validate supply lm core functionality. Ensure user buffer size is not greater than expected stack buffer size to avoid out of bounds array accesses. Change-Id: I5a93774855241b50895c5e2b3ff939e4c33a0185 Signed-off-by: Manaf Meethalavalappu Pallikunhi From 5df3f6ae4f72312592465fd0b1b754aafc5b3629 Mon Sep 17 00:00:00 2001 From: Tarun Karra Date: Thu, 17 Mar 2016 21:10:36 -0700 Subject: [PATCH 018/320] msm: kgsl: verify user memory permissions before mapping to GPU driver For user memory of type KGSL_USER_MEM_TYPE_ADDR mapped to GPU driver verify permissions and map GPU permissions same as CPU permissions. If elevated permissions are requested return an error to prevent privilege escalation. Without this check user could map readonly memory into GPU driver as readwrite and gain elevated privilege. Write permissions check is currently inverted causing readonly user pages to be mapped as readwrite in GPU driver. Fix this check to map readonly pages as readonly. CRs-Fixed: 988993 Change-Id: I0e097d7e4e4c414c0849e33bcc61a26fb94291ad Signed-off-by: Tarun Karra Signed-off-by: Sunil Khatri From dca855065f0043ae5e13e0e436b8b7552a97f83f Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Tue, 15 Mar 2016 18:42:27 -0700 Subject: [PATCH 019/320] msm: mdss: fix possible out-of-bounds and overflow issue in mdp debugfs There are few cases where the count argument passed by the user space is not validated, which can potentially lead to out of bounds or overflow issues. In some cases, kernel might copy more data than what is requested. Add necessary checks to avoid such cases. Change-Id: Ifa42fbd475665a0ca581c907ce5432584ea0e7ed Signed-off-by: Veera Sundaram Sankaran From 7ed6138841bc9e2e7ef898dd3030eaba2db7c5ca Mon Sep 17 00:00:00 2001 From: Ashish Jain Date: Fri, 15 Apr 2016 15:33:14 +0530 Subject: [PATCH 020/320] ASoC: msm: qdsp6v2: DAP: Fix buffer overflow Add check to avoid out of bound access. Check return value of get_user api. CRs-Fixed: 997025 Change-Id: Ibbace116ac206007fa1928555838285304737737 Signed-off-by: Ashish Jain --- sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c | 24 ++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c index 7761b9c725789..51f8b8c9e4086 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. @@ -1356,7 +1356,11 @@ static int msm_ds2_dap_handle_commands(u32 cmd, void *arg) int ret = 0, port_id = 0; int32_t data; struct dolby_param_data *dolby_data = (struct dolby_param_data *)arg; - get_user(data, &dolby_data->data[0]); + if (get_user(data, &dolby_data->data[0])) { + pr_debug("%s error getting data\n", __func__); + ret = -EFAULT; + goto end; + } pr_debug("%s: param_id %d,be_id %d,device_id 0x%x,length %d,data %d\n", __func__, dolby_data->param_id, dolby_data->be_id, @@ -1471,11 +1475,23 @@ static int msm_ds2_dap_set_param(u32 cmd, void *arg) goto end; } + off = ds2_dap_params_offset[idx]; + if ((dolby_data->length <= 0) || + (dolby_data->length > TOTAL_LENGTH_DS2_PARAM - off)) { + pr_err("%s: invalid length %d at idx %d\n", + __func__, dolby_data->length, idx); + rc = -EINVAL; + goto end; + } + /* cache the parameters */ ds2_dap_params[cdev].dap_params_modified[idx] += 1; for (j = 0; j < dolby_data->length; j++) { - off = ds2_dap_params_offset[idx]; - get_user(data, &dolby_data->data[j]); + if (get_user(data, &dolby_data->data[j])) { + pr_debug("%s:error getting data\n", __func__); + rc = -EFAULT; + goto end; + } ds2_dap_params[cdev].params_val[off + j] = data; pr_debug("%s:off %d,val[i/p:o/p]-[%d / %d]\n", __func__, off, data, From 7ca2574577ce8c4ed3c881bfc03709c8410bbb19 Mon Sep 17 00:00:00 2001 From: Suman Mukherjee Date: Mon, 2 May 2016 14:01:07 +0530 Subject: [PATCH 021/320] msm: camera: sensor: Validate step_boundary step_boundary can take values upto the total_steps Validate the step_boundary before consuming it. Convert the type of step_index and region_index to uint16_t step_index and region_index cannot be negative. CRs-Fixed: 1001092 Change-Id: I1f23fd6f28bb897824a1ef99a8873b9f986eee70 Signed-off-by: Rajesh Bondugula Signed-off-by: Suman Mukherjee --- .../camera_v2/sensor/actuator/msm_actuator.c | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c index 0ede1b944ea2b..3e329ada3ee23 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c +++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c @@ -452,20 +452,26 @@ static int32_t msm_actuator_init_step_table(struct msm_actuator_ctrl_t *a_ctrl, int16_t code_per_step = 0; uint32_t qvalue = 0; int16_t cur_code = 0; - int16_t step_index = 0, region_index = 0; + uint16_t step_index = 0, region_index = 0; uint16_t step_boundary = 0; uint32_t max_code_size = 1; uint16_t data_size = set_info->actuator_params.data_size; CDBG("Enter\n"); + /* validate the actuator state */ + if (a_ctrl->actuator_state != ACTUATOR_POWER_UP) { + pr_err("%s:%d invalid actuator_state %d\n" + , __func__, __LINE__, a_ctrl->actuator_state); + return -EINVAL; + } + for (; data_size > 0; data_size--) max_code_size *= 2; a_ctrl->max_code_size = max_code_size; - if ((a_ctrl->actuator_state == ACTUATOR_POWER_UP) && - (a_ctrl->step_position_table != NULL)) { - kfree(a_ctrl->step_position_table); - } + /* free the step_position_table to allocate a new one */ + kfree(a_ctrl->step_position_table); + a_ctrl->step_position_table = NULL; if (set_info->af_tuning_params.total_steps @@ -494,6 +500,15 @@ static int32_t msm_actuator_init_step_table(struct msm_actuator_ctrl_t *a_ctrl, step_boundary = a_ctrl->region_params[region_index]. step_bound[MOVE_NEAR]; + if (step_boundary > + set_info->af_tuning_params.total_steps) { + pr_err("invalid step_boundary = %d, max_val = %d", + step_boundary, + set_info->af_tuning_params.total_steps); + kfree(a_ctrl->step_position_table); + a_ctrl->step_position_table = NULL; + return -EINVAL; + } for (; step_index <= step_boundary; step_index++) { if (qvalue > 1 && qvalue <= MAX_QVALUE) cur_code = step_index * code_per_step / qvalue; From 834a64195d609cb53819697db8875f0da5a06ba2 Mon Sep 17 00:00:00 2001 From: Mallikarjuna Reddy Amireddy Date: Thu, 28 Apr 2016 15:27:00 +0530 Subject: [PATCH 022/320] qseecom: Change format specifier %p to %pK Format specifier %p can leak kernel addresses while not valuing the kptr_restrict system settings. When kptr_restrict is set to (1), kernel pointers printed using the %pK format specifier will be replaced with 0's. So that %pK will not leak kernel pointers to unprivileged users. So change the format specifier from %p to %pK. Debugging Note : &pK prints only Zeros as address. if you need actual address information, pls echo 0 to kptr_restrict. $ echo 0 > /proc/sys/kernel/kptr_restrict Change-Id: I0baf2be2d5a476e2e4267f20b99d0ddf5492469e Signed-off-by: Mallikarjuna Reddy Amireddy --- drivers/misc/qseecom.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index 416320807b3ab..b175965cfe119 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -1079,7 +1079,7 @@ static int qseecom_set_client_mem_param(struct qseecom_dev_handle *data, if ((req.ifd_data_fd <= 0) || (req.virt_sb_base == NULL) || (req.sb_len == 0)) { - pr_err("Inavlid input(s)ion_fd(%d), sb_len(%d), vaddr(0x%p)\n", + pr_err("Inavlid input(s)ion_fd(%d), sb_len(%d), vaddr(0x%pK)\n", req.ifd_data_fd, req.sb_len, req.virt_sb_base); return -EFAULT; } @@ -1646,7 +1646,7 @@ int __qseecom_process_rpmb_svc_cmd(struct qseecom_dev_handle *data_ptr, void *req_buf = NULL; if ((req_ptr == NULL) || (send_svc_ireq_ptr == NULL)) { - pr_err("Error with pointer: req_ptr = %p, send_svc_ptr = %p\n", + pr_err("Error with pointer: req_ptr = %pK, send_svc_ptr = %pK\n", req_ptr, send_svc_ireq_ptr); return -EINVAL; } @@ -1693,7 +1693,7 @@ int __qseecom_process_fsm_key_svc_cmd(struct qseecom_dev_handle *data_ptr, uint32_t reqd_len_sb_in = 0; if ((req_ptr == NULL) || (send_svc_ireq_ptr == NULL)) { - pr_err("Error with pointer: req_ptr = %p, send_svc_ptr = %p\n", + pr_err("Error with pointer: req_ptr = %pK, send_svc_ptr = %pK\n", req_ptr, send_svc_ireq_ptr); return -EINVAL; } @@ -3018,7 +3018,7 @@ int qseecom_send_command(struct qseecom_handle *handle, void *send_buf, if (ret) return ret; - pr_debug("sending cmd_req->rsp size: %u, ptr: 0x%p\n", + pr_debug("sending cmd_req->rsp size: %u, ptr: 0x%pK\n", req.resp_len, req.resp_buf); return ret; } @@ -4631,7 +4631,7 @@ long qseecom_ioctl(struct file *file, unsigned cmd, unsigned long arg) ret = -EINVAL; break; } - pr_debug("SET_MEM_PARAM: qseecom addr = 0x%p\n", data); + pr_debug("SET_MEM_PARAM: qseecom addr = 0x%pK\n", data); ret = qseecom_set_client_mem_param(data, argp); if (ret) pr_err("failed Qqseecom_set_mem_param request: %d\n", @@ -4647,7 +4647,7 @@ long qseecom_ioctl(struct file *file, unsigned cmd, unsigned long arg) break; } data->type = QSEECOM_CLIENT_APP; - pr_debug("LOAD_APP_REQ: qseecom_addr = 0x%p\n", data); + pr_debug("LOAD_APP_REQ: qseecom_addr = 0x%pK\n", data); mutex_lock(&app_access_lock); atomic_inc(&data->ioctl_count); if (qseecom.qsee_version > QSEEE_VERSION_00) { @@ -4673,7 +4673,7 @@ long qseecom_ioctl(struct file *file, unsigned cmd, unsigned long arg) ret = -EINVAL; break; } - pr_debug("UNLOAD_APP: qseecom_addr = 0x%p\n", data); + pr_debug("UNLOAD_APP: qseecom_addr = 0x%pK\n", data); mutex_lock(&app_access_lock); atomic_inc(&data->ioctl_count); ret = qseecom_unload_app(data, false); @@ -4804,7 +4804,7 @@ long qseecom_ioctl(struct file *file, unsigned cmd, unsigned long arg) data->type = QSEECOM_CLIENT_APP; mutex_lock(&app_access_lock); atomic_inc(&data->ioctl_count); - pr_debug("APP_LOAD_QUERY: qseecom_addr = 0x%p\n", data); + pr_debug("APP_LOAD_QUERY: qseecom_addr = 0x%pK\n", data); ret = qseecom_query_app_loaded(data, argp); atomic_dec(&data->ioctl_count); mutex_unlock(&app_access_lock); @@ -5057,7 +5057,7 @@ static int qseecom_release(struct inode *inode, struct file *file) int ret = 0; if (data->released == false) { - pr_debug("data: released=false, type=%d, mode=%d, data=0x%p\n", + pr_debug("data: released=false, type=%d, mode=%d, data=0x%pK\n", data->type, data->mode, data); switch (data->type) { case QSEECOM_LISTENER_SERVICE: From a1507a22f7ae55e8a5fd6c2932fe5a31929e56c3 Mon Sep 17 00:00:00 2001 From: Manu Gautam Date: Wed, 20 Apr 2016 17:01:31 +0530 Subject: [PATCH 023/320] USB: gadget: Remove configfs usage Userspace after mounting configfs may continue to use configfs if usb_gadget supports configfs. For this userspace just relies on the presence of /config/usb_gadget. As USB drivers don't full support configfs but rather rely on android gadget, hence remove compilation of usb configfs so that usb_gadget node doesn't appear in /config and userspace can fallback to android gadget. Change-Id: Ic59adfacd3972fd54608f916c98478525b9a9286 Signed-off-by: Manu Gautam --- drivers/usb/gadget/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index c608227491a06..46fe9ac81db18 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -6,7 +6,7 @@ ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG obj-$(CONFIG_USB_GADGET) += udc-core.o obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o libcomposite-y := usbstring.o config.o epautoconf.o -libcomposite-y += composite.o functions.o configfs.o +libcomposite-y += composite.o functions.o obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o obj-$(CONFIG_USB_NET2272) += net2272.o obj-$(CONFIG_USB_NET2280) += net2280.o From 6e71489cdef37113d6b35162ffb9631a6a36a1e1 Mon Sep 17 00:00:00 2001 From: Chet Lanctot Date: Wed, 7 Jan 2015 12:28:38 -0800 Subject: [PATCH 024/320] Revert "cfg80211: Pass PTK as part of key management offload completion" This reverts commit c03321683c20f65ff5803b6459a7e3165233d613. Key management offload (LFR3) cannot be dependent on kernel changes that have not yet been up-streamed. Therefore, all kernel support for key management offload needs to be reverted until the open source version of kernel support for key management offload is available. Conflicts: include/net/cfg80211.h CRs-Fixed: 778119 Change-Id: I5b3175c65d59a95e632200411b29fbd52cb87d94 Signed-off-by: Chet Lanctot --- include/net/cfg80211.h | 39 ------------------------- include/uapi/linux/nl80211.h | 6 ---- net/wireless/core.h | 5 +--- net/wireless/nl80211.c | 55 ++---------------------------------- net/wireless/util.c | 4 +-- 5 files changed, 4 insertions(+), 105 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 85d38d801ca8f..52fc7290d5518 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1872,24 +1872,6 @@ struct cfg80211_qos_map { struct cfg80211_dscp_range up[8]; }; -/** - * struct cfg80211_auth_params - Information about a key managment offload - * - * Information reported when a key managment offload has completed. - * - * @status: whether offload was successful - * @key_replay_ctr: Key Replay Counter value last used in a valid - * EAPOL-Key frame - * @ptk_kck: the derived PTK KCK - * @ptk_kek: the derived PTK KEK - */ -struct cfg80211_auth_params { - enum nl80211_authorization_status status; - const u8 *key_replay_ctr; - const u8 *ptk_kck; - const u8 *ptk_kek; -}; - /** * struct cfg80211_ops - backend description for wireless configuration * @@ -4572,27 +4554,6 @@ void cfg80211_authorization_event(struct net_device *dev, const u8 *key_replay_ctr, gfp_t gfp); -/** - * cfg80211_key_mgmt_auth - indicates key management offload complete - * @dev: the device reporting offload - * @auth_params: information about the offload - * @gfp: allocation flags - * - * This function reports that the device offloaded the key management - * operation and established temporal keys for an RSN connection. In - * this case, the device handled the exchange necessary to establish - * the temporal keys by processing the EAPOL-Key frames instead of - * the supplicant doing it. This means the initial connection, roam - * operation, or PKT rekeying is complete and the supplicant should - * enter the authorized state for the port. This event can be signaled - * after cfg80211_connect_result during initial connection or after - * cfg80211_roamed in the case of roaming. This event might also be - * signaled after the device handles a PTK rekeying operation. - */ -void cfg80211_key_mgmt_auth(struct net_device *dev, - struct cfg80211_auth_params *auth_params, - gfp_t gfp); - void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info); /* Logging, debugging and troubleshooting/diagnostic helpers. */ diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index f9bfc0acd94bd..85123e99892dd 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -1575,8 +1575,6 @@ enum nl80211_commands { * @NL80211_ATTR_PMK: The Pairwise Master Key to be used for the * connection. * @NL80211_ATTR_PMK_LEN: The length of the PMK. - * @NL80211_ATTR_PTK_KCK: Pairwise Transient Key, Key Confirmation Key. - * @NL80211_ATTR_PTK_KEK: Pairwise Transient Key, Key Encryption Key. * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -1922,8 +1920,6 @@ enum nl80211_attrs { NL80211_ATTR_KEY_DERIVE_OFFLOAD_SUPPORT, NL80211_ATTR_PMK, NL80211_ATTR_PMK_LEN, - NL80211_ATTR_PTK_KCK, - NL80211_ATTR_PTK_KEK, /* add attributes here, update the policy in nl80211.c */ @@ -4011,8 +4007,6 @@ enum nl80211_tdls_peer_capability { #define NL80211_KEY_LEN_PSK 32 #define NL80211_KEY_LEN_PMK 32 #define NL80211_KEY_REPLAY_CTR_LEN 8 -#define NL80211_KEY_LEN_PTK_KCK 16 -#define NL80211_KEY_LEN_PTK_KEK 16 /** * enum nl80211_key_mgmt_offload_support - key management offload types diff --git a/net/wireless/core.h b/net/wireless/core.h index 508a1fae008c2..6126920e65214 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -244,8 +244,6 @@ struct cfg80211_event { struct { enum nl80211_authorization_status auth_status; u8 key_replay_ctr[NL80211_KEY_REPLAY_CTR_LEN]; - u8 ptk_kck[NL80211_KEY_LEN_PTK_KCK]; - u8 ptk_kek[NL80211_KEY_LEN_PTK_KEK]; } au; }; }; @@ -405,8 +403,7 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev); void __cfg80211_authorization_event(struct net_device *dev, enum nl80211_authorization_status auth_status, - const u8 *key_replay_ctr, const u8 *ptk_kck, - const u8 *ptk_kek); + const u8 *key_replay_ctr); void cfg80211_conn_work(struct work_struct *work); void cfg80211_sme_failed_assoc(struct wireless_dev *wdev); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index e85cacfbbb99c..953f4d5045318 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -400,10 +400,6 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = NL80211_KEY_LEN_PMK }, [NL80211_ATTR_PMK_LEN] = { .type = NLA_U32 }, - [NL80211_ATTR_PTK_KCK] = { .type = NLA_BINARY, - .len = NL80211_KEY_LEN_PTK_KCK }, - [NL80211_ATTR_PTK_KEK] = { .type = NLA_BINARY, - .len = NL80211_KEY_LEN_PTK_KEK }, }; /* policy for the key attributes */ @@ -11293,8 +11289,7 @@ EXPORT_SYMBOL(cfg80211_ap_stopped); void __cfg80211_authorization_event(struct net_device *dev, enum nl80211_authorization_status auth_status, - const u8 *key_replay_ctr, const u8 *ptk_kck, - const u8 *ptk_kek) + const u8 *key_replay_ctr) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); @@ -11316,11 +11311,7 @@ void __cfg80211_authorization_event(struct net_device *dev, nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || nla_put_u8(msg, NL80211_ATTR_AUTHORIZATION_STATUS, auth_status) || nla_put(msg, NL80211_ATTR_KEY_REPLAY_CTR, - NL80211_KEY_REPLAY_CTR_LEN, key_replay_ctr) || - nla_put(msg, NL80211_ATTR_PTK_KCK, NL80211_KEY_LEN_PTK_KCK, - ptk_kck) || - nla_put(msg, NL80211_ATTR_PTK_KEK, NL80211_KEY_LEN_PTK_KEK, - ptk_kek)) + NL80211_KEY_REPLAY_CTR_LEN, key_replay_ctr)) goto nla_put_failure; err = genlmsg_end(msg, hdr); @@ -11370,48 +11361,6 @@ void cfg80211_authorization_event(struct net_device *dev, } EXPORT_SYMBOL(cfg80211_authorization_event); -void cfg80211_key_mgmt_auth(struct net_device *dev, - struct cfg80211_auth_params *auth_params, - gfp_t gfp) -{ - struct wireless_dev *wdev = dev->ieee80211_ptr; - struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); - struct cfg80211_event *ev; - unsigned long flags; - - /* Valid only in SME_CONNECTED state */ - if (wdev->sme_state != CFG80211_SME_CONNECTED) - return; - - ev = kzalloc(sizeof(*ev), gfp); - if (!ev) - return; - - trace_cfg80211_authorization_event(wdev->wiphy, dev, - auth_params->status); - - ev->type = EVENT_AUTHORIZATION; - ev->au.auth_status = auth_params->status; - if (auth_params->key_replay_ctr) { - memcpy(ev->au.key_replay_ctr, auth_params->key_replay_ctr, - NL80211_KEY_REPLAY_CTR_LEN); - } - if (auth_params->ptk_kck) { - memcpy(ev->au.ptk_kck, auth_params->ptk_kck, - NL80211_KEY_LEN_PTK_KCK); - } - if (auth_params->ptk_kek) { - memcpy(ev->au.ptk_kek, auth_params->ptk_kek, - NL80211_KEY_LEN_PTK_KEK); - } - - spin_lock_irqsave(&wdev->event_lock, flags); - list_add_tail(&ev->list, &wdev->event_list); - spin_unlock_irqrestore(&wdev->event_lock, flags); - queue_work(cfg80211_wq, &rdev->event_work); -} -EXPORT_SYMBOL(cfg80211_key_mgmt_auth); - /* initialisation/exit functions */ int nl80211_init(void) diff --git a/net/wireless/util.c b/net/wireless/util.c index 1b6f49020e635..e674a6e5f0620 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -793,9 +793,7 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev) case EVENT_AUTHORIZATION: __cfg80211_authorization_event(wdev->netdev, ev->au.auth_status, - ev->au.key_replay_ctr, - ev->au.ptk_kck, - ev->au.ptk_kek); + ev->au.key_replay_ctr); break; } wdev_unlock(wdev); From 7aecfd0bc0736fd34ed95b49c6cc0bf6c3d50725 Mon Sep 17 00:00:00 2001 From: Chet Lanctot Date: Wed, 7 Jan 2015 13:03:05 -0800 Subject: [PATCH 025/320] Revert "cfg80211: Key management offload support for 802.1X LEAP" This reverts commit 0aead796cc5f229a5f0cd69514552f9c815f57a0. Key management offload (LFR3) cannot be dependent on kernel changes that have not yet been up-streamed. Therefore, all kernel support for key management offload needs to be reverted until the open source version of kernel support for key management offload is available. CRs-Fixed: 778119 Change-Id: I8e2c27f84e0b8e3f52ecca9f71b269ec10d47990 Signed-off-by: Chet Lanctot --- include/net/cfg80211.h | 2 +- include/uapi/linux/nl80211.h | 2 -- net/wireless/nl80211.c | 8 +------- net/wireless/rdev-ops.h | 5 ++--- 4 files changed, 4 insertions(+), 13 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 52fc7290d5518..9912ce50627fc 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2358,7 +2358,7 @@ struct cfg80211_ops { struct cfg80211_chan_def *chandef); int (*key_mgmt_set_pmk)(struct wiphy *wiphy, struct net_device *dev, - const u8 *pmk, size_t pmk_len); + const u8 *pmk); }; /* diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 85123e99892dd..4d357473adf33 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -1574,7 +1574,6 @@ enum nl80211_commands { * derivation used as part of key management offload. * @NL80211_ATTR_PMK: The Pairwise Master Key to be used for the * connection. - * @NL80211_ATTR_PMK_LEN: The length of the PMK. * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -1919,7 +1918,6 @@ enum nl80211_attrs { NL80211_ATTR_KEY_MGMT_OFFLOAD_SUPPORT, NL80211_ATTR_KEY_DERIVE_OFFLOAD_SUPPORT, NL80211_ATTR_PMK, - NL80211_ATTR_PMK_LEN, /* add attributes here, update the policy in nl80211.c */ diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 953f4d5045318..9ba1fd5dd6101 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -399,7 +399,6 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_KEY_DERIVE_OFFLOAD_SUPPORT] = { .type = NLA_U32 }, [NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = NL80211_KEY_LEN_PMK }, - [NL80211_ATTR_PMK_LEN] = { .type = NLA_U32 }, }; /* policy for the key attributes */ @@ -8734,21 +8733,16 @@ static int nl80211_key_mgmt_set_pmk(struct sk_buff *skb, struct genl_info *info) struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct net_device *dev = info->user_ptr[1]; u8 *pmk; - size_t pmk_len; if (info->attrs[NL80211_ATTR_PMK]) pmk = nla_data(info->attrs[NL80211_ATTR_PMK]); else return -EINVAL; - if (info->attrs[NL80211_ATTR_PMK_LEN]) - pmk_len = nla_get_u32(info->attrs[NL80211_ATTR_PMK_LEN]); - else - return -EINVAL; if (!rdev->ops->key_mgmt_set_pmk) return -EOPNOTSUPP; - return rdev_key_mgmt_set_pmk(rdev, dev, pmk, pmk_len); + return rdev_key_mgmt_set_pmk(rdev, dev, pmk); } #define NL80211_FLAG_NEED_WIPHY 0x01 diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index 4291a7ff21176..03cf1a925a672 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -955,13 +955,12 @@ rdev_set_ap_chanwidth(struct cfg80211_registered_device *rdev, } static inline int rdev_key_mgmt_set_pmk(struct cfg80211_registered_device *rdev, - struct net_device *dev, u8 *pmk, - size_t pmk_len) + struct net_device *dev, u8 *pmk) { int ret; trace_rdev_key_mgmt_set_pmk(&rdev->wiphy, dev, pmk); - ret = rdev->ops->key_mgmt_set_pmk(&rdev->wiphy, dev, pmk, pmk_len); + ret = rdev->ops->key_mgmt_set_pmk(&rdev->wiphy, dev, pmk); trace_rdev_return_int(&rdev->wiphy, ret); return ret; From a47d602fc18a858fb0b95cfc66ee6ec2c93191dc Mon Sep 17 00:00:00 2001 From: Chet Lanctot Date: Wed, 7 Jan 2015 13:13:27 -0800 Subject: [PATCH 026/320] Revert "cfg80211: Key management offload support for SHA-256 and FT/8021.X" This reverts commit 3bb41fde0126a3f34a24d74c0cb694eb9d681db3. Key management offload (LFR3) cannot be dependent on kernel changes that have not yet been up-streamed. Therefore, all kernel support for key management offload needs to be reverted until the open source version of kernel support for key management offload is available. CRs-Fixed: 778119 Change-Id: Idd3d5847636da558a12f27396d43ca6c4e12a519 Signed-off-by: Chet Lanctot --- Documentation/networking/key-mgmt-offload.txt | 5 +++-- include/net/cfg80211.h | 10 ++++------ include/uapi/linux/nl80211.h | 18 +++++------------- net/wireless/nl80211.c | 2 +- net/wireless/util.c | 1 - 5 files changed, 13 insertions(+), 23 deletions(-) diff --git a/Documentation/networking/key-mgmt-offload.txt b/Documentation/networking/key-mgmt-offload.txt index 9b18b0208cce6..581082da4a236 100644 --- a/Documentation/networking/key-mgmt-offload.txt +++ b/Documentation/networking/key-mgmt-offload.txt @@ -6,7 +6,7 @@ Security Network during initial connection or after a roam between APs occurs. It might also happen during after the device handles a PTK rekeying operation. -This design only supports key management offload in a station +This design only supports key managment offload in a station (non-AP STA). There are a couple of possible advantages to offloading key @@ -83,7 +83,8 @@ NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PMKSA association connect time because the 802.1X authentication must first take place before the PMK is established. The PMK will be passed to the driver using cfg80211_key_mgmt_set_pmk in this case - once it is known. + once it is known. A new cipher suite type is defined to identify + the value as a PMK when cfg80211_add_key is used in this way. Indication ---------- diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 9912ce50627fc..99724b35d17f4 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2110,9 +2110,7 @@ struct cfg80211_qos_map { * * @key_mgmt_set_pmk: Used to pass the PMK to the device for key management * offload. This will be used in the case of key management offload on an - * already established PMKSA. If connection is FT (802.11r) enabled with - * 802.1X, then the second 256 bits of the MSK is passed instead of the - * PMK. + * already established PMKSA. */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); @@ -2358,7 +2356,7 @@ struct cfg80211_ops { struct cfg80211_chan_def *chandef); int (*key_mgmt_set_pmk)(struct wiphy *wiphy, struct net_device *dev, - const u8 *pmk); + u8 *pmk); }; /* @@ -2748,8 +2746,8 @@ struct wiphy_vendor_command { * * @key_mgmt_offload_support: Bitmap of supported types of key management * that can be offloaded to the device. See - * nl80211_key_mgmt_offload_support. Only valid when - * WIPHY_FLAG_HAS_KEY_MGMT_OFFLOAD is set. + * nl80211_key_mgmt_offload_support. + * Only valid when WIPHY_FLAG_HAS_KEY_MGMT_OFFLOAD is set. * @key_derive_offload_support: Bitmap of supported key derivations used as * part of key management offload. See nl80211_key_derive_offload_support. * Only valid when WIPHY_FLAG_HAS_KEY_MGMT_OFFLOAD is set. diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 4d357473adf33..e049285011f38 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -704,9 +704,7 @@ * @NL80211_CMD_KEY_MGMT_SET_PMK: Used to pass the PMK to the device for * key management offload. This will be used in the case of key * management offload on an already established PMKSA. The PMK is passed - * in NL80211_ATTR_PMK once it is known by the supplicant. If connection - * is FT (802.11r) enabled with 802.1X, then the second 256 bits of the - * MSK is passed instead of the PMK. + * in NL80211_ATTR_PMK once it is known by the supplicant. * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use @@ -4021,15 +4019,11 @@ enum nl80211_tdls_peer_capability { * @NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PMKSA: Key management on already * established PMKSA. The PMK will be passed using * NL80211_CMD_KEY_MGMT_SET_PMK once it is known. - * @NL80211_KEY_MGMT_OFFLOAD_SUPPORT_FT_802_1X: 802.11r (FT) with - * 802.1X. The second 256 bits of the MSK is passed using - * NL80211_CMD_KEY_MGMT_SET_PMK once it is known. */ enum nl80211_key_mgmt_offload_support { - NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PSK = 1 << 0, - NL80211_KEY_MGMT_OFFLOAD_SUPPORT_FT_PSK = 1 << 1, - NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PMKSA = 1 << 2, - NL80211_KEY_MGMT_OFFLOAD_SUPPORT_FT_802_1X = 1 << 3, + NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PSK = 1 << 0, + NL80211_KEY_MGMT_OFFLOAD_SUPPORT_FT_PSK = 1 << 1, + NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PMKSA = 1 << 2, }; /** @@ -4040,11 +4034,9 @@ enum nl80211_key_mgmt_offload_support { * by default for all supported key management offload types. * * @NL80211_KEY_DERIVE_OFFLOAD_SUPPORT_IGTK: IGTK key derivation. - * @NL80211_KEY_DERIVE_OFFLOAD_SUPPORT_SHA256: SHA-256 key derivation. */ enum nl80211_key_derive_offload_support { - NL80211_KEY_DERIVE_OFFLOAD_SUPPORT_IGTK = 1 << 0, - NL80211_KEY_DERIVE_OFFLOAD_SUPPORT_SHA256 = 1 << 1, + NL80211_KEY_DERIVE_OFFLOAD_SUPPORT_IGTK = 1 << 0, }; /** diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 9ba1fd5dd6101..1b9a0f4cfc74a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -9467,7 +9467,7 @@ static struct genl_ops nl80211_ops[] = { NL80211_FLAG_NEED_RTNL, }, { - .cmd = NL80211_CMD_KEY_MGMT_SET_PMK, + .cmd = NL80211_CMD_KEY_MGMT_SET_PMK, .doit = nl80211_key_mgmt_set_pmk, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, diff --git a/net/wireless/util.c b/net/wireless/util.c index e674a6e5f0620..29d849a90f44e 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -794,7 +794,6 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev) __cfg80211_authorization_event(wdev->netdev, ev->au.auth_status, ev->au.key_replay_ctr); - break; } wdev_unlock(wdev); From 991965f6e1bb769895eb44e14ad0ce09a20019c0 Mon Sep 17 00:00:00 2001 From: Chet Lanctot Date: Wed, 7 Jan 2015 13:35:43 -0800 Subject: [PATCH 027/320] Revert "nl80211: fixes for event reordering." This reverts commit 826d3568d5ce1e63623728e25ef67bee96e1c2b8. Key management offload (LFR3) cannot be dependent on kernel changes that have not yet been up-streamed. Therefore, all kernel support for key management offload needs to be reverted until the open source version of kernel support for key management offload is available. CRs-Fixed: 778119 Change-Id: Id5b7c93cb9a82f43f0a7195f8eba15e83a6cdcec Signed-off-by: Chet Lanctot --- net/wireless/core.h | 8 ------- net/wireless/nl80211.c | 48 +++++++++++------------------------------- net/wireless/util.c | 4 ---- 3 files changed, 12 insertions(+), 48 deletions(-) diff --git a/net/wireless/core.h b/net/wireless/core.h index 6126920e65214..36d2d64a401d4 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -210,7 +210,6 @@ enum cfg80211_event_type { EVENT_ROAMED, EVENT_DISCONNECTED, EVENT_IBSS_JOINED, - EVENT_AUTHORIZATION, }; struct cfg80211_event { @@ -241,10 +240,6 @@ struct cfg80211_event { struct { u8 bssid[ETH_ALEN]; } ij; - struct { - enum nl80211_authorization_status auth_status; - u8 key_replay_ctr[NL80211_KEY_REPLAY_CTR_LEN]; - } au; }; }; @@ -401,9 +396,6 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *resp_ie, size_t resp_ie_len); int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev); -void __cfg80211_authorization_event(struct net_device *dev, - enum nl80211_authorization_status auth_status, - const u8 *key_replay_ctr); void cfg80211_conn_work(struct work_struct *work); void cfg80211_sme_failed_assoc(struct wireless_dev *wdev); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 1b9a0f4cfc74a..0d75ae31c8fae 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -11281,9 +11281,10 @@ void cfg80211_ap_stopped(struct net_device *netdev, gfp_t gfp) } EXPORT_SYMBOL(cfg80211_ap_stopped); -void __cfg80211_authorization_event(struct net_device *dev, - enum nl80211_authorization_status auth_status, - const u8 *key_replay_ctr) +void cfg80211_authorization_event(struct net_device *dev, + enum nl80211_authorization_status auth_status, + const u8 *key_replay_ctr, + gfp_t gfp) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); @@ -11291,7 +11292,13 @@ void __cfg80211_authorization_event(struct net_device *dev, void *hdr; int err; - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + /* Valid only in SME_CONNECTED state */ + if (wdev->sme_state != CFG80211_SME_CONNECTED) + return; + + trace_cfg80211_authorization_event(wdev->wiphy, dev, auth_status); + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); if (!msg) return; @@ -11315,44 +11322,13 @@ void __cfg80211_authorization_event(struct net_device *dev, } genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, GFP_KERNEL); + nl80211_mlme_mcgrp.id, gfp); return; nla_put_failure: genlmsg_cancel(msg, hdr); nlmsg_free(msg); } - -void cfg80211_authorization_event(struct net_device *dev, - enum nl80211_authorization_status auth_status, - const u8 *key_replay_ctr, - gfp_t gfp) -{ - struct wireless_dev *wdev = dev->ieee80211_ptr; - struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); - struct cfg80211_event *ev; - unsigned long flags; - - /* Valid only in SME_CONNECTED state */ - if (wdev->sme_state != CFG80211_SME_CONNECTED) - return; - - ev = kzalloc(sizeof(*ev), gfp); - if (!ev) - return; - - trace_cfg80211_authorization_event(wdev->wiphy, dev, auth_status); - - ev->type = EVENT_AUTHORIZATION; - ev->au.auth_status = auth_status; - memcpy(ev->au.key_replay_ctr, key_replay_ctr, - NL80211_KEY_REPLAY_CTR_LEN); - - spin_lock_irqsave(&wdev->event_lock, flags); - list_add_tail(&ev->list, &wdev->event_list); - spin_unlock_irqrestore(&wdev->event_lock, flags); - queue_work(cfg80211_wq, &rdev->event_work); -} EXPORT_SYMBOL(cfg80211_authorization_event); /* initialisation/exit functions */ diff --git a/net/wireless/util.c b/net/wireless/util.c index 29d849a90f44e..6f093e4da8d87 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -790,10 +790,6 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev) case EVENT_IBSS_JOINED: __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid); break; - case EVENT_AUTHORIZATION: - __cfg80211_authorization_event(wdev->netdev, - ev->au.auth_status, - ev->au.key_replay_ctr); } wdev_unlock(wdev); From b337ddda769e1dfef1fb6e47d0336d35bfccbfe8 Mon Sep 17 00:00:00 2001 From: Chet Lanctot Date: Wed, 7 Jan 2015 13:56:27 -0800 Subject: [PATCH 028/320] Revert "cfg80211: Changes to support key managment offload" This reverts commit 269e7d4aee1b0f59d6bd9460d736a11e4a71d3b0. Key management offload (LFR3) cannot be dependent on kernel changes that have not yet been up-streamed. Therefore, all kernel support for key management offload needs to be reverted until the open source version of kernel support for key management offload is available. Conflicts: include/net/cfg80211.h CRs-Fixed: 778119 Change-Id: I4ea487d312504be3cc180e814a7807a89344bef1 Signed-off-by: Chet Lanctot --- Documentation/networking/key-mgmt-offload.txt | 148 ------------------ include/net/cfg80211.h | 64 +------- include/uapi/linux/nl80211.h | 102 ------------ net/wireless/nl80211.c | 97 ------------ net/wireless/rdev-ops.h | 12 -- net/wireless/trace.h | 23 --- 6 files changed, 1 insertion(+), 445 deletions(-) delete mode 100644 Documentation/networking/key-mgmt-offload.txt diff --git a/Documentation/networking/key-mgmt-offload.txt b/Documentation/networking/key-mgmt-offload.txt deleted file mode 100644 index 581082da4a236..0000000000000 --- a/Documentation/networking/key-mgmt-offload.txt +++ /dev/null @@ -1,148 +0,0 @@ -Key management offload is a mechanism where a station's device driver -or firmware/hardware does the exchange with the AP to establish the -temporal keys to be used for communications protection, rather than -having the supplicant do it. This exchange takes place in a Robust -Security Network during initial connection or after a roam between -APs occurs. It might also happen during after the device handles a -PTK rekeying operation. - -This design only supports key managment offload in a station -(non-AP STA). - -There are a couple of possible advantages to offloading key -management. - - Connection time might be reduced (initial connection and after - roaming) since fewer software components will be involved and - there will not need to be a switch between kernel space (device - driver) and user space (wpa_supplicant). - - Power savings might be achieved since user space modules might - run on a processor separate from the device driver and/or - firmware and that processor could be kept in a power saving mode - since it need not be involved in key manaqgement. - -Key management can be offloaded in the following cases. - - WPA or WPA2 with PSK - - 802.11r (Fast Transition) with PSK - - Opportunistic Key Caching (OKC) - -For WPA/WPA2 or 802.11r with PSK, the PSK is supplied to the device -driver by the supplicant. For the OKC case, the supplicant will handle -the initial 802.1X authentication. It will pass the resulting PMK -(session key) to the driver. The driver can subsequently use this key -for connection to an AP that has cached the security association -(PMKSA), allowing the device to offload key management while not having -to do the full 802.1X authentication. - -The following topics will now be covered. - 1. Advertisement - The capabilities of the device with relation to - key management offloads are made known to the supplicant. - 2. Information Passing - The supplicant provides necessary - information to the device to allow it to accomplish the offload. - 3. Indication - Mechanism for the driver to update the supplicant - that key management has taken place. - 4. Example - An example of how the interface is used to allow key - management offload to take place. - -Advertisement -------------- - -The host driver's capability to offload key management is advertised by -the wiphy capability flag WIPHY_FLAG_HAS_KEY_MGMT_OFFLOAD. Individual -key management and key derivation capabilities are advertised as part -of the device attributes. - -The following key management offload capabilities can be advertised. - NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PSK - NL80211_KEY_MGMT_OFFLOAD_SUPPORT_FT_PSK - NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PMKSA - -The following key derivation capabilities can be advertised. - NL80211_KEY_DERIVE_OFFLOAD_SUPPORT_IGTK - -The decision to enable key management offload for a particular -connection is indicated to the driver by the flag -ASSOC_REQ_OFFLOAD_KEY_MGMT in cfg80211_assoc_req_flags which is passed -in a cfg80211_connect command. - -Information Passing -------------------- -The device will need information from the supplicant to handle the key -management offload. For each type of key management offload, the -following information is needed. - -NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PSK - The PSK will be needed. The PSK will be included in the - cfg80211_connect_params that is passed as part of cfg80211_connect. - -NL80211_KEY_MGMT_OFFLOAD_SUPPORT_FT_PSK - The PSK will be needed. The PSK will be included in the - cfg80211_connect_params that is passed as part of cfg80211_connect. - -NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PMKSA - The PMK (MSK) will be needed. It is not available at initial - association connect time because the 802.1X authentication must - first take place before the PMK is established. The PMK will be - passed to the driver using cfg80211_key_mgmt_set_pmk in this case - once it is known. A new cipher suite type is defined to identify - the value as a PMK when cfg80211_add_key is used in this way. - -Indication ----------- - -On a successful key management offload, the driver will invoke -cfg80211_authorization_event with status NL80211_AUTHORIZED. If the -key management offload is not successful, then NL80211_CONNECTED is -passed as the status in cfg80211_authorization_event and it is expected -the supplicant will take over key management. - -The last used EAPOL key reply counter value is passed to the supplicant -in cfg80211_authorization_event. - -In the case of key management offload after roaming, -cfg80211_authorization_event will always be called immediately after a -call to cfg80211_roamed. - -In the case of PTK rekeying, cfg80211_authorization_event is called -after the device has handled rekeying. This allows the supplicant -to recieve an updated EAPOL key reply counter value. - -Example -------- - -As an example of how this interface can be used, the case of key -management offloading for a WPA2 connection is examined. - - 1. The driver advertises general key management offload capability - with the wiphy flag WIPHY_FLAG_HAS_KEY_MGMT_OFFLOAD. Device - attributes NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PSK and - NL80211_KEY_DERIVE_OFFLOAD_SUPPORT_IGTK are advertised. - - 2. Using existing mechanisms, the supplicant decides that a - connection should be made to a network. The network is an RSN - supporting WPA2 and Protected Management Frames. Seeing that the - device supports key management offload for WPA2 and key derivation - for IGTK, it signals to the driver that it wants to take advantage - of key management offload by specifying ASSOC_REQ_OFFLOAD_KEY_MGMT - in cfg80211_assoc_req_flags in the cfg80211_connect command. The - PSK for the connection is also included in cfg80211_connect. - - 3. The supplicant enters the "connected" state as it currently does, - waiting for the first EAPOL frame to arrive so that the security - exchange can be done. The EAPOL frame is presented to the - supplicant and it completes the security exchange. This is all - existing functionality. No key management offload took place - during this initial connection (but it could have). - - 4. Sometime later, the supplicant gets a cfg80211_roamed indication, - telling the supplicant that the device roamed to a different AP. - Again, the supplicant enters "connected" state, waiting for the - first EAPOL frame so that the security exchange can be done with - the new AP. - - 5. Immediately, the supplicant gets a cfg80211_authorization_event - with success status, indicating that the key management has been - done by the device. The supplicant enters "authorized" state for - the connection and allows transmission and reception of data - frames on the network. Here, during roaming, the key management - was offloaded to the device and did not need to be handled by the - supplicant. diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 99724b35d17f4..48007b3ce5f45 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1467,14 +1467,10 @@ struct cfg80211_auth_request { * * @ASSOC_REQ_DISABLE_HT: Disable HT (802.11n) * @ASSOC_REQ_DISABLE_VHT: Disable VHT - * @ASSOC_REQ_OFFLOAD_KEY_MGMT: Requests that device handle establishment - * of temporal keys if possible during initial RSN connection or after - * roaming */ enum cfg80211_assoc_req_flags { ASSOC_REQ_DISABLE_HT = BIT(0), ASSOC_REQ_DISABLE_VHT = BIT(1), - ASSOC_REQ_OFFLOAD_KEY_MGMT = BIT(2), }; /** @@ -1627,8 +1623,6 @@ struct cfg80211_ibss_params { * @ht_capa_mask: The bits of ht_capa which are to be used. * @vht_capa: VHT Capability overrides * @vht_capa_mask: The bits of vht_capa which are to be used. - * @psk: The Preshared Key to be used for the connection. - * (only valid if ASSOC_REQ_OFFLOAD_KEY_MGMT is set) */ struct cfg80211_connect_params { struct ieee80211_channel *channel; @@ -1651,7 +1645,6 @@ struct cfg80211_connect_params { struct ieee80211_ht_cap ht_capa_mask; struct ieee80211_vht_cap vht_capa; struct ieee80211_vht_cap vht_capa_mask; - const u8 *psk; }; /** @@ -2107,10 +2100,6 @@ struct cfg80211_qos_map { * @set_ap_chanwidth: Set the AP (including P2P GO) mode channel width for the * given interface This is used e.g. for dynamic HT 20/40 MHz channel width * changes during the lifetime of the BSS. - * - * @key_mgmt_set_pmk: Used to pass the PMK to the device for key management - * offload. This will be used in the case of key management offload on an - * already established PMKSA. */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); @@ -2354,9 +2343,6 @@ struct cfg80211_ops { int (*set_ap_chanwidth)(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_chan_def *chandef); - - int (*key_mgmt_set_pmk)(struct wiphy *wiphy, struct net_device *dev, - u8 *pmk); }; /* @@ -2428,14 +2414,6 @@ struct cfg80211_ops { * @WIPHY_FLAG_OFFCHAN_TX: Device supports direct off-channel TX. * @WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL: Device supports remain-on-channel call. * @WIPHY_FLAG_DFS_OFFLOAD: The driver handles all the DFS related operations. - * @WIPHY_FLAG_HAS_KEY_MGMT_OFFLOAD: Device operating as a station is - * capable of doing the exchange necessary to establish temporal keys - * during initial RSN connection, after roaming, or during a PTK rekeying - * operation. Supplicant should expect to do the exchange itself, by - * preparing to process the EAPOL-Key frames, until - * NL80211_CMD_AUTHORIZATION_EVENT is sent with success status. The - * supported types of key management offload are advertised by - * NL80211_ATTR_KEY_MGMT_OFFLOAD. */ enum wiphy_flags { WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), @@ -2459,8 +2437,7 @@ enum wiphy_flags { WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD = BIT(19), WIPHY_FLAG_OFFCHAN_TX = BIT(20), WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(21), - WIPHY_FLAG_DFS_OFFLOAD = BIT(22), - WIPHY_FLAG_HAS_KEY_MGMT_OFFLOAD = BIT(23), + WIPHY_FLAG_DFS_OFFLOAD = BIT(22) }; /** @@ -2743,14 +2720,6 @@ struct wiphy_vendor_command { * (including P2P GO) or 0 to indicate no such limit is advertised. The * driver is allowed to advertise a theoretical limit that it can reach in * some cases, but may not always reach. - * - * @key_mgmt_offload_support: Bitmap of supported types of key management - * that can be offloaded to the device. See - * nl80211_key_mgmt_offload_support. - * Only valid when WIPHY_FLAG_HAS_KEY_MGMT_OFFLOAD is set. - * @key_derive_offload_support: Bitmap of supported key derivations used as - * part of key management offload. See nl80211_key_derive_offload_support. - * Only valid when WIPHY_FLAG_HAS_KEY_MGMT_OFFLOAD is set. */ struct wiphy { /* assign these fields before you register the wiphy */ @@ -2867,9 +2836,6 @@ struct wiphy { u16 max_ap_assoc_sta; - u32 key_mgmt_offload_support; - u32 key_derive_offload_support; - char priv[0] __aligned(NETDEV_ALIGN); }; @@ -4524,34 +4490,6 @@ void cfg80211_ap_stopped(struct net_device *netdev, gfp_t gfp); */ bool cfg80211_is_gratuitous_arp_unsolicited_na(struct sk_buff *skb); -/** - * cfg80211_authorization_event - indicates key management offload complete - * @dev: the device reporting offload - * @auth_status: whether offload was successful - * @key_replay_ctr: Key Replay Counter value last used in a valid - * EAPOL-Key frame - * @gfp: allocation flags - * - * This function reports that the device offloaded the key management - * operation and established temporal keys for an RSN connection. In - * this case, the device handled the exchange necessary to establish - * the temporal keys by processing the EAPOL-Key frames instead of - * the supplicant doing it. This means the initial connection, roam - * operation, or PKT rekeying is complete and the supplicant should - * enter the authorized state for the port. This event can be signaled - * after cfg80211_connect_result during initial connection or after - * cfg80211_roamed in the case of roaming. This event might also be - * signaled after the device handles a PTK rekeying operation. If the - * auth_status parameter indicates that offload was not successful, - * then the supplicant should expect to do the necessary key management - * with the AP and the EAPOL-Key frames should be delivered to - * the supplicant. - */ -void cfg80211_authorization_event(struct net_device *dev, - enum nl80211_authorization_status auth_status, - const u8 *key_replay_ctr, - gfp_t gfp); - void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info); /* Logging, debugging and troubleshooting/diagnostic helpers. */ diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index e049285011f38..7e670c0f95474 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -688,24 +688,6 @@ * QoS mapping is relevant for IP packets, it is only valid during an * association. This is cleared on disassociation and AP restart. * - * @NL80211_CMD_AUTHORIZATION_EVENT: Indicates that the device offloaded - * the establishment of temporal keys for an RSN connection. This is - * used as part of key managment offload, where a device operating as a - * station is capable of doing the exchange necessary to establish - * temporal keys during initial RSN connection or after roaming. This - * event might also be sent after the device handles a PTK rekeying - * operation. The supplicant should expect to do the exchange itself, - * by preparing to process the EAPOL-Key frames, until - * NL80211_CMD_AUTHORIZATION_EVENT is sent with success status. The - * NL80211_ATTR_AUTHORIZATION_STATUS attribute provides the status of - * the offload and NL80211_KEY_REPLAY_CTR provides the Key Replay - * Counter value last used in a valid EAPOL-Key frame. - * - * @NL80211_CMD_KEY_MGMT_SET_PMK: Used to pass the PMK to the device for - * key management offload. This will be used in the case of key - * management offload on an already established PMKSA. The PMK is passed - * in NL80211_ATTR_PMK once it is known by the supplicant. - * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -877,9 +859,6 @@ enum nl80211_commands { NL80211_CMD_SET_QOS_MAP, - NL80211_CMD_AUTHORIZATION_EVENT, - NL80211_CMD_KEY_MGMT_SET_PMK, - /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -1560,19 +1539,6 @@ enum nl80211_commands { * @NL80211_ATTR_TDLS_PEER_CAPABILITY: flags for TDLS peer capabilities, u32. * As specified in the &enum nl80211_tdls_peer_capability. * - * @NL80211_ATTR_AUTHORIZATION_STATUS: Status of key management offload. - * @NL80211_ATTR_KEY_REPLAY_CTR: Key Replay Counter value last used in a - * valid EAPOL-Key frame. - * @NL80211_ATTR_PSK: The Preshared Key to be used for the connection. - * @NL80211_ATTR_OFFLOAD_KEY_MGMT: Requests that device handle establishment - * of temporal keys if possible. - * @NL80211_ATTR_KEY_MGMT_OFFLOAD_SUPPORT: Supported types of device key - * management offload. - * @NL80211_ATTR_KEY_DERIVE_OFFLOAD_SUPPORT: Supported types of device key - * derivation used as part of key management offload. - * @NL80211_ATTR_PMK: The Pairwise Master Key to be used for the - * connection. - * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -1909,14 +1875,6 @@ enum nl80211_attrs { NL80211_ATTR_TDLS_PEER_CAPABILITY, - NL80211_ATTR_AUTHORIZATION_STATUS, - NL80211_ATTR_KEY_REPLAY_CTR, - NL80211_ATTR_PSK, - NL80211_ATTR_OFFLOAD_KEY_MGMT, - NL80211_ATTR_KEY_MGMT_OFFLOAD_SUPPORT, - NL80211_ATTR_KEY_DERIVE_OFFLOAD_SUPPORT, - NL80211_ATTR_PMK, - /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -4000,64 +3958,4 @@ enum nl80211_tdls_peer_capability { NL80211_TDLS_PEER_WMM = 1<<2, }; -#define NL80211_KEY_LEN_PSK 32 -#define NL80211_KEY_LEN_PMK 32 -#define NL80211_KEY_REPLAY_CTR_LEN 8 - -/** - * enum nl80211_key_mgmt_offload_support - key management offload types - * - * Supported types of device key management offload. Allows device - * to advertise types of connections where it can offload establishment - * of temporal keys during initial RSN connection or after roaming. - * - * @NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PSK: WPA/WPA2 PSK key management. - * The NL80211_ATTR_PSK attribute is passed in NL80211_CMD_CONNECT. - * @NL80211_KEY_MGMT_OFFLOAD_SUPPORT_FT_PSK: 802.11r (FT) PSK key - * management. The NL80211_ATTR_PSK attribute is passed in - * NL80211_CMD_CONNECT. - * @NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PMKSA: Key management on already - * established PMKSA. The PMK will be passed using - * NL80211_CMD_KEY_MGMT_SET_PMK once it is known. - */ -enum nl80211_key_mgmt_offload_support { - NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PSK = 1 << 0, - NL80211_KEY_MGMT_OFFLOAD_SUPPORT_FT_PSK = 1 << 1, - NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PMKSA = 1 << 2, -}; - -/** - * enum nl80211_key_derive_offload_support - key derivation offload types - * - * Supported types of device key derivation used as part of key - * management offload. Assumes that GTK key derivation is supported - * by default for all supported key management offload types. - * - * @NL80211_KEY_DERIVE_OFFLOAD_SUPPORT_IGTK: IGTK key derivation. - */ -enum nl80211_key_derive_offload_support { - NL80211_KEY_DERIVE_OFFLOAD_SUPPORT_IGTK = 1 << 0, -}; - -/** - * enum nl80211_authorization_status - key management offload status - * - * Status of key management offload. Provided as part of - * NL80211_CMD_AUTHORIZATION_EVENT. - * - * @NL80211_CONNECTED: Device did not successfully offload key - * management. Supplicant should expect to do the security - * exchange necessary to establish the temporal keys for the - * connection. - * @NL80211_AUTHORIZED: Device successfully offloaded key - * management and established temporal keys for the connection, - * signfiying that the initial connection, roaming, or PTK - * rekeying is complete. Supplicant should enter the - * authorized state for the port. - */ -enum nl80211_authorization_status { - NL80211_CONNECTED, - NL80211_AUTHORIZED, -}; - #endif /* __LINUX_NL80211_H */ diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 0d75ae31c8fae..479d2ccca722a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -389,16 +389,6 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN }, [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 }, [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 }, - [NL80211_ATTR_AUTHORIZATION_STATUS] = { .type = NLA_U8 }, - [NL80211_ATTR_KEY_REPLAY_CTR] = { .type = NLA_BINARY, - .len = NL80211_KEY_REPLAY_CTR_LEN }, - [NL80211_ATTR_PSK] = { .type = NLA_BINARY, - .len = NL80211_KEY_LEN_PSK }, - [NL80211_ATTR_OFFLOAD_KEY_MGMT] = { .type = NLA_FLAG }, - [NL80211_ATTR_KEY_MGMT_OFFLOAD_SUPPORT] = { .type = NLA_U32 }, - [NL80211_ATTR_KEY_DERIVE_OFFLOAD_SUPPORT] = { .type = NLA_U32 }, - [NL80211_ATTR_PMK] = { .type = NLA_BINARY, - .len = NL80211_KEY_LEN_PMK }, }; /* policy for the key attributes */ @@ -1251,12 +1241,6 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) && nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP)) goto nla_put_failure; - if ((dev->wiphy.flags & WIPHY_FLAG_HAS_KEY_MGMT_OFFLOAD) && - (nla_put_u32(msg, NL80211_ATTR_KEY_MGMT_OFFLOAD_SUPPORT, - dev->wiphy.key_mgmt_offload_support) || - nla_put_u32(msg, NL80211_ATTR_KEY_DERIVE_OFFLOAD_SUPPORT, - dev->wiphy.key_derive_offload_support))) - goto nla_put_failure; (*split_start)++; if (split) @@ -6996,12 +6980,6 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) sizeof(connect.vht_capa)); } - if (nla_get_flag(info->attrs[NL80211_ATTR_OFFLOAD_KEY_MGMT])) - connect.flags |= ASSOC_REQ_OFFLOAD_KEY_MGMT; - - if (info->attrs[NL80211_ATTR_PSK]) - connect.psk = nla_data(info->attrs[NL80211_ATTR_PSK]); - err = cfg80211_connect(rdev, dev, &connect, connkeys); if (err) kfree(connkeys); @@ -8728,23 +8706,6 @@ static int nl80211_set_qos_map(struct sk_buff *skb, return ret; } -static int nl80211_key_mgmt_set_pmk(struct sk_buff *skb, struct genl_info *info) -{ - struct cfg80211_registered_device *rdev = info->user_ptr[0]; - struct net_device *dev = info->user_ptr[1]; - u8 *pmk; - - if (info->attrs[NL80211_ATTR_PMK]) - pmk = nla_data(info->attrs[NL80211_ATTR_PMK]); - else - return -EINVAL; - - if (!rdev->ops->key_mgmt_set_pmk) - return -EOPNOTSUPP; - - return rdev_key_mgmt_set_pmk(rdev, dev, pmk); -} - #define NL80211_FLAG_NEED_WIPHY 0x01 #define NL80211_FLAG_NEED_NETDEV 0x02 #define NL80211_FLAG_NEED_RTNL 0x04 @@ -9466,14 +9427,6 @@ static struct genl_ops nl80211_ops[] = { .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, - { - .cmd = NL80211_CMD_KEY_MGMT_SET_PMK, - .doit = nl80211_key_mgmt_set_pmk, - .policy = nl80211_policy, - .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | - NL80211_FLAG_NEED_RTNL, - }, }; static struct genl_multicast_group nl80211_mlme_mcgrp = { @@ -11281,56 +11234,6 @@ void cfg80211_ap_stopped(struct net_device *netdev, gfp_t gfp) } EXPORT_SYMBOL(cfg80211_ap_stopped); -void cfg80211_authorization_event(struct net_device *dev, - enum nl80211_authorization_status auth_status, - const u8 *key_replay_ctr, - gfp_t gfp) -{ - struct wireless_dev *wdev = dev->ieee80211_ptr; - struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); - struct sk_buff *msg; - void *hdr; - int err; - - /* Valid only in SME_CONNECTED state */ - if (wdev->sme_state != CFG80211_SME_CONNECTED) - return; - - trace_cfg80211_authorization_event(wdev->wiphy, dev, auth_status); - - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); - if (!msg) - return; - - hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_AUTHORIZATION_EVENT); - if (!hdr) { - nlmsg_free(msg); - return; - } - - if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || - nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || - nla_put_u8(msg, NL80211_ATTR_AUTHORIZATION_STATUS, auth_status) || - nla_put(msg, NL80211_ATTR_KEY_REPLAY_CTR, - NL80211_KEY_REPLAY_CTR_LEN, key_replay_ctr)) - goto nla_put_failure; - - err = genlmsg_end(msg, hdr); - if (err < 0) { - nlmsg_free(msg); - return; - } - - genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); - return; - -nla_put_failure: - genlmsg_cancel(msg, hdr); - nlmsg_free(msg); -} -EXPORT_SYMBOL(cfg80211_authorization_event); - /* initialisation/exit functions */ int nl80211_init(void) diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index 03cf1a925a672..bc1960bac7734 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -954,16 +954,4 @@ rdev_set_ap_chanwidth(struct cfg80211_registered_device *rdev, return ret; } -static inline int rdev_key_mgmt_set_pmk(struct cfg80211_registered_device *rdev, - struct net_device *dev, u8 *pmk) -{ - int ret; - - trace_rdev_key_mgmt_set_pmk(&rdev->wiphy, dev, pmk); - ret = rdev->ops->key_mgmt_set_pmk(&rdev->wiphy, dev, pmk); - trace_rdev_return_int(&rdev->wiphy, ret); - - return ret; -} - #endif /* __CFG80211_RDEV_OPS */ diff --git a/net/wireless/trace.h b/net/wireless/trace.h index d30f7a1048605..bf88313f0a78a 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -2586,29 +2586,6 @@ TRACE_EVENT(cfg80211_ft_event, WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(target_ap)) ); -DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_key_mgmt_set_pmk, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *pmk), - TP_ARGS(wiphy, netdev, pmk) -); - -TRACE_EVENT(cfg80211_authorization_event, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - enum nl80211_authorization_status auth_status), - TP_ARGS(wiphy, netdev, auth_status), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - __field(enum nl80211_authorization_status, auth_status) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - __entry->auth_status = auth_status; - ), - TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", auth_status: %d", - WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->auth_status) -); - #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ #undef TRACE_INCLUDE_PATH From 303296fc851a5cde678cc7cef915f7fc4bd2eb8b Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Wed, 25 May 2016 12:14:34 +0530 Subject: [PATCH 029/320] diag: Fix possible kernel addresses leak This patch addresses kernel addresses leak by changing the format specifier to adhere to the kptr_restrict system setting. CRs-Fixed: 987013 Change-Id: I32649a26f54d96c56d80aa2a1bd5f5d9dd0dd9d3 Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_dci.c | 16 ++++---- drivers/char/diag/diag_debugfs.c | 54 +++++++++++++-------------- drivers/char/diag/diag_masks.c | 26 ++++++------- drivers/char/diag/diag_memorydevice.c | 4 +- drivers/char/diag/diagchar_core.c | 4 +- drivers/char/diag/diagchar_hdlc.c | 4 +- drivers/char/diag/diagfwd.c | 10 ++--- drivers/char/diag/diagfwd_bridge.c | 4 +- drivers/char/diag/diagfwd_cntl.c | 4 +- drivers/char/diag/diagfwd_hsic.c | 4 +- drivers/char/diag/diagfwd_mhi.c | 14 +++---- 11 files changed, 71 insertions(+), 73 deletions(-) diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index 25b89dd9be3da..cb188b2f49601 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -405,7 +405,7 @@ static int diag_process_single_dci_pkt(unsigned char *buf, int len, uint8_t cmd_code = 0; if (!buf || len < 0) { - pr_err("diag: Invalid input in %s, buf: %p, len: %d\n", + pr_err("diag: Invalid input in %s, buf: %pK, len: %d\n", __func__, buf, len); return -EIO; } @@ -749,7 +749,7 @@ static int diag_dci_remove_req_entry(unsigned char *buf, int len, { uint16_t rsp_count = 0, delayed_rsp_id = 0; if (!buf || len <= 0 || !entry) { - pr_err("diag: In %s, invalid input buf: %p, len: %d, entry: %p\n", + pr_err("diag: In %s, invalid input buf: %pK, len: %d, entry: %pK\n", __func__, buf, len, entry); return -EIO; } @@ -803,7 +803,7 @@ static void dci_process_ctrl_status(unsigned char *buf, int len, int token) int peripheral_mask, status; if (!buf || (len < sizeof(struct diag_ctrl_dci_status))) { - pr_err("diag: In %s, invalid buf %p or length: %d\n", + pr_err("diag: In %s, invalid buf %pK or length: %d\n", __func__, buf, len); return; } @@ -1937,7 +1937,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len) __func__); return -ENOMEM; } - pr_debug("diag: head of dci log mask %p\n", head_log_mask_ptr); + pr_debug("diag: head of dci log mask %pK\n", head_log_mask_ptr); count = 0; /* iterator for extracting log codes */ while (count < num_codes) { @@ -1965,7 +1965,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len) while (log_mask_ptr && (offset < DCI_LOG_MASK_SIZE)) { if (*log_mask_ptr == equip_id) { found = 1; - pr_debug("diag: find equip id = %x at %p\n", + pr_debug("diag: find equip id = %x at %pK\n", equip_id, log_mask_ptr); break; } else { @@ -2043,7 +2043,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len) __func__); return -ENOMEM; } - pr_debug("diag: head of dci event mask %p\n", event_mask_ptr); + pr_debug("diag: head of dci event mask %pK\n", event_mask_ptr); count = 0; /* iterator for extracting log codes */ while (count < num_codes) { if (read_len >= USER_SPACE_DATA) { @@ -3096,7 +3096,7 @@ int diag_dci_write_proc(int peripheral, int pkt_type, char *buf, int len) if (!buf || (peripheral < 0 || peripheral >= NUM_SMD_DCI_CHANNELS) || !driver->rcvd_feature_mask[peripheral] || len < 0) { - pr_err("diag: In %s, invalid data 0x%p, peripheral: %d, len: %d\n", + pr_err("diag: In %s, invalid data 0x%pK, peripheral: %d, len: %d\n", __func__, buf, peripheral, len); return -EINVAL; } diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c index 6916507ec2b15..0812576732321 100644 --- a/drivers/char/diag/diag_debugfs.c +++ b/drivers/char/diag/diag_debugfs.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -50,26 +50,26 @@ static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf, } buf_size = ksize(buf); ret = scnprintf(buf, buf_size, - "modem ch: 0x%p\n" - "lpass ch: 0x%p\n" - "riva ch: 0x%p\n" - "sensors ch: 0x%p\n" - "modem dci ch: 0x%p\n" - "lpass dci ch: 0x%p\n" - "riva dci ch: 0x%p\n" - "sensors dci ch: 0x%p\n" - "modem cntl_ch: 0x%p\n" - "lpass cntl_ch: 0x%p\n" - "riva cntl_ch: 0x%p\n" - "sensors cntl_ch: 0x%p\n" - "modem cmd ch: 0x%p\n" - "adsp cmd ch: 0x%p\n" - "riva cmd ch: 0x%p\n" - "sensors cmd ch: 0x%p\n" - "modem dci cmd ch: 0x%p\n" - "lpass dci cmd ch: 0x%p\n" - "riva dci cmd ch: 0x%p\n" - "sensors dci cmd ch: 0x%p\n" + "modem ch: 0x%pK\n" + "lpass ch: 0x%pK\n" + "riva ch: 0x%pK\n" + "sensors ch: 0x%pK\n" + "modem dci ch: 0x%pK\n" + "lpass dci ch: 0x%pK\n" + "riva dci ch: 0x%pK\n" + "sensors dci ch: 0x%pK\n" + "modem cntl_ch: 0x%pK\n" + "lpass cntl_ch: 0x%pK\n" + "riva cntl_ch: 0x%pK\n" + "sensors cntl_ch: 0x%pK\n" + "modem cmd ch: 0x%pK\n" + "adsp cmd ch: 0x%pK\n" + "riva cmd ch: 0x%pK\n" + "sensors cmd ch: 0x%pK\n" + "modem dci cmd ch: 0x%pK\n" + "lpass dci cmd ch: 0x%pK\n" + "riva dci cmd ch: 0x%pK\n" + "sensors dci cmd ch: 0x%pK\n" "CPU Tools id: %d\n" "Apps only: %d\n" "Apps master: %d\n" @@ -723,7 +723,7 @@ static ssize_t diag_dbgfs_read_usbinfo(struct file *file, char __user *ubuf, bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining, "id: %d\n" "name: %s\n" - "hdl: %p\n" + "hdl: %pK\n" "connected: %d\n" "enabled: %d\n" "mempool: %s\n" @@ -865,9 +865,9 @@ static ssize_t diag_dbgfs_read_mhiinfo(struct file *file, char __user *ubuf, "bridge index: %s\n" "mempool: %s\n" "read ch opened: %d\n" - "read ch hdl: %p\n" + "read ch hdl: %pK\n" "write ch opened: %d\n" - "write ch hdl: %p\n" + "write ch hdl: %pK\n" "read work pending: %d\n" "read done work pending: %d\n" "open work pending: %d\n" @@ -936,9 +936,9 @@ static ssize_t diag_dbgfs_read_bridge(struct file *file, char __user *ubuf, "type: %d\n" "inited: %d\n" "ctxt: %d\n" - "dev_ops: %p\n" - "dci_read_buf: %p\n" - "dci_read_ptr: %p\n" + "dev_ops: %pK\n" + "dci_read_buf: %pK\n" + "dci_read_ptr: %pK\n" "dci_read_len: %d\n\n", info->id, info->name, diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c index 7c0f103b2fbe9..c007cb568fd48 100644 --- a/drivers/char/diag/diag_masks.c +++ b/drivers/char/diag/diag_masks.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -386,7 +386,7 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len, struct diag_ssid_range_t ssid_range; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -430,7 +430,7 @@ static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len, struct diag_msg_build_mask_t rsp; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -483,7 +483,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len, struct diag_msg_build_mask_t rsp; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -535,7 +535,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, uint32_t *temp = NULL; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -628,7 +628,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len, struct diag_msg_mask_t *mask = (struct diag_msg_mask_t *)msg_mask.ptr; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -674,7 +674,7 @@ static int diag_cmd_get_event_mask(unsigned char *src_buf, int src_len, struct diag_event_mask_config_t rsp; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -712,7 +712,7 @@ static int diag_cmd_update_event_mask(unsigned char *src_buf, int src_len, struct diag_event_mask_config_t *req; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -759,7 +759,7 @@ static int diag_cmd_toggle_events(unsigned char *src_buf, int src_len, struct diag_event_report_t header; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -805,7 +805,7 @@ static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len, struct diag_log_config_rsp_t rsp; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -875,7 +875,7 @@ static int diag_cmd_get_log_range(unsigned char *src_buf, int src_len, return 0; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -913,7 +913,7 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len, struct diag_log_config_set_rsp_t rsp; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -992,7 +992,7 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len, int i; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } diff --git a/drivers/char/diag/diag_memorydevice.c b/drivers/char/diag/diag_memorydevice.c index f00f2a9bc0103..53982079b90dd 100644 --- a/drivers/char/diag/diag_memorydevice.c +++ b/drivers/char/diag/diag_memorydevice.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -142,7 +142,7 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx) if (ch->tbl[i].buf != buf) continue; found = 1; - pr_err_ratelimited("diag: trying to write the same buffer buf: %p, ctxt: %d len: %d at i: %d back to the table, proc: %d, mode: %d\n", + pr_err_ratelimited("diag: trying to write the same buffer buf: %pK, ctxt: %d len: %d at i: %d back to the table, proc: %d, mode: %d\n", buf, ctx, ch->tbl[i].len, i, id, driver->logging_mode); } diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index bb14523f2ec3a..ffb34fb54a6a7 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -706,7 +706,7 @@ static int diag_process_userspace_remote(int proc, void *buf, int len) int bridge_index = proc - 1; if (!buf || len < 0) { - pr_err("diag: Invalid input in %s, buf: %p, len: %d\n", + pr_err("diag: Invalid input in %s, buf: %pK, len: %d\n", __func__, buf, len); return -EINVAL; } diff --git a/drivers/char/diag/diagchar_hdlc.c b/drivers/char/diag/diagchar_hdlc.c index 39f1f4487467c..4a6de7381793c 100644 --- a/drivers/char/diag/diagchar_hdlc.c +++ b/drivers/char/diag/diagchar_hdlc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2009, 2012-2013, The Linux Foundation. +/* Copyright (c) 2008-2009, 2012-2013, 2016, The Linux Foundation. * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -242,7 +242,7 @@ int crc_check(uint8_t *buf, uint16_t len) * of data and 3 bytes for CRC */ if (!buf || len < 4) { - pr_err_ratelimited("diag: In %s, invalid packet or length, buf: 0x%p, len: %d", + pr_err_ratelimited("diag: In %s, invalid packet or length, buf: 0x%pK, len: %d", __func__, buf, len); return -EIO; } diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c index cbb9dbc2db1ae..19e38d4800a07 100644 --- a/drivers/char/diag/diagfwd.c +++ b/drivers/char/diag/diagfwd.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -810,7 +810,7 @@ void diag_update_pkt_buffer(unsigned char *buf, int type) } if (!ptr || length == 0) { - pr_err("diag: Invalid ptr %p and length %d in %s", + pr_err("diag: Invalid ptr %pK and length %d in %s", ptr, length, __func__); return; } @@ -923,7 +923,7 @@ int diag_process_stm_cmd(unsigned char *buf, unsigned char *dest_buf) int i; if (!buf || !dest_buf) { - pr_err("diag: Invalid pointers buf: %p, dest_buf %p in %s\n", + pr_err("diag: Invalid pointers buf: %pK, dest_buf %pK in %s\n", buf, dest_buf, __func__); return -EIO; } @@ -1011,7 +1011,7 @@ int diag_cmd_log_on_demand(unsigned char *src_buf, int src_len, return 0; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -2038,7 +2038,7 @@ int diag_smd_write(struct diag_smd_info *smd_info, void *buf, int len) int max_retries = 3; if (!smd_info || !buf || len <= 0) { - pr_err_ratelimited("diag: In %s, invalid params, smd_info: %p, buf: %p, len: %d\n", + pr_err_ratelimited("diag: In %s, invalid params, smd_info: %pK, buf: %pK, len: %d\n", __func__, smd_info, buf, len); return -EINVAL; } diff --git a/drivers/char/diag/diagfwd_bridge.c b/drivers/char/diag/diagfwd_bridge.c index f6aa7962d5167..df2eafa7831bd 100644 --- a/drivers/char/diag/diagfwd_bridge.c +++ b/drivers/char/diag/diagfwd_bridge.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -133,7 +133,7 @@ int diagfwd_bridge_register(int id, int ctxt, struct diag_remote_dev_ops *ops) char wq_name[DIAG_BRIDGE_NAME_SZ + 10]; if (!ops) { - pr_err("diag: Invalid pointers ops: %p ctxt: %d\n", ops, ctxt); + pr_err("diag: Invalid pointers ops: %pK ctxt: %d\n", ops, ctxt); return -EINVAL; } diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c index 55ce976da9876..cf7284401b6ba 100644 --- a/drivers/char/diag/diagfwd_cntl.c +++ b/drivers/char/diag/diagfwd_cntl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -836,7 +836,7 @@ int diag_send_diag_mode_update_by_smd(struct diag_smd_info *smd_info, int err = 0; if (!smd_info || smd_info->type != SMD_CNTL_TYPE) { - pr_err("diag: In %s, invalid channel info, smd_info: %p type: %d\n", + pr_err("diag: In %s, invalid channel info, smd_info: %pK type: %d\n", __func__, smd_info, ((smd_info) ? smd_info->type : -1)); return -EIO; diff --git a/drivers/char/diag/diagfwd_hsic.c b/drivers/char/diag/diagfwd_hsic.c index 987931fdc7626..df9b9a6e37d1d 100644 --- a/drivers/char/diag/diagfwd_hsic.c +++ b/drivers/char/diag/diagfwd_hsic.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -354,7 +354,7 @@ static int hsic_write(int id, unsigned char *buf, int len, int ctxt) return -EINVAL; } if (!buf || len <= 0) { - pr_err_ratelimited("diag: In %s, ch %d, invalid buf %p len %d\n", + pr_err_ratelimited("diag: In %s, ch %d, invalid buf %pK len %d\n", __func__, id, buf, len); return -EINVAL; } diff --git a/drivers/char/diag/diagfwd_mhi.c b/drivers/char/diag/diagfwd_mhi.c index a2bea81449161..bf170ee2eef89 100644 --- a/drivers/char/diag/diagfwd_mhi.c +++ b/drivers/char/diag/diagfwd_mhi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -132,11 +132,9 @@ static int mhi_buf_tbl_add(struct diag_mhi_info *mhi_info, int type, } item = kzalloc(sizeof(struct diag_mhi_buf_tbl_t), GFP_KERNEL); - if (!item) { - pr_err_ratelimited("diag: In %s, unable to allocate new item for buf tbl, ch: %p, type: %d, buf: %p, len: %d\n", - __func__, ch, ch->type, buf, len); + if (!item) return -ENOMEM; - } + kmemleak_not_leak(item); spin_lock_irqsave(&ch->lock, flags); @@ -187,7 +185,7 @@ static void mhi_buf_tbl_remove(struct diag_mhi_info *mhi_info, int type, spin_unlock_irqrestore(&ch->lock, flags); if (!found) { - pr_err_ratelimited("diag: In %s, unable to find buffer, ch: %p, type: %d, buf: %p\n", + pr_err_ratelimited("diag: In %s, unable to find buffer, ch: %pK, type: %d, buf: %pK\n", __func__, ch, ch->type, buf); } } @@ -443,7 +441,7 @@ static int mhi_write(int id, unsigned char *buf, int len, int ctxt) } if (!buf || len <= 0) { - pr_err("diag: In %s, ch %d, invalid buf %p len %d\n", + pr_err("diag: In %s, ch %d, invalid buf %pK len %d\n", __func__, id, buf, len); return -EINVAL; } @@ -473,7 +471,7 @@ static int mhi_write(int id, unsigned char *buf, int len, int ctxt) err = mhi_queue_xfer(ch->hdl, dma_addr, len, flags); if (err) { - pr_err_ratelimited("diag: In %s, cannot write to MHI channel %p, len %d, err: %d\n", + pr_err_ratelimited("diag: In %s, cannot write to MHI channel %pK, len %d, err: %d\n", __func__, diag_mhi[id].name, len, err); dma_unmap_single(NULL, (dma_addr_t)dma_addr, len, DMA_TO_DEVICE); From b2dc799936868bd5aaa9749faa49414fa3c1c046 Mon Sep 17 00:00:00 2001 From: Jeevan Shriram Date: Tue, 12 May 2015 20:21:32 -0700 Subject: [PATCH 030/320] msm: mdss: suppress dsi fifo errors during refresh rate update When the frame rate is changed, there could be fifo errors for atleast one frame and it logs in kernel messages. During the stability tests, where there is continuous update to the frame rate, these error logs are causes crash. This change suppresses the log when there is dynamic refresh rate update. Change-Id: I59020948fa33b326d691d24fe30ddcbde74b1816 Signed-off-by: Jeevan Shriram Signed-off-by: Nirmal Abraham --- drivers/video/msm/mdss/mdss_dsi.c | 4 ++++ drivers/video/msm/mdss/mdss_dsi.h | 2 ++ drivers/video/msm/mdss/mdss_dsi_host.c | 12 +++++++++++- drivers/video/msm/mdss/mdss_mdp_intf_video.c | 4 ++-- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c index b852ecbd7ee0e..9d12dfb457d92 100644 --- a/drivers/video/msm/mdss/mdss_dsi.c +++ b/drivers/video/msm/mdss/mdss_dsi.c @@ -1113,6 +1113,10 @@ static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps) sctrl_pdata = mdss_dsi_get_other_ctrl(ctrl_pdata); } + ctrl_pdata->dfps_status = true; + if (sctrl_pdata) + sctrl_pdata->dfps_status = true; + if (new_fps != ctrl_pdata->panel_data.panel_info.mipi.frame_rate) { if (pdata->panel_info.dfps_update diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h index 19ca4c4032a2e..23c72f87089a0 100644 --- a/drivers/video/msm/mdss/mdss_dsi.h +++ b/drivers/video/msm/mdss/mdss_dsi.h @@ -418,6 +418,8 @@ struct mdss_dsi_ctrl_pdata { int horizontal_idle_cnt; struct panel_horizontal_idle *line_idle; struct mdss_util_intf *mdss_util; + + bool dfps_status; /* dynamic refresh status */ }; struct dsi_status_data { diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c index 7838edac6752e..24c3e63b13717 100644 --- a/drivers/video/msm/mdss/mdss_dsi_host.c +++ b/drivers/video/msm/mdss/mdss_dsi_host.c @@ -2339,7 +2339,14 @@ void mdss_dsi_fifo_status(struct mdss_dsi_ctrl_pdata *ctrl) /* fifo underflow, overflow and empty*/ if (status & 0xcccc4489) { MIPI_OUTP(base + 0x000c, status); - pr_err("%s: status=%x\n", __func__, status); + + /* + * During dynamic refresh rate update, DSI fifo errors are + * expected, Check the dfps status and avoid the log. However, + * FIFO errors needs to be cleared. + */ + if (!ctrl->dfps_status) + pr_err("%s: status=%x\n", __func__, status); /* * if DSI FIFO overflow is masked, @@ -2358,6 +2365,9 @@ void mdss_dsi_fifo_status(struct mdss_dsi_ctrl_pdata *ctrl) if (status & 0x11110000) /* DLN_FIFO_EMPTY */ dsi_send_events(ctrl, DSI_EV_DSI_FIFO_EMPTY, 0); } + + if (ctrl->dfps_status) + ctrl->dfps_status = false; } void mdss_dsi_status(struct mdss_dsi_ctrl_pdata *ctrl) diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c index 57fff13904c57..2bc8a1db0b109 100644 --- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c +++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -213,7 +213,7 @@ static void mdss_mdp_video_intf_recovery(void *data, int event) mutex_unlock(&ctl->offlock); return; } else { - pr_warn("line count is less. line_cnt = %d\n", + pr_warn_once("line count is less. line_cnt = %d\n", line_cnt); /* Add delay so that line count is in active region */ udelay(delay); From 06fe683f72932b0af0b669bdb1ad08a45a5d4bcb Mon Sep 17 00:00:00 2001 From: Sunil Khatri Date: Wed, 25 May 2016 21:13:46 +0530 Subject: [PATCH 031/320] msm: kgsl: Defer adding the mem entry to a process If we add the mem entry pointer in the process idr and rb tree too early, other threads can do operations on the entry by guessing the ID or GPU address before the object gets returned by the creating operation. Allocate an ID for the object but don't assign the pointer until right before the creating function returns ensuring that another operation can't access it until it is ready. CRs-Fixed: 1002974 Change-Id: Ic0dedbadc0dd2125bd2a7bcc152972c0555e07f8 Signed-off-by: Jordan Crouse Signed-off-by: Sunil Khatri Signed-off-by: Santhosh Punugu --- drivers/gpu/msm/kgsl.c | 62 ++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 5f06af5858a07..f4b6c83f8b7fd 100755 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -296,27 +296,20 @@ kgsl_mem_entry_destroy(struct kref *kref) EXPORT_SYMBOL(kgsl_mem_entry_destroy); /** - * kgsl_mem_entry_track_gpuaddr - Insert a mem_entry in the address tree and - * assign it with a gpu address space before insertion + * kgsl_mem_entry_track_gpuaddr - Get the entry gpu address space before + * insertion to the process * @process: the process that owns the memory * @entry: the memory entry * - * @returns - 0 on succcess else error code + * @returns - 0 on success else error code * - * Insert the kgsl_mem_entry in to the rb_tree for searching by GPU address. - * The assignment of gpu address and insertion into list needs to - * happen with the memory lock held to avoid race conditions between - * gpu address being selected and some other thread looking through the - * rb list in search of memory based on gpuaddr * This function should be called with processes memory spinlock held - */ +*/ static int kgsl_mem_entry_track_gpuaddr(struct kgsl_process_private *process, struct kgsl_mem_entry *entry) { int ret = 0; - struct rb_node **node; - struct rb_node *parent = NULL; struct kgsl_pagetable *pagetable = process->pagetable; size_t size = entry->memdesc.size; @@ -340,11 +333,22 @@ kgsl_mem_entry_track_gpuaddr(struct kgsl_process_private *process, pagetable = pagetable->mmu->securepagetable; ret = kgsl_mmu_get_gpuaddr(pagetable, &entry->memdesc); - if (ret) - goto done; - node = &process->mem_rb.rb_node; +done: + return ret; +} + +static void kgsl_mem_entry_commit_mem_list(struct kgsl_process_private *process, + struct kgsl_mem_entry *entry) +{ + struct rb_node **node; + struct rb_node *parent = NULL; + + if (!entry->memdesc.gpuaddr) + return; + /* Insert mem entry in mem_rb tree */ + node = &process->mem_rb.rb_node; while (*node) { struct kgsl_mem_entry *cur; @@ -359,9 +363,20 @@ kgsl_mem_entry_track_gpuaddr(struct kgsl_process_private *process, rb_link_node(&entry->node, parent, node); rb_insert_color(&entry->node, &process->mem_rb); +} -done: - return ret; +static void kgsl_mem_entry_commit_process(struct kgsl_process_private *process, + struct kgsl_mem_entry *entry) +{ + if (!entry) + return; + + spin_lock(&entry->priv->mem_lock); + /* Insert mem entry in mem_rb tree */ + kgsl_mem_entry_commit_mem_list(process, entry); + /* Replace mem entry in mem_idr using id */ + idr_replace(&entry->priv->mem_idr, entry, entry->id); + spin_unlock(&entry->priv->mem_lock); } /** @@ -410,7 +425,8 @@ kgsl_mem_entry_attach_process(struct kgsl_mem_entry *entry, return -EBADF; idr_preload(GFP_KERNEL); spin_lock(&process->mem_lock); - id = idr_alloc(&process->mem_idr, entry, 1, 0, GFP_NOWAIT); + /* Allocate the ID but don't attach the pointer just yet */ + id = idr_alloc(&process->mem_idr, NULL, 1, 0, GFP_NOWAIT); spin_unlock(&process->mem_lock); idr_preload_end(); @@ -3237,6 +3253,7 @@ long kgsl_ioctl_map_user_mem(struct kgsl_device_private *dev_priv, trace_kgsl_mem_map(entry, param->fd); + kgsl_mem_entry_commit_process(private, entry); return result; error_attach: @@ -3579,6 +3596,8 @@ long kgsl_ioctl_gpumem_alloc(struct kgsl_device_private *dev_priv, param->gpuaddr = entry->memdesc.gpuaddr; param->size = entry->memdesc.size; param->flags = entry->memdesc.flags; + + kgsl_mem_entry_commit_process(private, entry); return result; err: kgsl_sharedmem_free(&entry->memdesc); @@ -3619,6 +3638,8 @@ long kgsl_ioctl_gpumem_alloc_id(struct kgsl_device_private *dev_priv, param->size = entry->memdesc.size; param->mmapsize = kgsl_memdesc_mmapsize(&entry->memdesc); param->gpuaddr = entry->memdesc.gpuaddr; + + kgsl_mem_entry_commit_process(private, entry); return result; err: if (entry) @@ -4142,6 +4163,11 @@ static int kgsl_check_gpu_addr_collision( spin_lock(&private->mem_lock); kgsl_mem_entry_untrack_gpuaddr(private, entry); spin_unlock(&private->mem_lock); + } else { + /* Insert mem entry in mem_rb tree */ + spin_lock(&private->mem_lock); + kgsl_mem_entry_commit_mem_list(private, entry); + spin_unlock(&private->mem_lock); } } else { trace_kgsl_mem_unmapped_area_collision(entry, addr, len, From 9d74c39050ddea233bd2f017f2dda62dc4d473f1 Mon Sep 17 00:00:00 2001 From: Suman Mukherjee Date: Tue, 17 May 2016 11:36:40 +0530 Subject: [PATCH 032/320] msm: camera: isp: Fix warning and errors based on static analysis This change fixes the warning/errors from static analysis Conflicts: drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c CRs-fixed: 992942 Change-Id: Iaf90ab4c1d17f903d03458d76cab1b4c0a5c8836 Signed-off-by: Jing Zhou Signed-off-by: Suman Mukherjee --- .../platform/msm/camera_v2/isp/msm_buf_mgr.c | 5 +++-- .../msm/camera_v2/isp/msm_isp_axi_util.c | 16 ++++++---------- .../platform/msm/camera_v2/isp/msm_isp_util.c | 6 ++---- .../platform/msm/camera_v2/ispif/msm_ispif.c | 14 +++++++------- 4 files changed, 18 insertions(+), 23 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c index 7849c87a91b84..bf0d2016d8447 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -45,7 +45,8 @@ struct msm_isp_bufq *msm_isp_get_bufq( uint32_t bufq_index = bufq_handle & 0xFF; if ((bufq_handle == 0) || - (bufq_index > buf_mgr->num_buf_q)) + (bufq_index > buf_mgr->num_buf_q) || + (bufq_index >= BUF_MGR_NUM_BUF_Q) ) return NULL; bufq = &buf_mgr->bufq[bufq_index]; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index e76dd0484d323..054d26339a9e1 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -25,15 +25,11 @@ int msm_isp_axi_create_stream( struct msm_vfe_axi_shared_data *axi_data, struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd) { - int i, rc = -1; - for (i = 0; i < MAX_NUM_STREAM; i++) { - if (axi_data->stream_info[i].state == AVALIABLE) - break; - } - - if (i == MAX_NUM_STREAM) { - pr_err("%s: No free stream\n", __func__); - return rc; + uint32_t i = stream_cfg_cmd->stream_src; + if (i >= VFE_AXI_SRC_MAX) { + pr_err("%s:%d invalid stream_src %d\n", __func__, __LINE__, + stream_cfg_cmd->stream_src); + return -EINVAL; } if ((axi_data->stream_handle_cnt << 8) == 0) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c index c335ccd13b759..529757ac48244 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c @@ -1493,8 +1493,6 @@ void msm_isp_update_error_frame_count(struct vfe_device *vfe_dev) { struct msm_vfe_error_info *error_info = &vfe_dev->error_info; error_info->info_dump_frame_count++; - if (error_info->info_dump_frame_count == 0) - error_info->info_dump_frame_count++; } void msm_isp_process_error_info(struct vfe_device *vfe_dev) @@ -1603,6 +1601,7 @@ static void msm_isp_process_overflow_irq( *irq_status0 = 0; *irq_status1 = 0; + memset(&error_event, 0, sizeof(error_event)); error_event.frame_id = vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id; error_event.u.error_info.error_mask = 1 << ISP_WM_BUS_OVERFLOW; @@ -1619,8 +1618,7 @@ void msm_isp_reset_burst_count_and_frame_drop( stream_info->stream_type != BURST_STREAM) { return; } - if (stream_info->stream_type == BURST_STREAM && - stream_info->num_burst_capture != 0) { + if (stream_info->num_burst_capture != 0) { framedrop_period = msm_isp_get_framedrop_period( stream_info->frame_skip_pattern); stream_info->burst_frame_count = diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c index 94c962dd7f1d3..1fd8da1e50ead 100644 --- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c +++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c @@ -358,23 +358,23 @@ static void msm_ispif_sel_csid_core(struct ispif_device *ispif, switch (intftype) { case PIX0: data &= ~(BIT(1) | BIT(0)); - data |= csid; + data |= (uint32_t)csid; break; case RDI0: data &= ~(BIT(5) | BIT(4)); - data |= (csid << 4); + data |= (uint32_t)(csid << 4); break; case PIX1: data &= ~(BIT(9) | BIT(8)); - data |= (csid << 8); + data |= (uint32_t)(csid << 8); break; case RDI1: data &= ~(BIT(13) | BIT(12)); - data |= (csid << 12); + data |= (uint32_t)(csid << 12); break; case RDI2: data &= ~(BIT(21) | BIT(20)); - data |= (csid << 20); + data |= (uint32_t)(csid << 20); break; } @@ -450,9 +450,9 @@ static void msm_ispif_enable_intf_cids(struct ispif_device *ispif, data = msm_camera_io_r(ispif->base + intf_addr); if (enable) - data |= cid_mask; + data |= (uint32_t)cid_mask; else - data &= ~cid_mask; + data &= ~((uint32_t)cid_mask); msm_camera_io_w_mb(data, ispif->base + intf_addr); } From 975b8cf9851295a7513d51305228895c28f16f97 Mon Sep 17 00:00:00 2001 From: Vijayavardhan Vennapusa Date: Thu, 5 May 2016 14:37:08 +0530 Subject: [PATCH 033/320] USB: dwc3: debugfs: Add boundary check in dwc3_store_ep_num() User can pass arguments as part of write to requests and endpoint number will be calculated based on the arguments. There is a chance that driver can access ep structue that is not allocated due to invalid arguments passed by user. Hence fix the issue by having check and return error in case of invalid arguments. Change-Id: I060ea878b55ce0f9983b91c50e58718c8a2c2fa1 Signed-off-by: Vijayavardhan Vennapusa --- drivers/usb/dwc3/debugfs.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 9bd48e6ffe872..7fe942475e9f7 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -650,7 +650,7 @@ static ssize_t dwc3_store_ep_num(struct file *file, const char __user *ubuf, struct seq_file *s = file->private_data; struct dwc3 *dwc = s->private; char kbuf[10]; - unsigned int num, dir; + unsigned int num, dir, temp; unsigned long flags; memset(kbuf, 0, 10); @@ -661,8 +661,16 @@ static ssize_t dwc3_store_ep_num(struct file *file, const char __user *ubuf, if (sscanf(kbuf, "%u %u", &num, &dir) != 2) return -EINVAL; + if (dir != 0 && dir != 1) + return -EINVAL; + + temp = (num << 1) + dir; + if (temp >= (dwc->num_in_eps + dwc->num_out_eps) || + temp >= DWC3_ENDPOINTS_NUM) + return -EINVAL; + spin_lock_irqsave(&dwc->lock, flags); - ep_num = (num << 1) + dir; + ep_num = temp; spin_unlock_irqrestore(&dwc->lock, flags); return count; From 68062b6f3a4238900756e20bccf921160d717d0a Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 31 Oct 2014 09:54:53 +0530 Subject: [PATCH 034/320] mm: fix prctl_set_vma_anon_name prctl_set_vma_anon_name could attempt to set the name across two vmas at the same time due to a typo, which might corrupt the vma list. Fix it to use tmp instead of end to limit the name setting to a single vma at a time. Change-Id:I8dc2353f32b5f8510986d01c5f27d450b645902a Reported-by: Jed Davis Signed-off-by: Colin Cross Git-commit: 9bc0c15675840178cee1486c2a7f25faead1518e Git-Repo: https://android.googlesource.com/kernel/common.git Signed-off-by: Vinayak Menon --- kernel/sys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sys.c b/kernel/sys.c index 407abeef9f6e9..0b08c9f000f35 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -2187,7 +2187,7 @@ static int prctl_set_vma_anon_name(unsigned long start, unsigned long end, tmp = end; /* Here vma->vm_start <= start < tmp <= (end|vma->vm_end). */ - error = prctl_update_vma_anon_name(vma, &prev, start, end, + error = prctl_update_vma_anon_name(vma, &prev, start, tmp, (const char __user *)arg); if (error) return error; From 1085d27852b243f762cf5f06356804c9c371c637 Mon Sep 17 00:00:00 2001 From: Srinivasa Rao Kuppala Date: Thu, 14 Apr 2016 15:42:05 +0530 Subject: [PATCH 035/320] defconfig: Disable CONFIG_SYSVIPC for msm Android SELinux policies block SysV IPC. New kernels should not be built with it. Change-Id: Ic7a42d9d8a0cff3795cbc71cedbe394e36345ddc Signed-off-by: Srinivasa Rao Kuppala --- arch/arm/configs/msm8909-1gb-LMT-perf_defconfig | 2 +- arch/arm/configs/msm8909-1gb-perf_defconfig | 2 +- arch/arm/configs/msm8909-1gb_defconfig | 2 +- arch/arm/configs/msm8909-perf_defconfig | 2 +- arch/arm/configs/msm8909_defconfig | 2 +- arch/arm/configs/msm8909w-perf_defconfig | 2 +- arch/arm/configs/msm8909w_defconfig | 2 +- arch/arm/configs/msm8916-512mb-perf_defconfig | 2 +- arch/arm/configs/msm8916-512mb_defconfig | 2 +- arch/arm/configs/msm8916-LMT-perf_defconfig | 2 +- arch/arm/configs/msm8916-perf_defconfig | 2 +- arch/arm/configs/msm8916_defconfig | 2 +- arch/arm64/configs/msm-LMT-perf_defconfig | 2 +- arch/arm64/configs/msm-perf_defconfig | 2 +- arch/arm64/configs/msm_defconfig | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/arch/arm/configs/msm8909-1gb-LMT-perf_defconfig b/arch/arm/configs/msm8909-1gb-LMT-perf_defconfig index 6c67c525c083e..f755138ff7591 100644 --- a/arch/arm/configs/msm8909-1gb-LMT-perf_defconfig +++ b/arch/arm/configs/msm8909-1gb-LMT-perf_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y diff --git a/arch/arm/configs/msm8909-1gb-perf_defconfig b/arch/arm/configs/msm8909-1gb-perf_defconfig index cf2a357fb7672..3163de0b95dcb 100644 --- a/arch/arm/configs/msm8909-1gb-perf_defconfig +++ b/arch/arm/configs/msm8909-1gb-perf_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y diff --git a/arch/arm/configs/msm8909-1gb_defconfig b/arch/arm/configs/msm8909-1gb_defconfig index 663eef5801bd9..529d1cea2bf00 100644 --- a/arch/arm/configs/msm8909-1gb_defconfig +++ b/arch/arm/configs/msm8909-1gb_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y diff --git a/arch/arm/configs/msm8909-perf_defconfig b/arch/arm/configs/msm8909-perf_defconfig index 1551aa0421d41..28f641919597b 100644 --- a/arch/arm/configs/msm8909-perf_defconfig +++ b/arch/arm/configs/msm8909-perf_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y diff --git a/arch/arm/configs/msm8909_defconfig b/arch/arm/configs/msm8909_defconfig index bcb15f2957918..cb95945356ca7 100644 --- a/arch/arm/configs/msm8909_defconfig +++ b/arch/arm/configs/msm8909_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y diff --git a/arch/arm/configs/msm8909w-perf_defconfig b/arch/arm/configs/msm8909w-perf_defconfig index 27d65d33b8498..018f1584e2579 100644 --- a/arch/arm/configs/msm8909w-perf_defconfig +++ b/arch/arm/configs/msm8909w-perf_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y diff --git a/arch/arm/configs/msm8909w_defconfig b/arch/arm/configs/msm8909w_defconfig index 3ae54cb710105..86bb9a0330fd2 100644 --- a/arch/arm/configs/msm8909w_defconfig +++ b/arch/arm/configs/msm8909w_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y diff --git a/arch/arm/configs/msm8916-512mb-perf_defconfig b/arch/arm/configs/msm8916-512mb-perf_defconfig index b69905e625dc7..923fd7cde0c61 100755 --- a/arch/arm/configs/msm8916-512mb-perf_defconfig +++ b/arch/arm/configs/msm8916-512mb-perf_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y diff --git a/arch/arm/configs/msm8916-512mb_defconfig b/arch/arm/configs/msm8916-512mb_defconfig index 4c6ec5adb4c00..bfff5b603c384 100644 --- a/arch/arm/configs/msm8916-512mb_defconfig +++ b/arch/arm/configs/msm8916-512mb_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y diff --git a/arch/arm/configs/msm8916-LMT-perf_defconfig b/arch/arm/configs/msm8916-LMT-perf_defconfig index 337f283868697..abd29e9d6a56a 100644 --- a/arch/arm/configs/msm8916-LMT-perf_defconfig +++ b/arch/arm/configs/msm8916-LMT-perf_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y diff --git a/arch/arm/configs/msm8916-perf_defconfig b/arch/arm/configs/msm8916-perf_defconfig index 30ceb28fa270d..cd18ab7677e80 100644 --- a/arch/arm/configs/msm8916-perf_defconfig +++ b/arch/arm/configs/msm8916-perf_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y diff --git a/arch/arm/configs/msm8916_defconfig b/arch/arm/configs/msm8916_defconfig index 846b9eff1d71d..0609e27fe5a0e 100755 --- a/arch/arm/configs/msm8916_defconfig +++ b/arch/arm/configs/msm8916_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y diff --git a/arch/arm64/configs/msm-LMT-perf_defconfig b/arch/arm64/configs/msm-LMT-perf_defconfig index 5ff85619c2714..cf878ca433e54 100644 --- a/arch/arm64/configs/msm-LMT-perf_defconfig +++ b/arch/arm64/configs/msm-LMT-perf_defconfig @@ -1,5 +1,5 @@ CONFIG_LOCALVERSION="-perf" -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig index 60949ef47970a..6d371dc25176a 100644 --- a/arch/arm64/configs/msm-perf_defconfig +++ b/arch/arm64/configs/msm-perf_defconfig @@ -1,5 +1,5 @@ CONFIG_LOCALVERSION="-perf" -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig index 029e4637785e7..cc666ceb2bb15 100644 --- a/arch/arm64/configs/msm_defconfig +++ b/arch/arm64/configs/msm_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y From 75e1be941e9dd35a29b94d35bbea7652234c998c Mon Sep 17 00:00:00 2001 From: Srinivasarao P Date: Fri, 27 May 2016 14:11:24 +0530 Subject: [PATCH 036/320] defconfig: arm64: enable boot stats enable CONFIG_MSM_BOOT_STATS to check bootup performance. Change-Id: I6eff86791abbecb58acae7f9b88c87f345304118 Signed-off-by: Srinivasarao P --- arch/arm64/configs/msm-perf_defconfig | 1 + arch/arm64/configs/msm_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig index 60949ef47970a..50c5443d41ff7 100644 --- a/arch/arm64/configs/msm-perf_defconfig +++ b/arch/arm64/configs/msm-perf_defconfig @@ -531,3 +531,4 @@ CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y CONFIG_QMI_ENCDEC=y CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y CONFIG_UID_CPUTIME=y +CONFIG_MSM_BOOT_STATS=y diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig index 029e4637785e7..5623ebef77110 100644 --- a/arch/arm64/configs/msm_defconfig +++ b/arch/arm64/configs/msm_defconfig @@ -579,3 +579,4 @@ CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y CONFIG_QMI_ENCDEC=y CONFIG_STRICT_MEMORY_RWX=y CONFIG_UID_CPUTIME=y +CONFIG_MSM_BOOT_STATS=y From e844b238920a648df5c8a59bfc417528836ccef4 Mon Sep 17 00:00:00 2001 From: Sunil Khatri Date: Wed, 25 May 2016 21:13:46 +0530 Subject: [PATCH 037/320] msm: kgsl: Defer adding the mem entry to a process If we add the mem entry pointer in the process idr and rb tree too early, other threads can do operations on the entry by guessing the ID or GPU address before the object gets returned by the creating operation. Allocate an ID for the object but don't assign the pointer until right before the creating function returns ensuring that another operation can't access it until it is ready. CRs-Fixed: 1002974 Change-Id: Ic0dedbadc0dd2125bd2a7bcc152972c0555e07f8 Signed-off-by: Jordan Crouse Signed-off-by: Sunil Khatri Signed-off-by: Santhosh Punugu --- drivers/gpu/msm/kgsl.c | 62 ++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 5f06af5858a07..f4b6c83f8b7fd 100755 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -296,27 +296,20 @@ kgsl_mem_entry_destroy(struct kref *kref) EXPORT_SYMBOL(kgsl_mem_entry_destroy); /** - * kgsl_mem_entry_track_gpuaddr - Insert a mem_entry in the address tree and - * assign it with a gpu address space before insertion + * kgsl_mem_entry_track_gpuaddr - Get the entry gpu address space before + * insertion to the process * @process: the process that owns the memory * @entry: the memory entry * - * @returns - 0 on succcess else error code + * @returns - 0 on success else error code * - * Insert the kgsl_mem_entry in to the rb_tree for searching by GPU address. - * The assignment of gpu address and insertion into list needs to - * happen with the memory lock held to avoid race conditions between - * gpu address being selected and some other thread looking through the - * rb list in search of memory based on gpuaddr * This function should be called with processes memory spinlock held - */ +*/ static int kgsl_mem_entry_track_gpuaddr(struct kgsl_process_private *process, struct kgsl_mem_entry *entry) { int ret = 0; - struct rb_node **node; - struct rb_node *parent = NULL; struct kgsl_pagetable *pagetable = process->pagetable; size_t size = entry->memdesc.size; @@ -340,11 +333,22 @@ kgsl_mem_entry_track_gpuaddr(struct kgsl_process_private *process, pagetable = pagetable->mmu->securepagetable; ret = kgsl_mmu_get_gpuaddr(pagetable, &entry->memdesc); - if (ret) - goto done; - node = &process->mem_rb.rb_node; +done: + return ret; +} + +static void kgsl_mem_entry_commit_mem_list(struct kgsl_process_private *process, + struct kgsl_mem_entry *entry) +{ + struct rb_node **node; + struct rb_node *parent = NULL; + + if (!entry->memdesc.gpuaddr) + return; + /* Insert mem entry in mem_rb tree */ + node = &process->mem_rb.rb_node; while (*node) { struct kgsl_mem_entry *cur; @@ -359,9 +363,20 @@ kgsl_mem_entry_track_gpuaddr(struct kgsl_process_private *process, rb_link_node(&entry->node, parent, node); rb_insert_color(&entry->node, &process->mem_rb); +} -done: - return ret; +static void kgsl_mem_entry_commit_process(struct kgsl_process_private *process, + struct kgsl_mem_entry *entry) +{ + if (!entry) + return; + + spin_lock(&entry->priv->mem_lock); + /* Insert mem entry in mem_rb tree */ + kgsl_mem_entry_commit_mem_list(process, entry); + /* Replace mem entry in mem_idr using id */ + idr_replace(&entry->priv->mem_idr, entry, entry->id); + spin_unlock(&entry->priv->mem_lock); } /** @@ -410,7 +425,8 @@ kgsl_mem_entry_attach_process(struct kgsl_mem_entry *entry, return -EBADF; idr_preload(GFP_KERNEL); spin_lock(&process->mem_lock); - id = idr_alloc(&process->mem_idr, entry, 1, 0, GFP_NOWAIT); + /* Allocate the ID but don't attach the pointer just yet */ + id = idr_alloc(&process->mem_idr, NULL, 1, 0, GFP_NOWAIT); spin_unlock(&process->mem_lock); idr_preload_end(); @@ -3237,6 +3253,7 @@ long kgsl_ioctl_map_user_mem(struct kgsl_device_private *dev_priv, trace_kgsl_mem_map(entry, param->fd); + kgsl_mem_entry_commit_process(private, entry); return result; error_attach: @@ -3579,6 +3596,8 @@ long kgsl_ioctl_gpumem_alloc(struct kgsl_device_private *dev_priv, param->gpuaddr = entry->memdesc.gpuaddr; param->size = entry->memdesc.size; param->flags = entry->memdesc.flags; + + kgsl_mem_entry_commit_process(private, entry); return result; err: kgsl_sharedmem_free(&entry->memdesc); @@ -3619,6 +3638,8 @@ long kgsl_ioctl_gpumem_alloc_id(struct kgsl_device_private *dev_priv, param->size = entry->memdesc.size; param->mmapsize = kgsl_memdesc_mmapsize(&entry->memdesc); param->gpuaddr = entry->memdesc.gpuaddr; + + kgsl_mem_entry_commit_process(private, entry); return result; err: if (entry) @@ -4142,6 +4163,11 @@ static int kgsl_check_gpu_addr_collision( spin_lock(&private->mem_lock); kgsl_mem_entry_untrack_gpuaddr(private, entry); spin_unlock(&private->mem_lock); + } else { + /* Insert mem entry in mem_rb tree */ + spin_lock(&private->mem_lock); + kgsl_mem_entry_commit_mem_list(private, entry); + spin_unlock(&private->mem_lock); } } else { trace_kgsl_mem_unmapped_area_collision(entry, addr, len, From 4e818c626668c169160a0210cd8e9fa2c546d1a4 Mon Sep 17 00:00:00 2001 From: Divya Ponnusamy Date: Fri, 6 May 2016 13:24:37 -0600 Subject: [PATCH 038/320] msm: kgsl: Avoid race condition in ioctl_syncsource_destroy If the ioctl syncsource_destroy is accessed by parallel threads, where the spinlock is acquired by threads after getting syncsource, then the simultaneous processes try to remove the already destroyed syncsource->refcount by the first thread that acquires this spinlock. This leads to race condition while removing syncsource->idr. Avoid separate lock inside getting syncsource, instead acquire spinlock before we get the syncsource in destroy ioctl so that the threads access the spinlock and operate on syncsource without use-after-free issue. Change-Id: I6add3800c40cd09f6e6e0cf2720e69059bd83cbc Signed-off-by: Divya Ponnusamy --- drivers/gpu/msm/kgsl_sync.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/msm/kgsl_sync.c b/drivers/gpu/msm/kgsl_sync.c index 44a0f11cd0cf7..df181adb0a9d2 100644 --- a/drivers/gpu/msm/kgsl_sync.c +++ b/drivers/gpu/msm/kgsl_sync.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -473,23 +473,23 @@ long kgsl_ioctl_syncsource_create(struct kgsl_device_private *dev_priv, goto out; } + kref_init(&syncsource->refcount); + syncsource->private = private; + idr_preload(GFP_KERNEL); spin_lock(&private->syncsource_lock); id = idr_alloc(&private->syncsource_idr, syncsource, 1, 0, GFP_NOWAIT); - spin_unlock(&private->syncsource_lock); - idr_preload_end(); - if (id > 0) { - kref_init(&syncsource->refcount); syncsource->id = id; - syncsource->private = private; - param->id = id; ret = 0; } else { ret = id; } + spin_unlock(&private->syncsource_lock); + idr_preload_end(); + out: if (ret) { if (syncsource && syncsource->oneshot) @@ -547,25 +547,23 @@ long kgsl_ioctl_syncsource_destroy(struct kgsl_device_private *dev_priv, { struct kgsl_syncsource_destroy *param = data; struct kgsl_syncsource *syncsource = NULL; - struct kgsl_process_private *private; - - syncsource = kgsl_syncsource_get(dev_priv->process_priv, - param->id); + struct kgsl_process_private *private = dev_priv->process_priv; - if (syncsource == NULL) - return -EINVAL; + spin_lock(&private->syncsource_lock); + syncsource = idr_find(&private->syncsource_idr, param->id); - private = syncsource->private; + if (syncsource) { + idr_remove(&private->syncsource_idr, param->id); + syncsource->id = 0; + } - spin_lock(&private->syncsource_lock); - idr_remove(&private->syncsource_idr, param->id); - syncsource->id = 0; spin_unlock(&private->syncsource_lock); + if (syncsource == NULL) + return -EINVAL; + /* put reference from syncsource creation */ kgsl_syncsource_put(syncsource); - /* put reference from getting the syncsource above */ - kgsl_syncsource_put(syncsource); return 0; } From 4442d14857e027613206b1453ec0e56710a10a06 Mon Sep 17 00:00:00 2001 From: Vasily Kulikov Date: Wed, 9 Sep 2015 15:36:00 -0700 Subject: [PATCH 039/320] include/linux/poison.h: fix LIST_POISON{1,2} offset Poison pointer values should be small enough to find a room in non-mmap'able/hardly-mmap'able space. E.g. on x86 "poison pointer space" is located starting from 0x0. Given unprivileged users cannot mmap anything below mmap_min_addr, it should be safe to use poison pointers lower than mmap_min_addr. The current poison pointer values of LIST_POISON{1,2} might be too big for mmap_min_addr values equal or less than 1 MB (common case, e.g. Ubuntu uses only 0x10000). There is little point to use such a big value given the "poison pointer space" below 1 MB is not yet exhausted. Changing it to a smaller value solves the problem for small mmap_min_addr setups. The values are suggested by Solar Designer: http://www.openwall.com/lists/oss-security/2015/05/02/6 Change-Id: I4aff5bf048c42d1ca6c94f356a987e4ada563398 Signed-off-by: Vasily Kulikov Cc: Solar Designer Cc: Thomas Gleixner Cc: "Kirill A. Shutemov" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Git-commit: 8a5e5e02fc83aaf67053ab53b359af08c6c49aaf Git-repo: https://us.codeaurora.org/cgit/quic/la/kernel/msm CRs-Fixed: 987330 Signed-off-by: Ravi Kumar Siddojigari --- include/linux/poison.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/poison.h b/include/linux/poison.h index 2110a81c5e2af..253c9b4198eff 100644 --- a/include/linux/poison.h +++ b/include/linux/poison.h @@ -19,8 +19,8 @@ * under normal circumstances, used to verify that nobody uses * non-initialized list entries. */ -#define LIST_POISON1 ((void *) 0x00100100 + POISON_POINTER_DELTA) -#define LIST_POISON2 ((void *) 0x00200200 + POISON_POINTER_DELTA) +#define LIST_POISON1 ((void *) 0x100 + POISON_POINTER_DELTA) +#define LIST_POISON2 ((void *) 0x200 + POISON_POINTER_DELTA) /********** include/linux/timer.h **********/ /* From 730501aadfbe7113722175cc1360045cc661ebf3 Mon Sep 17 00:00:00 2001 From: Weiyin Jiang Date: Tue, 26 Apr 2016 14:35:38 +0800 Subject: [PATCH 040/320] ASoC: msm: audio-effects: misc fixes in h/w accelerated effect Adding memory copy size check and integer overflow check in h/w accelerated effect driver. Change-Id: I17d4cc0a38770f0c5067fa8047cd63e7bf085e48 CRs-Fixed: 1006609 Signed-off-by: Weiyin Jiang --- sound/soc/msm/qdsp6v2/q6asm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index 297c1a3f65281..4e38480ec1d22 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -1202,6 +1202,12 @@ int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir, ac->port[dir].buf = buf; + /* check for integer overflow */ + if ((bufcnt > 0) && ((INT_MAX / bufcnt) < bufsz)) { + pr_err("%s: integer overflow\n", __func__); + mutex_unlock(&ac->cmd_lock); + goto fail; + } bytes_to_alloc = bufsz * bufcnt; /* The size to allocate should be multiple of 4K bytes */ From e4c5ddb03442acd73cfa86890897b6c92cce646c Mon Sep 17 00:00:00 2001 From: Talel Shenhar Date: Tue, 30 Dec 2014 11:24:39 +0200 Subject: [PATCH 041/320] mmc: core: enable BKOPS by read-modify-write instead of override This change adds a read-modify-write logic to BKOPS feature enable. It is required in order to avoid overriding other fields defined in BKOPS_EN register. Change-Id: I689f5cd14d9ec1bb881f503a0418026a59e6c197 Signed-off-by: Talel Shenhar --- drivers/mmc/card/block.c | 9 +++++---- drivers/mmc/card/mmc_block_test.c | 2 +- drivers/mmc/core/core.c | 6 ++++-- drivers/mmc/core/debugfs.c | 3 ++- drivers/mmc/core/mmc.c | 20 ++++++++++++-------- include/linux/mmc/card.h | 19 ++++++++++++++++++- include/linux/mmc/mmc.h | 3 +++ 7 files changed, 45 insertions(+), 17 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index b7d1ef542ef30..f78e60a7fcb65 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1362,7 +1362,7 @@ static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) from = blk_rq_pos(req); nr = blk_rq_sectors(req); - if (card->ext_csd.bkops_en) + if (mmc_card_get_bkops_en_manual(card)) card->bkops_info.sectors_changed += blk_rq_sectors(req); if (mmc_can_discard(card)) @@ -2316,7 +2316,7 @@ static u8 mmc_blk_prep_packed_list(struct mmc_queue *mq, struct request *req) if (rq_data_dir(next) == WRITE) { mq->num_of_potential_packed_wr_reqs++; - if (card->ext_csd.bkops_en) + if (mmc_card_get_bkops_en_manual(card)) card->bkops_info.sectors_changed += blk_rq_sectors(next); } @@ -2573,7 +2573,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) return 0; if (rqc) { - if ((card->ext_csd.bkops_en) && (rq_data_dir(rqc) == WRITE)) + if (mmc_card_get_bkops_en_manual(card) && + (rq_data_dir(rqc) == WRITE)) card->bkops_info.sectors_changed += blk_rq_sectors(rqc); reqs = mmc_blk_prep_packed_list(mq, rqc); } @@ -2788,7 +2789,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) if (mmc_bus_needs_resume(card->host)) mmc_resume_bus(card->host); #endif - if (card->ext_csd.bkops_en) + if (mmc_card_get_bkops_en_manual(card)) mmc_stop_bkops(card); } diff --git a/drivers/mmc/card/mmc_block_test.c b/drivers/mmc/card/mmc_block_test.c index 6f017aca429ef..7b05bf81422ba 100644 --- a/drivers/mmc/card/mmc_block_test.c +++ b/drivers/mmc/card/mmc_block_test.c @@ -1788,7 +1788,7 @@ static int prepare_bkops(struct test_data *td) bkops_stat = &card->bkops_info.bkops_stats; - if (!card->ext_csd.bkops_en) { + if (!(mmc_card_get_bkops_en_manual(card))) { pr_err("%s: BKOPS is not enabled by card or host)", __func__); return -ENOTSUPP; diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index af8254d49f3ea..54fb79559a73b 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -400,7 +400,9 @@ EXPORT_SYMBOL(mmc_blk_init_bkops_statistics); */ void mmc_start_delayed_bkops(struct mmc_card *card) { - if (!card || !card->ext_csd.bkops_en || mmc_card_doing_bkops(card)) + if (!card || + !(mmc_card_get_bkops_en_manual(card)) || + mmc_card_doing_bkops(card)) return; if (card->bkops_info.sectors_changed < @@ -437,7 +439,7 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception) int err; BUG_ON(!card); - if (!card->ext_csd.bkops_en) + if (!(mmc_card_get_bkops_en_manual(card))) return; if ((card->bkops_info.cancel_delayed_work) && !from_exception) { diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index 69db61ca9b6fd..165c2f7b0af2f 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c @@ -19,6 +19,7 @@ #include #include +#include #include "core.h" #include "mmc_ops.h" @@ -725,7 +726,7 @@ void mmc_add_card_debugfs(struct mmc_card *card) goto err; if (mmc_card_mmc(card) && (card->ext_csd.rev >= 5) && - card->ext_csd.bkops_en) + (mmc_card_get_bkops_en_manual(card))) if (!debugfs_create_file("bkops_stats", S_IRUSR, root, card, &mmc_dbg_bkops_stats_fops)) goto err; diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 650cdd6cdb500..15a3738e7440c 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -10,6 +10,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include @@ -529,15 +530,19 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) card->ext_csd.bkops_en = ext_csd[EXT_CSD_BKOPS_EN]; card->ext_csd.raw_bkops_status = ext_csd[EXT_CSD_BKOPS_STATUS]; - if (!card->ext_csd.bkops_en && + if (!(mmc_card_get_bkops_en_manual(card)) && card->host->caps2 & MMC_CAP2_INIT_BKOPS) { - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BKOPS_EN, 1, 0); - if (err) + mmc_card_set_bkops_en_manual(card); + err = mmc_switch(card, + EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_BKOPS_EN, + card->ext_csd.bkops_en , 0); + if (err) { pr_warn("%s: Enabling BKOPS failed\n", mmc_hostname(card->host)); - else - card->ext_csd.bkops_en = 1; + mmc_card_clr_bkops_en_manual(card); + } + } } @@ -1697,8 +1702,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, goto free_card; } } - - if (card->ext_csd.bkops_en) { + if (mmc_card_get_bkops_en_manual(card)) { INIT_DELAYED_WORK(&card->bkops_info.dw, mmc_start_idle_time_bkops); diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index faeaaf0bf9f18..ba89e363f3576 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -84,7 +84,7 @@ struct mmc_ext_csd { bool hpi; /* HPI support bit */ unsigned int hpi_cmd; /* cmd used as HPI */ bool bkops; /* background support bit */ - bool bkops_en; /* background enable bit */ + u8 bkops_en; /* background enable bits */ unsigned int data_sector_size; /* 512 bytes or 4KB */ unsigned int data_tag_unit_size; /* DATA TAG UNIT size */ unsigned int boot_ro_lock; /* ro lock support */ @@ -401,6 +401,23 @@ struct mmc_card { u8 *cached_ext_csd; }; +/* + * mmc_csd registers get/set/clr helpers + */ +#define mmc_card_get_bkops_en_manual(card) ((card->ext_csd.bkops_en) &\ + EXT_CSD_BKOPS_EN_MANUAL_EN) +#define mmc_card_set_bkops_en_manual(card) ((card->ext_csd.bkops_en) |= \ + EXT_CSD_BKOPS_EN_MANUAL_EN) +#define mmc_card_clr_bkops_en_manual(card) ((card->ext_csd.bkops_en) &= \ + ~EXT_CSD_BKOPS_EN_MANUAL_EN) + +#define mmc_card_get_bkops_en_auto(card) ((card->ext_csd.bkops_en) & \ + EXT_CSD_BKOPS_EN_AUTO_EN) +#define mmc_card_set_bkops_en_auto(card) ((card->ext_csd.bkops_en) |= \ + EXT_CSD_BKOPS_EN_AUTO_EN) +#define mmc_card_clr_bkops_en_auto(card) ((card->ext_csd.bkops_en) &= \ + ~EXT_CSD_BKOPS_EN_AUTO_EN) + /* * This function fill contents in mmc_part. */ diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index addf849db89d5..d8cbe40c8f5fb 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -282,6 +282,9 @@ struct _mmc_csd { * EXT_CSD field definitions */ +#define EXT_CSD_BKOPS_EN_MANUAL_EN BIT(0) +#define EXT_CSD_BKOPS_EN_AUTO_EN BIT(1) + #define EXT_CSD_WR_REL_PARAM_EN (1<<2) #define EXT_CSD_WR_REL_PARAM_EN_RPMB (1<<4) From 75033fed8b6c96cb6b78f62483a3a5d5d75f6bed Mon Sep 17 00:00:00 2001 From: Rajesh Kemisetti Date: Tue, 31 May 2016 14:41:35 +0530 Subject: [PATCH 042/320] msm: kgsl: Check for integer overflow before allocating memory In _kgsl_sharedmem_page_alloc(), if the requested size is very large then there could be a possibility of integer overflow during memory allocation for scatterlist. To fix this, check for integer overflow condition before allocating the memory. CRs-Fixed: 1005344 Change-Id: I6e0015ab67d6b13fc94d94dafec41788f53820d3 Signed-off-by: Rajesh Kemisetti --- drivers/gpu/msm/kgsl_sharedmem.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c index a4c584b0e3518..b1b925edd9e3c 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.c +++ b/drivers/gpu/msm/kgsl_sharedmem.c @@ -625,6 +625,9 @@ _kgsl_sharedmem_page_alloc(struct kgsl_memdesc *memdesc, memdesc->pagetable = pagetable; memdesc->ops = &kgsl_page_alloc_ops; + /* Check for integer overflow */ + if (sglen_alloc && (sizeof(struct scatterlist) > INT_MAX / sglen_alloc)) + return -EINVAL; memdesc->sg = kgsl_malloc(sglen_alloc * sizeof(struct scatterlist)); if (memdesc->sg == NULL) { From a4185250c3cb0c7023e6fa39713cb227bef8b084 Mon Sep 17 00:00:00 2001 From: Maya Erez Date: Thu, 17 Sep 2015 15:10:26 +0300 Subject: [PATCH 043/320] mmc: block: stop BKOPs before handling RPMB and ioctl IOCTL and RPMB commands can be issues while the device is busy with background Operations handling. Stop the device BKOPs before handling the RPMB / IOCTL command. Change-Id: I088f74c77026ccd901276e1214e4466ac7815bf1 Signed-off-by: Maya Erez Signed-off-by: Swetha Chikkaboraiah Signed-off-by: Pavan Anamula --- drivers/mmc/card/block.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index b7d1ef542ef30..ca9d4fa31a370 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -734,6 +734,9 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, mmc_rpm_hold(card->host, &card->dev); mmc_claim_host(card->host); + if (mmc_card_get_bkops_en_manual(card)) + mmc_stop_bkops(card); + err = mmc_blk_part_switch(card, md); if (err) goto cmd_rel_host; @@ -876,6 +879,9 @@ static int mmc_blk_ioctl_rpmb_cmd(struct block_device *bdev, mmc_rpm_hold(card->host, &card->dev); mmc_claim_host(card->host); + if (mmc_card_get_bkops_en_manual(card)) + mmc_stop_bkops(card); + err = mmc_blk_part_switch(card, md); if (err) goto cmd_rel_host; From b6f09e1aeeda0fe54e04c133062dcc04aa271c2f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 9 Jul 2015 17:17:57 -0700 Subject: [PATCH 044/320] net: fix iterating over hashtable in tcp_nuke_addr() The actual size of the tcp hashinfo table is tcp_hashinfo.ehash_mask + 1 so we need to adjust the loop accordingly to get the sockets hashed into the last bucket. Change-Id: I5a00b5e25fd619741505b995ccea0f6d3773c116 Signed-off-by: Dmitry Torokhov Git-commit: b35e1a7ab50ea07cbb1372f4689f3df888d89014 Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: Ashwanth Goli --- net/ipv4/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 19e2fc64a6582..65fd0484cbed6 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3537,7 +3537,7 @@ int tcp_nuke_addr(struct net *net, struct sockaddr *addr) return -EAFNOSUPPORT; } - for (bucket = 0; bucket < tcp_hashinfo.ehash_mask; bucket++) { + for (bucket = 0; bucket <= tcp_hashinfo.ehash_mask; bucket++) { struct hlist_nulls_node *node; struct sock *sk; spinlock_t *lock = inet_ehash_lockp(&tcp_hashinfo, bucket); From ee8e88b6400d05443776953ec163fbd4dd64b649 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 15 Mar 2015 21:12:12 -0700 Subject: [PATCH 045/320] net: add sk_fullsock() helper We have many places where we want to check if a socket is not a timewait or request socket. Use a helper to avoid hard coding this. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller [backported from net-next 1d0ab253872cdd3d8e7913f59c266c7fd01771d0] [lorenzo@google.com: removed TCPF_NEW_SYN_RECV, and added a comment to add it back.] Signed-off-by: Lorenzo Colitti Bug: 24163529 Change-Id: I196485fe3bbb6b471567e5865a688c93b6f52150 Git-commit: cdab04e3612c55f0906c84c3c05996a0507eab7d Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: Ashwanth Goli --- include/net/sock.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/net/sock.h b/include/net/sock.h index a06bb129785f2..887be91daa8b8 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -67,6 +67,7 @@ #include #include #include +#include struct cgroup; struct cgroup_subsys; @@ -2244,6 +2245,15 @@ static inline struct sock *skb_steal_sock(struct sk_buff *skb) return NULL; } +/* This helper checks if a socket is a full socket, + * ie _not_ a timewait or request socket. + * TODO: Check for TCPF_NEW_SYN_RECV when that starts to exist. + */ +static inline bool sk_fullsock(const struct sock *sk) +{ + return (1 << sk->sk_state) & ~(TCPF_TIME_WAIT); +} + extern void sock_enable_timestamp(struct sock *sk, int flag); extern int sock_get_timestamp(struct sock *, struct timeval __user *); extern int sock_get_timestampns(struct sock *, struct timespec __user *); From 8b4f5aa528cf67b77a14b730a601b1c315cac2e6 Mon Sep 17 00:00:00 2001 From: Erik Kline Date: Tue, 28 Oct 2014 18:11:14 +0900 Subject: [PATCH 046/320] net: ipv6: Add a sysctl to make optimistic addresses useful candidates Add a sysctl that causes an interface's optimistic addresses to be considered equivalent to other non-deprecated addresses for source address selection purposes. Preferred addresses will still take precedence over optimistic addresses, subject to other ranking in the source address selection algorithm. This is useful where different interfaces are connected to different networks from different ISPs (e.g., a cell network and a home wifi network). The current behaviour complies with RFC 3484/6724, and it makes sense if the host has only one interface, or has multiple interfaces on the same network (same or cooperating administrative domain(s), but not in the multiple distinct networks case. For example, if a mobile device has an IPv6 address on an LTE network and then connects to IPv6-enabled wifi, while the wifi IPv6 address is undergoing DAD, IPv6 connections will try use the wifi default route with the LTE IPv6 address, and will get stuck until they time out. Also, because optimistic nodes can receive frames, issue an RTM_NEWADDR as soon as DAD starts (with the IFA_F_OPTIMSTIC flag appropriately set). A second RTM_NEWADDR is sent if DAD completes (the address flags have changed), otherwise an RTM_DELADDR is sent. Also: add an entry in ip-sysctl.txt for optimistic_dad. [cherry-pick of net-next 7fd2561e4ebdd070ebba6d3326c4c5b13942323f] Change-Id: I68bfdd36823c4d51c46b8c30a89322806a5e7531 Signed-off-by: Erik Kline Acked-by: Lorenzo Colitti Acked-by: Hannes Frederic Sowa Signed-off-by: David S. Miller Bug: 17769720 Git-commit: 2ce95507d5ce6a5d3fd7993c35667a98c2f11f3b Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: Ashwanth Goli --- Documentation/networking/ip-sysctl.txt | 13 ++++++++ include/linux/ipv6.h | 1 + include/uapi/linux/ipv6.h | 1 + net/ipv6/addrconf.c | 46 ++++++++++++++++++++++++-- 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index fd22b040a2ac3..44fdcafc67e47 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -1357,6 +1357,19 @@ ndisc_notify - BOOLEAN 1 - Generate unsolicited neighbour advertisements when device is brought up or hardware address changes. +optimistic_dad - BOOLEAN + Whether to perform Optimistic Duplicate Address Detection (RFC 4429). + 0: disabled (default) + 1: enabled + +use_optimistic - BOOLEAN + If enabled, do not classify optimistic addresses as deprecated during + source address selection. Preferred addresses will still be chosen + before optimistic addresses, subject to other ranking in the source + address selection algorithm. + 0: disabled (default) + 1: enabled + icmp/*: ratelimit - INTEGER Limit the maximal rates for sending ICMPv6 packets. diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index a6c5471822d38..4aacb6a4a5ba5 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -41,6 +41,7 @@ struct ipv6_devconf { __s32 accept_source_route; #ifdef CONFIG_IPV6_OPTIMISTIC_DAD __s32 optimistic_dad; + __s32 use_optimistic; #endif #ifdef CONFIG_IPV6_MROUTE __s32 mc_forwarding; diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h index 80e15fa366517..c14b8dc97a947 100644 --- a/include/uapi/linux/ipv6.h +++ b/include/uapi/linux/ipv6.h @@ -163,6 +163,7 @@ enum { DEVCONF_ACCEPT_RA_PREFIX_ROUTE, DEVCONF_ACCEPT_RA_RT_TABLE, DEVCONF_ACCEPT_RA_MTU, + DEVCONF_USE_OPTIMISTIC, DEVCONF_MAX }; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 86b4a49ccecad..3c8e605a3875e 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1181,6 +1181,9 @@ enum { #endif IPV6_SADDR_RULE_ORCHID, IPV6_SADDR_RULE_PREFIX, +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + IPV6_SADDR_RULE_NOT_OPTIMISTIC, +#endif IPV6_SADDR_RULE_MAX }; @@ -1208,6 +1211,15 @@ static inline int ipv6_saddr_preferred(int type) return 0; } +static inline bool ipv6_use_optimistic_addr(struct inet6_dev *idev) +{ +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + return idev && idev->cnf.optimistic_dad && idev->cnf.use_optimistic; +#else + return false; +#endif +} + static int ipv6_get_saddr_eval(struct net *net, struct ipv6_saddr_score *score, struct ipv6_saddr_dst *dst, @@ -1268,10 +1280,16 @@ static int ipv6_get_saddr_eval(struct net *net, score->scopedist = ret; break; case IPV6_SADDR_RULE_PREFERRED: + { /* Rule 3: Avoid deprecated and optimistic addresses */ + u8 avoid = IFA_F_DEPRECATED; + + if (!ipv6_use_optimistic_addr(score->ifa->idev)) + avoid |= IFA_F_OPTIMISTIC; ret = ipv6_saddr_preferred(score->addr_type) || - !(score->ifa->flags & (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)); + !(score->ifa->flags & avoid); break; + } #ifdef CONFIG_IPV6_MIP6 case IPV6_SADDR_RULE_HOA: { @@ -1319,6 +1337,14 @@ static int ipv6_get_saddr_eval(struct net *net, ret = score->ifa->prefix_len; score->matchlen = ret; break; +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + case IPV6_SADDR_RULE_NOT_OPTIMISTIC: + /* Optimistic addresses still have lower precedence than other + * preferred addresses. + */ + ret = !(score->ifa->flags & IFA_F_OPTIMISTIC); + break; +#endif default: ret = 0; } @@ -3296,8 +3322,15 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp) * Optimistic nodes can start receiving * Frames right away */ - if (ifp->flags & IFA_F_OPTIMISTIC) + if (ifp->flags & IFA_F_OPTIMISTIC) { ip6_ins_rt(ifp->rt); + if (ipv6_use_optimistic_addr(idev)) { + /* Because optimistic nodes can use this address, + * notify listeners. If DAD fails, RTM_DELADDR is sent. + */ + ipv6_ifa_notify(RTM_NEWADDR, ifp); + } + } addrconf_dad_kick(ifp); out: @@ -4243,6 +4276,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_ACCEPT_SOURCE_ROUTE] = cnf->accept_source_route; #ifdef CONFIG_IPV6_OPTIMISTIC_DAD array[DEVCONF_OPTIMISTIC_DAD] = cnf->optimistic_dad; + array[DEVCONF_USE_OPTIMISTIC] = cnf->use_optimistic; #endif #ifdef CONFIG_IPV6_MROUTE array[DEVCONF_MC_FORWARDING] = cnf->mc_forwarding; @@ -4978,6 +5012,14 @@ static struct addrconf_sysctl_table .proc_handler = proc_dointvec, }, + { + .procname = "use_optimistic", + .data = &ipv6_devconf.use_optimistic, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + + }, #endif #ifdef CONFIG_IPV6_MROUTE { From 3b8ec3331cc79f8205a843d158c8e3bbe50a2112 Mon Sep 17 00:00:00 2001 From: Erik Kline Date: Fri, 5 Dec 2014 19:45:10 +0900 Subject: [PATCH 047/320] net: ipv6: allow choosing optimistic addresses with use_optimistic The use_optimistic sysctl makes optimistic IPv6 addresses equivalent to preferred addresses for source address selection (e.g., when calling connect()), but it does not allow an application to bind to optimistic addresses. This behaviour is inconsistent - for example, it doesn't make sense for bind() to an optimistic address fail with EADDRNOTAVAIL, but connect() to choose that address outgoing address on the same socket. Bug: 17769720 Bug: 18609055 Change-Id: Ia0ed70a3698fdc78ffa2a50113872b4b3ee66450 Signed-off-by: Erik Kline Signed-off-by: Lorenzo Colitti Git-commit: 0065bf4206cd4fecb482aef751fd39360fa8bafa Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: Ashwanth Goli --- net/ipv6/addrconf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 3c8e605a3875e..457ce55ede84f 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1540,7 +1540,9 @@ int ipv6_chk_addr(struct net *net, const struct in6_addr *addr, if (!net_eq(dev_net(ifp->idev->dev), net)) continue; if (ipv6_addr_equal(&ifp->addr, addr) && - !(ifp->flags&IFA_F_TENTATIVE) && + (!(ifp->flags&IFA_F_TENTATIVE) || + (ipv6_use_optimistic_addr(ifp->idev) && + ifp->flags&IFA_F_OPTIMISTIC)) && (dev == NULL || ifp->idev->dev == dev || !(ifp->scope&(IFA_LINK|IFA_HOST) || strict))) { rcu_read_unlock_bh(); From 18e2c5b3cfe33daf0f5792fd92c880c3b8b0a831 Mon Sep 17 00:00:00 2001 From: Erik Kline Date: Wed, 22 Jul 2015 16:38:25 +0900 Subject: [PATCH 048/320] ipv6: sysctl to restrict candidate source addresses Per RFC 6724, section 4, "Candidate Source Addresses": It is RECOMMENDED that the candidate source addresses be the set of unicast addresses assigned to the interface that will be used to send to the destination (the "outgoing" interface). Add a sysctl to enable this behaviour. Signed-off-by: Erik Kline Signed-off-by: David S. Miller [Simplified back-port of net-next 3985e8a3611a93bb36789f65db862e5700aab65e] Bug: 19470192 Bug: 21832279 Bug: 22464419 Change-Id: I92e56d0db5b4945261ee0609d6dcac20376c4edf Git-commit: 0633924e7776754ccb473d649e5fa9ee45617a46 Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: Ashwanth Goli --- Documentation/networking/ip-sysctl.txt | 7 +++++++ include/linux/ipv6.h | 1 + include/uapi/linux/ipv6.h | 1 + net/ipv6/addrconf.c | 19 ++++++++++++++++++- 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 44fdcafc67e47..c1db21030e504 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -1276,6 +1276,13 @@ router_solicitations - INTEGER routers are present. Default: 3 +use_oif_addrs_only - BOOLEAN + When enabled, the candidate source addresses for destinations + routed via this interface are restricted to the set of addresses + configured on this interface (vis. RFC 6724, section 4). + + Default: false + use_tempaddr - INTEGER Preference for Privacy Extensions (RFC3041). <= 0 : disable Privacy Extensions diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 4aacb6a4a5ba5..d8ad57edc6963 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -52,6 +52,7 @@ struct ipv6_devconf { __s32 ndisc_notify; __s32 accept_ra_prefix_route; __s32 accept_ra_mtu; + __s32 use_oif_addrs_only; void *sysctl; }; diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h index c14b8dc97a947..ff6c5f3549c1b 100644 --- a/include/uapi/linux/ipv6.h +++ b/include/uapi/linux/ipv6.h @@ -164,6 +164,7 @@ enum { DEVCONF_ACCEPT_RA_RT_TABLE, DEVCONF_ACCEPT_RA_MTU, DEVCONF_USE_OPTIMISTIC, + DEVCONF_USE_OIF_ADDRS_ONLY, DEVCONF_MAX }; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 457ce55ede84f..f679d1cf1daaa 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -207,6 +207,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = { .accept_dad = 1, .accept_ra_prefix_route = 1, .accept_ra_mtu = 1, + .use_oif_addrs_only = 0, }; static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { @@ -244,6 +245,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { .accept_dad = 1, .accept_ra_prefix_route = 1, .accept_ra_mtu = 1, + .use_oif_addrs_only = 0, }; /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ @@ -1392,9 +1394,15 @@ int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev, * include addresses assigned to interfaces * belonging to the same site as the outgoing * interface.) + * - "It is RECOMMENDED that the candidate source addresses + * be the set of unicast addresses assigned to the + * interface that will be used to send to the destination + * (the 'outgoing' interface)." (RFC 6724) */ + idev = dst_dev ? __in6_dev_get(dst_dev) : NULL; if (((dst_type & IPV6_ADDR_MULTICAST) || - dst.scope <= IPV6_ADDR_SCOPE_LINKLOCAL) && + dst.scope <= IPV6_ADDR_SCOPE_LINKLOCAL || + (idev && idev->cnf.use_oif_addrs_only)) && dst.ifindex && dev->ifindex != dst.ifindex) continue; @@ -4288,6 +4296,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao; array[DEVCONF_NDISC_NOTIFY] = cnf->ndisc_notify; array[DEVCONF_ACCEPT_RA_MTU] = cnf->accept_ra_mtu; + array[DEVCONF_USE_OIF_ADDRS_ONLY] = cnf->use_oif_addrs_only; } static inline size_t inet6_ifla6_size(void) @@ -5074,6 +5083,14 @@ static struct addrconf_sysctl_table .mode = 0644, .proc_handler = proc_dointvec, }, + { + .procname = "use_oif_addrs_only", + .data = &ipv6_devconf.use_oif_addrs_only, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + + }, { /* sentinel */ } From 3cc494f9f2d3ebbd74643671f7ad6d051f51c54f Mon Sep 17 00:00:00 2001 From: Ping Li Date: Fri, 15 Apr 2016 15:27:36 -0700 Subject: [PATCH 049/320] msm: mdss: Correct block id check for mdss_mdp_misr_table DISPLAY_MISR_LCDC block doesn't have corresponding mdss_mdp_misr_table, this change corrects the block id check for mdss_mdp_misr_table. CRs-Fixed: 1001224 Change-Id: I74b03c31542d4b239eb2ffdc4dc6345dff5eab86 Signed-off-by: Ping Li --- drivers/video/msm/mdss/mdss_debug.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c index 389125e603de5..93b2a213f5f8f 100644 --- a/drivers/video/msm/mdss/mdss_debug.c +++ b/drivers/video/msm/mdss/mdss_debug.c @@ -1058,7 +1058,7 @@ static inline struct mdss_mdp_misr_map *mdss_misr_get_map(u32 block_id, char *ctrl_reg = NULL, *value_reg = NULL; char *intf_base = NULL; - if (block_id > DISPLAY_MISR_MDP) { + if (block_id > DISPLAY_MISR_HDMI && block_id != DISPLAY_MISR_MDP) { pr_err("MISR Block id (%d) out of range\n", block_id); return NULL; } @@ -1146,6 +1146,12 @@ int mdss_misr_set(struct mdss_data_type *mdata, bool is_valid_wb_mixer = true; bool use_mdp_up_misr = false; + if (!mdata || !req || !ctl) { + pr_err("Invalid input params: mdata = %p req = %p ctl = %p", + mdata, req, ctl); + return -EINVAL; + } + map = mdss_misr_get_map(req->block_id, ctl, mdata); if (!map) { From 8c027dbd729dfe24c7d7976bde28e2f9917305a3 Mon Sep 17 00:00:00 2001 From: Divya Narayanan Poojary Date: Mon, 6 Jun 2016 19:12:02 +0530 Subject: [PATCH 050/320] ASoC: msm-lsm-client: Add poll_enable to snd_lsm_detection_params_32 Polling doesn't gets enabled even though poll_enable is set from userspace. This is because, "poll_enable" is not added in snd_lsm_detection_params_32 structure, resulting in setting wrong value for "poll_enable" Added "poll_enable" to snd_lsm_detection_params_32 Change-Id: I7a5fe2669dfec9a1cb236802c4428ed8b021614a Signed-off-by: Divya Narayanan Poojary --- sound/soc/msm/qdsp6v2/msm-lsm-client.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/sound/soc/msm/qdsp6v2/msm-lsm-client.c index 09dd65ab4f4f2..51530fc02023c 100644 --- a/sound/soc/msm/qdsp6v2/msm-lsm-client.c +++ b/sound/soc/msm/qdsp6v2/msm-lsm-client.c @@ -1112,6 +1112,7 @@ struct snd_lsm_detection_params_32 { enum lsm_detection_mode detect_mode; u8 num_confidence_levels; bool detect_failure; + bool poll_enable; }; struct lsm_params_info_32 { @@ -1293,6 +1294,7 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, det_params32.num_confidence_levels; det_params.detect_failure = det_params32.detect_failure; + det_params.poll_enable = det_params32.poll_enable; cmd = SNDRV_LSM_SET_PARAMS; err = msm_lsm_ioctl_shared(substream, cmd, &det_params); From 09dcc1f24e0223561c45e319bc3cd60f688da35e Mon Sep 17 00:00:00 2001 From: Arun KS Date: Wed, 11 May 2016 10:11:36 +0530 Subject: [PATCH 051/320] msm: perf: Do not allocate new hw_event if event is duplicate. During a perf_event_enable, kernel/events/core.c calls pmu->add() which is platform implementation(arch/arm/kernel/perf_event.c). Due to the duplicate constraints, arch/arm/mach-msm/perf_event_msm_krait_l2.c drivers marks the event as OFF but returns TRUE to perf_event.c which goes ahead and allocates the hw_event and enables it. Since event is marked OFF, kernel events core will try to enable this event again during next perf_event_enable. Which results in same event enabled on multiple hw_events. But during the perf_release, event struct is freed and only one hw_event is released. This results in dereferencing the invalid pointer and hence the crash. Fix this by returning error in case of constraint event duplicate. Hence avoiding the same event programmed on multiple hw event counters. Change-Id: Ia3360be027dfe87ac753191ffe7e0bc947e72455 Signed-off-by: Arun KS Signed-off-by: Chetan Ravindranath --- arch/arm/kernel/perf_event.c | 1 + arch/arm/mach-msm/perf_event_msm_krait_l2.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 0f288a7c035f9..a0c1e318a7905 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -240,6 +240,7 @@ armpmu_add(struct perf_event *event, int flags) pr_err("Event: %llx failed constraint check.\n", event->attr.config); event->state = PERF_EVENT_STATE_OFF; + err = -EPERM; goto out; } diff --git a/arch/arm/mach-msm/perf_event_msm_krait_l2.c b/arch/arm/mach-msm/perf_event_msm_krait_l2.c index 43233abe24ca4..2e0c3af3dc1cd 100644 --- a/arch/arm/mach-msm/perf_event_msm_krait_l2.c +++ b/arch/arm/mach-msm/perf_event_msm_krait_l2.c @@ -474,6 +474,7 @@ static int msm_l2_test_set_ev_constraint(struct perf_event *event) if (!(event->cpu < 0)) { event->state = PERF_EVENT_STATE_OFF; event->attr.constraint_duplicate = 1; + err = -EPERM; } } out: From ad4729ad13e923b6f441ba5e3d33af90ad09d619 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Tue, 24 May 2016 11:16:48 +0800 Subject: [PATCH 052/320] ASoC: compress: fix unsigned integer overflow check Parameter fragments and fragment_size are type of u32. U32_MAX is the correct check. CRs-Fixed: 1014726 Change-Id: Ia6d4755408646ac4a75724f3c6f2177651875da3 Signed-off-by: Xiaojun Sang --- sound/core/compress_offload.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index 4f48bc3eca73e..fe57c7d54ff78 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -44,6 +44,8 @@ #include #include +#define U32_MAX ((u32)~0U) + /* TODO: * - add substream support for multiple devices in case of * SND_DYNAMIC_MINORS is not used @@ -496,7 +498,7 @@ static int snd_compress_check_input(struct snd_compr_params *params) { /* first let's check the buffer parameter's */ if (params->buffer.fragment_size == 0 || - params->buffer.fragments > SIZE_MAX / params->buffer.fragment_size) + params->buffer.fragments > U32_MAX / params->buffer.fragment_size) return -EINVAL; /* now codec parameters */ From fc84e6a7b9a7f0a7a27a88c5094b94ef09d172b7 Mon Sep 17 00:00:00 2001 From: Puneet Mishra Date: Fri, 14 Aug 2015 15:02:38 +0100 Subject: [PATCH 053/320] NFC: Fix function descriptions Fix function description comments according to kernel-doc. Also, remove unnecessary arguments Change-Id: I66c9e47ee5cd6fe6ae8676256e4b6ee30fe2d61f Acked-by: Afroditi Ilioudi Signed-off-by: Puneet Mishra --- drivers/nfc/nq-nci.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c index 99075945654f2..d17f9429731af 100644 --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -253,22 +253,20 @@ static int nfc_open(struct inode *inode, struct file *filp) return ret; } -/* - * Inside nfc_ioctl_power_states - * - * @brief ioctl functions +/** + * nfc_ioctl_power_states() - power control + * @filp: pointer to the file descriptor + * @arg: mode that we want to move to * - * - * Device control - * remove control via ioctl + * Device power control. Depending on the arg value, device moves to + * different states * (arg = 0): NFC_ENABLE GPIO = 0, FW_DL GPIO = 0 * (arg = 1): NFC_ENABLE GPIO = 1, FW_DL GPIO = 0 * (arg = 2): FW_DL GPIO = 1 * - * + * Return: -ENOIOCTLCMD if arg is not supported, 0 in any other case */ -int nfc_ioctl_power_states(struct file *filp, unsigned int cmd, - unsigned long arg) +int nfc_ioctl_power_states(struct file *filp, unsigned long arg) { int r = 0; struct nqx_dev *nqx_dev = filp->private_data; @@ -323,7 +321,7 @@ static long nfc_compat_ioctl(struct file *pfile, unsigned int cmd, switch (cmd) { case NFC_SET_PWR: - nfc_ioctl_power_states(pfile, cmd, arg); + nfc_ioctl_power_states(pfile, arg); break; case SET_RX_BLOCK: break; @@ -336,18 +334,15 @@ static long nfc_compat_ioctl(struct file *pfile, unsigned int cmd, } #endif -/* - * Inside nfc_ioctl_core_reset_ntf - * - * @brief nfc_ioctl_core_reset_ntf +/** + * nfc_ioctl_core_reset_ntf() + * @filp: pointer to the file descriptor * * Allows callers to determine if a CORE_RESET_NTF has arrived * - * Returns the value of variable core_reset_ntf - * + * Return: the value of variable core_reset_ntf */ -int nfc_ioctl_core_reset_ntf(struct file *filp, unsigned int cmd, - unsigned long arg) +int nfc_ioctl_core_reset_ntf(struct file *filp) { struct nqx_dev *nqx_dev = filp->private_data; dev_dbg(&nqx_dev->client->dev, "%s: returning = %d\n", __func__, @@ -362,7 +357,7 @@ static long nfc_ioctl(struct file *pfile, unsigned int cmd, switch (cmd) { case NFC_SET_PWR: - r = nfc_ioctl_power_states(pfile, cmd, arg); + r = nfc_ioctl_power_states(pfile, arg); break; case NFC_CLK_REQ: break; @@ -371,7 +366,7 @@ static long nfc_ioctl(struct file *pfile, unsigned int cmd, case SET_EMULATOR_TEST_POINT: break; case NFCC_INITIAL_CORE_RESET_NTF: - r = nfc_ioctl_core_reset_ntf(pfile, cmd, arg); + r = nfc_ioctl_core_reset_ntf(pfile); break; default: r = -ENOIOCTLCMD; From a15e88a1a44102c25a89cd23baac4521d177c264 Mon Sep 17 00:00:00 2001 From: Puneet Mishra Date: Wed, 18 Nov 2015 15:43:34 +0000 Subject: [PATCH 054/320] nq-nci: enable NFCC hardware check and clock to NQxx Enable NFCC hardware check in the probe by probing i2c NCI data. Enable\disable BBCLK2 clock for NQxx polling on NFCC on off Change-Id: I9683ae29c1688516ae6d73dda3a7261d0155b273 Acked-by: Umesh Jagga Signed-off-by: Puneet Mishra --- drivers/nfc/nq-nci.c | 180 +++++++++++++++++++++++++++++++++++++------ drivers/nfc/nq-nci.h | 11 ++- 2 files changed, 162 insertions(+), 29 deletions(-) diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c index d17f9429731af..8d66ccba0fa0e 100644 --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -26,6 +26,7 @@ #include "nq-nci.h" #include #include +#include #ifdef CONFIG_COMPAT #include #endif @@ -44,16 +45,8 @@ static struct of_device_id msm_match_table[] = { }; MODULE_DEVICE_TABLE(of, msm_match_table); + #define MAX_BUFFER_SIZE (320) -#define PACKET_MAX_LENGTH (258) -/* Read data */ -#define PACKET_HEADER_SIZE_NCIPACKET_HEADER_SIZE_NCI (4) -#define MAX_PACKET_SIZE (PACKET_HEADER_SIZE_NCI + 255) -/* will timeout in approx. 100ms as 10us steps */ -#define NTF_TIMEOUT (100) -#define CORE_RESET_RSP_GID (0x60) -#define CORE_RESET_OID (0x00) -#define CORE_RST_NTF_LENGTH (0x02) #define WAKEUP_SRC_TIMEOUT (2000) struct nqx_dev { @@ -61,6 +54,7 @@ struct nqx_dev { struct mutex read_mutex; struct i2c_client *client; struct miscdevice nqx_device; + /* NFC GPIO variables */ unsigned int irq_gpio; unsigned int en_gpio; unsigned int firm_gpio; @@ -69,9 +63,12 @@ struct nqx_dev { bool irq_enabled; spinlock_t irq_enabled_lock; unsigned int count_irq; - /* CLK control */ + /* Initial CORE RESET notification */ unsigned int core_reset_ntf; + /* CLK control */ bool clk_run; + struct clk *s_clk; + /* Enable DMA to read data*/ struct dma_pool *nfc_dma_pool; dma_addr_t dma_handle_physical_addr; void *dma_virtual_addr; @@ -79,7 +76,10 @@ struct nqx_dev { static int nfcc_reboot(struct notifier_block *notifier, unsigned long val, void *v); - +/*clock enable function*/ +static int nqx_clock_select(struct nqx_dev *nqx_dev); +/*clock disable function*/ +static int nqx_clock_deselect(struct nqx_dev *nqx_dev); static struct notifier_block nfcc_notifier = { .notifier_call = nfcc_reboot, .next = NULL, @@ -129,8 +129,10 @@ static irqreturn_t nqx_dev_irq_handler(int irq, void *dev_id) } ret = gpio_get_value_cansleep(nqx_dev->irq_gpio); if (!ret) { +#ifdef NFC_KERNEL_BU dev_info(&nqx_dev->client->dev, "nqx nfc : nqx_dev_irq_handler error = %d\n", ret); +#endif return IRQ_HANDLED; } @@ -197,6 +199,10 @@ static ssize_t nfc_read(struct file *filp, char __user *buf, __func__, ret); return -EIO; } +#ifdef NFC_KERNEL_BU + dev_dbg(&nqx_dev->client->dev, "%s : NfcNciRx %x %x %x\n", + __func__, tmp[0], tmp[1], tmp[2]); +#endif if (copy_to_user(buf, tmp, ret)) { dev_warn(&nqx_dev->client->dev, "%s : failed to copy to user space\n", __func__); @@ -231,8 +237,10 @@ static ssize_t nfc_write(struct file *filp, const char __user *buf, "%s: failed to write %d\n", __func__, ret); ret = -EIO; } +#ifdef NFC_KERNEL_BU dev_dbg(&nqx_dev->client->dev, "%s : NfcNciTx %x %x %x\n", __func__, tmp[0], tmp[1], tmp[2]); +#endif usleep_range(1000, 1100); return ret; } @@ -283,6 +291,9 @@ int nfc_ioctl_power_states(struct file *filp, unsigned long arg) if (gpio_is_valid(nqx_dev->firm_gpio)) gpio_set_value(nqx_dev->firm_gpio, 0); gpio_set_value(nqx_dev->en_gpio, 0); + r = nqx_clock_deselect(nqx_dev); + if (r < 0) + dev_err(&nqx_dev->client->dev, "unable to disable clock\n"); /* hardware dependent delay */ msleep(100); } else if (arg == 1) { @@ -292,7 +303,11 @@ int nfc_ioctl_power_states(struct file *filp, unsigned long arg) if (gpio_is_valid(nqx_dev->firm_gpio)) gpio_set_value(nqx_dev->firm_gpio, 0); gpio_set_value(nqx_dev->en_gpio, 1); - msleep(100); + r = nqx_clock_select(nqx_dev); + if (r < 0) + dev_err(&nqx_dev->client->dev, "unable to enable clock\n"); + + msleep(20); } else if (arg == 2) { /* We are switching to Dowload Mode, toggle the enable pin * in order to set the NFCC in the new mode @@ -386,6 +401,98 @@ static const struct file_operations nfc_dev_fops = { #endif }; +/* Check for availability of NQ_ NFC controller hardware */ +static int nfcc_hw_check(struct i2c_client *client, unsigned int enable_gpio) +{ + int ret = 0; + + unsigned char raw_nci_reset_cmd[] = {0x20, 0x00, 0x01, 0x00}; + unsigned char nci_reset_rsp[6]; + + /* making sure that the NFCC starts in a clean state. */ + gpio_set_value(enable_gpio, 0);/* ULPM: Disable */ + /* hardware dependent delay */ + msleep(20); + gpio_set_value(enable_gpio, 1);/* HPD : Enable*/ + /* hardware dependent delay */ + msleep(20); + + /* send NCI CORE RESET CMD with Keep Config parameters */ + ret = i2c_master_send(client, raw_nci_reset_cmd, + sizeof(raw_nci_reset_cmd)); + if (ret < 0) { + dev_err(&client->dev, + "%s: - i2c_master_send Error\n", __func__); + goto err_nfcc_hw_check; + } + /* hardware dependent delay */ + msleep(30); + + /* Read Response of RESET command */ + ret = i2c_master_recv(client, nci_reset_rsp, + sizeof(nci_reset_rsp)); + if (ret < 0) { + dev_err(&client->dev, + "%s: - i2c_master_recv Error\n", __func__); + goto err_nfcc_hw_check; + } + ret = 0; + goto done; + +err_nfcc_hw_check: + ret = -ENXIO; + dev_err(&client->dev, + "%s: - NFCC HW not available\n", __func__); +done: + return ret; +} + +/* + Routine to enable clock. + this routine can be extended to select from multiple + sources based on clk_src_name. +*/ +static int nqx_clock_select(struct nqx_dev *nqx_dev) +{ + int r = 0; + + nqx_dev->s_clk = + clk_get(&nqx_dev->client->dev, "ref_clk"); + + if (nqx_dev->s_clk == NULL) + goto err_clk; + + if (nqx_dev->clk_run == false) + r = clk_prepare_enable(nqx_dev->s_clk); + + if (r) + goto err_clk; + + nqx_dev->clk_run = true; + + return r; + +err_clk: + r = -1; + return r; +} +/* + Routine to disable clocks +*/ +static int nqx_clock_deselect(struct nqx_dev *nqx_dev) +{ + int r = -1; + + if (nqx_dev->s_clk != NULL) { + if (nqx_dev->clk_run == true) { + clk_disable_unprepare(nqx_dev->s_clk); + nqx_dev->clk_run = false; + } + return 0; + } + return r; +} + static int nfc_parse_dt(struct device *dev, struct nqx_platform_data *pdata) { int r = 0; @@ -523,14 +630,6 @@ static int nqx_probe(struct i2c_client *client, goto err_free_dev; } - /* Register reboot notifier here */ - r = register_reboot_notifier(&nfcc_notifier); - if (r) { - dev_err(&client->dev, - "%s: cannot register reboot notifier(err = %d)\n", - __func__, r); - goto err_en_gpio; - } if (gpio_is_valid(platform_data->irq_gpio)) { r = gpio_request(platform_data->irq_gpio, "nfc_irq_gpio"); if (r) { @@ -629,16 +728,49 @@ static int nqx_probe(struct i2c_client *client, } nqx_disable_irq(nqx_dev); + /* + * To be efficient we need to test whether nfcc hardware is physically + * present before attempting further hardware initialisation. + * + */ + + r = nfcc_hw_check(client , platform_data->en_gpio); + if (r) { + /* We don't think there is hardware switch NFC OFF */ + goto err_request_hw_check_failed; + } + + /* Register reboot notifier here */ + r = register_reboot_notifier(&nfcc_notifier); + if (r) { + dev_err(&client->dev, + "%s: cannot register reboot notifier(err = %d)\n", + __func__, r); + goto err_request_notifier_failed; + } + device_init_wakeup(&client->dev, true); device_set_wakeup_capable(&client->dev, true); i2c_set_clientdata(client, nqx_dev); +#ifdef NFC_KERNEL_BU + r = nqx_clock_select(nqx_dev); + if (r < 0) { + dev_err(&client->dev, + "%s: nqx_clock_select failed\n", __func__); + goto err_request_notifier_failed; + } gpio_set_value(platform_data->en_gpio, 1); - +#endif dev_dbg(&client->dev, - "%s: probing nq0 exited successfully\n", + "%s: probing NFCC NQxxx exited successfully\n", __func__); return 0; +err_request_notifier_failed: + unregister_reboot_notifier(&nfcc_notifier); +err_request_hw_check_failed: + /* make sure NFCC is not enabled */ + gpio_set_value(platform_data->en_gpio, 0); err_request_irq_failed: misc_deregister(&nqx_dev->nqx_device); err_misc_register: @@ -651,7 +783,9 @@ static int nqx_probe(struct i2c_client *client, gpio_free(platform_data->en_gpio); err_free_dev: kfree(nqx_dev); - + dev_err(&client->dev, + "%s: probing nqxx failed, check hardware\n", + __func__); return r; } diff --git a/drivers/nfc/nq-nci.h b/drivers/nfc/nq-nci.h index ca8f20354d2a1..7c45d941e32ee 100644 --- a/drivers/nfc/nq-nci.h +++ b/drivers/nfc/nq-nci.h @@ -10,8 +10,8 @@ * GNU General Public License for more details. */ -#ifndef __NFC_NCI_H -#define __NFC_NCI_H +#ifndef __NQ_NCI_H +#define __NQ_NCI_H #include #include @@ -23,14 +23,13 @@ #include #include -#define NFC_SET_PWR _IOW(0xE9, 0x01, unsigned int) -#define SET_RX_BLOCK _IOW(0xE9, 0x04, unsigned int) -#define NFC_CLK_REQ _IOW(0xE9, 0x02, unsigned int) +#define NFC_SET_PWR _IOW(0xE9, 0x01, unsigned int) +#define NFC_CLK_REQ _IOW(0xE9, 0x02, unsigned int) +#define SET_RX_BLOCK _IOW(0xE9, 0x04, unsigned int) #define SET_EMULATOR_TEST_POINT _IOW(0xE9, 0x05, unsigned int) #define NFCC_INITIAL_CORE_RESET_NTF _IOW(0xE9, 0x10, unsigned int) #define NFC_RX_BUFFER_CNT_START (0x0) - #define PAYLOAD_HEADER_LENGTH (0x3) #define PAYLOAD_LENGTH_MAX (256) #define BYTE (0x8) From 73587faee2dbc8c3529a44cbf11edef709c74d59 Mon Sep 17 00:00:00 2001 From: Puneet Mishra Date: Tue, 22 Dec 2015 19:09:48 +0000 Subject: [PATCH 055/320] nq-nci: XO shut down issue fix Fixing XO shut down issue hapening due to nfc enable pin Change-Id: I12c8bce00e70162324761b4f5ff3406178e50878 Signed-off-by: Puneet Mishra --- drivers/nfc/nq-nci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c index 8d66ccba0fa0e..50a6dab9e7369 100644 --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -436,6 +436,7 @@ static int nfcc_hw_check(struct i2c_client *client, unsigned int enable_gpio) "%s: - i2c_master_recv Error\n", __func__); goto err_nfcc_hw_check; } + gpio_set_value(enable_gpio, 0);/* ULPM: Disable */ ret = 0; goto done; @@ -778,6 +779,7 @@ static int nqx_probe(struct i2c_client *client, err_clkreq_gpio: gpio_free(platform_data->clkreq_gpio); err_irq: + free_irq(client->irq, nqx_dev); gpio_free(platform_data->irq_gpio); err_en_gpio: gpio_free(platform_data->en_gpio); @@ -807,8 +809,9 @@ static int nqx_remove(struct i2c_client *client) static int nqx_suspend(struct device *device) { struct i2c_client *client = to_i2c_client(device); + struct nqx_dev *nqx_dev = i2c_get_clientdata(client); - if (device_may_wakeup(&client->dev)) + if (device_may_wakeup(&client->dev) && nqx_dev->irq_enabled) enable_irq_wake(client->irq); return 0; } From c8f7f93658b3b2e740cf5d97137cf8f1e0ab7e13 Mon Sep 17 00:00:00 2001 From: Puneet Mishra Date: Wed, 27 Jan 2016 17:48:09 +0000 Subject: [PATCH 056/320] NFC: Remove sleep from irq handler Removed gpio_get_value_cansleep call from interrupt handler CRs-Fixed: 968399 Change-Id: I739bde46be3a976117ded596da093415bd661064 Signed-off-by: Puneet Mishra --- drivers/nfc/nq-nci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c index 50a6dab9e7369..0336e4c24ef00 100644 --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -127,7 +127,7 @@ static irqreturn_t nqx_dev_irq_handler(int irq, void *dev_id) (nqx_dev->client->dev.power.is_suspended == true)) { pm_wakeup_event(&nqx_dev->client->dev, WAKEUP_SRC_TIMEOUT); } - ret = gpio_get_value_cansleep(nqx_dev->irq_gpio); + ret = gpio_get_value(nqx_dev->irq_gpio); if (!ret) { #ifdef NFC_KERNEL_BU dev_info(&nqx_dev->client->dev, From e98e0677bc28a42384e7a491b775700d18cae579 Mon Sep 17 00:00:00 2001 From: Puneet Mishra Date: Tue, 22 Mar 2016 19:57:35 +0000 Subject: [PATCH 057/320] NFC: Remove DMA allocation and stack use in write Removed DMA use in NFC kernel driver to stop boot time crash and use memdup_user to copy buffer from user in the write function instead of using stack memory. CRs-Fixed: 993292 Change-Id: Id2eefdf34e1393da2a0357478c55d7b4716b0818 Signed-off-by: Puneet Mishra --- drivers/nfc/nq-nci.c | 103 ++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 56 deletions(-) diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c index 0336e4c24ef00..0fffbb1acdf8a 100644 --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -24,8 +24,6 @@ #include #include #include "nq-nci.h" -#include -#include #include #ifdef CONFIG_COMPAT #include @@ -68,10 +66,10 @@ struct nqx_dev { /* CLK control */ bool clk_run; struct clk *s_clk; - /* Enable DMA to read data*/ - struct dma_pool *nfc_dma_pool; - dma_addr_t dma_handle_physical_addr; - void *dma_virtual_addr; + /* read buffer*/ + size_t kbuflen; + u8 *kbuf; + }; static int nfcc_reboot(struct notifier_block *notifier, unsigned long val, @@ -152,8 +150,8 @@ static ssize_t nfc_read(struct file *filp, char __user *buf, int ret; int irq_gpio_val = 0; - if (count > MAX_BUFFER_SIZE) - count = MAX_BUFFER_SIZE; + if (count > nqx_dev->kbuflen) + count = nqx_dev->kbuflen; dev_dbg(&nqx_dev->client->dev, "%s : reading %zu bytes.\n", __func__, count); @@ -181,9 +179,10 @@ static ssize_t nfc_read(struct file *filp, char __user *buf, } } + tmp = nqx_dev->kbuf; + + memset(tmp, 0x00, count); /* Read data */ - tmp = nqx_dev->dma_virtual_addr; - memset(tmp, 0x00, MAX_BUFFER_SIZE); ret = i2c_master_recv(nqx_dev->client, tmp, count); mutex_unlock(&nqx_dev->read_mutex); @@ -219,18 +218,20 @@ static ssize_t nfc_write(struct file *filp, const char __user *buf, size_t count, loff_t *offset) { struct nqx_dev *nqx_dev = filp->private_data; - char tmp[MAX_BUFFER_SIZE]; + char *tmp; int ret = 0; - if (count > MAX_BUFFER_SIZE) { + + if (count > nqx_dev->kbuflen) { dev_err(&nqx_dev->client->dev, "%s: out of memory\n", __func__); return -ENOMEM; } - if (copy_from_user(tmp, buf, count)) { - dev_err(&nqx_dev->client->dev, - "%s: failed to copy from user space\n", __func__); - return -EFAULT; - } + + tmp = memdup_user(buf, count); + + if (IS_ERR(tmp)) + return PTR_ERR(tmp); + ret = i2c_master_send(nqx_dev->client, tmp, count); if (ret != count) { dev_err(&nqx_dev->client->dev, @@ -238,10 +239,13 @@ static ssize_t nfc_write(struct file *filp, const char __user *buf, ret = -EIO; } #ifdef NFC_KERNEL_BU - dev_dbg(&nqx_dev->client->dev, "%s : NfcNciTx %x %x %x\n", - __func__, tmp[0], tmp[1], tmp[2]); + dev_dbg(&nqx_dev->client->dev, + "%s : i2c-%d: NfcNciTx %x %x %x\n", + __func__, iminor(file_inode(filp)), + tmp[0], tmp[1], tmp[2]); #endif usleep_range(1000, 1100); + kfree(tmp); return ret; } @@ -431,6 +435,10 @@ static int nfcc_hw_check(struct i2c_client *client, unsigned int enable_gpio) /* Read Response of RESET command */ ret = i2c_master_recv(client, nci_reset_rsp, sizeof(nci_reset_rsp)); + dev_err(&client->dev, + "%s: - nq - reset cmd answer : NfcNciRx %x %x %x\n", + __func__, nci_reset_rsp[0], + nci_reset_rsp[1], nci_reset_rsp[2]); if (ret < 0) { dev_err(&client->dev, "%s: - i2c_master_recv Error\n", __func__); @@ -581,33 +589,14 @@ static int nqx_probe(struct i2c_client *client, return -ENOMEM; } nqx_dev->client = client; - - /* if coherent_dma_mask not set by the device, set it to ULONG_MAX */ - if (client->dev.coherent_dma_mask == 0) - client->dev.coherent_dma_mask = ULONG_MAX; - - nqx_dev->nfc_dma_pool = NULL; - nqx_dev->dma_virtual_addr = NULL; - - nqx_dev->nfc_dma_pool = dma_pool_create( - "NFC-DMA", &client->dev, - MAX_BUFFER_SIZE, 64, 4096); - if (!nqx_dev->nfc_dma_pool) { - dev_err(&client->dev, - "nfc-nci probe: failed to allocate memory for dma_pool\n"); - r = -ENOMEM; - goto err_free_dev; - } - - nqx_dev->dma_virtual_addr = dma_pool_alloc( - nqx_dev->nfc_dma_pool, GFP_KERNEL, - &nqx_dev->dma_handle_physical_addr); - if (!nqx_dev->dma_virtual_addr) { - dev_err(&client->dev, - "nfc-nci probe: failed to allocate coherent memory for i2c dma buffer\n"); - r = -ENOMEM; - goto err_free_dev; - } + nqx_dev->kbuflen = MAX_BUFFER_SIZE; + nqx_dev->kbuf = kzalloc(MAX_BUFFER_SIZE, GFP_KERNEL); + if (!nqx_dev->kbuf) { + dev_err(&client->dev, + "failed to allocate memory for nqx_dev->kbuf\n"); + r = -ENOMEM; + goto err_free_dev; + } if (gpio_is_valid(platform_data->en_gpio)) { r = gpio_request(platform_data->en_gpio, "nfc_reset_gpio"); @@ -616,7 +605,7 @@ static int nqx_probe(struct i2c_client *client, "%s: unable to request gpio [%d]\n", __func__, platform_data->en_gpio); - goto err_free_dev; + goto err_mem; } r = gpio_direction_output(platform_data->en_gpio, 0); if (r) { @@ -628,13 +617,13 @@ static int nqx_probe(struct i2c_client *client, } } else { dev_err(&client->dev, "%s: dis gpio not provided\n", __func__); - goto err_free_dev; + goto err_mem; } if (gpio_is_valid(platform_data->irq_gpio)) { r = gpio_request(platform_data->irq_gpio, "nfc_irq_gpio"); if (r) { - dev_err(&client->dev, "%s: unable to request gpio [%d]\n", + dev_err(&client->dev, "%s: unable to req irq gpio [%d]\n", __func__, platform_data->irq_gpio); goto err_en_gpio; } @@ -642,7 +631,7 @@ static int nqx_probe(struct i2c_client *client, if (r) { dev_err(&client->dev, - "%s: unable to set direction for gpio [%d]\n", + "%s: unable to set direction for irq gpio [%d]\n", __func__, platform_data->irq_gpio); goto err_irq; @@ -662,14 +651,14 @@ static int nqx_probe(struct i2c_client *client, "nfc_firm_gpio"); if (r) { dev_err(&client->dev, - "%s: unable to request gpio [%d]\n", + "%s: unable to request firm gpio [%d]\n", __func__, platform_data->firm_gpio); goto err_irq; } r = gpio_direction_output(platform_data->firm_gpio, 0); if (r) { dev_err(&client->dev, - "%s: cannot set direction for gpio [%d]\n", + "%s: cannot set direction for firm gpio [%d]\n", __func__, platform_data->firm_gpio); goto err_irq; } @@ -683,14 +672,14 @@ static int nqx_probe(struct i2c_client *client, "nfc_clkreq_gpio"); if (r) { dev_err(&client->dev, - "%s: unable to request gpio [%d]\n", + "%s: unable to request clk gpio [%d]\n", __func__, platform_data->clkreq_gpio); goto err_clkreq_gpio; } r = gpio_direction_input(platform_data->clkreq_gpio); if (r) { dev_err(&client->dev, - "%s: cannot set direction for gpio [%d]\n", + "%s: cannot set direction for clk gpio [%d]\n", __func__, platform_data->clkreq_gpio); goto err_clkreq_gpio; } @@ -762,7 +751,7 @@ static int nqx_probe(struct i2c_client *client, } gpio_set_value(platform_data->en_gpio, 1); #endif - dev_dbg(&client->dev, + dev_err(&client->dev, "%s: probing NFCC NQxxx exited successfully\n", __func__); return 0; @@ -783,6 +772,8 @@ static int nqx_probe(struct i2c_client *client, gpio_free(platform_data->irq_gpio); err_en_gpio: gpio_free(platform_data->en_gpio); +err_mem: + kfree(nqx_dev->kbuf); err_free_dev: kfree(nqx_dev); dev_err(&client->dev, @@ -801,7 +792,7 @@ static int nqx_remove(struct i2c_client *client) mutex_destroy(&nqx_dev->read_mutex); gpio_free(nqx_dev->irq_gpio); gpio_free(nqx_dev->en_gpio); - + kfree(nqx_dev->kbuf); kfree(nqx_dev); return 0; } From cb14783664c3241b5c29b58cd14b394f39519c23 Mon Sep 17 00:00:00 2001 From: Gaurav Singhal Date: Fri, 20 May 2016 13:01:15 +0530 Subject: [PATCH 058/320] NFC: CE transaction failed during system suspend IRQ was disabled at suspend so system was not able to wake up during CE transaction. Even after irq was enabled we were not able to wake up in irq handler because wakeup event was not going due to is_suspended condition Change-Id: I5a088230786ef780cca0a3b767ad80e7b0c69f9e Signed-off-by: Gaurav Singhal --- drivers/nfc/nq-nci.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c index 0fffbb1acdf8a..84583aa6c70cb 100644 --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -121,10 +121,9 @@ static irqreturn_t nqx_dev_irq_handler(int irq, void *dev_id) unsigned long flags; int ret; - if (device_may_wakeup(&nqx_dev->client->dev) && - (nqx_dev->client->dev.power.is_suspended == true)) { + if (device_may_wakeup(&nqx_dev->client->dev)) pm_wakeup_event(&nqx_dev->client->dev, WAKEUP_SRC_TIMEOUT); - } + ret = gpio_get_value(nqx_dev->irq_gpio); if (!ret) { #ifdef NFC_KERNEL_BU @@ -134,6 +133,7 @@ static irqreturn_t nqx_dev_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } + nqx_disable_irq(nqx_dev); spin_lock_irqsave(&nqx_dev->irq_enabled_lock, flags); nqx_dev->count_irq++; spin_unlock_irqrestore(&nqx_dev->irq_enabled_lock, flags); @@ -158,7 +158,7 @@ static ssize_t nfc_read(struct file *filp, char __user *buf, mutex_lock(&nqx_dev->read_mutex); - irq_gpio_val = gpio_get_value_cansleep(nqx_dev->irq_gpio); + irq_gpio_val = gpio_get_value(nqx_dev->irq_gpio); if (irq_gpio_val == 0) { if (filp->f_flags & O_NONBLOCK) { dev_err(&nqx_dev->client->dev, @@ -166,17 +166,15 @@ static ssize_t nfc_read(struct file *filp, char __user *buf, ret = -EAGAIN; goto err; } - nqx_dev->irq_enabled = true; - enable_irq(nqx_dev->client->irq); - if (gpio_get_value_cansleep(nqx_dev->irq_gpio)) { - nqx_disable_irq(nqx_dev); - } else { - ret = wait_event_interruptible(nqx_dev->read_wq, - gpio_get_value(nqx_dev->irq_gpio)); - nqx_disable_irq(nqx_dev); - if (ret) - goto err; + if (!nqx_dev->irq_enabled) { + enable_irq(nqx_dev->client->irq); + nqx_dev->irq_enabled = true; } + ret = wait_event_interruptible(nqx_dev->read_wq, + gpio_get_value(nqx_dev->irq_gpio)); + if (ret) + goto err; + nqx_disable_irq(nqx_dev); } tmp = nqx_dev->kbuf; @@ -257,8 +255,6 @@ static int nfc_open(struct inode *inode, struct file *filp) filp->private_data = nqx_dev; nqx_init_stat(nqx_dev); - /* Enable interrupts from NFCC NFC_INT new NCI data available */ - nqx_enable_irq(nqx_dev); dev_dbg(&nqx_dev->client->dev, "%s: %d,%d\n", __func__, imajor(inode), iminor(inode)); @@ -301,6 +297,7 @@ int nfc_ioctl_power_states(struct file *filp, unsigned long arg) /* hardware dependent delay */ msleep(100); } else if (arg == 1) { + nqx_enable_irq(nqx_dev); dev_dbg(&nqx_dev->client->dev, "gpio_set_value enable: %s: info: %p\n", __func__, nqx_dev); @@ -711,7 +708,7 @@ static int nqx_probe(struct i2c_client *client, /* NFC_INT IRQ */ nqx_dev->irq_enabled = true; r = request_irq(client->irq, nqx_dev_irq_handler, - IRQF_TRIGGER_RISING, client->name, nqx_dev); + IRQF_TRIGGER_HIGH, client->name, nqx_dev); if (r) { dev_err(&client->dev, "%s: request_irq failed\n", __func__); goto err_request_irq_failed; From 439b5392997b47f2bdbad8b287cbcd06cee836aa Mon Sep 17 00:00:00 2001 From: Gaurav Singhal Date: Sun, 3 Apr 2016 23:37:56 +0530 Subject: [PATCH 059/320] NFC: Error handling correction in probe Error handling check added in probe function and memory cleanup in remove function. Change-Id: Ic8f02dcc89e716ec88b711496d1e43754b95968d Signed-off-by: Gaurav Singhal --- drivers/nfc/nq-nci.c | 158 ++++++++++++++++++++++++++++--------------- 1 file changed, 105 insertions(+), 53 deletions(-) diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c index 84583aa6c70cb..b1c4d33ff8cfd 100644 --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -69,7 +69,7 @@ struct nqx_dev { /* read buffer*/ size_t kbuflen; u8 *kbuf; - + struct nqx_platform_data *pdata; }; static int nfcc_reboot(struct notifier_block *notifier, unsigned long val, @@ -150,6 +150,11 @@ static ssize_t nfc_read(struct file *filp, char __user *buf, int ret; int irq_gpio_val = 0; + if (!nqx_dev) { + ret = -ENODEV; + goto out; + } + if (count > nqx_dev->kbuflen) count = nqx_dev->kbuflen; @@ -178,23 +183,27 @@ static ssize_t nfc_read(struct file *filp, char __user *buf, } tmp = nqx_dev->kbuf; - + if (!tmp) { + dev_err(&nqx_dev->client->dev, + "%s: device doesn't exist anymore\n", __func__); + ret = -ENODEV; + goto err; + } memset(tmp, 0x00, count); + /* Read data */ ret = i2c_master_recv(nqx_dev->client, tmp, count); - - mutex_unlock(&nqx_dev->read_mutex); - if (ret < 0) { dev_err(&nqx_dev->client->dev, "%s: i2c_master_recv returned %d\n", __func__, ret); - return ret; + goto err; } if (ret > count) { dev_err(&nqx_dev->client->dev, "%s: received too many bytes from i2c (%d)\n", __func__, ret); - return -EIO; + ret = -EIO; + goto err; } #ifdef NFC_KERNEL_BU dev_dbg(&nqx_dev->client->dev, "%s : NfcNciRx %x %x %x\n", @@ -203,12 +212,15 @@ static ssize_t nfc_read(struct file *filp, char __user *buf, if (copy_to_user(buf, tmp, ret)) { dev_warn(&nqx_dev->client->dev, "%s : failed to copy to user space\n", __func__); - return -EFAULT; + ret = -EFAULT; + goto err; } + mutex_unlock(&nqx_dev->read_mutex); return ret; err: mutex_unlock(&nqx_dev->read_mutex); +out: return ret; } @@ -216,25 +228,34 @@ static ssize_t nfc_write(struct file *filp, const char __user *buf, size_t count, loff_t *offset) { struct nqx_dev *nqx_dev = filp->private_data; - char *tmp; + char *tmp = NULL; int ret = 0; + if (!nqx_dev) { + ret = -ENODEV; + goto out; + } if (count > nqx_dev->kbuflen) { dev_err(&nqx_dev->client->dev, "%s: out of memory\n", __func__); - return -ENOMEM; + ret = -ENOMEM; + goto out; } tmp = memdup_user(buf, count); - - if (IS_ERR(tmp)) - return PTR_ERR(tmp); + if (IS_ERR(tmp)) { + dev_err(&nqx_dev->client->dev, "%s: memdup_user failed\n", + __func__); + ret = PTR_ERR(tmp); + goto out; + } ret = i2c_master_send(nqx_dev->client, tmp, count); if (ret != count) { dev_err(&nqx_dev->client->dev, "%s: failed to write %d\n", __func__, ret); ret = -EIO; + goto out_free; } #ifdef NFC_KERNEL_BU dev_dbg(&nqx_dev->client->dev, @@ -243,7 +264,9 @@ static ssize_t nfc_write(struct file *filp, const char __user *buf, tmp[0], tmp[1], tmp[2]); #endif usleep_range(1000, 1100); +out_free: kfree(tmp); +out: return ret; } @@ -558,32 +581,33 @@ static int nqx_probe(struct i2c_client *client, platform_data = devm_kzalloc(&client->dev, sizeof(struct nqx_platform_data), GFP_KERNEL); if (!platform_data) { - dev_err(&client->dev, - "%s: Failed to allocate memory\n", __func__); - return -ENOMEM; + r = -ENOMEM; + goto err_platform_data; } r = nfc_parse_dt(&client->dev, platform_data); if (r) - return r; - } else { + goto err_free_data; + } else platform_data = client->dev.platform_data; - } + dev_dbg(&client->dev, "%s, inside nfc-nci flags = %x\n", __func__, client->flags); + if (platform_data == NULL) { dev_err(&client->dev, "%s: failed\n", __func__); - return -ENODEV; + r = -ENODEV; + goto err_platform_data; } if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "%s: need I2C_FUNC_I2C\n", __func__); - return -ENODEV; + r = -ENODEV; + goto err_free_data; } nqx_dev = kzalloc(sizeof(*nqx_dev), GFP_KERNEL); if (nqx_dev == NULL) { - dev_err(&client->dev, - "%s: failed to allocate memory for module data\n", __func__); - return -ENOMEM; + r = -ENOMEM; + goto err_free_data; } nqx_dev->client = client; nqx_dev->kbuflen = MAX_BUFFER_SIZE; @@ -599,7 +623,7 @@ static int nqx_probe(struct i2c_client *client, r = gpio_request(platform_data->en_gpio, "nfc_reset_gpio"); if (r) { dev_err(&client->dev, - "%s: unable to request gpio [%d]\n", + "%s: unable to request nfc reset gpio [%d]\n", __func__, platform_data->en_gpio); goto err_mem; @@ -607,36 +631,36 @@ static int nqx_probe(struct i2c_client *client, r = gpio_direction_output(platform_data->en_gpio, 0); if (r) { dev_err(&client->dev, - "%s: unable to set direction for gpio [%d]\n", + "%s: unable to set direction for nfc reset gpio [%d]\n", __func__, platform_data->en_gpio); goto err_en_gpio; } } else { - dev_err(&client->dev, "%s: dis gpio not provided\n", __func__); + dev_err(&client->dev, + "%s: nfc reset gpio not provided\n", __func__); goto err_mem; } if (gpio_is_valid(platform_data->irq_gpio)) { r = gpio_request(platform_data->irq_gpio, "nfc_irq_gpio"); if (r) { - dev_err(&client->dev, "%s: unable to req irq gpio [%d]\n", + dev_err(&client->dev, "%s: unable to request nfc irq gpio [%d]\n", __func__, platform_data->irq_gpio); goto err_en_gpio; } r = gpio_direction_input(platform_data->irq_gpio); if (r) { - dev_err(&client->dev, - "%s: unable to set direction for irq gpio [%d]\n", + "%s: unable to set direction for nfc irq gpio [%d]\n", __func__, platform_data->irq_gpio); - goto err_irq; + goto err_irq_gpio; } irqn = gpio_to_irq(platform_data->irq_gpio); if (irqn < 0) { r = irqn; - goto err_irq; + goto err_irq_gpio; } client->irq = irqn; } else { @@ -648,47 +672,49 @@ static int nqx_probe(struct i2c_client *client, "nfc_firm_gpio"); if (r) { dev_err(&client->dev, - "%s: unable to request firm gpio [%d]\n", + "%s: unable to request nfc firmware gpio [%d]\n", __func__, platform_data->firm_gpio); - goto err_irq; + goto err_irq_gpio; } r = gpio_direction_output(platform_data->firm_gpio, 0); if (r) { dev_err(&client->dev, - "%s: cannot set direction for firm gpio [%d]\n", + "%s: cannot set direction for nfc firmware gpio [%d]\n", __func__, platform_data->firm_gpio); - goto err_irq; + goto err_firm_gpio; } - nqx_dev->firm_gpio = platform_data->firm_gpio; } else { dev_err(&client->dev, "%s: firm gpio not provided\n", __func__); + goto err_irq_gpio; } if (gpio_is_valid(platform_data->clkreq_gpio)) { r = gpio_request(platform_data->clkreq_gpio, "nfc_clkreq_gpio"); if (r) { dev_err(&client->dev, - "%s: unable to request clk gpio [%d]\n", + "%s: unable to request nfc clkreq gpio [%d]\n", __func__, platform_data->clkreq_gpio); - goto err_clkreq_gpio; + goto err_firm_gpio; } r = gpio_direction_input(platform_data->clkreq_gpio); if (r) { dev_err(&client->dev, - "%s: cannot set direction for clk gpio [%d]\n", + "%s: cannot set direction for nfc clkreq gpio [%d]\n", __func__, platform_data->clkreq_gpio); goto err_clkreq_gpio; } - nqx_dev->clkreq_gpio = platform_data->clkreq_gpio; } else { dev_err(&client->dev, "%s: clkreq gpio not provided\n", __func__); + goto err_firm_gpio; } nqx_dev->en_gpio = platform_data->en_gpio; nqx_dev->irq_gpio = platform_data->irq_gpio; nqx_dev->firm_gpio = platform_data->firm_gpio; + nqx_dev->clkreq_gpio = platform_data->clkreq_gpio; + nqx_dev->pdata = platform_data; /* init mutex and queues */ init_waitqueue_head(&nqx_dev->read_wq); @@ -720,9 +746,10 @@ static int nqx_probe(struct i2c_client *client, * present before attempting further hardware initialisation. * */ - r = nfcc_hw_check(client , platform_data->en_gpio); if (r) { + /* make sure NFCC is not enabled */ + gpio_set_value(platform_data->en_gpio, 0); /* We don't think there is hardware switch NFC OFF */ goto err_request_hw_check_failed; } @@ -733,39 +760,45 @@ static int nqx_probe(struct i2c_client *client, dev_err(&client->dev, "%s: cannot register reboot notifier(err = %d)\n", __func__, r); - goto err_request_notifier_failed; + /* nfcc_hw_check function not doing memory + allocation so using same goto target here + */ + goto err_request_hw_check_failed; } - device_init_wakeup(&client->dev, true); - device_set_wakeup_capable(&client->dev, true); - i2c_set_clientdata(client, nqx_dev); #ifdef NFC_KERNEL_BU r = nqx_clock_select(nqx_dev); if (r < 0) { dev_err(&client->dev, "%s: nqx_clock_select failed\n", __func__); - goto err_request_notifier_failed; + goto err_clock_en_failed; } gpio_set_value(platform_data->en_gpio, 1); #endif + device_init_wakeup(&client->dev, true); + device_set_wakeup_capable(&client->dev, true); + i2c_set_clientdata(client, nqx_dev); + dev_err(&client->dev, "%s: probing NFCC NQxxx exited successfully\n", __func__); return 0; -err_request_notifier_failed: +#ifdef NFC_KERNEL_BU +err_clock_en_failed: unregister_reboot_notifier(&nfcc_notifier); +#endif err_request_hw_check_failed: - /* make sure NFCC is not enabled */ - gpio_set_value(platform_data->en_gpio, 0); + free_irq(client->irq, nqx_dev); err_request_irq_failed: misc_deregister(&nqx_dev->nqx_device); err_misc_register: mutex_destroy(&nqx_dev->read_mutex); err_clkreq_gpio: gpio_free(platform_data->clkreq_gpio); -err_irq: - free_irq(client->irq, nqx_dev); +err_firm_gpio: + gpio_free(platform_data->firm_gpio); +err_irq_gpio: gpio_free(platform_data->irq_gpio); err_en_gpio: gpio_free(platform_data->en_gpio); @@ -773,6 +806,10 @@ static int nqx_probe(struct i2c_client *client, kfree(nqx_dev->kbuf); err_free_dev: kfree(nqx_dev); +err_free_data: + if (client->dev.of_node) + devm_kfree(&client->dev, platform_data); +err_platform_data: dev_err(&client->dev, "%s: probing nqxx failed, check hardware\n", __func__); @@ -781,17 +818,32 @@ static int nqx_probe(struct i2c_client *client, static int nqx_remove(struct i2c_client *client) { + int ret = 0; struct nqx_dev *nqx_dev; nqx_dev = i2c_get_clientdata(client); + if (!nqx_dev) { + dev_err(&client->dev, + "%s: device doesn't exist anymore\n", __func__); + ret = -ENODEV; + goto err; + } + + unregister_reboot_notifier(&nfcc_notifier); free_irq(client->irq, nqx_dev); misc_deregister(&nqx_dev->nqx_device); mutex_destroy(&nqx_dev->read_mutex); + gpio_free(nqx_dev->clkreq_gpio); + gpio_free(nqx_dev->firm_gpio); gpio_free(nqx_dev->irq_gpio); gpio_free(nqx_dev->en_gpio); kfree(nqx_dev->kbuf); + if (client->dev.of_node) + devm_kfree(&client->dev, nqx_dev->pdata); + kfree(nqx_dev); - return 0; +err: + return ret; } static int nqx_suspend(struct device *device) From ffab39dbe4d110e94b6c928f57128443377e3d82 Mon Sep 17 00:00:00 2001 From: Gaurav Singhal Date: Wed, 27 Apr 2016 13:18:45 +0530 Subject: [PATCH 060/320] NFC: eSE power request implementation we are going to use the eSE for features which are independent from NFC, so we need to use the power request pin from the eSE Change-Id: I60651052d7bf97a8a0505e76904cebe2b7c69ce2 Signed-off-by: Gaurav Singhal --- drivers/nfc/nq-nci.c | 128 +++++++++++++++++++++++++++++++++++++++++-- drivers/nfc/nq-nci.h | 5 +- 2 files changed, 126 insertions(+), 7 deletions(-) diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c index b1c4d33ff8cfd..ed163bb7a6d80 100644 --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -34,6 +34,7 @@ struct nqx_platform_data { unsigned int en_gpio; unsigned int clkreq_gpio; unsigned int firm_gpio; + unsigned int ese_gpio; const char *clk_src_name; }; @@ -57,6 +58,9 @@ struct nqx_dev { unsigned int en_gpio; unsigned int firm_gpio; unsigned int clkreq_gpio; + unsigned int ese_gpio; + /* NFC VEN pin state powered by Nfc */ + bool nfc_ven_enabled; /* NFC_IRQ state */ bool irq_enabled; spinlock_t irq_enabled_lock; @@ -270,6 +274,62 @@ static ssize_t nfc_write(struct file *filp, const char __user *buf, return ret; } +/* + Power management of the eSE + NFC & eSE ON : NFC_EN high and eSE_pwr_req high. + NFC OFF & eSE ON : NFC_EN high and eSE_pwr_req high. + NFC OFF & eSE OFF : NFC_EN low and eSE_pwr_req low. +*/ +static int nqx_ese_pwr(struct nqx_dev *nqx_dev, unsigned long int arg) +{ + int r = -1; + + /* Let's store the NFC_EN pin state*/ + if (arg == 0) { + /* We want to power on the eSE and to do so we need the + * eSE_pwr_req pin and the NFC_EN pin to be high + */ + nqx_dev->nfc_ven_enabled = gpio_get_value(nqx_dev->en_gpio); + if (!nqx_dev->nfc_ven_enabled) { + gpio_set_value(nqx_dev->en_gpio, 1); + /* hardware dependent delay */ + usleep_range(1000, 1100); + } + if (gpio_is_valid(nqx_dev->ese_gpio)) { + if (gpio_get_value(nqx_dev->ese_gpio)) { + dev_dbg(&nqx_dev->client->dev, "ese_gpio is already high\n"); + r = 0; + } else { + gpio_set_value(nqx_dev->ese_gpio, 1); + if (gpio_get_value(nqx_dev->ese_gpio)) { + dev_dbg(&nqx_dev->client->dev, "ese_gpio is enabled\n"); + r = 0; + } + } + } + } else if (arg == 1) { + if (gpio_is_valid(nqx_dev->ese_gpio)) { + gpio_set_value(nqx_dev->ese_gpio, 0); + if (!gpio_get_value(nqx_dev->ese_gpio)) { + dev_dbg(&nqx_dev->client->dev, "ese_gpio is disabled\n"); + r = 0; + } + } + if (!nqx_dev->nfc_ven_enabled) { + /* hardware dependent delay */ + usleep_range(1000, 1100); + dev_dbg(&nqx_dev->client->dev, "disabling en_gpio\n"); + gpio_set_value(nqx_dev->en_gpio, 0); + } + } else if (arg == 3) { + if (!nqx_dev->nfc_ven_enabled) + r = 0; + else + r = gpio_get_value(nqx_dev->ese_gpio); + } + return r; +} + static int nfc_open(struct inode *inode, struct file *filp) { int ret = 0; @@ -313,10 +373,16 @@ int nfc_ioctl_power_states(struct file *filp, unsigned long arg) __func__, nqx_dev); if (gpio_is_valid(nqx_dev->firm_gpio)) gpio_set_value(nqx_dev->firm_gpio, 0); - gpio_set_value(nqx_dev->en_gpio, 0); + if (!gpio_get_value(nqx_dev->ese_gpio)) { + dev_dbg(&nqx_dev->client->dev, "disabling en_gpio\n"); + gpio_set_value(nqx_dev->en_gpio, 0); + } else { + dev_dbg(&nqx_dev->client->dev, "keeping en_gpio high\n"); + } r = nqx_clock_deselect(nqx_dev); if (r < 0) dev_err(&nqx_dev->client->dev, "unable to disable clock\n"); + nqx_dev->nfc_ven_enabled = false; /* hardware dependent delay */ msleep(100); } else if (arg == 1) { @@ -330,12 +396,16 @@ int nfc_ioctl_power_states(struct file *filp, unsigned long arg) r = nqx_clock_select(nqx_dev); if (r < 0) dev_err(&nqx_dev->client->dev, "unable to enable clock\n"); - + nqx_dev->nfc_ven_enabled = true; msleep(20); } else if (arg == 2) { /* We are switching to Dowload Mode, toggle the enable pin * in order to set the NFCC in the new mode */ + if (gpio_get_value(nqx_dev->ese_gpio)) { + dev_err(&nqx_dev->client->dev, "FW download forbidden while ese is on\n"); + return -EBUSY; /* Device or resource busy */ + } gpio_set_value(nqx_dev->en_gpio, 1); msleep(20); if (gpio_is_valid(nqx_dev->firm_gpio)) @@ -348,6 +418,7 @@ int nfc_ioctl_power_states(struct file *filp, unsigned long arg) } else { r = -ENOIOCTLCMD; } + return r; } @@ -362,6 +433,12 @@ static long nfc_compat_ioctl(struct file *pfile, unsigned int cmd, case NFC_SET_PWR: nfc_ioctl_power_states(pfile, arg); break; + case ESE_SET_PWR: + nqx_ese_pwr(pfile->private_data, arg); + break; + case ESE_GET_PWR: + nqx_ese_pwr(pfile->private_data, 3); + break; case SET_RX_BLOCK: break; case SET_EMULATOR_TEST_POINT: @@ -398,7 +475,11 @@ static long nfc_ioctl(struct file *pfile, unsigned int cmd, case NFC_SET_PWR: r = nfc_ioctl_power_states(pfile, arg); break; - case NFC_CLK_REQ: + case ESE_SET_PWR: + r = nqx_ese_pwr(pfile->private_data, arg); + break; + case ESE_GET_PWR: + r = nqx_ese_pwr(pfile->private_data, 3); break; case SET_RX_BLOCK: break; @@ -543,6 +624,13 @@ static int nfc_parse_dt(struct device *dev, struct nqx_platform_data *pdata) pdata->firm_gpio = -EINVAL; } + pdata->ese_gpio = of_get_named_gpio(np, "qcom,nq-esepwr", 0); + if (!gpio_is_valid(pdata->ese_gpio)) { + dev_warn(dev, + "ese GPIO error getting from OF node\n"); + pdata->ese_gpio = -EINVAL; + } + r = of_property_read_string(np, "qcom,clk-src", &pdata->clk_src_name); pdata->clkreq_gpio = of_get_named_gpio(np, "qcom,nq-clkreq", 0); @@ -688,6 +776,29 @@ static int nqx_probe(struct i2c_client *client, "%s: firm gpio not provided\n", __func__); goto err_irq_gpio; } + if (gpio_is_valid(platform_data->ese_gpio)) { + r = gpio_request(platform_data->ese_gpio, + "nfc-ese_pwr"); + if (r) { + dev_err(&client->dev, + "%s: unable to request nfc ese gpio [%d]\n", + __func__, platform_data->ese_gpio); + /* ese gpio optional so we should continue */ + } else { + nqx_dev->ese_gpio = platform_data->ese_gpio; + } + r = gpio_direction_output(platform_data->ese_gpio, 0); + if (r) { + dev_err(&client->dev, + "%s: cannot set direction for nfc ese gpio [%d]\n", + __func__, platform_data->ese_gpio); + /* ese gpio optional so we should continue */ + } + } else { + dev_err(&client->dev, + "%s: ese gpio not provided\n", __func__); + /* ese gpio optional so we should continue */ + } if (gpio_is_valid(platform_data->clkreq_gpio)) { r = gpio_request(platform_data->clkreq_gpio, "nfc_clkreq_gpio"); @@ -695,7 +806,7 @@ static int nqx_probe(struct i2c_client *client, dev_err(&client->dev, "%s: unable to request nfc clkreq gpio [%d]\n", __func__, platform_data->clkreq_gpio); - goto err_firm_gpio; + goto err_ese_gpio; } r = gpio_direction_input(platform_data->clkreq_gpio); if (r) { @@ -707,7 +818,7 @@ static int nqx_probe(struct i2c_client *client, } else { dev_err(&client->dev, "%s: clkreq gpio not provided\n", __func__); - goto err_firm_gpio; + goto err_ese_gpio; } nqx_dev->en_gpio = platform_data->en_gpio; @@ -796,6 +907,10 @@ static int nqx_probe(struct i2c_client *client, mutex_destroy(&nqx_dev->read_mutex); err_clkreq_gpio: gpio_free(platform_data->clkreq_gpio); +err_ese_gpio: + /* optional gpio, not sure was configured in probe */ + if (nqx_dev->ese_gpio) + gpio_free(platform_data->ese_gpio); err_firm_gpio: gpio_free(platform_data->firm_gpio); err_irq_gpio: @@ -834,6 +949,9 @@ static int nqx_remove(struct i2c_client *client) misc_deregister(&nqx_dev->nqx_device); mutex_destroy(&nqx_dev->read_mutex); gpio_free(nqx_dev->clkreq_gpio); + /* optional gpio, not sure was configured in probe */ + if (nqx_dev->ese_gpio) + gpio_free(nqx_dev->ese_gpio); gpio_free(nqx_dev->firm_gpio); gpio_free(nqx_dev->irq_gpio); gpio_free(nqx_dev->en_gpio); diff --git a/drivers/nfc/nq-nci.h b/drivers/nfc/nq-nci.h index 7c45d941e32ee..7656e9e8917ec 100644 --- a/drivers/nfc/nq-nci.h +++ b/drivers/nfc/nq-nci.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -24,7 +24,8 @@ #include #define NFC_SET_PWR _IOW(0xE9, 0x01, unsigned int) -#define NFC_CLK_REQ _IOW(0xE9, 0x02, unsigned int) +#define ESE_SET_PWR _IOW(0xE9, 0x02, unsigned int) +#define ESE_GET_PWR _IOR(0xE9, 0x03, unsigned int) #define SET_RX_BLOCK _IOW(0xE9, 0x04, unsigned int) #define SET_EMULATOR_TEST_POINT _IOW(0xE9, 0x05, unsigned int) #define NFCC_INITIAL_CORE_RESET_NTF _IOW(0xE9, 0x10, unsigned int) From defbfe6a9568403411ac7442d50dbbb6d6cf1da3 Mon Sep 17 00:00:00 2001 From: Dibyendu Roy Date: Wed, 23 Mar 2016 14:00:19 +0530 Subject: [PATCH 061/320] Bluetooth : Replace %p with %pK The %pK restrictions are used to eliminate exposing kernel addresses. When kptr_restrict is set to "0" there are no restrictions. When kptr_restrict is set to "1", kernel pointers printed using the %pK format specifier will be replaced with 0's unless the user has CAP_SYSLOG. When kptr_restrict is set to "2", kernel pointers printed using %pK will be replaced with 0's regardless of privileges. Change-Id: Iacd8f7b7cdafed3a111507d3da899be9261ff09f Signed-off-by: Dibyendu Roy --- drivers/bluetooth/hci_h4.c | 8 +- drivers/bluetooth/hci_ldisc.c | 10 +- net/bluetooth/af_bluetooth.c | 16 +-- net/bluetooth/bnep/core.c | 2 +- net/bluetooth/bnep/netdev.c | 4 +- net/bluetooth/bnep/sock.c | 4 +- net/bluetooth/cmtp/capi.c | 31 +++--- net/bluetooth/cmtp/core.c | 10 +- net/bluetooth/cmtp/sock.c | 4 +- net/bluetooth/hci_conn.c | 46 ++++----- net/bluetooth/hci_core.c | 48 ++++----- net/bluetooth/hci_event.c | 10 +- net/bluetooth/hci_sock.c | 20 ++-- net/bluetooth/hci_sysfs.c | 8 +- net/bluetooth/hidp/core.c | 21 ++-- net/bluetooth/hidp/sock.c | 4 +- net/bluetooth/l2cap_core.c | 185 +++++++++++++++++----------------- net/bluetooth/l2cap_sock.c | 38 +++---- net/bluetooth/lib.c | 4 +- net/bluetooth/mgmt.c | 12 +-- net/bluetooth/rfcomm/core.c | 128 +++++++++++------------ net/bluetooth/rfcomm/sock.c | 47 ++++----- net/bluetooth/rfcomm/tty.c | 50 ++++----- net/bluetooth/sco.c | 64 ++++++------ net/bluetooth/smp.c | 20 ++-- 25 files changed, 399 insertions(+), 395 deletions(-) diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index 8ae9f1ea2bb5e..3bbaa9828c09e 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c @@ -67,7 +67,7 @@ static int h4_open(struct hci_uart *hu) { struct h4_struct *h4; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); h4 = kzalloc(sizeof(*h4), GFP_KERNEL); if (!h4) @@ -84,7 +84,7 @@ static int h4_flush(struct hci_uart *hu) { struct h4_struct *h4 = hu->priv; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); skb_queue_purge(&h4->txq); @@ -98,7 +98,7 @@ static int h4_close(struct hci_uart *hu) hu->priv = NULL; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); skb_queue_purge(&h4->txq); @@ -115,7 +115,7 @@ static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb) { struct h4_struct *h4 = hu->priv; - BT_DBG("hu %p skb %p", hu, skb); + BT_DBG("hu %pK skb %pK", hu, skb); /* Prepend skb with frame type */ memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 8b49b56dc4d5e..c5975ca87ec14 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -200,7 +200,7 @@ int hci_uart_init_ready(struct hci_uart *hu) /* Initialize device */ static int hci_uart_open(struct hci_dev *hdev) { - BT_DBG("%s %p", hdev->name, hdev); + BT_DBG("%s %pK", hdev->name, hdev); /* Nothing to do for UART driver */ @@ -215,7 +215,7 @@ static int hci_uart_flush(struct hci_dev *hdev) struct hci_uart *hu = hci_get_drvdata(hdev); struct tty_struct *tty = hu->tty; - BT_DBG("hdev %p tty %p", hdev, tty); + BT_DBG("hdev %pK tty %pK", hdev, tty); if (hu->tx_skb) { kfree_skb(hu->tx_skb); hu->tx_skb = NULL; @@ -234,7 +234,7 @@ static int hci_uart_flush(struct hci_dev *hdev) /* Close device */ static int hci_uart_close(struct hci_dev *hdev) { - BT_DBG("hdev %p", hdev); + BT_DBG("hdev %pK", hdev); if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) return 0; @@ -283,7 +283,7 @@ static int hci_uart_tty_open(struct tty_struct *tty) { struct hci_uart *hu; - BT_DBG("tty %p", tty); + BT_DBG("tty %pK", tty); /* Error if the tty has no write op instead of leaving an exploitable hole */ @@ -326,7 +326,7 @@ static void hci_uart_tty_close(struct tty_struct *tty) struct hci_uart *hu = (void *)tty->disc_data; struct hci_dev *hdev; - BT_DBG("tty %p", tty); + BT_DBG("tty %pK", tty); /* Detach from the tty */ tty->disc_data = NULL; diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index f7c36826f3f4d..3b6e2439f7ab5 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -185,7 +185,7 @@ EXPORT_SYMBOL(bt_sock_unlink); void bt_accept_enqueue(struct sock *parent, struct sock *sk) { - BT_DBG("parent %p, sk %p", parent, sk); + BT_DBG("parent %pK, sk %pK", parent, sk); sock_hold(sk); list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q); @@ -196,7 +196,7 @@ EXPORT_SYMBOL(bt_accept_enqueue); void bt_accept_unlink(struct sock *sk) { - BT_DBG("sk %p state %d", sk, sk->sk_state); + BT_DBG("sk %pK state %d", sk, sk->sk_state); list_del_init(&bt_sk(sk)->accept_q); bt_sk(sk)->parent->sk_ack_backlog--; @@ -210,7 +210,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock) struct list_head *p, *n; struct sock *sk; - BT_DBG("parent %p", parent); + BT_DBG("parent %pK", parent); list_for_each_safe(p, n, &bt_sk(parent)->accept_q) { sk = (struct sock *) list_entry(p, struct bt_sock, accept_q); @@ -250,7 +250,7 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, size_t copied; int err; - BT_DBG("sock %p sk %p len %zu", sock, sk, len); + BT_DBG("sock %pK sk %pK len %zu", sock, sk, len); if (flags & (MSG_OOB)) return -EOPNOTSUPP; @@ -319,7 +319,7 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, if (flags & MSG_OOB) return -EOPNOTSUPP; - BT_DBG("sk %p size %zu", sk, size); + BT_DBG("sk %pK size %zu", sk, size); lock_sock(sk); @@ -435,7 +435,7 @@ unsigned int bt_sock_poll(struct file *file, struct socket *sock, struct sock *sk = sock->sk; unsigned int mask = 0; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); poll_wait(file, sk_sleep(sk), wait); @@ -479,7 +479,7 @@ int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) long amount; int err; - BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg); + BT_DBG("sk %pK cmd %x arg %lx", sk, cmd, arg); switch (cmd) { case TIOCOUTQ: @@ -525,7 +525,7 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) DECLARE_WAITQUEUE(wait, current); int err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); add_wait_queue(sk_sleep(sk), &wait); set_current_state(TASK_INTERRUPTIBLE); diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index e430b1abcd2fa..13f3b1ff245d9 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -393,7 +393,7 @@ static int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb) int len = 0, il = 0; u8 type = 0; - BT_DBG("skb %p dev %p type %d", skb, skb->dev, skb->pkt_type); + BT_DBG("skb %pK dev %pK type %d", skb, skb->dev, skb->pkt_type); if (!skb->dev) { /* Control frame sent by us */ diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c index 4b488ec261054..601b7b21ab581 100644 --- a/net/bluetooth/bnep/netdev.c +++ b/net/bluetooth/bnep/netdev.c @@ -156,7 +156,7 @@ static int bnep_net_proto_filter(struct sk_buff *skb, struct bnep_session *s) return 0; } - BT_DBG("BNEP: filtered skb %p, proto 0x%.4x", skb, proto); + BT_DBG("BNEP: filtered skb %pK, proto 0x%.4x", skb, proto); return 1; } #endif @@ -167,7 +167,7 @@ static netdev_tx_t bnep_net_xmit(struct sk_buff *skb, struct bnep_session *s = netdev_priv(dev); struct sock *sk = s->sock->sk; - BT_DBG("skb %p, dev %p", skb, dev); + BT_DBG("skb %pK, dev %pK", skb, dev); #ifdef CONFIG_BT_BNEP_MC_FILTER if (bnep_net_mc_filter(skb, s)) { diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c index 5f051290dabab..9340bf18063ce 100644 --- a/net/bluetooth/bnep/sock.c +++ b/net/bluetooth/bnep/sock.c @@ -37,7 +37,7 @@ static int bnep_sock_release(struct socket *sock) { struct sock *sk = sock->sk; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (!sk) return 0; @@ -190,7 +190,7 @@ static int bnep_sock_create(struct net *net, struct socket *sock, int protocol, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index cd75e4d64b909..d09f976f35970 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c @@ -74,7 +74,7 @@ static struct cmtp_application *cmtp_application_add(struct cmtp_session *sessio { struct cmtp_application *app = kzalloc(sizeof(*app), GFP_KERNEL); - BT_DBG("session %p application %p appl %d", session, app, appl); + BT_DBG("session %pK application %pK appl %d", session, app, appl); if (!app) return NULL; @@ -89,7 +89,7 @@ static struct cmtp_application *cmtp_application_add(struct cmtp_session *sessio static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app) { - BT_DBG("session %p application %p", session, app); + BT_DBG("session %pK application %pK", session, app); if (app) { list_del(&app->list); @@ -137,7 +137,7 @@ static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb) { struct cmtp_scb *scb = (void *) skb->cb; - BT_DBG("session %p skb %p len %d", session, skb, skb->len); + BT_DBG("session %pK skb %pK len %d", session, skb, skb->len); scb->id = -1; scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3); @@ -154,7 +154,8 @@ static void cmtp_send_interopmsg(struct cmtp_session *session, struct sk_buff *skb; unsigned char *s; - BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum); + BT_DBG("session %pK subcmd 0x%02x appl %d msgnum %d", + session, subcmd, appl, msgnum); skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC); if (!skb) { @@ -190,7 +191,7 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s __u16 appl, msgnum, func, info; __u32 controller; - BT_DBG("session %p skb %p len %d", session, skb, skb->len); + BT_DBG("session %pK skb %pK len %d", session, skb, skb->len); switch (CAPIMSG_SUBCOMMAND(skb->data)) { case CAPI_CONF: @@ -329,7 +330,7 @@ void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb) __u16 appl; __u32 contr; - BT_DBG("session %p skb %p len %d", session, skb, skb->len); + BT_DBG("session %pK skb %pK len %d", session, skb, skb->len); if (skb->len < CAPI_MSG_BASELEN) return; @@ -373,7 +374,7 @@ void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb) static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) { - BT_DBG("ctrl %p data %p", ctrl, data); + BT_DBG("ctrl %pK data %pK", ctrl, data); return 0; } @@ -382,7 +383,7 @@ static void cmtp_reset_ctr(struct capi_ctr *ctrl) { struct cmtp_session *session = ctrl->driverdata; - BT_DBG("ctrl %p", ctrl); + BT_DBG("ctrl %pK", ctrl); capi_ctr_down(ctrl); @@ -399,8 +400,8 @@ static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_ unsigned char buf[8]; int err = 0, nconn, want = rp->level3cnt; - BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d", - ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen); + BT_DBG("ctrl %pK appl %d level3cnt %d datablkcnt %d datablklen %d", + ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen); application = cmtp_application_add(session, appl); if (!application) { @@ -464,7 +465,7 @@ static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl) struct cmtp_session *session = ctrl->driverdata; struct cmtp_application *application; - BT_DBG("ctrl %p appl %d", ctrl, appl); + BT_DBG("ctrl %pK appl %d", ctrl, appl); application = cmtp_application_get(session, CMTP_APPLID, appl); if (!application) { @@ -490,7 +491,7 @@ static u16 cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) __u16 appl; __u32 contr; - BT_DBG("ctrl %p skb %p", ctrl, skb); + BT_DBG("ctrl %pK skb %pK", ctrl, skb); appl = CAPIMSG_APPID(skb->data); contr = CAPIMSG_CONTROL(skb->data); @@ -555,7 +556,7 @@ int cmtp_attach_device(struct cmtp_session *session) unsigned char buf[4]; long ret; - BT_DBG("session %p", session); + BT_DBG("session %pK", session); capimsg_setu32(buf, 0, 0); @@ -597,7 +598,7 @@ int cmtp_attach_device(struct cmtp_session *session) session->num = session->ctrl.cnr; - BT_DBG("session %p num %d", session, session->num); + BT_DBG("session %pK num %d", session, session->num); capimsg_setu32(buf, 0, 1); @@ -618,7 +619,7 @@ int cmtp_attach_device(struct cmtp_session *session) void cmtp_detach_device(struct cmtp_session *session) { - BT_DBG("session %p", session); + BT_DBG("session %pK", session); detach_capi_ctr(&session->ctrl); } diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index e0a6ebf2baa6f..d74d9fe541189 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -108,7 +108,7 @@ static inline void cmtp_add_msgpart(struct cmtp_session *session, int id, const struct sk_buff *skb = session->reassembly[id], *nskb; int size; - BT_DBG("session %p buf %p count %d", session, buf, count); + BT_DBG("session %pK buf %pK count %d", session, buf, count); size = (skb) ? skb->len + count : count; @@ -133,7 +133,7 @@ static inline int cmtp_recv_frame(struct cmtp_session *session, struct sk_buff * __u8 hdr, hdrlen, id; __u16 len; - BT_DBG("session %p skb %p len %d", session, skb, skb->len); + BT_DBG("session %pK skb %pK len %d", session, skb, skb->len); while (skb->len > 0) { hdr = skb->data[0]; @@ -196,7 +196,7 @@ static int cmtp_send_frame(struct cmtp_session *session, unsigned char *data, in struct kvec iv = { data, len }; struct msghdr msg; - BT_DBG("session %p data %p len %d", session, data, len); + BT_DBG("session %pK data %pK len %d", session, data, len); if (!len) return 0; @@ -212,7 +212,7 @@ static void cmtp_process_transmit(struct cmtp_session *session) unsigned char *hdr; unsigned int size, tail; - BT_DBG("session %p", session); + BT_DBG("session %pK", session); nskb = alloc_skb(session->mtu, GFP_ATOMIC); if (!nskb) { @@ -282,7 +282,7 @@ static int cmtp_session(void *arg) struct sk_buff *skb; wait_queue_t wait; - BT_DBG("session %p", session); + BT_DBG("session %pK", session); set_user_nice(current, -15); diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c index d82787d417bdc..8d7d3c16c8b6f 100644 --- a/net/bluetooth/cmtp/sock.c +++ b/net/bluetooth/cmtp/sock.c @@ -50,7 +50,7 @@ static int cmtp_sock_release(struct socket *sock) { struct sock *sk = sock->sk; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (!sk) return 0; @@ -200,7 +200,7 @@ static int cmtp_sock_create(struct net *net, struct socket *sock, int protocol, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 44ed20c84745f..600a8acc61496 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -66,7 +66,7 @@ static void hci_acl_create_connection(struct hci_conn *conn) struct inquiry_entry *ie; struct hci_cp_create_conn cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); conn->state = BT_CONNECT; conn->out = true; @@ -110,7 +110,7 @@ static void hci_acl_create_connection_cancel(struct hci_conn *conn) { struct hci_cp_create_conn_cancel cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (conn->hdev->hci_ver < BLUETOOTH_VER_1_2) return; @@ -133,7 +133,7 @@ void hci_disconnect(struct hci_conn *conn, __u8 reason) { struct hci_cp_disconnect cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); conn->state = BT_DISCONN; @@ -146,7 +146,7 @@ static void hci_amp_disconn(struct hci_conn *conn, __u8 reason) { struct hci_cp_disconn_phy_link cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); conn->state = BT_DISCONN; @@ -161,7 +161,7 @@ static void hci_add_sco(struct hci_conn *conn, __u16 handle) struct hci_dev *hdev = conn->hdev; struct hci_cp_add_sco cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); conn->state = BT_CONNECT; conn->out = true; @@ -179,7 +179,7 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle) struct hci_dev *hdev = conn->hdev; struct hci_cp_setup_sync_conn cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); conn->state = BT_CONNECT; conn->out = true; @@ -223,7 +223,7 @@ void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], struct hci_dev *hdev = conn->hdev; struct hci_cp_le_start_enc cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); memset(&cp, 0, sizeof(cp)); @@ -243,7 +243,7 @@ void hci_sco_setup(struct hci_conn *conn, __u8 status) if (!sco) return; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (!status) { if (lmp_esco_capable(conn->hdev)) @@ -275,7 +275,7 @@ static void hci_conn_timeout(struct work_struct *work) struct hci_conn *conn = container_of(work, struct hci_conn, disc_work.work); - BT_DBG("hcon %p state %s", conn, state_to_string(conn->state)); + BT_DBG("hcon %pK state %s", conn, state_to_string(conn->state)); if (atomic_read(&conn->refcnt)) return; @@ -307,7 +307,7 @@ static void hci_conn_enter_sniff_mode(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; - BT_DBG("hcon %p mode %d", conn, conn->mode); + BT_DBG("hcon %pK mode %d", conn, conn->mode); if (test_bit(HCI_RAW, &hdev->flags)) return; @@ -345,7 +345,7 @@ static void hci_conn_idle(unsigned long arg) { struct hci_conn *conn = (void *) arg; - BT_DBG("hcon %p mode %d", conn, conn->mode); + BT_DBG("hcon %pK mode %d", conn, conn->mode); hci_conn_enter_sniff_mode(conn); } @@ -433,7 +433,7 @@ int hci_conn_del(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; - BT_DBG("%s hcon %p handle %d", hdev->name, conn, conn->handle); + BT_DBG("%s hcon %pK handle %d", hdev->name, conn, conn->handle); del_timer(&conn->idle_timer); @@ -650,7 +650,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, /* Check link security requirement */ int hci_conn_check_link_mode(struct hci_conn *conn) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (hci_conn_ssp_enabled(conn) && !(conn->link_mode & HCI_LM_ENCRYPT)) return 0; @@ -661,7 +661,7 @@ int hci_conn_check_link_mode(struct hci_conn *conn) /* Authenticate remote device */ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (conn->pending_sec_level > sec_level) sec_level = conn->pending_sec_level; @@ -698,7 +698,7 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) /* Encrypt the the link */ static void hci_conn_encrypt(struct hci_conn *conn) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) { struct hci_cp_set_conn_encrypt cp; @@ -712,7 +712,7 @@ static void hci_conn_encrypt(struct hci_conn *conn) /* Enable security */ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (conn->type == LE_LINK) return smp_conn_security(conn, sec_level); @@ -768,7 +768,7 @@ EXPORT_SYMBOL(hci_conn_security); /* Check secure link requirement */ int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (sec_level != BT_SECURITY_HIGH) return 1; /* Accept if non-secure is required */ @@ -783,7 +783,7 @@ EXPORT_SYMBOL(hci_conn_check_secure); /* Change link key */ int hci_conn_change_link_key(struct hci_conn *conn) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { struct hci_cp_change_conn_link_key cp; @@ -798,7 +798,7 @@ int hci_conn_change_link_key(struct hci_conn *conn) /* Switch role */ int hci_conn_switch_role(struct hci_conn *conn, __u8 role) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (!role && conn->link_mode & HCI_LM_MASTER) return 1; @@ -837,7 +837,7 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active) { struct hci_dev *hdev = conn->hdev; - BT_DBG("hcon %p mode %d", conn, conn->mode); + BT_DBG("hcon %pK mode %d", conn, conn->mode); if (test_bit(HCI_RAW, &hdev->flags)) return; @@ -1019,7 +1019,7 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn) struct hci_dev *hdev = conn->hdev; struct hci_chan *chan; - BT_DBG("%s hcon %p", hdev->name, conn); + BT_DBG("%s hcon %pK", hdev->name, conn); chan = kzalloc(sizeof(struct hci_chan), GFP_KERNEL); if (!chan) @@ -1039,7 +1039,7 @@ void hci_chan_del(struct hci_chan *chan) struct hci_conn *conn = chan->conn; struct hci_dev *hdev = conn->hdev; - BT_DBG("%s hcon %p chan %p", hdev->name, conn, chan); + BT_DBG("%s hcon %pK chan %pK", hdev->name, conn, chan); list_del_rcu(&chan->list); @@ -1055,7 +1055,7 @@ void hci_chan_list_flush(struct hci_conn *conn) { struct hci_chan *chan, *n; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); list_for_each_entry_safe(chan, n, &conn->chan_list, list) hci_chan_del(chan); diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index f91b3baf3e14a..3d8e183a5c3cf 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -771,7 +771,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *e; - BT_DBG("cache %p, %pMR", cache, bdaddr); + BT_DBG("cache %pK, %pMR", cache, bdaddr); list_for_each_entry(e, &cache->all, all) { if (!bacmp(&e->data.bdaddr, bdaddr)) @@ -787,7 +787,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *e; - BT_DBG("cache %p, %pMR", cache, bdaddr); + BT_DBG("cache %pK, %pMR", cache, bdaddr); list_for_each_entry(e, &cache->unknown, list) { if (!bacmp(&e->data.bdaddr, bdaddr)) @@ -804,7 +804,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *e; - BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); + BT_DBG("cache %pK bdaddr %pMR state %d", cache, bdaddr, state); list_for_each_entry(e, &cache->resolve, list) { if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) @@ -841,7 +841,7 @@ bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *ie; - BT_DBG("cache %p, %pMR", cache, &data->bdaddr); + BT_DBG("cache %pK, %pMR", cache, &data->bdaddr); hci_remove_remote_oob_data(hdev, &data->bdaddr); @@ -917,7 +917,7 @@ static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) copied++; } - BT_DBG("cache %p, copied %d", cache, copied); + BT_DBG("cache %pK, copied %d", cache, copied); return copied; } @@ -1114,7 +1114,7 @@ int hci_dev_open(__u16 dev) if (!hdev) return -ENODEV; - BT_DBG("%s %p", hdev->name, hdev); + BT_DBG("%s %pK", hdev->name, hdev); hci_req_lock(hdev); @@ -1203,7 +1203,7 @@ int hci_dev_open(__u16 dev) static int hci_dev_do_close(struct hci_dev *hdev) { - BT_DBG("%s %p", hdev->name, hdev); + BT_DBG("%s %pK", hdev->name, hdev); cancel_work_sync(&hdev->le_scan); @@ -1546,7 +1546,7 @@ static int hci_rfkill_set_block(void *data, bool blocked) { struct hci_dev *hdev = data; - BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); + BT_DBG("%pK name %s blocked %d", hdev, hdev->name, blocked); if (blocked) { set_bit(HCI_RFKILLED, &hdev->dev_flags); @@ -2215,7 +2215,7 @@ int hci_register_dev(struct hci_dev *hdev) snprintf(hdev->name, sizeof(hdev->name), "hci%d", id); hdev->id = id; - BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); + BT_DBG("%pK name %s bus %d", hdev, hdev->name, hdev->bus); write_lock(&hci_dev_list_lock); list_add(&hdev->list, &hci_dev_list); @@ -2284,7 +2284,7 @@ void hci_unregister_dev(struct hci_dev *hdev) { int i, id; - BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); + BT_DBG("%pK name %s bus %d", hdev, hdev->name, hdev->bus); set_bit(HCI_UNREGISTER, &hdev->dev_flags); @@ -2545,7 +2545,7 @@ EXPORT_SYMBOL(hci_recv_stream_fragment); int hci_register_cb(struct hci_cb *cb) { - BT_DBG("%p name %s", cb, cb->name); + BT_DBG("%pK name %s", cb, cb->name); write_lock(&hci_cb_list_lock); list_add(&cb->list, &hci_cb_list); @@ -2557,7 +2557,7 @@ EXPORT_SYMBOL(hci_register_cb); int hci_unregister_cb(struct hci_cb *cb) { - BT_DBG("%p name %s", cb, cb->name); + BT_DBG("%pK name %s", cb, cb->name); write_lock(&hci_cb_list_lock); list_del(&cb->list); @@ -2780,12 +2780,12 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, list = skb_shinfo(skb)->frag_list; if (!list) { /* Non fragmented */ - BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); + BT_DBG("%s nonfrag skb %pK len %d", hdev->name, skb, skb->len); skb_queue_tail(queue, skb); } else { /* Fragmented */ - BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); + BT_DBG("%s frag %pK len %d", hdev->name, skb, skb->len); skb_shinfo(skb)->frag_list = NULL; @@ -2803,7 +2803,7 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; hci_add_acl_hdr(skb, conn->handle, flags); - BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); + BT_DBG("%s frag %pK len %d", hdev->name, skb, skb->len); __skb_queue_tail(queue, skb); } while (list); @@ -2816,7 +2816,7 @@ void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) { struct hci_dev *hdev = chan->conn->hdev; - BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); + BT_DBG("%s chan %pK flags 0x%4.4x", hdev->name, chan, flags); skb->dev = (void *) hdev; @@ -2906,7 +2906,7 @@ static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, } else *quote = 0; - BT_DBG("conn %p quote %d", conn, *quote); + BT_DBG("conn %pK quote %d", conn, *quote); return conn; } @@ -3009,7 +3009,7 @@ static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, q = cnt / num; *quote = q ? q : 1; - BT_DBG("chan %p quote %d", chan, *quote); + BT_DBG("chan %pK quote %d", chan, *quote); return chan; } @@ -3051,7 +3051,7 @@ static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) skb->priority = HCI_PRIO_MAX - 1; - BT_DBG("chan %p skb %p promoted to %d", chan, skb, + BT_DBG("chan %pK skb %pK promoted to %d", chan, skb, skb->priority); } @@ -3093,7 +3093,7 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev) (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { u32 priority = (skb_peek(&chan->data_q))->priority; while (quote-- && (skb = skb_peek(&chan->data_q))) { - BT_DBG("chan %p skb %p len %d priority %u", chan, skb, + BT_DBG("chan %pK skb %pK len %d priority %u", chan, skb, skb->len, skb->priority); /* Stop if priority has changed */ @@ -3141,7 +3141,7 @@ static void hci_sched_acl_blk(struct hci_dev *hdev) while (quote > 0 && (skb = skb_peek(&chan->data_q))) { int blocks; - BT_DBG("chan %p skb %p len %d priority %u", chan, skb, + BT_DBG("chan %pK skb %pK len %d priority %u", chan, skb, skb->len, skb->priority); /* Stop if priority has changed */ @@ -3209,7 +3209,7 @@ static void hci_sched_sco(struct hci_dev *hdev) while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { while (quote-- && (skb = skb_dequeue(&conn->data_q))) { - BT_DBG("skb %p len %d", skb, skb->len); + BT_DBG("skb %pK len %d", skb, skb->len); hci_send_frame(skb); conn->sent++; @@ -3233,7 +3233,7 @@ static void hci_sched_esco(struct hci_dev *hdev) while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, "e))) { while (quote-- && (skb = skb_dequeue(&conn->data_q))) { - BT_DBG("skb %p len %d", skb, skb->len); + BT_DBG("skb %pK len %d", skb, skb->len); hci_send_frame(skb); conn->sent++; @@ -3267,7 +3267,7 @@ static void hci_sched_le(struct hci_dev *hdev) while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { u32 priority = (skb_peek(&chan->data_q))->priority; while (quote-- && (skb = skb_peek(&chan->data_q))) { - BT_DBG("chan %p skb %p len %d priority %u", chan, skb, + BT_DBG("chan %pK skb %pK len %d priority %u", chan, skb, skb->len, skb->priority); /* Stop if priority has changed */ diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 9918688c78995..39f900d199ff1 100755 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1106,7 +1106,7 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); - BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn); + BT_DBG("%s bdaddr %pMR hcon %pK", hdev->name, &cp->bdaddr, conn); if (status) { if (conn && conn->state == BT_CONNECT) { @@ -1535,7 +1535,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) return; } - BT_DBG("%s bdaddr %pMR conn %p", hdev->name, &conn->dst, conn); + BT_DBG("%s bdaddr %pMR conn %pK", hdev->name, &conn->dst, conn); conn->state = BT_CLOSED; mgmt_connect_failed(hdev, &conn->dst, conn->type, @@ -2533,7 +2533,7 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) break; default: - BT_ERR("Unknown type %d conn %p", conn->type, conn); + BT_ERR("Unknown type %d conn %pK", conn->type, conn); break; } } @@ -2604,7 +2604,7 @@ static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) break; default: - BT_ERR("Unknown type %d conn %p", conn->type, conn); + BT_ERR("Unknown type %d conn %pK", conn->type, conn); break; } } @@ -3488,7 +3488,7 @@ static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hchan->handle = le16_to_cpu(ev->handle); - BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan); + BT_DBG("hcon %pK mgr %pK hchan %pK", hcon, hcon->amp_mgr, hchan); mgr = hcon->amp_mgr; if (mgr && mgr->bredr_chan) { diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index fa4bf66314255..4f5acc0247025 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -72,7 +72,7 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) struct sock *sk; struct sk_buff *skb_copy = NULL; - BT_DBG("hdev %p len %d", hdev, skb->len); + BT_DBG("hdev %pK len %d", hdev, skb->len); read_lock(&hci_sk_list.lock); @@ -180,7 +180,7 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb) if (!atomic_read(&monitor_promisc)) return; - BT_DBG("hdev %p len %d", hdev, skb->len); + BT_DBG("hdev %pK len %d", hdev, skb->len); switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: @@ -413,7 +413,7 @@ static int hci_sock_release(struct socket *sock) struct sock *sk = sock->sk; struct hci_dev *hdev; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (!sk) return 0; @@ -590,7 +590,7 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, struct hci_dev *hdev = NULL; int len, err = 0; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (!addr) return -EINVAL; @@ -679,7 +679,7 @@ static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, struct sock *sk = sock->sk; struct hci_dev *hdev = hci_pi(sk)->hdev; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (!hdev) return -EBADFD; @@ -740,7 +740,7 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct sk_buff *skb; int copied, err; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (flags & (MSG_OOB)) return -EOPNOTSUPP; @@ -784,7 +784,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct sk_buff *skb; int err; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (msg->msg_flags & MSG_OOB) return -EOPNOTSUPP; @@ -888,7 +888,7 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname, struct sock *sk = sock->sk; int err = 0, opt = 0; - BT_DBG("sk %p, opt %d", sk, optname); + BT_DBG("sk %pK, opt %d", sk, optname); lock_sock(sk); @@ -971,7 +971,7 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname, struct sock *sk = sock->sk; int len, opt, err = 0; - BT_DBG("sk %p, opt %d", sk, optname); + BT_DBG("sk %pK, opt %d", sk, optname); if (get_user(len, optlen)) return -EFAULT; @@ -1061,7 +1061,7 @@ static int hci_sock_create(struct net *net, struct socket *sock, int protocol, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 7ad6ecf36f20a..1c207bf0afec4 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -103,7 +103,7 @@ void hci_conn_init_sysfs(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); conn->dev.type = &bt_link; conn->dev.class = bt_class; @@ -116,7 +116,7 @@ void hci_conn_add_sysfs(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); @@ -547,7 +547,7 @@ int hci_add_sysfs(struct hci_dev *hdev) struct device *dev = &hdev->dev; int err; - BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); + BT_DBG("%pK name %s bus %d", hdev, hdev->name, hdev->bus); dev_set_name(dev, "%s", hdev->name); @@ -577,7 +577,7 @@ int hci_add_sysfs(struct hci_dev *hdev) void hci_del_sysfs(struct hci_dev *hdev) { - BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); + BT_DBG("%pK name %s bus %d", hdev, hdev->name, hdev->bus); debugfs_remove_recursive(hdev->debugfs); diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index b5cfba13bd379..5afd337cfa075 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -106,7 +106,7 @@ static int hidp_send_message(struct hidp_session *session, struct socket *sock, struct sk_buff *skb; struct sock *sk = sock->sk; - BT_DBG("session %p data %p size %d", session, data, size); + BT_DBG("session %pK data %pK size %d", session, data, size); if (atomic_read(&session->terminate)) return -EIO; @@ -150,7 +150,7 @@ static int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned char newleds; unsigned char hdr, data[2]; - BT_DBG("session %p type %d code %d value %d", + BT_DBG("session %pK type %d code %d value %d", session, type, code, value); if (type != EV_LED) @@ -414,7 +414,7 @@ static void hidp_del_timer(struct hidp_session *session) static void hidp_process_handshake(struct hidp_session *session, unsigned char param) { - BT_DBG("session %p param 0x%02x", session, param); + BT_DBG("session %pK param 0x%02x", session, param); session->output_report_success = 0; /* default condition */ switch (param) { @@ -457,7 +457,7 @@ static void hidp_process_handshake(struct hidp_session *session, static void hidp_process_hid_control(struct hidp_session *session, unsigned char param) { - BT_DBG("session %p param 0x%02x", session, param); + BT_DBG("session %pK param 0x%02x", session, param); if (param == HIDP_CTRL_VIRTUAL_CABLE_UNPLUG) { /* Flush the transmit queues */ @@ -473,7 +473,8 @@ static int hidp_process_data(struct hidp_session *session, struct sk_buff *skb, unsigned char param) { int done_with_skb = 1; - BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param); + BT_DBG("session %pK skb %pK len %d param 0x%02x", + session, skb, skb->len, param); switch (param) { case HIDP_DATA_RTYPE_INPUT: @@ -517,7 +518,7 @@ static void hidp_recv_ctrl_frame(struct hidp_session *session, unsigned char hdr, type, param; int free_skb = 1; - BT_DBG("session %p skb %p len %d", session, skb, skb->len); + BT_DBG("session %pK skb %pK len %d", session, skb, skb->len); hdr = skb->data[0]; skb_pull(skb, 1); @@ -553,7 +554,7 @@ static void hidp_recv_intr_frame(struct hidp_session *session, { unsigned char hdr; - BT_DBG("session %p skb %p len %d", session, skb, skb->len); + BT_DBG("session %pK skb %pK len %d", session, skb, skb->len); hdr = skb->data[0]; skb_pull(skb, 1); @@ -580,7 +581,7 @@ static int hidp_send_frame(struct socket *sock, unsigned char *data, int len) struct kvec iv = { data, len }; struct msghdr msg; - BT_DBG("sock %p data %p len %d", sock, data, len); + BT_DBG("sock %pK data %pK len %d", sock, data, len); if (!len) return 0; @@ -598,7 +599,7 @@ static void hidp_process_transmit(struct hidp_session *session, struct sk_buff *skb; int ret; - BT_DBG("session %p", session); + BT_DBG("session %pK", session); while ((skb = skb_dequeue(transmit))) { ret = hidp_send_frame(sock, skb->data, skb->len); @@ -1192,7 +1193,7 @@ static int hidp_session_thread(void *arg) struct hidp_session *session = arg; wait_queue_t ctrl_wait, intr_wait; - BT_DBG("session %p", session); + BT_DBG("session %pK", session); /* initialize runtime environment */ hidp_session_get(session); diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c index cb3fdde1968a0..5b7abfad038b3 100644 --- a/net/bluetooth/hidp/sock.c +++ b/net/bluetooth/hidp/sock.c @@ -33,7 +33,7 @@ static int hidp_sock_release(struct socket *sock) { struct sock *sk = sock->sk; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (!sk) return 0; @@ -230,7 +230,7 @@ static int hidp_sock_create(struct net *net, struct socket *sock, int protocol, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 79a680a122691..03c52804c3dcf 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -212,7 +212,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn) static void __l2cap_state_change(struct l2cap_chan *chan, int state) { - BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state), + BT_DBG("chan %pK %s -> %s", chan, state_to_string(chan->state), state_to_string(state)); chan->state = state; @@ -400,7 +400,7 @@ static void l2cap_chan_timeout(struct work_struct *work) struct l2cap_conn *conn = chan->conn; int reason; - BT_DBG("chan %p state %s", chan, state_to_string(chan->state)); + BT_DBG("chan %pK state %s", chan, state_to_string(chan->state)); mutex_lock(&conn->chan_lock); l2cap_chan_lock(chan); @@ -446,7 +446,7 @@ struct l2cap_chan *l2cap_chan_create(void) /* This flag is cleared in l2cap_chan_ready() */ set_bit(CONF_NOT_COMPLETE, &chan->conf_state); - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); return chan; } @@ -455,7 +455,7 @@ static void l2cap_chan_destroy(struct kref *kref) { struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref); - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); write_lock(&chan_list_lock); list_del(&chan->global_l); @@ -466,14 +466,14 @@ static void l2cap_chan_destroy(struct kref *kref) void l2cap_chan_hold(struct l2cap_chan *c) { - BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount)); + BT_DBG("chan %pK orig refcnt %d", c, atomic_read(&c->kref.refcount)); kref_get(&c->kref); } void l2cap_chan_put(struct l2cap_chan *c) { - BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount)); + BT_DBG("chan %pK orig refcnt %d", c, atomic_read(&c->kref.refcount)); kref_put(&c->kref, l2cap_chan_destroy); } @@ -492,7 +492,7 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan) void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) { - BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, + BT_DBG("conn %pK, psm 0x%2.2x, dcid 0x%4.4x", conn, __le16_to_cpu(chan->psm), chan->dcid); conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM; @@ -559,7 +559,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) __clear_chan_timer(chan); - BT_DBG("chan %p, conn %p, err %d", chan, conn, err); + BT_DBG("chan %pK, conn %pK, err %d", chan, conn, err); if (conn) { struct amp_mgr *mgr = conn->hcon->amp_mgr; @@ -580,7 +580,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) if (chan->hs_hchan) { struct hci_chan *hs_hchan = chan->hs_hchan; - BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan); + BT_DBG("chan %pK disconnect hs_hchan %pK", chan, hs_hchan); amp_disconnect_logical_link(hs_hchan); } @@ -618,7 +618,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) struct l2cap_conn *conn = chan->conn; struct sock *sk = chan->sk; - BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state), + BT_DBG("chan %pK state %s sk %pK", chan, state_to_string(chan->state), sk); switch (chan->state) { @@ -770,7 +770,7 @@ static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) struct hci_conn *hcon = chan->conn->hcon; u16 flags; - BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len, + BT_DBG("chan %pK, skb %pK len %d priority %u", chan, skb, skb->len, skb->priority); if (chan->hs_hcon && !__chan_is_moving(chan)) { @@ -952,7 +952,7 @@ static void l2cap_send_sframe(struct l2cap_chan *chan, struct sk_buff *skb; u32 control_field; - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); if (!control->sframe) return; @@ -991,7 +991,7 @@ static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll) { struct l2cap_ctrl control; - BT_DBG("chan %p, poll %d", chan, poll); + BT_DBG("chan %pK, poll %d", chan, poll); memset(&control, 0, sizeof(control)); control.sframe = 1; @@ -1062,7 +1062,7 @@ static void l2cap_move_setup(struct l2cap_chan *chan) { struct sk_buff *skb; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); if (chan->mode != L2CAP_MODE_ERTM) return; @@ -1096,7 +1096,7 @@ static void l2cap_move_setup(struct l2cap_chan *chan) static void l2cap_move_done(struct l2cap_chan *chan) { u8 move_role = chan->move_role; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); chan->move_state = L2CAP_MOVE_STABLE; chan->move_role = L2CAP_MOVE_ROLE_NONE; @@ -1129,7 +1129,7 @@ static void l2cap_chan_ready(struct l2cap_chan *chan) static void l2cap_start_connection(struct l2cap_chan *chan) { if (__amp_capable(chan)) { - BT_DBG("chan %p AMP capable: discover AMPs", chan); + BT_DBG("chan %pK AMP capable: discover AMPs", chan); a2mp_discover_amp(chan); } else { l2cap_send_conn_req(chan); @@ -1219,7 +1219,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) { struct l2cap_chan *chan, *tmp; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); mutex_lock(&conn->chan_lock); @@ -1381,7 +1381,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) struct l2cap_chan *chan; struct hci_conn *hcon = conn->hcon; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); if (!hcon->out && hcon->type == LE_LINK) l2cap_le_conn_ready(conn); @@ -1426,7 +1426,7 @@ static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err) { struct l2cap_chan *chan; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); mutex_lock(&conn->chan_lock); @@ -1540,7 +1540,7 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) if (!conn) return; - BT_DBG("hcon %p conn %p, err %d", hcon, conn, err); + BT_DBG("hcon %pK conn %pK, err %d", hcon, conn, err); kfree_skb(conn->rx_skb); @@ -1583,7 +1583,7 @@ static void security_timeout(struct work_struct *work) struct l2cap_conn *conn = container_of(work, struct l2cap_conn, security_timer.work); - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) { smp_chan_destroy(conn); @@ -1615,7 +1615,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon) hci_conn_get(conn->hcon); conn->hchan = hchan; - BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan); + BT_DBG("hcon %pK conn %pK hchan %pK", hcon, conn, hchan); switch (hcon->type) { case LE_LINK: @@ -1891,7 +1891,7 @@ static void l2cap_monitor_timeout(struct work_struct *work) struct l2cap_chan *chan = container_of(work, struct l2cap_chan, monitor_timer.work); - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); l2cap_chan_lock(chan); @@ -1912,7 +1912,7 @@ static void l2cap_retrans_timeout(struct work_struct *work) struct l2cap_chan *chan = container_of(work, struct l2cap_chan, retrans_timer.work); - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); l2cap_chan_lock(chan); @@ -1933,7 +1933,7 @@ static void l2cap_streaming_send(struct l2cap_chan *chan, struct sk_buff *skb; struct l2cap_ctrl *control; - BT_DBG("chan %p, skbs %p", chan, skbs); + BT_DBG("chan %pK, skbs %pK", chan, skbs); if (__chan_is_moving(chan)) return; @@ -1972,7 +1972,7 @@ static int l2cap_ertm_send(struct l2cap_chan *chan) struct l2cap_ctrl *control; int sent = 0; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); if (chan->state != BT_CONNECTED) return -ENOTCONN; @@ -2043,7 +2043,7 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan) struct sk_buff *tx_skb; u16 seq; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) return; @@ -2118,7 +2118,7 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan) static void l2cap_retransmit(struct l2cap_chan *chan, struct l2cap_ctrl *control) { - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); l2cap_seq_list_append(&chan->retrans_list, control->reqseq); l2cap_ertm_resend(chan); @@ -2129,7 +2129,7 @@ static void l2cap_retransmit_all(struct l2cap_chan *chan, { struct sk_buff *skb; - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); if (control->poll) set_bit(CONN_SEND_FBIT, &chan->conn_state); @@ -2165,7 +2165,7 @@ static void l2cap_send_ack(struct l2cap_chan *chan) chan->last_acked_seq); int threshold; - BT_DBG("chan %p last_acked_seq %d buffer_seq %d", + BT_DBG("chan %pK last_acked_seq %d buffer_seq %d", chan, chan->last_acked_seq, chan->buffer_seq); memset(&control, 0, sizeof(control)); @@ -2262,7 +2262,7 @@ static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE; struct l2cap_hdr *lh; - BT_DBG("chan %p len %zu priority %u", chan, len, priority); + BT_DBG("chan %pK len %zu priority %u", chan, len, priority); count = min_t(unsigned int, (conn->mtu - hlen), len); @@ -2296,7 +2296,7 @@ static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, int err, count; struct l2cap_hdr *lh; - BT_DBG("chan %p len %zu", chan, len); + BT_DBG("chan %pK len %zu", chan, len); count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len); @@ -2329,7 +2329,7 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, int err, count, hlen; struct l2cap_hdr *lh; - BT_DBG("chan %p len %zu", chan, len); + BT_DBG("chan %pK len %zu", chan, len); if (!conn) return ERR_PTR(-ENOTCONN); @@ -2383,7 +2383,7 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, size_t pdu_len; u8 sar; - BT_DBG("chan %p, msg %p, len %zu", chan, msg, len); + BT_DBG("chan %pK, msg %pK, len %zu", chan, msg, len); /* It is critical that ERTM PDUs fit in a single HCI fragment, * so fragmented skbs are not used. The HCI layer's handling @@ -2529,7 +2529,7 @@ static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq) struct l2cap_ctrl control; u16 seq; - BT_DBG("chan %p, txseq %u", chan, txseq); + BT_DBG("chan %pK, txseq %u", chan, txseq); memset(&control, 0, sizeof(control)); control.sframe = 1; @@ -2551,7 +2551,7 @@ static void l2cap_send_srej_tail(struct l2cap_chan *chan) { struct l2cap_ctrl control; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR) return; @@ -2569,7 +2569,7 @@ static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq) u16 initial_head; u16 seq; - BT_DBG("chan %p, txseq %u", chan, txseq); + BT_DBG("chan %pK, txseq %u", chan, txseq); memset(&control, 0, sizeof(control)); control.sframe = 1; @@ -2594,7 +2594,7 @@ static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq) struct sk_buff *acked_skb; u16 ackseq; - BT_DBG("chan %p, reqseq %u", chan, reqseq); + BT_DBG("chan %pK, reqseq %u", chan, reqseq); if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq) return; @@ -2623,7 +2623,7 @@ static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq) static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan) { - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); chan->expected_tx_seq = chan->buffer_seq; l2cap_seq_list_clear(&chan->srej_list); @@ -2635,7 +2635,7 @@ static void l2cap_tx_state_xmit(struct l2cap_chan *chan, struct l2cap_ctrl *control, struct sk_buff_head *skbs, u8 event) { - BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs, + BT_DBG("chan %pK, control %pK, skbs %pK, event %d", chan, control, skbs, event); switch (event) { @@ -2707,7 +2707,7 @@ static void l2cap_tx_state_wait_f(struct l2cap_chan *chan, struct l2cap_ctrl *control, struct sk_buff_head *skbs, u8 event) { - BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs, + BT_DBG("chan %pK, control %pK, skbs %pK, event %d", chan, control, skbs, event); switch (event) { @@ -2784,7 +2784,7 @@ static void l2cap_tx_state_wait_f(struct l2cap_chan *chan, static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, struct sk_buff_head *skbs, u8 event) { - BT_DBG("chan %p, control %p, skbs %p, event %d, state %d", + BT_DBG("chan %pK, control %pK, skbs %pK, event %d, state %d", chan, control, skbs, event, chan->tx_state); switch (chan->tx_state) { @@ -2803,14 +2803,14 @@ static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, static void l2cap_pass_to_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control) { - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT); } static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan, struct l2cap_ctrl *control) { - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT); } @@ -2820,7 +2820,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) struct sk_buff *nskb; struct l2cap_chan *chan; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); mutex_lock(&conn->chan_lock); @@ -2852,7 +2852,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code, struct l2cap_hdr *lh; int len, count; - BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u", + BT_DBG("conn %pK, code 0x%2.2x, ident 0x%2.2x, len %u", conn, code, ident, dlen); if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE) @@ -3011,7 +3011,7 @@ static void l2cap_ack_timeout(struct work_struct *work) ack_timer.work); u16 frames_to_ack; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); l2cap_chan_lock(chan); @@ -3153,7 +3153,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) void *ptr = req->data; u16 size; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); if (chan->num_conf_req || chan->num_conf_rsp) goto done; @@ -3279,7 +3279,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) u16 result = L2CAP_CONF_SUCCESS; u16 size; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); while (len >= L2CAP_CONF_OPT_SIZE) { len -= l2cap_get_conf_opt(&req, &type, &olen, &val); @@ -3488,7 +3488,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; struct l2cap_conf_efs efs; - BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data); + BT_DBG("chan %pK, rsp %pK, len %d, req %pK", chan, rsp, len, data); while (len >= L2CAP_CONF_OPT_SIZE) { len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); @@ -3593,7 +3593,7 @@ static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, struct l2cap_conf_rsp *rsp = data; void *ptr = rsp->data; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); rsp->scid = cpu_to_le16(chan->dcid); rsp->result = cpu_to_le16(result); @@ -3619,7 +3619,7 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan) else rsp_code = L2CAP_CONN_RSP; - BT_DBG("chan %p rsp_code %u", chan, rsp_code); + BT_DBG("chan %pK rsp_code %u", chan, rsp_code); l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp); @@ -3647,7 +3647,7 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW), }; - BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len); + BT_DBG("chan %pK, rsp %pK, len %d", chan, rsp, len); if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING)) return; @@ -3948,7 +3948,7 @@ static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data, { struct l2cap_conn *conn = chan->conn; - BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident, + BT_DBG("conn %pK chan %pK ident %d flags 0x%4.4x", conn, chan, ident, flags); clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state); @@ -4442,7 +4442,8 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn, return -EFAULT; } - BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon); + BT_DBG("mgr %pK bredr_chan %pK hs_hcon %pK", + mgr, chan, hs_hcon); mgr->bredr_chan = chan; chan->hs_hcon = hs_hcon; @@ -4471,7 +4472,7 @@ static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id) struct l2cap_move_chan_req req; u8 ident; - BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id); + BT_DBG("chan %pK, dest_amp_id %d", chan, dest_amp_id); ident = l2cap_get_ident(chan->conn); chan->ident = ident; @@ -4489,7 +4490,7 @@ static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result) { struct l2cap_move_chan_rsp rsp; - BT_DBG("chan %p, result 0x%4.4x", chan, result); + BT_DBG("chan %pK, result 0x%4.4x", chan, result); rsp.icid = cpu_to_le16(chan->dcid); rsp.result = cpu_to_le16(result); @@ -4502,7 +4503,7 @@ static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result) { struct l2cap_move_chan_cfm cfm; - BT_DBG("chan %p, result 0x%4.4x", chan, result); + BT_DBG("chan %pK, result 0x%4.4x", chan, result); chan->ident = l2cap_get_ident(chan->conn); @@ -4519,7 +4520,7 @@ static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid) { struct l2cap_move_chan_cfm cfm; - BT_DBG("conn %p, icid 0x%4.4x", conn, icid); + BT_DBG("conn %pK, icid 0x%4.4x", conn, icid); cfm.icid = cpu_to_le16(icid); cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED); @@ -4639,7 +4640,7 @@ static void l2cap_logical_finish_move(struct l2cap_chan *chan, void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, u8 status) { - BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status); + BT_DBG("chan %pK, hchan %pK, status %d", chan, hchan, status); if (status) { l2cap_logical_fail(chan); @@ -4658,7 +4659,7 @@ void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, void l2cap_move_start(struct l2cap_chan *chan) { - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); if (chan->local_amp_id == HCI_BREDR_ID) { if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED) @@ -4678,7 +4679,7 @@ void l2cap_move_start(struct l2cap_chan *chan) static void l2cap_do_create(struct l2cap_chan *chan, int result, u8 local_amp_id, u8 remote_amp_id) { - BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state), + BT_DBG("chan %pK state %s %u -> %u", chan, state_to_string(chan->state), local_amp_id, remote_amp_id); chan->fcs = L2CAP_FCS_NONE; @@ -4787,7 +4788,7 @@ void __l2cap_physical_cfm(struct l2cap_chan *chan, int result) u8 local_amp_id = chan->local_amp_id; u8 remote_amp_id = chan->remote_amp_id; - BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d", + BT_DBG("chan %pK, result %d, local_amp_id %d, remote_amp_id %d", chan, result, local_amp_id, remote_amp_id); if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) { @@ -5369,7 +5370,7 @@ static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) { struct l2cap_ctrl control; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); memset(&control, 0, sizeof(control)); control.sframe = 1; @@ -5524,7 +5525,7 @@ static int l2cap_rx_queued_iframes(struct l2cap_chan *chan) * until a gap is encountered. */ - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { struct sk_buff *skb; @@ -5556,7 +5557,7 @@ static void l2cap_handle_srej(struct l2cap_chan *chan, { struct sk_buff *skb; - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); if (control->reqseq == chan->next_tx_seq) { BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq); @@ -5614,7 +5615,7 @@ static void l2cap_handle_rej(struct l2cap_chan *chan, { struct sk_buff *skb; - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); if (control->reqseq == chan->next_tx_seq) { BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq); @@ -5648,7 +5649,7 @@ static void l2cap_handle_rej(struct l2cap_chan *chan, static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq) { - BT_DBG("chan %p, txseq %d", chan, txseq); + BT_DBG("chan %pK, txseq %d", chan, txseq); BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq, chan->expected_tx_seq); @@ -5739,7 +5740,7 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan, int err = 0; bool skb_in_use = 0; - BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb, + BT_DBG("chan %pK, control %pK, skb %pK, event %d", chan, control, skb, event); switch (event) { @@ -5795,7 +5796,7 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan, */ skb_queue_tail(&chan->srej_q, skb); skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, + BT_DBG("Queued %pK (queue len %d)", skb, skb_queue_len(&chan->srej_q)); clear_bit(CONN_SREJ_ACT, &chan->conn_state); @@ -5859,7 +5860,7 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan, } if (skb && !skb_in_use) { - BT_DBG("Freeing %p", skb); + BT_DBG("Freeing %pK", skb); kfree_skb(skb); } @@ -5874,7 +5875,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, u16 txseq = control->txseq; bool skb_in_use = 0; - BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb, + BT_DBG("chan %pK, control %pK, skb %pK, event %d", chan, control, skb, event); switch (event) { @@ -5885,7 +5886,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, l2cap_pass_to_tx(chan, control); skb_queue_tail(&chan->srej_q, skb); skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, + BT_DBG("Queued %pK (queue len %d)", skb, skb_queue_len(&chan->srej_q)); chan->expected_tx_seq = __next_seq(chan, txseq); @@ -5896,7 +5897,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, l2cap_pass_to_tx(chan, control); skb_queue_tail(&chan->srej_q, skb); skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, + BT_DBG("Queued %pK (queue len %d)", skb, skb_queue_len(&chan->srej_q)); err = l2cap_rx_queued_iframes(chan); @@ -5911,7 +5912,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, */ skb_queue_tail(&chan->srej_q, skb); skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, + BT_DBG("Queued %pK (queue len %d)", skb, skb_queue_len(&chan->srej_q)); l2cap_pass_to_tx(chan, control); @@ -5925,7 +5926,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, */ skb_queue_tail(&chan->srej_q, skb); skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, + BT_DBG("Queued %pK (queue len %d)", skb, skb_queue_len(&chan->srej_q)); l2cap_pass_to_tx(chan, control); @@ -6002,7 +6003,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, } if (skb && !skb_in_use) { - BT_DBG("Freeing %p", skb); + BT_DBG("Freeing %pK", skb); kfree_skb(skb); } @@ -6011,7 +6012,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, static int l2cap_finish_move(struct l2cap_chan *chan) { - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); chan->rx_state = L2CAP_RX_STATE_RECV; @@ -6029,7 +6030,7 @@ static int l2cap_rx_state_wait_p(struct l2cap_chan *chan, { int err; - BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb, + BT_DBG("chan %pK, control %pK, skb %pK, event %d", chan, control, skb, event); if (!control->poll) @@ -6113,7 +6114,7 @@ static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, { int err = 0; - BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan, + BT_DBG("chan %pK, control %pK, skb %pK, event %d, state %d", chan, control, skb, event, chan->rx_state); if (__valid_reqseq(chan, control->reqseq)) { @@ -6150,7 +6151,7 @@ static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, { int err = 0; - BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb, + BT_DBG("chan %pK, control %pK, skb %pK, state %d", chan, control, skb, chan->rx_state); if (l2cap_classify_txseq(chan, control->txseq) == @@ -6172,7 +6173,7 @@ static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, chan->sdu_len = 0; if (skb) { - BT_DBG("Freeing %p", skb); + BT_DBG("Freeing %pK", skb); kfree_skb(skb); } } @@ -6294,7 +6295,7 @@ static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid, } } - BT_DBG("chan %p, len %d", chan, skb->len); + BT_DBG("chan %pK, len %d", chan, skb->len); if (chan->state != BT_CONNECTED) goto drop; @@ -6319,7 +6320,7 @@ static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid, goto done; default: - BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode); + BT_DBG("chan %pK: bad mode 0x%2.2x", chan, chan->mode); break; } @@ -6339,7 +6340,7 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, if (!chan) goto drop; - BT_DBG("chan %p, len %d", chan, skb->len); + BT_DBG("chan %pK, len %d", chan, skb->len); if (chan->state != BT_BOUND && chan->state != BT_CONNECTED) goto drop; @@ -6364,7 +6365,7 @@ static void l2cap_att_channel(struct l2cap_conn *conn, if (!chan) goto drop; - BT_DBG("chan %p, len %d", chan, skb->len); + BT_DBG("chan %pK, len %d", chan, skb->len); if (chan->state != BT_BOUND && chan->state != BT_CONNECTED) goto drop; @@ -6460,7 +6461,7 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status) { struct l2cap_conn *conn; - BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status); + BT_DBG("hcon %pK bdaddr %pMR status %d", hcon, &hcon->dst, status); if (!status) { conn = l2cap_conn_add(hcon); @@ -6475,7 +6476,7 @@ int l2cap_disconn_ind(struct hci_conn *hcon) { struct l2cap_conn *conn = hcon->l2cap_data; - BT_DBG("hcon %p", hcon); + BT_DBG("hcon %pK", hcon); if (!conn) return HCI_ERROR_REMOTE_USER_TERM; @@ -6484,7 +6485,7 @@ int l2cap_disconn_ind(struct hci_conn *hcon) void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason) { - BT_DBG("hcon %p reason %d", hcon, reason); + BT_DBG("hcon %pK reason %d", hcon, reason); l2cap_conn_del(hcon, bt_to_errno(reason)); } @@ -6513,7 +6514,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) if (!conn) return 0; - BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt); + BT_DBG("conn %pK status 0x%2.2x encrypt %u", conn, status, encrypt); if (hcon->type == LE_LINK) { if (!status && encrypt) @@ -6526,7 +6527,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) list_for_each_entry(chan, &conn->chan_l, list) { l2cap_chan_lock(chan); - BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid, + BT_DBG("chan %pK scid 0x%4.4x state %s", chan, chan->scid, state_to_string(chan->state)); if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) { @@ -6637,7 +6638,7 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) if (!conn) goto drop; - BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags); + BT_DBG("conn %pK len %d flags 0x%x", conn, skb->len, flags); switch (flags) { case ACL_START: diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 302d29b3744d4..c676811c25797 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -56,7 +56,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) struct sockaddr_l2 la; int len, err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (!addr || addr->sa_family != AF_BLUETOOTH) return -EINVAL; @@ -121,7 +121,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, struct sockaddr_l2 la; int len, err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (!addr || alen < sizeof(addr->sa_family) || addr->sa_family != AF_BLUETOOTH) @@ -155,7 +155,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog) struct l2cap_chan *chan = l2cap_pi(sk)->chan; int err = 0; - BT_DBG("sk %p backlog %d", sk, backlog); + BT_DBG("sk %pK backlog %d", sk, backlog); lock_sock(sk); @@ -205,7 +205,7 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); - BT_DBG("sk %p timeo %ld", sk, timeo); + BT_DBG("sk %pK timeo %ld", sk, timeo); /* Wait for an incoming connection. (wake-one). */ add_wait_queue_exclusive(sk_sleep(sk), &wait); @@ -243,7 +243,7 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, newsock->state = SS_CONNECTED; - BT_DBG("new socket %p", nsk); + BT_DBG("new socket %pK", nsk); done: release_sock(sk); @@ -257,7 +257,7 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, struct sock *sk = sock->sk; struct l2cap_chan *chan = l2cap_pi(sk)->chan; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); memset(la, 0, sizeof(struct sockaddr_l2)); addr->sa_family = AF_BLUETOOTH; @@ -286,7 +286,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, int len, err = 0; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (get_user(len, optlen)) return -EFAULT; @@ -373,7 +373,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, struct bt_power pwr; int len, err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (level == SOL_L2CAP) return l2cap_sock_getsockopt_old(sock, optname, optval, optlen); @@ -488,7 +488,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, int len, err = 0; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); lock_sock(sk); @@ -590,7 +590,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, int len, err = 0; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (level == SOL_L2CAP) return l2cap_sock_setsockopt_old(sock, optname, optval, optlen); @@ -765,7 +765,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct l2cap_chan *chan = l2cap_pi(sk)->chan; int err; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); err = sock_error(sk); if (err) @@ -847,7 +847,7 @@ static void l2cap_sock_kill(struct sock *sk) if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) return; - BT_DBG("sk %p state %s", sk, state_to_string(sk->sk_state)); + BT_DBG("sk %pK state %s", sk, state_to_string(sk->sk_state)); /* Kill poor orphan */ @@ -863,7 +863,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) struct l2cap_conn *conn; int err = 0; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (!sk) return 0; @@ -909,7 +909,7 @@ static int l2cap_sock_release(struct socket *sock) struct sock *sk = sock->sk; int err; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (!sk) return 0; @@ -927,7 +927,7 @@ static void l2cap_sock_cleanup_listen(struct sock *parent) { struct sock *sk; - BT_DBG("parent %p", parent); + BT_DBG("parent %pK", parent); /* Close not yet accepted channels */ while ((sk = bt_accept_dequeue(parent, NULL))) { @@ -1085,7 +1085,7 @@ static void l2cap_sock_ready_cb(struct l2cap_chan *chan) parent = bt_sk(sk)->parent; - BT_DBG("sk %p, parent %p", sk, parent); + BT_DBG("sk %pK, parent %pK", sk, parent); sk->sk_state = BT_CONNECTED; sk->sk_state_change(sk); @@ -1119,7 +1119,7 @@ static struct l2cap_ops l2cap_chan_ops = { static void l2cap_sock_destruct(struct sock *sk) { - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (l2cap_pi(sk)->chan) l2cap_chan_put(l2cap_pi(sk)->chan); @@ -1137,7 +1137,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) struct l2cap_pinfo *pi = l2cap_pi(sk); struct l2cap_chan *chan = pi->chan; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (parent) { struct l2cap_chan *pchan = l2cap_pi(parent)->chan; @@ -1239,7 +1239,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); sock->state = SS_UNCONNECTED; diff --git a/net/bluetooth/lib.c b/net/bluetooth/lib.c index b3fbc73516c41..79c8f55d695ea 100644 --- a/net/bluetooth/lib.c +++ b/net/bluetooth/lib.c @@ -145,7 +145,7 @@ int bt_info(const char *format, ...) vaf.fmt = format; vaf.va = &args; - r = pr_info("%pV", &vaf); + r = pr_info("%pKV", &vaf); va_end(args); @@ -164,7 +164,7 @@ int bt_err(const char *format, ...) vaf.fmt = format; vaf.va = &args; - r = pr_err("%pV", &vaf); + r = pr_err("%pKV", &vaf); va_end(args); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 3e574540b2c2f..b21964051ef81 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -213,7 +213,7 @@ static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) struct mgmt_ev_cmd_status *ev; int err; - BT_DBG("sock %p, index %u, cmd %u, status %u", sk, index, cmd, status); + BT_DBG("sock %pK, index %u, cmd %u, status %u", sk, index, cmd, status); skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_KERNEL); if (!skb) @@ -244,7 +244,7 @@ static int cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, struct mgmt_ev_cmd_complete *ev; int err; - BT_DBG("sock %p", sk); + BT_DBG("sock %pK", sk); skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_KERNEL); if (!skb) @@ -275,7 +275,7 @@ static int read_version(struct sock *sk, struct hci_dev *hdev, void *data, { struct mgmt_rp_read_version rp; - BT_DBG("sock %p", sk); + BT_DBG("sock %pK", sk); rp.version = MGMT_VERSION; rp.revision = __constant_cpu_to_le16(MGMT_REVISION); @@ -294,7 +294,7 @@ static int read_commands(struct sock *sk, struct hci_dev *hdev, void *data, size_t rp_size; int i, err; - BT_DBG("sock %p", sk); + BT_DBG("sock %pK", sk); rp_size = sizeof(*rp) + ((num_commands + num_events) * sizeof(u16)); @@ -327,7 +327,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, u16 count; int err; - BT_DBG("sock %p", sk); + BT_DBG("sock %pK", sk); read_lock(&hci_dev_list_lock); @@ -698,7 +698,7 @@ static int read_controller_info(struct sock *sk, struct hci_dev *hdev, { struct mgmt_rp_read_info rp; - BT_DBG("sock %p %s", sk, hdev->name); + BT_DBG("sock %pK %s", sk, hdev->name); hci_dev_lock(hdev); diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 0c77476d33d20..03a9c68e6c833 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -182,13 +182,13 @@ static inline int __check_fcs(u8 *data, int type, u8 fcs) /* ---- L2CAP callbacks ---- */ static void rfcomm_l2state_change(struct sock *sk) { - BT_DBG("%p state %d", sk, sk->sk_state); + BT_DBG("%pK state %d", sk, sk->sk_state); rfcomm_schedule(); } static void rfcomm_l2data_ready(struct sock *sk, int bytes) { - BT_DBG("%p bytes %d", sk, bytes); + BT_DBG("%pK bytes %d", sk, bytes); rfcomm_schedule(); } @@ -233,7 +233,7 @@ static void rfcomm_session_timeout(unsigned long arg) { struct rfcomm_session *s = (void *) arg; - BT_DBG("session %p state %ld", s, s->state); + BT_DBG("session %pK state %ld", s, s->state); set_bit(RFCOMM_TIMED_OUT, &s->flags); rfcomm_schedule(); @@ -241,14 +241,14 @@ static void rfcomm_session_timeout(unsigned long arg) static void rfcomm_session_set_timer(struct rfcomm_session *s, long timeout) { - BT_DBG("session %p state %ld timeout %ld", s, s->state, timeout); + BT_DBG("session %pK state %ld timeout %ld", s, s->state, timeout); mod_timer(&s->timer, jiffies + timeout); } static void rfcomm_session_clear_timer(struct rfcomm_session *s) { - BT_DBG("session %p state %ld", s, s->state); + BT_DBG("session %pK state %ld", s, s->state); del_timer_sync(&s->timer); } @@ -258,7 +258,7 @@ static void rfcomm_dlc_timeout(unsigned long arg) { struct rfcomm_dlc *d = (void *) arg; - BT_DBG("dlc %p state %ld", d, d->state); + BT_DBG("dlc %pK state %ld", d, d->state); set_bit(RFCOMM_TIMED_OUT, &d->flags); rfcomm_dlc_put(d); @@ -267,7 +267,7 @@ static void rfcomm_dlc_timeout(unsigned long arg) static void rfcomm_dlc_set_timer(struct rfcomm_dlc *d, long timeout) { - BT_DBG("dlc %p state %ld timeout %ld", d, d->state, timeout); + BT_DBG("dlc %pK state %ld timeout %ld", d, d->state, timeout); if (!mod_timer(&d->timer, jiffies + timeout)) rfcomm_dlc_hold(d); @@ -275,7 +275,7 @@ static void rfcomm_dlc_set_timer(struct rfcomm_dlc *d, long timeout) static void rfcomm_dlc_clear_timer(struct rfcomm_dlc *d) { - BT_DBG("dlc %p state %ld", d, d->state); + BT_DBG("dlc %pK state %ld", d, d->state); if (del_timer(&d->timer)) rfcomm_dlc_put(d); @@ -283,7 +283,7 @@ static void rfcomm_dlc_clear_timer(struct rfcomm_dlc *d) static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d) { - BT_DBG("%p", d); + BT_DBG("%pK", d); d->state = BT_OPEN; d->flags = 0; @@ -311,14 +311,14 @@ struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio) rfcomm_dlc_clear_state(d); - BT_DBG("%p", d); + BT_DBG("%pK", d); return d; } void rfcomm_dlc_free(struct rfcomm_dlc *d) { - BT_DBG("%p", d); + BT_DBG("%pK", d); skb_queue_purge(&d->tx_queue); kfree(d); @@ -326,7 +326,7 @@ void rfcomm_dlc_free(struct rfcomm_dlc *d) static void rfcomm_dlc_link(struct rfcomm_session *s, struct rfcomm_dlc *d) { - BT_DBG("dlc %p session %p", d, s); + BT_DBG("dlc %pK session %pK", d, s); rfcomm_session_clear_timer(s); rfcomm_dlc_hold(d); @@ -338,7 +338,7 @@ static void rfcomm_dlc_unlink(struct rfcomm_dlc *d) { struct rfcomm_session *s = d->session; - BT_DBG("dlc %p refcnt %d session %p", d, atomic_read(&d->refcnt), s); + BT_DBG("dlc %pK refcnt %d session %pK", d, atomic_read(&d->refcnt), s); list_del(&d->list); d->session = NULL; @@ -365,7 +365,7 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, int err = 0; u8 dlci; - BT_DBG("dlc %p state %ld %pMR -> %pMR channel %d", + BT_DBG("dlc %pK state %ld %pMR -> %pMR channel %d", d, d->state, src, dst, channel); if (channel < 1 || channel > 30) @@ -431,8 +431,8 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err) if (!s) return 0; - BT_DBG("dlc %p state %ld dlci %d err %d session %p", - d, d->state, d->dlci, err, s); + BT_DBG("dlc %pK state %ld dlci %d err %d session %pK", + d, d->state, d->dlci, err, s); switch (d->state) { case BT_CONNECT: @@ -484,7 +484,7 @@ int rfcomm_dlc_close(struct rfcomm_dlc *d, int err) struct rfcomm_dlc *d_list; struct rfcomm_session *s, *s_list; - BT_DBG("dlc %p state %ld dlci %d err %d", d, d->state, d->dlci, err); + BT_DBG("dlc %pK state %ld dlci %d err %d", d, d->state, d->dlci, err); rfcomm_lock(); @@ -519,7 +519,7 @@ int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb) if (d->state != BT_CONNECTED) return -ENOTCONN; - BT_DBG("dlc %p mtu %d len %d", d, d->mtu, len); + BT_DBG("dlc %pK mtu %d len %d", d, d->mtu, len); if (len > d->mtu) return -EINVAL; @@ -534,7 +534,7 @@ int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb) void __rfcomm_dlc_throttle(struct rfcomm_dlc *d) { - BT_DBG("dlc %p state %ld", d, d->state); + BT_DBG("dlc %pK state %ld", d, d->state); if (!d->cfc) { d->v24_sig |= RFCOMM_V24_FC; @@ -545,7 +545,7 @@ void __rfcomm_dlc_throttle(struct rfcomm_dlc *d) void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d) { - BT_DBG("dlc %p state %ld", d, d->state); + BT_DBG("dlc %pK state %ld", d, d->state); if (!d->cfc) { d->v24_sig &= ~RFCOMM_V24_FC; @@ -561,8 +561,8 @@ void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d) */ int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig) { - BT_DBG("dlc %p state %ld v24_sig 0x%x", - d, d->state, v24_sig); + BT_DBG("dlc %pK state %ld v24_sig 0x%x", + d, d->state, v24_sig); if (test_bit(RFCOMM_RX_THROTTLED, &d->flags)) v24_sig |= RFCOMM_V24_FC; @@ -579,8 +579,8 @@ int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig) int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig) { - BT_DBG("dlc %p state %ld v24_sig 0x%x", - d, d->state, d->v24_sig); + BT_DBG("dlc %pK state %ld v24_sig 0x%x", + d, d->state, d->v24_sig); *v24_sig = d->v24_sig; return 0; @@ -594,7 +594,7 @@ static struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state) if (!s) return NULL; - BT_DBG("session %p sock %p", s, sock); + BT_DBG("session %pK sock %pK", s, sock); setup_timer(&s->timer, rfcomm_session_timeout, (unsigned long) s); @@ -622,7 +622,7 @@ static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s) { int state = s->state; - BT_DBG("session %p state %ld", s, s->state); + BT_DBG("session %pK state %ld", s, s->state); list_del(&s->list); @@ -660,7 +660,7 @@ static struct rfcomm_session *rfcomm_session_close(struct rfcomm_session *s, s->state = BT_CLOSED; - BT_DBG("session %p state %ld err %d", s, s->state, err); + BT_DBG("session %pK state %ld err %d", s, s->state, err); /* Close all dlcs */ list_for_each_safe(p, n, &s->dlcs) { @@ -744,7 +744,7 @@ static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len) struct kvec iv = { data, len }; struct msghdr msg; - BT_DBG("session %p len %d", s, len); + BT_DBG("session %pK len %d", s, len); memset(&msg, 0, sizeof(msg)); @@ -753,7 +753,7 @@ static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len) static int rfcomm_send_cmd(struct rfcomm_session *s, struct rfcomm_cmd *cmd) { - BT_DBG("%p cmd %u", s, cmd->ctrl); + BT_DBG("%pK cmd %u", s, cmd->ctrl); return rfcomm_send_frame(s, (void *) cmd, sizeof(*cmd)); } @@ -762,7 +762,7 @@ static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci) { struct rfcomm_cmd cmd; - BT_DBG("%p dlci %d", s, dlci); + BT_DBG("%pK dlci %d", s, dlci); cmd.addr = __addr(s->initiator, dlci); cmd.ctrl = __ctrl(RFCOMM_SABM, 1); @@ -776,7 +776,7 @@ static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci) { struct rfcomm_cmd cmd; - BT_DBG("%p dlci %d", s, dlci); + BT_DBG("%pK dlci %d", s, dlci); cmd.addr = __addr(!s->initiator, dlci); cmd.ctrl = __ctrl(RFCOMM_UA, 1); @@ -790,7 +790,7 @@ static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci) { struct rfcomm_cmd cmd; - BT_DBG("%p dlci %d", s, dlci); + BT_DBG("%pK dlci %d", s, dlci); cmd.addr = __addr(s->initiator, dlci); cmd.ctrl = __ctrl(RFCOMM_DISC, 1); @@ -805,7 +805,7 @@ static int rfcomm_queue_disc(struct rfcomm_dlc *d) struct rfcomm_cmd *cmd; struct sk_buff *skb; - BT_DBG("dlc %p dlci %d", d, d->dlci); + BT_DBG("dlc %pK dlci %d", d, d->dlci); skb = alloc_skb(sizeof(*cmd), GFP_KERNEL); if (!skb) @@ -826,7 +826,7 @@ static int rfcomm_send_dm(struct rfcomm_session *s, u8 dlci) { struct rfcomm_cmd cmd; - BT_DBG("%p dlci %d", s, dlci); + BT_DBG("%pK dlci %d", s, dlci); cmd.addr = __addr(!s->initiator, dlci); cmd.ctrl = __ctrl(RFCOMM_DM, 1); @@ -842,7 +842,7 @@ static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type) struct rfcomm_mcc *mcc; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d type %d", s, cr, type); + BT_DBG("%pK cr %d type %d", s, cr, type); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -868,7 +868,7 @@ static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d struct rfcomm_pn *pn; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d dlci %d mtu %d", s, cr, d->dlci, d->mtu); + BT_DBG("%pK cr %d dlci %d mtu %d", s, cr, d->dlci, d->mtu); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -913,10 +913,9 @@ int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci, struct rfcomm_rpn *rpn; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d dlci %d bit_r 0x%x data_b 0x%x stop_b 0x%x parity 0x%x" - " flwc_s 0x%x xon_c 0x%x xoff_c 0x%x p_mask 0x%x", - s, cr, dlci, bit_rate, data_bits, stop_bits, parity, - flow_ctrl_settings, xon_char, xoff_char, param_mask); + BT_DBG("%pK cr %d dlci %d bit_r 0x%x data_b 0x%x stop_b 0x%x parity 0x%x flwc_s 0x%x xon_c 0x%x xoff_c 0x%x p_mask 0x%x", + s, cr, dlci, bit_rate, data_bits, stop_bits, parity, + flow_ctrl_settings, xon_char, xoff_char, param_mask); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -948,7 +947,7 @@ static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status) struct rfcomm_rls *rls; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d status 0x%x", s, cr, status); + BT_DBG("%pK cr %d status 0x%x", s, cr, status); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -975,7 +974,7 @@ static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig struct rfcomm_msc *msc; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d v24 0x%x", s, cr, v24_sig); + BT_DBG("%pK cr %d v24 0x%x", s, cr, v24_sig); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -1001,7 +1000,7 @@ static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr) struct rfcomm_mcc *mcc; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d", s, cr); + BT_DBG("%pK cr %d", s, cr); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -1023,7 +1022,7 @@ static int rfcomm_send_fcon(struct rfcomm_session *s, int cr) struct rfcomm_mcc *mcc; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d", s, cr); + BT_DBG("%pK cr %d", s, cr); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -1049,7 +1048,7 @@ static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int l if (len > 125) return -EINVAL; - BT_DBG("%p cr %d", s, cr); + BT_DBG("%pK cr %d", s, cr); hdr[0] = __addr(s->initiator, 0); hdr[1] = __ctrl(RFCOMM_UIH, 0); @@ -1076,7 +1075,7 @@ static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits) struct rfcomm_hdr *hdr; u8 buf[16], *ptr = buf; - BT_DBG("%p addr %d credits %d", s, addr, credits); + BT_DBG("%pK addr %d credits %d", s, addr, credits); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = addr; @@ -1113,7 +1112,7 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr) /* ---- RFCOMM frame reception ---- */ static struct rfcomm_session *rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci) { - BT_DBG("session %p state %ld dlci %d", s, s->state, dlci); + BT_DBG("session %pK state %ld dlci %d", s, s->state, dlci); if (dlci) { /* Data channel */ @@ -1167,7 +1166,7 @@ static struct rfcomm_session *rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci) { int err = 0; - BT_DBG("session %p state %ld dlci %d", s, s->state, dlci); + BT_DBG("session %pK state %ld dlci %d", s, s->state, dlci); if (dlci) { /* Data DLC */ @@ -1197,7 +1196,7 @@ static struct rfcomm_session *rfcomm_recv_disc(struct rfcomm_session *s, { int err = 0; - BT_DBG("session %p state %ld dlci %d", s, s->state, dlci); + BT_DBG("session %pK state %ld dlci %d", s, s->state, dlci); if (dlci) { struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci); @@ -1232,7 +1231,7 @@ void rfcomm_dlc_accept(struct rfcomm_dlc *d) struct sock *sk = d->session->sock->sk; struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn; - BT_DBG("dlc %p", d); + BT_DBG("dlc %pK", d); rfcomm_send_ua(d->session, d->dlci); @@ -1273,7 +1272,7 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci) struct rfcomm_dlc *d; u8 channel; - BT_DBG("session %p state %ld dlci %d", s, s->state, dlci); + BT_DBG("session %pK state %ld dlci %d", s, s->state, dlci); if (!dlci) { rfcomm_send_ua(s, 0); @@ -1314,8 +1313,8 @@ static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn) { struct rfcomm_session *s = d->session; - BT_DBG("dlc %p state %ld dlci %d mtu %d fc 0x%x credits %d", - d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits); + BT_DBG("dlc %pK state %ld dlci %d mtu %d fc 0x%x credits %d", + d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits); if ((pn->flow_ctrl == 0xf0 && s->cfc != RFCOMM_CFC_DISABLED) || pn->flow_ctrl == 0xe0) { @@ -1345,7 +1344,7 @@ static int rfcomm_recv_pn(struct rfcomm_session *s, int cr, struct sk_buff *skb) struct rfcomm_dlc *d; u8 dlci = pn->dlci; - BT_DBG("session %p state %ld dlci %d", s, s->state, dlci); + BT_DBG("session %pK state %ld dlci %d", s, s->state, dlci); if (!dlci) return 0; @@ -1561,7 +1560,7 @@ static int rfcomm_recv_mcc(struct rfcomm_session *s, struct sk_buff *skb) type = __get_mcc_type(mcc->type); len = __get_mcc_len(mcc->len); - BT_DBG("%p type 0x%x cr %d", s, type, cr); + BT_DBG("%pK type 0x%x cr %d", s, type, cr); skb_pull(skb, 2); @@ -1616,7 +1615,7 @@ static int rfcomm_recv_data(struct rfcomm_session *s, u8 dlci, int pf, struct sk { struct rfcomm_dlc *d; - BT_DBG("session %p state %ld dlci %d pf %d", s, s->state, dlci, pf); + BT_DBG("session %pK state %ld dlci %d pf %d", s, s->state, dlci, pf); d = rfcomm_dlc_get(s, dlci); if (!d) { @@ -1718,7 +1717,7 @@ static void rfcomm_process_connect(struct rfcomm_session *s) struct rfcomm_dlc *d; struct list_head *p, *n; - BT_DBG("session %p state %ld", s, s->state); + BT_DBG("session %pK state %ld", s, s->state); list_for_each_safe(p, n, &s->dlcs) { d = list_entry(p, struct rfcomm_dlc, list); @@ -1742,8 +1741,8 @@ static int rfcomm_process_tx(struct rfcomm_dlc *d) struct sk_buff *skb; int err; - BT_DBG("dlc %p state %ld cfc %d rx_credits %d tx_credits %d", - d, d->state, d->cfc, d->rx_credits, d->tx_credits); + BT_DBG("dlc %pK state %ld cfc %d rx_credits %d tx_credits %d", + d, d->state, d->cfc, d->rx_credits, d->tx_credits); /* Send pending MSC */ if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags)) @@ -1790,7 +1789,7 @@ static void rfcomm_process_dlcs(struct rfcomm_session *s) struct rfcomm_dlc *d; struct list_head *p, *n; - BT_DBG("session %p state %ld", s, s->state); + BT_DBG("session %pK state %ld", s, s->state); list_for_each_safe(p, n, &s->dlcs) { d = list_entry(p, struct rfcomm_dlc, list); @@ -1851,7 +1850,8 @@ static struct rfcomm_session *rfcomm_process_rx(struct rfcomm_session *s) struct sock *sk = sock->sk; struct sk_buff *skb; - BT_DBG("session %p state %ld qlen %d", s, s->state, skb_queue_len(&sk->sk_receive_queue)); + BT_DBG("session %pK state %ld qlen %d", s, s->state, + skb_queue_len(&sk->sk_receive_queue)); /* Get data directly from socket receive queue without copying it. */ while ((skb = skb_dequeue(&sk->sk_receive_queue))) { @@ -1878,7 +1878,7 @@ static void rfcomm_accept_connection(struct rfcomm_session *s) if (list_empty(&bt_sk(sock->sk)->accept_q)) return; - BT_DBG("session %p", s); + BT_DBG("session %pK", s); err = kernel_accept(sock, &nsock, O_NONBLOCK); if (err < 0) @@ -1904,7 +1904,7 @@ static struct rfcomm_session *rfcomm_check_connection(struct rfcomm_session *s) { struct sock *sk = s->sock->sk; - BT_DBG("%p state %ld", s, s->state); + BT_DBG("%pK state %ld", s, s->state); switch (sk->sk_state) { case BT_CONNECTED: @@ -2059,7 +2059,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt) struct rfcomm_dlc *d; struct list_head *p, *n; - BT_DBG("conn %p status 0x%02x encrypt 0x%02x", conn, status, encrypt); + BT_DBG("conn %pK status 0x%02x encrypt 0x%02x", conn, status, encrypt); s = rfcomm_session_get(&conn->hdev->bdaddr, &conn->dst); if (!s) diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index c1c6028e389ad..75f10eee71f01 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -68,7 +68,7 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) if (!sk) return; - BT_DBG("dlc %p state %ld err %d", d, d->state, err); + BT_DBG("dlc %pK state %ld err %d", d, d->state, err); local_irq_save(flags); bh_lock_sock(sk); @@ -150,7 +150,7 @@ static void rfcomm_sock_destruct(struct sock *sk) { struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; - BT_DBG("sk %p dlc %p", sk, d); + BT_DBG("sk %pK dlc %pK", sk, d); skb_queue_purge(&sk->sk_receive_queue); skb_queue_purge(&sk->sk_write_queue); @@ -170,7 +170,7 @@ static void rfcomm_sock_cleanup_listen(struct sock *parent) { struct sock *sk; - BT_DBG("parent %p", parent); + BT_DBG("parent %pK", parent); /* Close not yet accepted dlcs */ while ((sk = bt_accept_dequeue(parent, NULL))) { @@ -190,7 +190,8 @@ static void rfcomm_sock_kill(struct sock *sk) if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) return; - BT_DBG("sk %p state %d refcnt %d", sk, sk->sk_state, atomic_read(&sk->sk_refcnt)); + BT_DBG("sk %pK state %d refcnt %d", sk, sk->sk_state, + atomic_read(&sk->sk_refcnt)); /* Kill poor orphan */ bt_sock_unlink(&rfcomm_sk_list, sk); @@ -202,7 +203,7 @@ static void __rfcomm_sock_close(struct sock *sk) { struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; - BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); + BT_DBG("sk %pK state %d socket %pK", sk, sk->sk_state, sk->sk_socket); switch (sk->sk_state) { case BT_LISTEN: @@ -235,7 +236,7 @@ static void rfcomm_sock_init(struct sock *sk, struct sock *parent) { struct rfcomm_pinfo *pi = rfcomm_pi(sk); - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (parent) { sk->sk_type = parent->sk_type; @@ -300,7 +301,7 @@ static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock, int bt_sock_link(&rfcomm_sk_list, sk); - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); return sk; } @@ -309,7 +310,7 @@ static int rfcomm_sock_create(struct net *net, struct socket *sock, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); sock->state = SS_UNCONNECTED; @@ -332,7 +333,7 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr struct sock *sk = sock->sk; int err = 0; - BT_DBG("sk %p %pMR", sk, &sa->rc_bdaddr); + BT_DBG("sk %pK %pMR", sk, &sa->rc_bdaddr); if (!addr || addr->sa_family != AF_BLUETOOTH) return -EINVAL; @@ -374,7 +375,7 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; int err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (alen < sizeof(struct sockaddr_rc) || addr->sa_family != AF_BLUETOOTH) @@ -414,7 +415,7 @@ static int rfcomm_sock_listen(struct socket *sock, int backlog) struct sock *sk = sock->sk; int err = 0; - BT_DBG("sk %p backlog %d", sk, backlog); + BT_DBG("sk %pK backlog %d", sk, backlog); lock_sock(sk); @@ -474,7 +475,7 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); - BT_DBG("sk %p timeo %ld", sk, timeo); + BT_DBG("sk %pK timeo %ld", sk, timeo); /* Wait for an incoming connection. (wake-one). */ add_wait_queue_exclusive(sk_sleep(sk), &wait); @@ -512,7 +513,7 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f newsock->state = SS_CONNECTED; - BT_DBG("new socket %p", nsk); + BT_DBG("new socket %pK", nsk); done: release_sock(sk); @@ -524,7 +525,7 @@ static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int * struct sockaddr_rc *sa = (struct sockaddr_rc *) addr; struct sock *sk = sock->sk; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); memset(sa, 0, sizeof(*sa)); sa->rc_family = AF_BLUETOOTH; @@ -555,7 +556,7 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, if (sk->sk_shutdown & SEND_SHUTDOWN) return -EPIPE; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); lock_sock(sk); @@ -630,7 +631,7 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __u int err = 0; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); lock_sock(sk); @@ -668,7 +669,7 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c size_t len; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (level == SOL_RFCOMM) return rfcomm_sock_setsockopt_old(sock, optname, optval, optlen); @@ -736,7 +737,7 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u int len, err = 0; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (get_user(len, optlen)) return -EFAULT; @@ -800,7 +801,7 @@ static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, c struct bt_security sec; int len, err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (level == SOL_RFCOMM) return rfcomm_sock_getsockopt_old(sock, optname, optval, optlen); @@ -855,7 +856,7 @@ static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned lon struct sock *sk __maybe_unused = sock->sk; int err; - BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg); + BT_DBG("sk %pK cmd %x arg %lx", sk, cmd, arg); err = bt_sock_ioctl(sock, cmd, arg); @@ -877,7 +878,7 @@ static int rfcomm_sock_shutdown(struct socket *sock, int how) struct sock *sk = sock->sk; int err = 0; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (!sk) return 0; @@ -899,7 +900,7 @@ static int rfcomm_sock_release(struct socket *sock) struct sock *sk = sock->sk; int err; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (!sk) return 0; @@ -921,7 +922,7 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc * bdaddr_t src, dst; int result = 0; - BT_DBG("session %p channel %d", s, channel); + BT_DBG("session %pK channel %d", s, channel); rfcomm_session_getaddr(s, &src, &dst); diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index b6e44ad6cca6e..d2ce585a3c152 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -88,7 +88,7 @@ static void rfcomm_dev_destruct(struct tty_port *port) struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port); struct rfcomm_dlc *dlc = dev->dlc; - BT_DBG("dev %p dlc %p", dev, dlc); + BT_DBG("dev %pK dlc %pK", dev, dlc); /* Refcount should only hit zero when called from rfcomm_dev_del() which will have taken us off the list. Everything else are @@ -304,7 +304,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) static void rfcomm_dev_del(struct rfcomm_dev *dev) { unsigned long flags; - BT_DBG("dev %p", dev); + BT_DBG("dev %pK", dev); BUG_ON(test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags)); @@ -373,7 +373,7 @@ static int rfcomm_create_dev(struct sock *sk, void __user *arg) if (copy_from_user(&req, arg, sizeof(req))) return -EFAULT; - BT_DBG("sk %p dev_id %d flags 0x%x", sk, req.dev_id, req.flags); + BT_DBG("sk %pK dev_id %d flags 0x%x", sk, req.dev_id, req.flags); if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) return -EPERM; @@ -518,7 +518,7 @@ static int rfcomm_get_dev_info(void __user *arg) int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) { - BT_DBG("cmd %d arg %p", cmd, arg); + BT_DBG("cmd %d arg %pK", cmd, arg); switch (cmd) { case RFCOMMCREATEDEV: @@ -552,7 +552,7 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb) return; } - BT_DBG("dlc %p len %d", dlc, skb->len); + BT_DBG("dlc %pK len %d", dlc, skb->len); tty_insert_flip_string(&dev->port, skb->data, skb->len); tty_flip_buffer_push(&dev->port); @@ -566,7 +566,7 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err) if (!dev) return; - BT_DBG("dlc %p dev %p err %d", dlc, dev, err); + BT_DBG("dlc %pK dev %pK err %d", dlc, dev, err); dev->err = err; wake_up_interruptible(&dev->wait); @@ -602,7 +602,7 @@ static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig) if (!dev) return; - BT_DBG("dlc %p dev %p v24_sig 0x%02x", dlc, dev, v24_sig); + BT_DBG("dlc %pK dev %pK v24_sig 0x%02x", dlc, dev, v24_sig); if ((dev->modem_status & TIOCM_CD) && !(v24_sig & RFCOMM_V24_DV)) { if (dev->port.tty && !C_CLOCAL(dev->port.tty)) @@ -622,7 +622,7 @@ static void rfcomm_tty_copy_pending(struct rfcomm_dev *dev) struct sk_buff *skb; int inserted = 0; - BT_DBG("dev %p", dev); + BT_DBG("dev %pK", dev); rfcomm_dlc_lock(dev->dlc); @@ -648,7 +648,7 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) id = tty->index; - BT_DBG("tty %p id %d", tty, id); + BT_DBG("tty %pK id %d", tty, id); /* We don't leak this refcount. For reasons which are not entirely clear, the TTY layer will call our ->close() method even if the @@ -658,7 +658,7 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) if (!dev) return -ENODEV; - BT_DBG("dev %p dst %pMR channel %d opened %d", dev, &dev->dst, + BT_DBG("dev %pK dst %pMR channel %d opened %d", dev, &dev->dst, dev->channel, dev->port.count); spin_lock_irqsave(&dev->port.lock, flags); @@ -726,8 +726,8 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp) if (!dev) return; - BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc, - dev->port.count); + BT_DBG("tty %pK dev %pK dlc %pK opened %d", tty, dev, dev->dlc, + dev->port.count); spin_lock_irqsave(&dev->port.lock, flags); if (!--dev->port.count) { @@ -765,7 +765,7 @@ static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, in struct sk_buff *skb; int err = 0, sent = 0, size; - BT_DBG("tty %p count %d", tty, count); + BT_DBG("tty %pK count %d", tty, count); while (count) { size = min_t(uint, count, dlc->mtu); @@ -797,7 +797,7 @@ static int rfcomm_tty_write_room(struct tty_struct *tty) struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; int room; - BT_DBG("tty %p", tty); + BT_DBG("tty %pK", tty); if (!dev || !dev->dlc) return 0; @@ -811,7 +811,7 @@ static int rfcomm_tty_write_room(struct tty_struct *tty) static int rfcomm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { - BT_DBG("tty %p cmd 0x%02x", tty, cmd); + BT_DBG("tty %pK cmd 0x%02x", tty, cmd); switch (cmd) { case TCGETS: @@ -865,7 +865,7 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old) struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p termios %p", tty, old); + BT_DBG("tty %pK termios %pK", tty, old); if (!dev || !dev->dlc || !dev->dlc->session) return; @@ -997,7 +997,7 @@ static void rfcomm_tty_throttle(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p dev %p", tty, dev); + BT_DBG("tty %pK dev %pK", tty, dev); rfcomm_dlc_throttle(dev->dlc); } @@ -1006,7 +1006,7 @@ static void rfcomm_tty_unthrottle(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p dev %p", tty, dev); + BT_DBG("tty %pK dev %pK", tty, dev); rfcomm_dlc_unthrottle(dev->dlc); } @@ -1015,7 +1015,7 @@ static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p dev %p", tty, dev); + BT_DBG("tty %pK dev %pK", tty, dev); if (!dev || !dev->dlc) return 0; @@ -1030,7 +1030,7 @@ static void rfcomm_tty_flush_buffer(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p dev %p", tty, dev); + BT_DBG("tty %pK dev %pK", tty, dev); if (!dev || !dev->dlc) return; @@ -1041,19 +1041,19 @@ static void rfcomm_tty_flush_buffer(struct tty_struct *tty) static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch) { - BT_DBG("tty %p ch %c", tty, ch); + BT_DBG("tty %pK ch %c", tty, ch); } static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout) { - BT_DBG("tty %p timeout %d", tty, timeout); + BT_DBG("tty %pK timeout %d", tty, timeout); } static void rfcomm_tty_hangup(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p dev %p", tty, dev); + BT_DBG("tty %pK dev %pK", tty, dev); if (!dev) return; @@ -1072,7 +1072,7 @@ static int rfcomm_tty_tiocmget(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p dev %p", tty, dev); + BT_DBG("tty %pK dev %pK", tty, dev); return dev->modem_status; } @@ -1083,7 +1083,7 @@ static int rfcomm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigne struct rfcomm_dlc *dlc = dev->dlc; u8 v24_sig; - BT_DBG("tty %p dev %p set 0x%02x clear 0x%02x", tty, dev, set, clear); + BT_DBG("tty %pK dev %pK set 0x%02x clear 0x%02x", tty, dev, set, clear); rfcomm_dlc_get_modem_status(dlc, &v24_sig); diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 11797c13a0c37..5bf2937fd1509 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -51,7 +51,7 @@ static void sco_sock_timeout(unsigned long arg) { struct sock *sk = (struct sock *) arg; - BT_DBG("sock %p state %d", sk, sk->sk_state); + BT_DBG("sock %pK state %d", sk, sk->sk_state); bh_lock_sock(sk); sk->sk_err = ETIMEDOUT; @@ -64,13 +64,13 @@ static void sco_sock_timeout(unsigned long arg) static void sco_sock_set_timer(struct sock *sk, long timeout) { - BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout); + BT_DBG("sock %pK state %d timeout %ld", sk, sk->sk_state, timeout); sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout); } static void sco_sock_clear_timer(struct sock *sk) { - BT_DBG("sock %p state %d", sk, sk->sk_state); + BT_DBG("sock %pK state %d", sk, sk->sk_state); sk_stop_timer(sk, &sk->sk_timer); } @@ -100,7 +100,7 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon) else conn->mtu = 60; - BT_DBG("hcon %p conn %p", hcon, conn); + BT_DBG("hcon %pK conn %pK", hcon, conn); return conn; } @@ -122,7 +122,7 @@ static int sco_conn_del(struct hci_conn *hcon, int err) if (!conn) return 0; - BT_DBG("hcon %p conn %p, err %d", hcon, conn, err); + BT_DBG("hcon %pK conn %pK, err %d", hcon, conn, err); /* Kill socket */ sk = sco_chan_get(conn); @@ -224,7 +224,7 @@ static int sco_send_frame(struct sock *sk, struct msghdr *msg, int len) if (len > conn->mtu) return -EINVAL; - BT_DBG("sk %p len %d", sk, len); + BT_DBG("sk %pK len %d", sk, len); skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err); if (!skb) @@ -247,7 +247,7 @@ static void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb) if (!sk) goto drop; - BT_DBG("sk %p len %d", sk, skb->len); + BT_DBG("sk %pK len %d", sk, skb->len); if (sk->sk_state != BT_CONNECTED) goto drop; @@ -304,7 +304,7 @@ static struct sock *sco_get_sock_listen(bdaddr_t *src) static void sco_sock_destruct(struct sock *sk) { - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); skb_queue_purge(&sk->sk_receive_queue); skb_queue_purge(&sk->sk_write_queue); @@ -314,7 +314,7 @@ static void sco_sock_cleanup_listen(struct sock *parent) { struct sock *sk; - BT_DBG("parent %p", parent); + BT_DBG("parent %pK", parent); /* Close not yet accepted channels */ while ((sk = bt_accept_dequeue(parent, NULL))) { @@ -334,7 +334,7 @@ static void sco_sock_kill(struct sock *sk) if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) return; - BT_DBG("sk %p state %d", sk, sk->sk_state); + BT_DBG("sk %pK state %d", sk, sk->sk_state); /* Kill poor orphan */ bt_sock_unlink(&sco_sk_list, sk); @@ -344,7 +344,7 @@ static void sco_sock_kill(struct sock *sk) static void __sco_sock_close(struct sock *sk) { - BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); + BT_DBG("sk %pK state %d socket %pK", sk, sk->sk_state, sk->sk_socket); switch (sk->sk_state) { case BT_LISTEN: @@ -388,7 +388,7 @@ static void sco_sock_close(struct sock *sk) static void sco_sock_init(struct sock *sk, struct sock *parent) { - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (parent) { sk->sk_type = parent->sk_type; @@ -433,7 +433,7 @@ static int sco_sock_create(struct net *net, struct socket *sock, int protocol, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); sock->state = SS_UNCONNECTED; @@ -456,7 +456,7 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) struct sock *sk = sock->sk; int len, err = 0; - BT_DBG("sk %p %pMR", sk, &sa.sco_bdaddr); + BT_DBG("sk %pK %pMR", sk, &sa.sco_bdaddr); if (!addr || addr->sa_family != AF_BLUETOOTH) return -EINVAL; @@ -493,7 +493,7 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen struct sockaddr_sco sa; int len, err; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (!addr || addr->sa_family != AF_BLUETOOTH) return -EINVAL; @@ -536,7 +536,7 @@ static int sco_sock_listen(struct socket *sock, int backlog) bdaddr_t *src = &bt_sk(sk)->src; int err = 0; - BT_DBG("sk %p backlog %d", sk, backlog); + BT_DBG("sk %pK backlog %d", sk, backlog); lock_sock(sk); @@ -581,7 +581,7 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); - BT_DBG("sk %p timeo %ld", sk, timeo); + BT_DBG("sk %pK timeo %ld", sk, timeo); /* Wait for an incoming connection. (wake-one). */ add_wait_queue_exclusive(sk_sleep(sk), &wait); @@ -619,7 +619,7 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag newsock->state = SS_CONNECTED; - BT_DBG("new socket %p", ch); + BT_DBG("new socket %pK", ch); done: release_sock(sk); @@ -631,7 +631,7 @@ static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len struct sockaddr_sco *sa = (struct sockaddr_sco *) addr; struct sock *sk = sock->sk; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); addr->sa_family = AF_BLUETOOTH; *len = sizeof(struct sockaddr_sco); @@ -651,7 +651,7 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct sock *sk = sock->sk; int err; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); err = sock_error(sk); if (err) @@ -675,7 +675,7 @@ static void sco_conn_defer_accept(struct hci_conn *conn, int mask) { struct hci_dev *hdev = conn->hdev; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); conn->state = BT_CONFIG; @@ -735,7 +735,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char int err = 0; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); lock_sock(sk); @@ -774,7 +774,7 @@ static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user struct sco_conninfo cinfo; int len, err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (get_user(len, optlen)) return -EFAULT; @@ -828,7 +828,7 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char struct sock *sk = sock->sk; int len, err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (level == SOL_SCO) return sco_sock_getsockopt_old(sock, optname, optval, optlen); @@ -866,7 +866,7 @@ static int sco_sock_shutdown(struct socket *sock, int how) struct sock *sk = sock->sk; int err = 0; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (!sk) return 0; @@ -890,7 +890,7 @@ static int sco_sock_release(struct socket *sock) struct sock *sk = sock->sk; int err = 0; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (!sk) return 0; @@ -910,7 +910,7 @@ static int sco_sock_release(struct socket *sock) static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent) { - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); sco_pi(sk)->conn = conn; conn->sk = sk; @@ -927,7 +927,7 @@ static void sco_chan_del(struct sock *sk, int err) conn = sco_pi(sk)->conn; - BT_DBG("sk %p, conn %p, err %d", sk, conn, err); + BT_DBG("sk %pK, conn %pK, err %d", sk, conn, err); if (conn) { sco_conn_lock(conn); @@ -951,7 +951,7 @@ static void sco_conn_ready(struct sco_conn *conn) struct sock *parent; struct sock *sk = conn->sk; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); if (sk) { sco_sock_clear_timer(sk); @@ -1030,7 +1030,7 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) void sco_connect_cfm(struct hci_conn *hcon, __u8 status) { - BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status); + BT_DBG("hcon %pK bdaddr %pMR status %d", hcon, &hcon->dst, status); if (!status) { struct sco_conn *conn; @@ -1043,7 +1043,7 @@ void sco_connect_cfm(struct hci_conn *hcon, __u8 status) void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason) { - BT_DBG("hcon %p reason %d", hcon, reason); + BT_DBG("hcon %pK reason %d", hcon, reason); sco_conn_del(hcon, bt_to_errno(reason)); } @@ -1055,7 +1055,7 @@ int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb) if (!conn) goto drop; - BT_DBG("conn %p len %d", conn, skb->len); + BT_DBG("conn %pK len %d", conn, skb->len); if (skb->len) { sco_recv_frame(conn, skb); diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 3c66c2922c21f..d937dd0821803 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -56,7 +56,7 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r) unsigned char iv[128]; if (tfm == NULL) { - BT_ERR("tfm %p", tfm); + BT_ERR("tfm %pK", tfm); return -EINVAL; } @@ -375,7 +375,7 @@ static void confirm_work(struct work_struct *work) int ret; u8 res[16], reason; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); tfm = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm)) { @@ -422,7 +422,7 @@ static void random_work(struct work_struct *work) goto error; } - BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); + BT_DBG("conn %pK %s", conn, conn->hcon->out ? "master" : "slave"); if (hcon->out) ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp, 0, @@ -574,7 +574,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) u8 auth = SMP_AUTH_NONE; int ret; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); if (conn->hcon->link_mode & HCI_LM_MASTER) return SMP_CMD_NOTSUPP; @@ -628,7 +628,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) u8 key_size, auth = SMP_AUTH_NONE; int ret; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); if (!(conn->hcon->link_mode & HCI_LM_MASTER)) return SMP_CMD_NOTSUPP; @@ -674,7 +674,7 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) struct smp_chan *smp = conn->smp_chan; struct hci_dev *hdev = conn->hcon->hdev; - BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); + BT_DBG("conn %pK %s", conn, conn->hcon->out ? "master" : "slave"); memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); skb_pull(skb, sizeof(smp->pcnf)); @@ -699,7 +699,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) struct smp_chan *smp = conn->smp_chan; struct hci_dev *hdev = conn->hcon->hdev; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); swap128(skb->data, smp->rrnd); skb_pull(skb, sizeof(smp->rrnd)); @@ -737,7 +737,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) struct hci_conn *hcon = conn->hcon; struct smp_chan *smp; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req); @@ -770,7 +770,7 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) struct smp_chan *smp = conn->smp_chan; __u8 authreq; - BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); + BT_DBG("conn %pK hcon %pK level 0x%2.2x", conn, hcon, sec_level); if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) return 1; @@ -938,7 +938,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force) struct smp_chan *smp = conn->smp_chan; __u8 *keydist; - BT_DBG("conn %p force %d", conn, force); + BT_DBG("conn %pK force %d", conn, force); if (!test_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) return 0; From 93d395cd574a1e74e40cda24885171191dec37b4 Mon Sep 17 00:00:00 2001 From: Arun KS Date: Wed, 11 May 2016 10:11:36 +0530 Subject: [PATCH 062/320] msm: perf: Do not allocate new hw_event if event is duplicate. During a perf_event_enable, kernel/events/core.c calls pmu->add() which is platform implementation(arch/arm/kernel/perf_event.c). Due to the duplicate constraints, arch/arm/mach-msm/perf_event_msm_krait_l2.c drivers marks the event as OFF but returns TRUE to perf_event.c which goes ahead and allocates the hw_event and enables it. Since event is marked OFF, kernel events core will try to enable this event again during next perf_event_enable. Which results in same event enabled on multiple hw_events. But during the perf_release, event struct is freed and only one hw_event is released. This results in dereferencing the invalid pointer and hence the crash. Fix this by returning error in case of constraint event duplicate. Hence avoiding the same event programmed on multiple hw event counters. Change-Id: Ia3360be027dfe87ac753191ffe7e0bc947e72455 Signed-off-by: Arun KS Signed-off-by: Chetan Ravindranath --- arch/arm/kernel/perf_event.c | 1 + arch/arm/mach-msm/perf_event_msm_krait_l2.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 0f288a7c035f9..a0c1e318a7905 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -240,6 +240,7 @@ armpmu_add(struct perf_event *event, int flags) pr_err("Event: %llx failed constraint check.\n", event->attr.config); event->state = PERF_EVENT_STATE_OFF; + err = -EPERM; goto out; } diff --git a/arch/arm/mach-msm/perf_event_msm_krait_l2.c b/arch/arm/mach-msm/perf_event_msm_krait_l2.c index 43233abe24ca4..2e0c3af3dc1cd 100644 --- a/arch/arm/mach-msm/perf_event_msm_krait_l2.c +++ b/arch/arm/mach-msm/perf_event_msm_krait_l2.c @@ -474,6 +474,7 @@ static int msm_l2_test_set_ev_constraint(struct perf_event *event) if (!(event->cpu < 0)) { event->state = PERF_EVENT_STATE_OFF; event->attr.constraint_duplicate = 1; + err = -EPERM; } } out: From a37480c16c152de51fe7a43f30ebbe458ab9cd23 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Wed, 16 Dec 2015 12:30:02 +0900 Subject: [PATCH 063/320] net: diag: split inet_diag_dump_one_icsk into two Currently, inet_diag_dump_one_icsk finds a socket and then dumps its information to userspace. Split it into a part that finds the socket and a part that dumps the information. [Backport of net-next b613f56ec9baf30edf5d9d607b822532a273dad7] Change-Id: I95c68c4ca41e891fa834febb982c4bdf387687dd Signed-off-by: Lorenzo Colitti Acked-by: Eric Dumazet Signed-off-by: David S. Miller Git-commit: 9eaff90376303bc2fe72b82433782a63eadf2697 Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: Ashwanth Goli --- include/linux/inet_diag.h | 5 +++++ net/ipv4/inet_diag.c | 46 +++++++++++++++++++++++++++------------ 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h index 46da02410a096..0f3eddff8eeae 100644 --- a/include/linux/inet_diag.h +++ b/include/linux/inet_diag.h @@ -3,6 +3,7 @@ #include +struct net; struct sock; struct inet_hashinfo; struct nlattr; @@ -39,6 +40,10 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb, const struct nlmsghdr *nlh, struct inet_diag_req_v2 *req); +struct sock *inet_diag_find_one_icsk(struct net *net, + struct inet_hashinfo *hashinfo, + struct inet_diag_req_v2 *req); + int inet_diag_bc_sk(const struct nlattr *_bc, struct sock *sk); extern int inet_diag_register(const struct inet_diag_handler *handler); diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 45dbdab915e20..150a760bfa6c9 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -290,15 +290,12 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, return inet_csk_diag_fill(sk, skb, r, user_ns, portid, seq, nlmsg_flags, unlh); } -int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb, - const struct nlmsghdr *nlh, struct inet_diag_req_v2 *req) +struct sock *inet_diag_find_one_icsk(struct net *net, + struct inet_hashinfo *hashinfo, + struct inet_diag_req_v2 *req) { - int err; struct sock *sk; - struct sk_buff *rep; - struct net *net = sock_net(in_skb->sk); - err = -EINVAL; if (req->sdiag_family == AF_INET) { sk = inet_lookup(net, hashinfo, req->id.idiag_dst[0], req->id.idiag_dport, req->id.idiag_src[0], @@ -315,16 +312,38 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s } #endif else { - goto out_nosk; + return ERR_PTR(-EINVAL); } - err = -ENOENT; - if (sk == NULL) - goto out_nosk; + if (!sk) + return ERR_PTR(-ENOENT); - err = sock_diag_check_cookie(sk, req->id.idiag_cookie); - if (err) - goto out; + if (sock_diag_check_cookie(sk, req->id.idiag_cookie)) { + /* NOTE: forward-ports should use sock_gen_put(sk) instead. */ + if (sk->sk_state == TCP_TIME_WAIT) + inet_twsk_put((struct inet_timewait_sock *)sk); + else + sock_put(sk); + return ERR_PTR(-ENOENT); + } + + return sk; +} +EXPORT_SYMBOL_GPL(inet_diag_find_one_icsk); + +int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, + struct sk_buff *in_skb, + const struct nlmsghdr *nlh, + struct inet_diag_req_v2 *req) +{ + struct net *net = sock_net(in_skb->sk); + struct sk_buff *rep; + struct sock *sk; + int err; + + sk = inet_diag_find_one_icsk(net, hashinfo, req); + if (IS_ERR(sk)) + return PTR_ERR(sk); rep = nlmsg_new(sizeof(struct inet_diag_msg) + sizeof(struct inet_diag_meminfo) + @@ -355,7 +374,6 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s else sock_put(sk); } -out_nosk: return err; } EXPORT_SYMBOL_GPL(inet_diag_dump_one_icsk); From 348179614305f4e53416621c642cdf9eee142e13 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Wed, 16 Dec 2015 12:30:03 +0900 Subject: [PATCH 064/320] net: diag: Add the ability to destroy a socket. This patch adds a SOCK_DESTROY operation, a destroy function pointer to sock_diag_handler, and a diag_destroy function pointer. It does not include any implementation code. [Backport of net-next 64be0aed59ad519d6f2160868734f7e278290ac1] Change-Id: Ia459d14b7368624adda225c4ebd55f4fc40fc02e Signed-off-by: Lorenzo Colitti Acked-by: Eric Dumazet Signed-off-by: David S. Miller Git-commit: d60326cb49d76f60ef8c742944a58136ddfd0f63 Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: Ashwanth Goli --- include/linux/sock_diag.h | 2 ++ include/net/sock.h | 1 + include/uapi/linux/sock_diag.h | 1 + net/core/sock_diag.c | 23 ++++++++++++++++++++--- 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h index 46cca4c068483..1a3b383ba4e61 100644 --- a/include/linux/sock_diag.h +++ b/include/linux/sock_diag.h @@ -11,6 +11,7 @@ struct sock; struct sock_diag_handler { __u8 family; int (*dump)(struct sk_buff *skb, struct nlmsghdr *nlh); + int (*destroy)(struct sk_buff *skb, struct nlmsghdr *nlh); }; int sock_diag_register(const struct sock_diag_handler *h); @@ -26,4 +27,5 @@ int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr); int sock_diag_put_filterinfo(bool may_report_filterinfo, struct sock *sk, struct sk_buff *skb, int attrtype); +int sock_diag_destroy(struct sock *sk, int err); #endif diff --git a/include/net/sock.h b/include/net/sock.h index 887be91daa8b8..1ddde6d31e37c 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -999,6 +999,7 @@ struct proto { void (*destroy_cgroup)(struct mem_cgroup *memcg); struct cg_proto *(*proto_cgroup)(struct mem_cgroup *memcg); #endif + int (*diag_destroy)(struct sock *sk, int err); }; /* diff --git a/include/uapi/linux/sock_diag.h b/include/uapi/linux/sock_diag.h index b00e29efb1619..472adbb711ed5 100644 --- a/include/uapi/linux/sock_diag.h +++ b/include/uapi/linux/sock_diag.h @@ -4,6 +4,7 @@ #include #define SOCK_DIAG_BY_FAMILY 20 +#define SOCK_DESTROY_BACKPORT 21 struct sock_diag_req { __u8 sdiag_family; diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index c38e7a2b5a8ee..3f78978b21730 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c @@ -135,7 +135,7 @@ void sock_diag_unregister(const struct sock_diag_handler *hnld) } EXPORT_SYMBOL_GPL(sock_diag_unregister); -static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) +static int __sock_diag_cmd(struct sk_buff *skb, struct nlmsghdr *nlh) { int err; struct sock_diag_req *req = nlmsg_data(nlh); @@ -155,8 +155,12 @@ static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) hndl = sock_diag_handlers[req->sdiag_family]; if (hndl == NULL) err = -ENOENT; - else + else if (nlh->nlmsg_type == SOCK_DIAG_BY_FAMILY) err = hndl->dump(skb, nlh); + else if (nlh->nlmsg_type == SOCK_DESTROY_BACKPORT && hndl->destroy) + err = hndl->destroy(skb, nlh); + else + err = -EOPNOTSUPP; mutex_unlock(&sock_diag_table_mutex); return err; @@ -182,7 +186,8 @@ static int sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) return ret; case SOCK_DIAG_BY_FAMILY: - return __sock_diag_rcv_msg(skb, nlh); + case SOCK_DESTROY_BACKPORT: + return __sock_diag_cmd(skb, nlh); default: return -EINVAL; } @@ -197,6 +202,18 @@ static void sock_diag_rcv(struct sk_buff *skb) mutex_unlock(&sock_diag_mutex); } +int sock_diag_destroy(struct sock *sk, int err) +{ + if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) + return -EPERM; + + if (!sk->sk_prot->diag_destroy) + return -EOPNOTSUPP; + + return sk->sk_prot->diag_destroy(sk, err); +} +EXPORT_SYMBOL_GPL(sock_diag_destroy); + static int __net_init diag_net_init(struct net *net) { struct netlink_kernel_cfg cfg = { From 197c89347366feb01b36df5b51015a539b6d90e1 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Wed, 16 Dec 2015 12:30:04 +0900 Subject: [PATCH 065/320] net: diag: Support SOCK_DESTROY for inet sockets. This passes the SOCK_DESTROY operation to the underlying protocol diag handler, or returns -EOPNOTSUPP if that handler does not define a destroy operation. Most of this patch is just renaming functions. This is not strictly necessary, but it would be fairly counterintuitive to have the code to destroy inet sockets be in a function whose name starts with inet_diag_get. [Backport of net-next 6eb5d2e08f071c05ecbe135369c9ad418826cab2] Change-Id: Id9e9d85591bfbb885e5640b7865d24d0604544ad Signed-off-by: Lorenzo Colitti Acked-by: Eric Dumazet Signed-off-by: David S. Miller Git-commit: 3d4ce855f63645ca647950ab13ce46b80d32065a Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: Ashwanth Goli --- include/linux/inet_diag.h | 4 ++++ net/ipv4/inet_diag.c | 23 +++++++++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h index 0f3eddff8eeae..25de5e73845cb 100644 --- a/include/linux/inet_diag.h +++ b/include/linux/inet_diag.h @@ -24,6 +24,10 @@ struct inet_diag_handler { void (*idiag_get_info)(struct sock *sk, struct inet_diag_msg *r, void *info); + + int (*destroy)(struct sk_buff *in_skb, + struct inet_diag_req_v2 *req); + __u16 idiag_type; }; diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 150a760bfa6c9..20aab56df89b2 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -378,7 +378,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, } EXPORT_SYMBOL_GPL(inet_diag_dump_one_icsk); -static int inet_diag_get_exact(struct sk_buff *in_skb, +static int inet_diag_cmd_exact(int cmd, struct sk_buff *in_skb, const struct nlmsghdr *nlh, struct inet_diag_req_v2 *req) { @@ -388,8 +388,12 @@ static int inet_diag_get_exact(struct sk_buff *in_skb, handler = inet_diag_lock_handler(req->sdiag_protocol); if (IS_ERR(handler)) err = PTR_ERR(handler); - else + else if (cmd == SOCK_DIAG_BY_FAMILY) err = handler->dump_one(in_skb, nlh, req); + else if (cmd == SOCK_DESTROY_BACKPORT && handler->destroy) + err = handler->destroy(in_skb, req); + else + err = -EOPNOTSUPP; inet_diag_unlock_handler(handler); return err; @@ -1089,7 +1093,7 @@ static int inet_diag_get_exact_compat(struct sk_buff *in_skb, req.idiag_states = rc->idiag_states; req.id = rc->id; - return inet_diag_get_exact(in_skb, nlh, &req); + return inet_diag_cmd_exact(SOCK_DIAG_BY_FAMILY, in_skb, nlh, &req); } static int inet_diag_rcv_msg_compat(struct sk_buff *skb, struct nlmsghdr *nlh) @@ -1123,7 +1127,7 @@ static int inet_diag_rcv_msg_compat(struct sk_buff *skb, struct nlmsghdr *nlh) return inet_diag_get_exact_compat(skb, nlh); } -static int inet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h) +static int inet_diag_handler_cmd(struct sk_buff *skb, struct nlmsghdr *h) { int hdrlen = sizeof(struct inet_diag_req_v2); struct net *net = sock_net(skb->sk); @@ -1131,7 +1135,8 @@ static int inet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h) if (nlmsg_len(h) < hdrlen) return -EINVAL; - if (h->nlmsg_flags & NLM_F_DUMP) { + if (h->nlmsg_type == SOCK_DIAG_BY_FAMILY && + h->nlmsg_flags & NLM_F_DUMP) { if (nlmsg_attrlen(h, hdrlen)) { struct nlattr *attr; attr = nlmsg_find_attr(h, hdrlen, @@ -1149,17 +1154,19 @@ static int inet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h) } } - return inet_diag_get_exact(skb, h, nlmsg_data(h)); + return inet_diag_cmd_exact(h->nlmsg_type, skb, h, nlmsg_data(h)); } static const struct sock_diag_handler inet_diag_handler = { .family = AF_INET, - .dump = inet_diag_handler_dump, + .dump = inet_diag_handler_cmd, + .destroy = inet_diag_handler_cmd, }; static const struct sock_diag_handler inet6_diag_handler = { .family = AF_INET6, - .dump = inet_diag_handler_dump, + .dump = inet_diag_handler_cmd, + .destroy = inet_diag_handler_cmd, }; int inet_diag_register(const struct inet_diag_handler *h) From e165dd5e874c84c351795bc3004bcafc2dbc1cf8 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Wed, 16 Dec 2015 12:30:05 +0900 Subject: [PATCH 066/320] net: diag: Support destroying TCP sockets. This implements SOCK_DESTROY for TCP sockets. It causes all blocking calls on the socket to fail fast with ECONNABORTED and causes a protocol close of the socket. It informs the other end of the connection by sending a RST, i.e., initiating a TCP ABORT as per RFC 793. ECONNABORTED was chosen for consistency with FreeBSD. [Backport of net-next c1e64e298b8cad309091b95d8436a0255c84f54a] Change-Id: I6fde455d856059fd1ef841051c651dd146d41829 Signed-off-by: Lorenzo Colitti Acked-by: Eric Dumazet Signed-off-by: David S. Miller Git-commit: 529dfc601d43af562473d5cd85393440f61969a9 Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: Ashwanth Goli --- include/net/tcp.h | 2 ++ net/ipv4/Kconfig | 13 +++++++++++++ net/ipv4/tcp.c | 32 ++++++++++++++++++++++++++++++++ net/ipv4/tcp_diag.c | 19 +++++++++++++++++++ net/ipv4/tcp_ipv4.c | 1 + net/ipv6/tcp_ipv6.c | 1 + 6 files changed, 68 insertions(+) diff --git a/include/net/tcp.h b/include/net/tcp.h index 4cc1f2268cee0..9e015ac6a4575 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1057,6 +1057,8 @@ extern void tcp_set_state(struct sock *sk, int state); extern void tcp_done(struct sock *sk); +int tcp_abort(struct sock *sk, int err); + static inline void tcp_sack_reset(struct tcp_options_received *rx_opt) { rx_opt->dsack = 0; diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 8603ca8271041..0ee167c3ee3bc 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig @@ -433,6 +433,19 @@ config INET_UDP_DIAG Support for UDP socket monitoring interface used by the ss tool. If unsure, say Y. +config INET_DIAG_DESTROY + bool "INET: allow privileged process to administratively close sockets" + depends on INET_DIAG + default n + ---help--- + Provides a SOCK_DESTROY_BACKPORT operation that allows privileged processes + (e.g., a connection manager or a network administration tool such as + ss) to close sockets opened by other processes. Closing a socket in + this way interrupts any blocking read/write/connect operations on + the socket and causes future socket calls to behave as if the socket + had been disconnected. + If unsure, say N. + menuconfig TCP_CONG_ADVANCED bool "TCP: advanced congestion control" ---help--- diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 65fd0484cbed6..351510f7f6aff 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3386,6 +3386,38 @@ void tcp_done(struct sock *sk) } EXPORT_SYMBOL_GPL(tcp_done); +int tcp_abort(struct sock *sk, int err) +{ + if (sk->sk_state == TCP_TIME_WAIT) { + inet_twsk_put((struct inet_timewait_sock *)sk); + return -EOPNOTSUPP; + } + + /* Don't race with userspace socket closes such as tcp_close. */ + lock_sock(sk); + + /* Don't race with BH socket closes such as inet_csk_listen_stop. */ + local_bh_disable(); + bh_lock_sock(sk); + + if (!sock_flag(sk, SOCK_DEAD)) { + sk->sk_err = err; + /* This barrier is coupled with smp_rmb() in tcp_poll() */ + smp_wmb(); + sk->sk_error_report(sk); + if (tcp_need_reset(sk->sk_state)) + tcp_send_active_reset(sk, GFP_ATOMIC); + tcp_done(sk); + } + + bh_unlock_sock(sk); + local_bh_enable(); + release_sock(sk); + sock_put(sk); + return 0; +} +EXPORT_SYMBOL_GPL(tcp_abort); + extern struct tcp_congestion_ops tcp_reno; static __initdata unsigned long thash_entries; diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c index ed3f2ad42e0f0..a56461c21b97d 100644 --- a/net/ipv4/tcp_diag.c +++ b/net/ipv4/tcp_diag.c @@ -11,6 +11,8 @@ #include +#include +#include #include #include @@ -46,11 +48,28 @@ static int tcp_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *nlh, return inet_diag_dump_one_icsk(&tcp_hashinfo, in_skb, nlh, req); } +#ifdef CONFIG_INET_DIAG_DESTROY +static int tcp_diag_destroy(struct sk_buff *in_skb, + struct inet_diag_req_v2 *req) +{ + struct net *net = sock_net(in_skb->sk); + struct sock *sk = inet_diag_find_one_icsk(net, &tcp_hashinfo, req); + + if (IS_ERR(sk)) + return PTR_ERR(sk); + + return sock_diag_destroy(sk, ECONNABORTED); +} +#endif + static const struct inet_diag_handler tcp_diag_handler = { .dump = tcp_diag_dump, .dump_one = tcp_diag_dump_one, .idiag_get_info = tcp_diag_get_info, .idiag_type = IPPROTO_TCP, +#ifdef CONFIG_INET_DIAG_DESTROY + .destroy = tcp_diag_destroy, +#endif }; static int __init tcp_diag_init(void) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index fefe36a6d3d7f..fbfe33afc5591 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2892,6 +2892,7 @@ struct proto tcp_prot = { .destroy_cgroup = tcp_destroy_cgroup, .proto_cgroup = tcp_proto_cgroup, #endif + .diag_destroy = tcp_abort, }; EXPORT_SYMBOL(tcp_prot); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 9c2f2b9c17e6b..3dd3f01bcb06b 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1948,6 +1948,7 @@ struct proto tcpv6_prot = { .proto_cgroup = tcp_proto_cgroup, #endif .clear_sk = tcp_v6_clear_sk, + .diag_destroy = tcp_abort, }; static const struct inet6_protocol tcpv6_protocol = { From a1ff677d4515ee1053bad9419d6346dc8d6c7656 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Sun, 20 Dec 2015 02:39:43 +0900 Subject: [PATCH 067/320] net: tcp: deal with listen sockets properly in tcp_abort. When closing a listen socket, tcp_abort currently calls tcp_done without clearing the request queue. If the socket has a child socket that is established but not yet accepted, the child socket is then left without a parent, causing a leak. Fix this by setting the socket state to TCP_CLOSE and calling inet_csk_listen_stop with the socket lock held, like tcp_close does. Tested using net_test. With this patch, calling SOCK_DESTROY on a listen socket that has an established but not yet accepted child socket results in the parent and the child being closed, such that they no longer appear in sock_diag dumps. [Backport of net-next 2010b93e9317cc12acd20c4aed385af7f9d1681e] Change-Id: I7e8bc9d1041c5b1d0a27d8bcea627322f3c54404 Reported-by: Eric Dumazet Signed-off-by: Lorenzo Colitti Acked-by: Eric Dumazet Git-commit: 9c712fe0f4a1317e33fb5c5b4529cea630aa1027 Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: David S. Miller Signed-off-by: Ashwanth Goli --- net/ipv4/tcp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 351510f7f6aff..8ec0db2d54077 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3396,6 +3396,11 @@ int tcp_abort(struct sock *sk, int err) /* Don't race with userspace socket closes such as tcp_close. */ lock_sock(sk); + if (sk->sk_state == TCP_LISTEN) { + tcp_set_state(sk, TCP_CLOSE); + inet_csk_listen_stop(sk); + } + /* Don't race with BH socket closes such as inet_csk_listen_stop. */ local_bh_disable(); bh_lock_sock(sk); From 151e1430b128de4f8efa4cc78a46d4ee05d5aa66 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 4 Oct 2015 21:08:09 -0700 Subject: [PATCH 068/320] ipv6: inet6_sk() should use sk_fullsock() SYN_RECV & TIMEWAIT sockets are not full blown, they do not have a pinet6 pointer. Bug: 24163529 Change-Id: Ie2c924ab7fd99a1ea7593e4dfbb013a01c9849e9 Fixes: ca6fb0651883 ("tcp: attach SYNACK messages to request sockets instead of listener") Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Lorenzo Colitti Git-commit: feee3c175c23ae72ed17154caaa82a3002de0023 Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: Ashwanth Goli --- include/linux/ipv6.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index d8ad57edc6963..9f3792c1dcde3 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -275,9 +275,9 @@ static inline struct inet6_timewait_sock *inet6_twsk(const struct sock *sk) } #if IS_ENABLED(CONFIG_IPV6) -static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk) +static inline struct ipv6_pinfo *inet6_sk(const struct sock *__sk) { - return inet_sk(__sk)->pinet6; + return sk_fullsock(__sk) ? inet_sk(__sk)->pinet6 : NULL; } static inline struct inet6_request_sock * From 4841547085f6c7fa720336c42d441d0f67168e00 Mon Sep 17 00:00:00 2001 From: Arumuga Durai A Date: Fri, 27 May 2016 16:36:01 +0530 Subject: [PATCH 069/320] USB: gadget: serial: Fix debugfs crash Serial function driver creates debugfs files even though ports are not allocated. Fetching/reading those files without allocation of ports leads to crash. Check port allocation before creating the files. CRs-Fixed: 1003498 Change-Id: I85b050a261cca6f961d5d9058efb8b7facf242ce Signed-off-by: Arumuga Durai A --- drivers/usb/gadget/u_serial.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 030a47ed55985..7f0c734100a38 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c @@ -1258,6 +1258,9 @@ static ssize_t debug_read_status(struct file *file, char __user *ubuf, int ret; int result = 0; + if (!ui_dev) + return -EINVAL; + tty = ui_dev->port.tty; gser = ui_dev->port_usb; @@ -1310,6 +1313,9 @@ static ssize_t debug_write_reset(struct file *file, const char __user *buf, struct gs_port *ui_dev = file->private_data; unsigned long flags; + if (!ui_dev) + return -EINVAL; + spin_lock_irqsave(&ui_dev->port_lock, flags); ui_dev->nbytes_from_host = ui_dev->nbytes_to_tty = ui_dev->nbytes_from_tty = ui_dev->nbytes_to_host = 0; @@ -1339,6 +1345,9 @@ static void usb_debugfs_init(struct gs_port *ui_dev, int port_num) { char buf[48]; + if (!ui_dev) + return; + snprintf(buf, 48, "usb_serial%d", port_num); gs_dent = debugfs_create_dir(buf, 0); if (!gs_dent || IS_ERR(gs_dent)) From 52a431aa74701589d02e9be66edf4980c92b95b6 Mon Sep 17 00:00:00 2001 From: Nirmal Abraham Date: Fri, 17 Jun 2016 10:54:33 +0530 Subject: [PATCH 070/320] msm: mdss: Enable GDSC before enabling clocks in mdp3 probe For splash disable in LK or simulated panel / no panel connected usecases, device was crashing at kernel bootup as GDSC was not turned on before enabling the clock to read MDP version. Fix this by adding calls for turning on GDSC before enabling clocks to read MDP version. Change-Id: I16413a33c895294acb049e78d55bc3ec89746f1e Signed-off-by: Nirmal Abraham --- drivers/video/msm/mdss/mdp3.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c index fcf9cd1f3dcaf..2a9c9156ac5e1 100644 --- a/drivers/video/msm/mdss/mdp3.c +++ b/drivers/video/msm/mdss/mdp3.c @@ -909,11 +909,19 @@ static int mdp3_check_version(void) { int rc; + rc = mdp3_footswitch_ctrl(1); + if (rc) { + pr_err("unable to turn on FS\n"); + return rc; + } + rc = mdp3_clk_update(MDP3_CLK_AHB, 1); rc |= mdp3_clk_update(MDP3_CLK_AXI, 1); rc |= mdp3_clk_update(MDP3_CLK_MDP_CORE, 1); - if (rc) + if (rc) { + mdp3_footswitch_ctrl(0); return rc; + } mdp3_res->mdp_rev = MDP3_REG_READ(MDP3_REG_HW_VERSION); @@ -923,6 +931,10 @@ static int mdp3_check_version(void) if (rc) pr_err("fail to turn off the MDP3_CLK_AHB clk\n"); + rc = mdp3_footswitch_ctrl(0); + if (rc) + pr_err("unable to turn off FS\n"); + if (mdp3_res->mdp_rev != MDP_CORE_HW_VERSION) { pr_err("mdp_hw_revision=%x mismatch\n", mdp3_res->mdp_rev); rc = -ENODEV; From b6b222a19c920bc88cef3465b7a4cbc85fe8aedd Mon Sep 17 00:00:00 2001 From: "Sravan Kumar D.V.N" Date: Tue, 3 May 2016 18:38:47 +0530 Subject: [PATCH 071/320] msm: mdss: Move PP programming after mdp wait for ping pong done To ensure PP registers are not programming in the middle of the frame transfer moving PP programming to after wait4pingpong for command mode panel devices. Change-Id: Ie639a26543e2f20b61d6dfc73b3bcbd6a43b24be Signed-off-by: Sravan Kumar D.V.N Signed-off-by: Nirmal Abraham --- drivers/video/msm/mdss/mdss_mdp_ctl.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c index 0f04a1230f673..491f3eb3d4573 100644 --- a/drivers/video/msm/mdss/mdss_mdp_ctl.c +++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -3316,7 +3316,7 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, } ATRACE_BEGIN("postproc_programming"); - if (ctl->mfd && ctl->mfd->dcm_state != DTM_ENTER) + if (ctl->is_video_mode && ctl->mfd && ctl->mfd->dcm_state != DTM_ENTER) /* postprocessing setup, including dspp */ mdss_mdp_pp_setup_locked(ctl); @@ -3359,6 +3359,14 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, ATRACE_END("wait_pingpong sctl"); } } + + /* + * Moved pp programming to post ping pong + */ + if (!ctl->is_video_mode && ctl->mfd && ctl->mfd->dcm_state != DTM_ENTER) + /* postprocessing setup, including dspp */ + mdss_mdp_pp_setup_locked(ctl); + if (commit_cb) commit_cb->commit_cb_fnc(MDP_COMMIT_STAGE_READY_FOR_KICKOFF, commit_cb->data); From 78b1864edf77cf36328ff7a2892cc833197c7652 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 20 Jan 2016 16:25:01 -0800 Subject: [PATCH 072/320] net: diag: support v4mapped sockets in inet_diag_find_one_icsk() Lorenzo reported that we could not properly find v4mapped sockets in inet_diag_find_one_icsk(). This patch fixes the issue. [Cherry-pick of net 7c1306723ee916ea9f1fa7d9e4c7a6d029ca7aaf] Reported-by: Lorenzo Colitti Signed-off-by: Eric Dumazet Acked-by: Lorenzo Colitti Signed-off-by: David S. Miller Change-Id: I88ce179a5aec7800f8a100d9c80e6b63e1963219 Git-commit: 15d65ff63accb0fb58ec59b1d6fd9b1db8c25684 Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: Ashwanth Goli --- net/ipv4/inet_diag.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 20aab56df89b2..b7527bfdc6a72 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -303,12 +303,18 @@ struct sock *inet_diag_find_one_icsk(struct net *net, } #if IS_ENABLED(CONFIG_IPV6) else if (req->sdiag_family == AF_INET6) { - sk = inet6_lookup(net, hashinfo, - (struct in6_addr *)req->id.idiag_dst, - req->id.idiag_dport, - (struct in6_addr *)req->id.idiag_src, - req->id.idiag_sport, - req->id.idiag_if); + if (ipv6_addr_v4mapped((struct in6_addr *)req->id.idiag_dst) && + ipv6_addr_v4mapped((struct in6_addr *)req->id.idiag_src)) + sk = inet_lookup(net, hashinfo, req->id.idiag_dst[3], + req->id.idiag_dport, req->id.idiag_src[3], + req->id.idiag_sport, req->id.idiag_if); + else + sk = inet6_lookup(net, hashinfo, + (struct in6_addr *)req->id.idiag_dst, + req->id.idiag_dport, + (struct in6_addr *)req->id.idiag_src, + req->id.idiag_sport, + req->id.idiag_if); } #endif else { From 35322afa91ca6c3ec72d295e251143f39aa60f36 Mon Sep 17 00:00:00 2001 From: Viraja Kommaraju Date: Sat, 11 Jun 2016 13:52:18 +0530 Subject: [PATCH 073/320] ASoC: msm: qdsp6v2: Change audio drivers to use %pK Change all qdsp6v2 audio driver to use %pK instead of %p. %pK hides addresses when the users doesn't have kernel permissions. If address information is needed echo 0 > /proc/sys/kernel/kptr_restrict. Change-Id: Ifcd61bd2615505be80dd834e9dbee9c22f3d72ac Signed-off-by: Viraja Kommaraju --- drivers/soc/qcom/qdsp6v2/apr.c | 12 ++-- drivers/soc/qcom/qdsp6v2/msm_audio_ion.c | 36 +++++----- sound/soc/msm/qdsp6v2/audio_cal_utils.c | 2 +- sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c | 16 ++--- sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c | 4 +- sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c | 4 +- sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c | 4 +- sound/soc/msm/qdsp6v2/msm-dts-eagle.c | 32 ++++----- sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c | 6 +- sound/soc/msm/qdsp6v2/msm-lsm-client.c | 22 +++--- sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c | 6 +- sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c | 6 +- sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c | 6 +- sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c | 6 +- sound/soc/msm/qdsp6v2/q6adm.c | 22 +++--- sound/soc/msm/qdsp6v2/q6afe.c | 22 +++--- sound/soc/msm/qdsp6v2/q6asm.c | 70 +++++++++---------- sound/soc/msm/qdsp6v2/q6core.c | 8 +-- sound/soc/msm/qdsp6v2/q6lsm.c | 20 +++--- sound/soc/msm/qdsp6v2/q6voice.c | 30 ++++---- sound/soc/msm/qdsp6v2/rtac.c | 26 +++---- 21 files changed, 180 insertions(+), 180 deletions(-) diff --git a/drivers/soc/qcom/qdsp6v2/apr.c b/drivers/soc/qcom/qdsp6v2/apr.c index f2d3260c263bd..d723432aa1ca7 100644 --- a/drivers/soc/qcom/qdsp6v2/apr.c +++ b/drivers/soc/qcom/qdsp6v2/apr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -457,7 +457,7 @@ void apr_cb_func(void *buf, int len, void *priv) pr_debug("\n*****************\n"); if (!buf || len <= APR_HDR_SIZE) { - pr_err("APR: Improper apr pkt received:%p %d\n", buf, len); + pr_err("APR: Improper apr pkt received:%pK %d\n", buf, len); return; } hdr = buf; @@ -543,7 +543,7 @@ void apr_cb_func(void *buf, int len, void *priv) return; } pr_debug("svc_idx = %d\n", i); - pr_debug("%x %x %x %p %p\n", c_svc->id, c_svc->dest_id, + pr_debug("%x %x %x %pK %pK\n", c_svc->id, c_svc->dest_id, c_svc->client_id, c_svc->fn, c_svc->priv); data.payload_size = hdr->pkt_size - hdr_size; data.opcode = hdr->opcode; @@ -607,7 +607,7 @@ static void apr_reset_deregister(struct work_struct *work) container_of(work, struct apr_reset_work, work); handle = apr_reset->handle; - pr_debug("%s:handle[%p]\n", __func__, handle); + pr_debug("%s:handle[%pK]\n", __func__, handle); apr_deregister(handle); kfree(apr_reset); } @@ -640,7 +640,7 @@ int apr_deregister(void *handle) client[dest_id][client_id].svc_cnt--; if (!client[dest_id][client_id].svc_cnt) { svc->need_reset = 0x0; - pr_debug("%s: service is reset %p\n", __func__, svc); + pr_debug("%s: service is reset %pK\n", __func__, svc); } } @@ -668,7 +668,7 @@ void apr_reset(void *handle) if (!handle) return; - pr_debug("%s: handle[%p]\n", __func__, handle); + pr_debug("%s: handle[%pK]\n", __func__, handle); if (apr_reset_workqueue == NULL) { pr_err("%s: apr_reset_workqueue is NULL\n", __func__); diff --git a/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c b/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c index 52c97e4e60bd0..8921c581273bd 100644 --- a/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c +++ b/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -103,11 +103,11 @@ int msm_audio_ion_alloc(const char *name, struct ion_client **client, pr_err("%s: ION memory mapping for AUDIO failed\n", __func__); goto err_ion_handle; } - pr_debug("%s: mapped address = %p, size=%zd\n", __func__, + pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, *vaddr, bufsz); if (bufsz != 0) { - pr_debug("%s: memset to 0 %p %zd\n", __func__, *vaddr, bufsz); + pr_debug("%s: memset to 0 %pK %zd\n", __func__, *vaddr, bufsz); memset((void *)*vaddr, 0, bufsz); } @@ -153,7 +153,7 @@ int msm_audio_ion_import(const char *name, struct ion_client **client, bufsz should be 0 and fd shouldn't be 0 as of now */ *handle = ion_import_dma_buf(*client, fd); - pr_debug("%s: DMA Buf name=%s, fd=%d handle=%p\n", __func__, + pr_debug("%s: DMA Buf name=%s, fd=%d handle=%pK\n", __func__, name, fd, *handle); if (IS_ERR_OR_NULL((void *) (*handle))) { pr_err("%s: ion import dma buffer failed\n", @@ -184,7 +184,7 @@ int msm_audio_ion_import(const char *name, struct ion_client **client, rc = -ENOMEM; goto err_ion_handle; } - pr_debug("%s: mapped address = %p, size=%zd\n", __func__, + pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, *vaddr, bufsz); return 0; @@ -207,7 +207,7 @@ int msm_audio_ion_free(struct ion_client *client, struct ion_handle *handle) } if (msm_audio_ion_data.smmu_enabled) { /* Need to populate book kept infomation */ - pr_debug("client=%p, domain=%p, domain_id=%d, group=%p", + pr_debug("client=%pK, domain=%pK, domain_id=%d, group=%pK", client, msm_audio_ion_data.domain, msm_audio_ion_data.domain_id, msm_audio_ion_data.group); @@ -273,7 +273,7 @@ int msm_audio_ion_mmap(struct audio_buffer *ab, offset = 0; } len = min(len, remainder); - pr_debug("vma=%p, addr=%x len=%ld vm_start=%x vm_end=%x vm_page_prot=%ld\n", + pr_debug("vma=%pK, addr=%x len=%ld vm_start=%x vm_end=%x vm_page_prot=%ld\n", vma, (unsigned int)addr, len, (unsigned int)vma->vm_start, (unsigned int)vma->vm_end, @@ -296,8 +296,8 @@ int msm_audio_ion_mmap(struct audio_buffer *ab, , __func__ , ret); return ret; } - pr_debug("phys=%pa len=%zd\n", &phys_addr, phys_len); - pr_debug("vma=%p, vm_start=%x vm_end=%x vm_pgoff=%ld vm_page_prot=%ld\n", + pr_debug("phys=%pK len=%zd\n", &phys_addr, phys_len); + pr_debug("vma=%pK, vm_start=%x vm_end=%x vm_pgoff=%ld vm_page_prot=%ld\n", vma, (unsigned int)vma->vm_start, (unsigned int)vma->vm_end, vma->vm_pgoff, (unsigned long int)vma->vm_page_prot); @@ -333,7 +333,7 @@ struct ion_client *msm_audio_ion_client_create(const char *name) void msm_audio_ion_client_destroy(struct ion_client *client) { - pr_debug("%s: client = %p smmu_enabled = %d\n", __func__, + pr_debug("%s: client = %pK smmu_enabled = %d\n", __func__, client, msm_audio_ion_data.smmu_enabled); ion_client_destroy(client); @@ -355,7 +355,7 @@ int msm_audio_ion_import_legacy(const char *name, struct ion_client *client, bufsz should be 0 and fd shouldn't be 0 as of now */ *handle = ion_import_dma_buf(client, fd); - pr_debug("%s: DMA Buf name=%s, fd=%d handle=%p\n", __func__, + pr_debug("%s: DMA Buf name=%s, fd=%d handle=%pK\n", __func__, name, fd, *handle); if (IS_ERR_OR_NULL((void *)(*handle))) { pr_err("%s: ion import dma buffer failed\n", @@ -421,7 +421,7 @@ int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op) int msm_cache_ops = 0; if (!abuff) { - pr_err("Invalid params: %p, %p\n", __func__, abuff); + pr_err("Invalid params: %pK, %pK\n", __func__, abuff); return -EINVAL; } rc = ion_handle_get_flags(abuff->client, abuff->handle, @@ -467,7 +467,7 @@ static int msm_audio_ion_get_phys(struct ion_client *client, pr_err("%s: ION map iommu failed %d\n", __func__, rc); return rc; } - pr_debug("client=%p, domain=%p, domain_id=%d, group=%p", + pr_debug("client=%pK, domain=%pK, domain_id=%d, group=%pK", client, msm_audio_ion_data.domain, msm_audio_ion_data.domain_id, msm_audio_ion_data.group); /* Append the SMMU SID information to the address */ @@ -476,7 +476,7 @@ static int msm_audio_ion_get_phys(struct ion_client *client, /* SMMU is disabled*/ rc = ion_phys(client, handle, addr, len); } - pr_debug("phys=%pa, len=%zd, rc=%d\n", &(*addr), *len, rc); + pr_debug("phys=%pK, len=%zd, rc=%d\n", &(*addr), *len, rc); return rc; } @@ -540,18 +540,18 @@ static int msm_audio_ion_probe(struct platform_device *pdev) msm_audio_ion_data.domain = iommu_group_get_iommudata(msm_audio_ion_data.group); if (IS_ERR_OR_NULL(msm_audio_ion_data.domain)) { - pr_err("Failed to get domain data for group %p", + pr_err("Failed to get domain data for group %pK", msm_audio_ion_data.group); goto fail_group; } msm_audio_ion_data.domain_id = msm_find_domain_no(msm_audio_ion_data.domain); if (msm_audio_ion_data.domain_id < 0) { - pr_err("Failed to get domain index for domain %p", + pr_err("Failed to get domain index for domain %pK", msm_audio_ion_data.domain); goto fail_group; } - pr_debug("domain=%p, domain_id=%d, group=%p", + pr_debug("domain=%pK, domain_id=%d, group=%pK", msm_audio_ion_data.domain, msm_audio_ion_data.domain_id, msm_audio_ion_data.group); @@ -575,7 +575,7 @@ static int msm_audio_ion_probe(struct platform_device *pdev) static int msm_audio_ion_remove(struct platform_device *pdev) { - pr_debug("%s: msm audio ion is unloaded, domain=%p, group=%p\n", + pr_debug("%s: msm audio ion is unloaded, domain=%pK, group=%pK\n", __func__, msm_audio_ion_data.domain, msm_audio_ion_data.group); iommu_detach_group(msm_audio_ion_data.domain, msm_audio_ion_data.group); diff --git a/sound/soc/msm/qdsp6v2/audio_cal_utils.c b/sound/soc/msm/qdsp6v2/audio_cal_utils.c index 95ad79af15bd8..33e5dfc6950c8 100644 --- a/sound/soc/msm/qdsp6v2/audio_cal_utils.c +++ b/sound/soc/msm/qdsp6v2/audio_cal_utils.c @@ -580,7 +580,7 @@ static struct cal_block_data *create_cal_block(struct cal_type_data *cal_type, goto err; } cal_block->buffer_number = basic_cal->cal_hdr.buffer_number; - pr_debug("%s: created block for cal type %d, buf num %d, map handle %d, map size %zd paddr 0x%pa!\n", + pr_debug("%s: created block for cal type %d, buf num %d, map handle %d, map size %zd paddr 0x%pK!\n", __func__, cal_type->info.reg.cal_type, cal_block->buffer_number, cal_block->map_data.ion_map_handle, diff --git a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c index 82de46ccc6d06..931f473bc84f2 100644 --- a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -192,7 +192,7 @@ static void compr_event_handler(uint32_t opcode, pr_debug("%s:writing %d bytes of buffer[%d] to dsp 2\n", __func__, prtd->pcm_count, prtd->out_head); temp = buf[0].phys + (prtd->out_head * prtd->pcm_count); - pr_debug("%s:writing buffer[%d] from 0x%pa\n", + pr_debug("%s:writing buffer[%d] from 0x%pK\n", __func__, prtd->out_head, &temp); if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) @@ -243,7 +243,7 @@ static void compr_event_handler(uint32_t opcode, break; case ASM_DATA_EVENT_READ_DONE_V2: { pr_debug("ASM_DATA_EVENT_READ_DONE\n"); - pr_debug("buf = %p, data = 0x%X, *data = %p,\n" + pr_debug("buf = %pK, data = 0x%X, *data = %pK,\n" "prtd->pcm_irq_pos = %d\n", prtd->audio_client->port[OUT].buf, *(uint32_t *)prtd->audio_client->port[OUT].buf->data, @@ -253,7 +253,7 @@ static void compr_event_handler(uint32_t opcode, memcpy(prtd->audio_client->port[OUT].buf->data + prtd->pcm_irq_pos, (ptrmem + READDONE_IDX_SIZE), COMPRE_CAPTURE_HEADER_SIZE); - pr_debug("buf = %p, updated data = 0x%X, *data = %p\n", + pr_debug("buf = %pK, updated data = 0x%X, *data = %pK\n", prtd->audio_client->port[OUT].buf, *(uint32_t *)(prtd->audio_client->port[OUT].buf->data + prtd->pcm_irq_pos), @@ -269,7 +269,7 @@ static void compr_event_handler(uint32_t opcode, } buf = prtd->audio_client->port[OUT].buf; - pr_debug("pcm_irq_pos=%d, buf[0].phys = 0x%pa\n", + pr_debug("pcm_irq_pos=%d, buf[0].phys = 0x%pK\n", prtd->pcm_irq_pos, &buf[0].phys); read_param.len = prtd->pcm_count - COMPRE_CAPTURE_HEADER_SIZE; read_param.paddr = buf[0].phys + @@ -295,7 +295,7 @@ static void compr_event_handler(uint32_t opcode, pr_debug("%s: writing %d bytes of buffer[%d] to dsp\n", __func__, prtd->pcm_count, prtd->out_head); buf = prtd->audio_client->port[IN].buf; - pr_debug("%s: writing buffer[%d] from 0x%pa head %d count %d\n", + pr_debug("%s: writing buffer[%d] from 0x%pK head %d count %d\n", __func__, prtd->out_head, &buf[0].phys, prtd->pcm_count, prtd->out_head); if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) @@ -602,7 +602,7 @@ static int msm_compr_capture_prepare(struct snd_pcm_substream *substream) - COMPRE_CAPTURE_HEADER_SIZE; read_param.paddr = buf[i].phys + COMPRE_CAPTURE_HEADER_SIZE; - pr_debug("Push buffer [%d] to DSP, paddr: %pa, vaddr: %p\n", + pr_debug("Push buffer [%d] to DSP, paddr: %pK, vaddr: %pK\n", i, &read_param.paddr, buf[i].data); q6asm_async_read(prtd->audio_client, &read_param); @@ -963,7 +963,7 @@ static int msm_compr_hw_params(struct snd_pcm_substream *substream, dma_buf->addr = buf[0].phys; dma_buf->bytes = runtime->hw.buffer_bytes_max; - pr_debug("%s: buf[%p]dma_buf->area[%p]dma_buf->addr[%pa]\n" + pr_debug("%s: buf[%pK]dma_buf->area[%pK]dma_buf->addr[%pK]\n" "dma_buf->bytes[%zd]\n", __func__, (void *)buf, (void *)dma_buf->area, &dma_buf->addr, dma_buf->bytes); diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c index 3bb207a101ee1..2f5ff04efd30c 100644 --- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1992,7 +1992,7 @@ static int msm_compr_get_caps(struct snd_compr_stream *cstream, memcpy(arg, &prtd->compr_cap, sizeof(struct snd_compr_caps)); } else { ret = -EINVAL; - pr_err("%s: arg (0x%p), prtd (0x%p)\n", __func__, arg, prtd); + pr_err("%s: arg (0x%pK), prtd (0x%pK)\n", __func__, arg, prtd); } return ret; diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c index 8787fb35e7a5e..0ad6f9f1c15d9 100644 --- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1666,7 +1666,7 @@ static int msm_auxpcm_dev_probe(struct platform_device *pdev) goto fail_pdata_nomem; } - dev_dbg(&pdev->dev, "%s: dev %p, dai_data %p, auxpcm_pdata %p\n", + dev_dbg(&pdev->dev, "%s: dev %pK, dai_data %pK, auxpcm_pdata %pK\n", __func__, &pdev->dev, dai_data, auxpcm_pdata); rc = of_property_read_u32_array(pdev->dev.of_node, diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c index 51f8b8c9e4086..aac11f3084980 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c @@ -1103,7 +1103,7 @@ static int msm_ds2_dap_send_end_point(int dev_map_idx, int endp_idx) ds2_ap_params_obj = &ds2_dap_params[cache_device]; pr_debug("%s: cache dev %d, dev_map_idx %d\n", __func__, cache_device, dev_map_idx); - pr_debug("%s: endp - %p %p\n", __func__, + pr_debug("%s: endp - %pK %pK\n", __func__, &ds2_dap_params[cache_device], ds2_ap_params_obj); params_value = kzalloc(params_length, GFP_KERNEL); @@ -1189,7 +1189,7 @@ static int msm_ds2_dap_send_cached_params(int dev_map_idx, } ds2_ap_params_obj = &ds2_dap_params[cache_device]; - pr_debug("%s: cached param - %p %p, cache_device %d\n", __func__, + pr_debug("%s: cached param - %pK %pK, cache_device %d\n", __func__, &ds2_dap_params[cache_device], ds2_ap_params_obj, cache_device); params_value = kzalloc(params_length, GFP_KERNEL); diff --git a/sound/soc/msm/qdsp6v2/msm-dts-eagle.c b/sound/soc/msm/qdsp6v2/msm-dts-eagle.c index 3b334c3fc9152..359cdc96ca272 100644 --- a/sound/soc/msm/qdsp6v2/msm-dts-eagle.c +++ b/sound/soc/msm/qdsp6v2/msm-dts-eagle.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -487,7 +487,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) pr_info("DTS_EAGLE_DRIVER_POST: %s called with control 0x%X (allocate param cache)\n", __func__, cmd); if (copy_from_user((void *)&size, (void *)arg, sizeof(size))) { - pr_err("DTS_EAGLE_DRIVER_POST: error copying size (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error copying size (src:%pK, tgt:%pK, size:%zu)\n", (void *)arg, &size, sizeof(size)); return -EFAULT; } else if (size < 0 || size > DEPC_MAX_SIZE) { @@ -527,7 +527,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) pr_info("DTS_EAGLE_DRIVER_POST: %s called, control 0x%X (get param)\n", __func__, cmd); if (copy_from_user((void *)&depd, (void *)arg, sizeof(depd))) { - pr_err("DTS_EAGLE_DRIVER_POST: error copying dts_eagle_param_desc (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error copying dts_eagle_param_desc (src:%pK, tgt:%pK, size:%zu)\n", (void *)arg, &depd, sizeof(depd)); return -EFAULT; } @@ -583,7 +583,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) pr_info("DTS_EAGLE_DRIVER_POST: %s called, control 0x%X (set param)\n", __func__, cmd); if (copy_from_user((void *)&depd, (void *)arg, sizeof(depd))) { - pr_err("DTS_EAGLE_DRIVER_POST: error copying dts_eagle_param_desc (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error copying dts_eagle_param_desc (src:%pK, tgt:%pK, size:%zu)\n", (void *)arg, &depd, sizeof(depd)); return -EFAULT; } @@ -603,7 +603,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) if (copy_from_user((void *)&_depc[offset], (void *)(((char *)arg)+sizeof(depd)), depd.size)) { - pr_err("DTS_EAGLE_DRIVER_POST: error copying param to cache (src:%p, tgt:%p, size:%i)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error copying param to cache (src:%pK, tgt:%pK, size:%i)\n", ((char *)arg)+sizeof(depd), &_depc[offset], depd.size); return -EFAULT; @@ -639,7 +639,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) pr_info("DTS_EAGLE_DRIVER_POST: %s called with control 0x%X (set param cache block)\n", __func__, cmd); if (copy_from_user((void *)b_, (void *)arg, sizeof(b_))) { - pr_err("DTS_EAGLE_DRIVER_POST: error copying cache block data (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error copying cache block data (src:%pK, tgt:%pK, size:%zu)\n", (void *)arg, b_, sizeof(b_)); return -EFAULT; } @@ -669,7 +669,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) pr_info("DTS_EAGLE_DRIVER_POST: %s called with control 0x%X (set active device)\n", __func__, cmd); if (copy_from_user((void *)data, (void *)arg, sizeof(data))) { - pr_err("DTS_EAGLE_DRIVER_POST: error copying active device data (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error copying active device data (src:%pK, tgt:%pK, size:%zu)\n", (void *)arg, data, sizeof(data)); return -EFAULT; } @@ -691,7 +691,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) __func__, cmd); if (copy_from_user((void *)&target, (void *)arg, sizeof(target))) { - pr_err("DTS_EAGLE_DRIVER_POST: error reading license index. (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error reading license index. (src:%pK, tgt:%pK, size:%zu)\n", (void *)arg, &target, sizeof(target)); return -EFAULT; } @@ -736,7 +736,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) __func__, cmd); if (copy_from_user((void *)target, (void *)arg, sizeof(target))) { - pr_err("DTS_EAGLE_DRIVER_POST: error reading license index (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error reading license index (src:%pK, tgt:%pK, size:%zu)\n", (void *)arg, target, sizeof(target)); return -EFAULT; } @@ -777,7 +777,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) if (copy_from_user((void *)&(((__s32 *)sec_blob[target[0]])[1]), (void *)(((char *)arg)+sizeof(target)), target[1])) { - pr_err("DTS_EAGLE_DRIVER_POST: error copying license to index %i, size %i (src:%p, tgt:%p, size:%i)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error copying license to index %i, size %i (src:%pK, tgt:%pK, size:%i)\n", target[0], target[1], ((char *)arg)+sizeof(target), &(((__s32 *)sec_blob[target[0]])[1]), @@ -795,7 +795,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) __func__, cmd); if (copy_from_user((void *)&target, (void *)arg, sizeof(target))) { - pr_err("DTS_EAGLE_DRIVER_POST: error reading license index (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error reading license index (src:%pK, tgt:%pK, size:%zu)\n", (void *)arg, &target, sizeof(target)); return -EFAULT; } @@ -825,7 +825,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) __func__, cmd); if (copy_from_user((void *)&spec, (void *)arg, sizeof(spec))) { - pr_err("DTS_EAGLE_DRIVER_POST: error reading volume command specifier (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error reading volume command specifier (src:%pK, tgt:%pK, size:%zu)\n", (void *)arg, &spec, sizeof(spec)); return -EFAULT; } @@ -846,7 +846,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) if (copy_from_user((void *)&vol_cmds_d[idx], (void *)(((char *)arg) + sizeof(int)), sizeof(struct vol_cmds_d_))) { - pr_err("DTS_EAGLE_DRIVER_POST: error reading volume command descriptor (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error reading volume command descriptor (src:%pK, tgt:%pK, size:%zu)\n", ((char *)arg) + sizeof(int), &vol_cmds_d[idx], sizeof(struct vol_cmds_d_)); @@ -859,7 +859,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) if (copy_from_user((void *)vol_cmds[idx], (void *)(((char *)arg) + (sizeof(int) + sizeof(struct vol_cmds_d_))), size)) { - pr_err("DTS_EAGLE_DRIVER_POST: error reading volume command string (src:%p, tgt:%p, size:%i)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error reading volume command string (src:%pK, tgt:%pK, size:%i)\n", ((char *)arg) + (sizeof(int) + sizeof(struct vol_cmds_d_)), vol_cmds[idx], size); @@ -909,7 +909,7 @@ int msm_dts_eagle_init_pre(struct audio_client *ac) if (_depc_size == 0 || !_depc || offset < 0 || size <= 0 || cmd == 0 || (offset + size) > _depc_size) { - pr_err("DTS_EAGLE_DRIVER_SENDCACHE_PRE: in %s, primary device %i cache index %i general error - cache size = %u, cache ptr = %p, offset = %i, size = %i, cmd = %i\n", + pr_err("DTS_EAGLE_DRIVER_SENDCACHE_PRE: in %s, primary device %i cache index %i general error - cache size = %u, cache ptr = %pK, offset = %i, size = %i, cmd = %i\n", __func__, _device_primary, cidx, _depc_size, _depc, offset, size, cmd); return -EINVAL; @@ -984,7 +984,7 @@ int msm_dts_eagle_init_post(int port_id, int copp_idx, int topology) if (_depc_size == 0 || !_depc || offset < 0 || size <= 0 || cmd == 0 || (offset + size) > _depc_size) { - pr_err("DTS_EAGLE_DRIVER_SENDCACHE_POST: in %s, primary device %i cache index %i port_id 0x%X general error - cache size = %u, cache ptr = %p, offset = %i, size = %i, cmd = %i\n", + pr_err("DTS_EAGLE_DRIVER_SENDCACHE_POST: in %s, primary device %i cache index %i port_id 0x%X general error - cache size = %u, cache ptr = %pK, offset = %i, size = %i, cmd = %i\n", __func__, _device_primary, cidx, port_id, _depc_size, _depc, offset, size, cmd); return -EINVAL; diff --git a/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c b/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c index dc5e84fb7e5eb..1fb31ea331ede 100644 --- a/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c +++ b/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -289,8 +289,8 @@ static int reg_ion_mem(void) &po.kvaddr); if (rc != 0) pr_err("%s: failed to allocate memory.\n", __func__); - pr_debug("%s: exited ion_client = %p, ion_handle = %p, phys_addr = %lu,\ - length = %d, vaddr = %p, rc = 0x%x\n", + pr_debug("%s: exited ion_client = %pK, ion_handle = %pK, phys_addr = %lu,\ + length = %d, vaddr = %pK, rc = 0x%x\n", __func__, ion_client, ion_handle, (long)po.paddr, (unsigned int)po.size, po.kvaddr, rc); return rc; diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/sound/soc/msm/qdsp6v2/msm-lsm-client.c index 09dd65ab4f4f2..7be50676423ad 100644 --- a/sound/soc/msm/qdsp6v2/msm-lsm-client.c +++ b/sound/soc/msm/qdsp6v2/msm-lsm-client.c @@ -100,7 +100,7 @@ static int msm_lsm_queue_lab_buffer(struct lsm_priv *prtd, int i) struct snd_soc_pcm_runtime *rtd; if (!prtd || !prtd->lsm_client) { - pr_err("%s: Invalid params prtd %p lsm client %p\n", + pr_err("%s: Invalid params prtd %pK lsm client %pK\n", __func__, prtd, ((!prtd) ? NULL : prtd->lsm_client)); return -EINVAL; } @@ -114,7 +114,7 @@ static int msm_lsm_queue_lab_buffer(struct lsm_priv *prtd, int i) if (!prtd->lsm_client->lab_buffer || i >= prtd->lsm_client->hw_params.period_count) { dev_err(rtd->dev, - "%s: Lab buffer not setup %p incorrect index %d period count %d\n", + "%s: Lab buffer not setup %pK incorrect index %d period count %d\n", __func__, prtd->lsm_client->lab_buffer, i, prtd->lsm_client->hw_params.period_count); return -EINVAL; @@ -141,7 +141,7 @@ static int lsm_lab_buffer_sanity(struct lsm_priv *prtd, struct snd_soc_pcm_runtime *rtd; if (!prtd || !read_done || !index) { - pr_err("%s: Invalid params prtd %p read_done %p index %p\n", + pr_err("%s: Invalid params prtd %pK read_done %pK index %pK\n", __func__, prtd, read_done, index); return -EINVAL; } @@ -155,7 +155,7 @@ static int lsm_lab_buffer_sanity(struct lsm_priv *prtd, if (!prtd->lsm_client->lab_enable || !prtd->lsm_client->lab_buffer) { dev_err(rtd->dev, - "%s: Lab not enabled %d invalid lab buffer %p\n", + "%s: Lab not enabled %d invalid lab buffer %pK\n", __func__, prtd->lsm_client->lab_enable, prtd->lsm_client->lab_buffer); return -EINVAL; @@ -169,7 +169,7 @@ static int lsm_lab_buffer_sanity(struct lsm_priv *prtd, (prtd->lsm_client->lab_buffer[i].mem_map_handle == read_done->mem_map_handle)) { dev_dbg(rtd->dev, - "%s: Buffer found %pa memmap handle %d\n", + "%s: Buffer found %pK memmap handle %d\n", __func__, &prtd->lsm_client->lab_buffer[i].phys, prtd->lsm_client->lab_buffer[i].mem_map_handle); if (read_done->total_size > @@ -216,7 +216,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, if (prtd->lsm_client->session != token || !read_done) { dev_err(rtd->dev, - "%s: EVENT_READ_DONE invalid callback, session %d callback %d payload %p", + "%s: EVENT_READ_DONE invalid callback, session %d callback %d payload %pK", __func__, prtd->lsm_client->session, token, read_done); return; @@ -315,7 +315,7 @@ static int msm_lsm_lab_buffer_alloc(struct lsm_priv *lsm, int alloc) int ret = 0; struct snd_dma_buffer *dma_buf = NULL; if (!lsm) { - pr_err("%s: Invalid param lsm %p\n", __func__, lsm); + pr_err("%s: Invalid param lsm %pK\n", __func__, lsm); return -EINVAL; } if (alloc) { @@ -788,7 +788,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, snd_model_v2.data, snd_model_v2.data_size)) { dev_err(rtd->dev, "%s: copy from user data failed\n" - "data %p size %d\n", __func__, + "data %pK size %d\n", __func__, snd_model_v2.data, snd_model_v2.data_size); q6lsm_snd_model_buf_free(prtd->lsm_client); rc = -EFAULT; @@ -1846,7 +1846,7 @@ static int msm_lsm_hw_params(struct snd_pcm_substream *substream, if (!prtd || !params) { dev_err(rtd->dev, - "%s: invalid params prtd %p params %p", + "%s: invalid params prtd %pK params %pK", __func__, prtd, params); return -EINVAL; } @@ -1888,7 +1888,7 @@ static snd_pcm_uframes_t msm_lsm_pcm_pointer( if (!prtd) { dev_err(rtd->dev, - "%s: Invalid param %p\n", __func__, prtd); + "%s: Invalid param %pK\n", __func__, prtd); return 0; } @@ -1916,7 +1916,7 @@ static int msm_lsm_pcm_copy(struct snd_pcm_substream *substream, int ch, if (!prtd) { dev_err(rtd->dev, - "%s: Invalid param %p\n", __func__, prtd); + "%s: Invalid param %pK\n", __func__, prtd); return -EINVAL; } diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c index d3d1891763dca..f40db1a2b7da9 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -387,7 +387,7 @@ static int msm_afe_open(struct snd_pcm_substream *substream) pr_err("Failed to allocate memory for msm_audio\n"); return -ENOMEM; } else - pr_debug("prtd %p\n", prtd); + pr_debug("prtd %pK\n", prtd); mutex_init(&prtd->lock); spin_lock_init(&prtd->dsp_lock); @@ -606,7 +606,7 @@ static int msm_afe_hw_params(struct snd_pcm_substream *substream, return -ENOMEM; } - pr_debug("%s:buf = %p\n", __func__, buf); + pr_debug("%s:buf = %pK\n", __func__, buf); dma_buf->dev.type = SNDRV_DMA_TYPE_DEV; dma_buf->dev.dev = substream->pcm->card->dev; dma_buf->private_data = NULL; diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c index c1909778e0822..48f4a2456c847 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -504,7 +504,7 @@ static int hpcm_allocate_shared_memory(struct hpcm_drv *prtd) sess->tp_mem_table.size = sizeof(struct vss_imemory_table_t); - pr_debug("%s: data %p phys %pa\n", __func__, + pr_debug("%s: data %pK phys %pK\n", __func__, sess->tp_mem_table.data, &sess->tp_mem_table.phys); /* Split 4096 block into four 1024 byte blocks for each dai */ @@ -682,7 +682,7 @@ void hpcm_notify_evt_processing(uint8_t *data, char *session, } if (tp == NULL || tmd == NULL) { - pr_err("%s: tp = %p or tmd = %p is null\n", __func__, + pr_err("%s: tp = %pK or tmd = %pK is null\n", __func__, tp, tmd); return; diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c index 64d3fe086a6a1..3d31e1eea430d 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -132,7 +132,7 @@ static void event_handler(uint32_t opcode, pr_debug("%s:writing %d bytes of buffer[%d] to dsp 2\n", __func__, prtd->pcm_count, prtd->out_head); temp = buf[0].phys + (prtd->out_head * prtd->pcm_count); - pr_debug("%s:writing buffer[%d] from 0x%pa\n", + pr_debug("%s:writing buffer[%d] from 0x%pK\n", __func__, prtd->out_head, &temp); if (prtd->meta_data_mode) { memcpy(&output_meta_data, (char *)(buf->data + @@ -623,7 +623,7 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream, if (buf == NULL || buf[0].data == NULL) return -ENOMEM; - pr_debug("%s:buf = %p\n", __func__, buf); + pr_debug("%s:buf = %pK\n", __func__, buf); dma_buf->dev.type = SNDRV_DMA_TYPE_DEV; dma_buf->dev.dev = substream->pcm->card->dev; dma_buf->private_data = NULL; diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c index 528c6bd246499..3593da589ed2c 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -740,7 +740,7 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, pr_debug("%s: pcm stopped in_count 0\n", __func__); return 0; } - pr_debug("Checking if valid buffer is available...%p\n", + pr_debug("Checking if valid buffer is available...%pK\n", data); data = q6asm_is_cpu_buf_avail(OUT, prtd->audio_client, &size, &idx); bufptr = data; @@ -897,7 +897,7 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream, if (buf == NULL || buf[0].data == NULL) return -ENOMEM; - pr_debug("%s:buf = %p\n", __func__, buf); + pr_debug("%s:buf = %pK\n", __func__, buf); dma_buf->dev.type = SNDRV_DMA_TYPE_DEV; dma_buf->dev.dev = substream->pcm->card->dev; dma_buf->private_data = NULL; diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c index a7c01ce922447..55b646451c7fd 100644 --- a/sound/soc/msm/qdsp6v2/q6adm.c +++ b/sound/soc/msm/qdsp6v2/q6adm.c @@ -329,7 +329,7 @@ int adm_dts_eagle_get(int port_id, int copp_idx, int param_id, } if ((size == 0) || !data) { - pr_err("DTS_EAGLE_ADM - %s: invalid size %u or pointer %p.\n", + pr_err("DTS_EAGLE_ADM - %s: invalid size %u or pointer %pK.\n", __func__, size, data); return -EINVAL; } @@ -1082,7 +1082,7 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) payload = data->payload; if (data->opcode == RESET_EVENTS) { - pr_debug("%s: Reset event is received: %d %d apr[%p]\n", + pr_debug("%s: Reset event is received: %d %d apr[%pK]\n", __func__, data->reset_event, data->reset_proc, this_adm.apr); if (this_adm.apr) { @@ -1531,7 +1531,7 @@ static void remap_cal_data(struct cal_block_data *cal_block, int cal_index) pr_err("%s: ADM mmap did not work! size = %zd ret %d\n", __func__, cal_block->map_data.map_size, ret); - pr_debug("%s: ADM mmap did not work! addr = 0x%pa, size = %zd ret %d\n", + pr_debug("%s: ADM mmap did not work! addr = 0x%pK, size = %zd ret %d\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size, ret); @@ -1593,7 +1593,7 @@ static void send_adm_custom_topology(void) adm_top.payload_size = cal_block->cal_data.size; atomic_set(&this_adm.adm_stat, 0); - pr_debug("%s: Sending ADM_CMD_ADD_TOPOLOGIES payload = 0x%pa, size = %d\n", + pr_debug("%s: Sending ADM_CMD_ADD_TOPOLOGIES payload = 0x%pK, size = %d\n", __func__, &cal_block->cal_data.paddr, adm_top.payload_size); result = apr_send_pkt(this_adm.apr, (uint32_t *)&adm_top); @@ -1675,14 +1675,14 @@ static int send_adm_cal_block(int port_id, int copp_idx, adm_params.payload_size = cal_block->cal_data.size; atomic_set(&this_adm.copp.stat[port_idx][copp_idx], 0); - pr_debug("%s: Sending SET_PARAMS payload = 0x%pa, size = %d\n", + pr_debug("%s: Sending SET_PARAMS payload = 0x%pK, size = %d\n", __func__, &cal_block->cal_data.paddr, adm_params.payload_size); result = apr_send_pkt(this_adm.apr, (uint32_t *)&adm_params); if (result < 0) { pr_err("%s: Set params failed port 0x%x result %d\n", __func__, port_id, result); - pr_debug("%s: Set params failed port = 0x%x payload = 0x%pa result %d\n", + pr_debug("%s: Set params failed port = 0x%x payload = 0x%pK result %d\n", __func__, port_id, &cal_block->cal_data.paddr, result); result = -EINVAL; goto done; @@ -1694,7 +1694,7 @@ static int send_adm_cal_block(int port_id, int copp_idx, if (!result) { pr_err("%s: Set params timed out port = 0x%x\n", __func__, port_id); - pr_debug("%s: Set params timed out port = 0x%x, payload = 0x%pa\n", + pr_debug("%s: Set params timed out port = 0x%x, payload = 0x%pK\n", __func__, port_id, &cal_block->cal_data.paddr); result = -EINVAL; goto done; @@ -2047,7 +2047,7 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, res = adm_memory_map_regions(&this_adm.outband_memmap.paddr, 0, (uint32_t *)&this_adm.outband_memmap.size, 1); if (res < 0) { - pr_err("%s: SRS adm_memory_map_regions failed ! addr = 0x%p, size = %d\n", + pr_err("%s: SRS adm_memory_map_regions failed ! addr = 0x%pK, size = %d\n", __func__, (void*)this_adm.outband_memmap.paddr, (uint32_t)this_adm.outband_memmap.size); } @@ -2513,7 +2513,7 @@ int adm_map_rtac_block(struct rtac_cal_block_data *cal_block) pr_err("%s: RTAC mmap did not work! size = %d result %d\n", __func__, cal_block->map_data.map_size, result); - pr_debug("%s: RTAC mmap did not work! addr = 0x%pa, size = %d\n", + pr_debug("%s: RTAC mmap did not work! addr = 0x%pK, size = %d\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size); @@ -3625,7 +3625,7 @@ static int adm_source_tracking_alloc_map_memory(void) (uint32_t *)&this_adm.sourceTrackingData.memmap.size, 1); if (ret < 0) { - pr_err("%s: failed to map memory, paddr = 0x%p, size = %d\n", + pr_err("%s: failed to map memory, paddr = 0x%pK, size = %d\n", __func__, (void *)this_adm.sourceTrackingData.memmap.paddr, (uint32_t)this_adm.sourceTrackingData.memmap.size); @@ -3645,7 +3645,7 @@ static int adm_source_tracking_alloc_map_memory(void) goto done; } ret = 0; - pr_debug("%s: paddr = 0x%p, size = %d, mem_map_handle = 0x%x\n", + pr_debug("%s: paddr = 0x%pK, size = %d, mem_map_handle = 0x%x\n", __func__, (void *)this_adm.sourceTrackingData.memmap.paddr, (uint32_t)this_adm.sourceTrackingData.memmap.size, atomic_read(&this_adm.mem_map_handles diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c index 95f92f5c10f34..ae720468ff89d 100644 --- a/sound/soc/msm/qdsp6v2/q6afe.c +++ b/sound/soc/msm/qdsp6v2/q6afe.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -154,7 +154,7 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) return -EINVAL; } if (data->opcode == RESET_EVENTS) { - pr_debug("%s: reset event = %d %d apr[%p]\n", + pr_debug("%s: reset event = %d %d apr[%pK]\n", __func__, data->reset_event, data->reset_proc, this_afe.apr); @@ -184,7 +184,7 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) if ((data->payload_size < sizeof(this_afe.calib_data)) || !payload || (data->token >= AFE_MAX_PORTS)) { - pr_err("%s: Error: size %d payload %p token %d\n", + pr_err("%s: Error: size %d payload %pK token %d\n", __func__, data->payload_size, payload, data->token); return -EINVAL; @@ -504,7 +504,7 @@ static int afe_send_cal_block(u16 port_id, struct cal_block_data *cal_block) upper_32_bits(cal_block->cal_data.paddr); afe_cal.param.mem_map_handle = cal_block->map_data.q6map_handle; - pr_debug("%s: AFE cal sent for device port = 0x%x, cal size = %zd, cal addr = 0x%pa\n", + pr_debug("%s: AFE cal sent for device port = 0x%x, cal size = %zd, cal addr = 0x%pK\n", __func__, port_id, cal_block->cal_data.size, &cal_block->cal_data.paddr); @@ -838,7 +838,7 @@ static void remap_cal_data(struct cal_block_data *cal_block, int cal_index) pr_err("%s: mmap did not work! size = %zd ret %d\n", __func__, cal_block->map_data.map_size, ret); - pr_debug("%s: mmap did not work! addr = 0x%pa, size = %zd\n", + pr_debug("%s: mmap did not work! addr = 0x%pK, size = %zd\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size); @@ -2520,7 +2520,7 @@ int q6afe_audio_client_buf_alloc_contiguous(unsigned int dir, size_t len; if (!(ac) || ((dir != IN) && (dir != OUT))) { - pr_err("%s: ac %p dir %d\n", __func__, ac, dir); + pr_err("%s: ac %pK dir %d\n", __func__, ac, dir); return -EINVAL; } @@ -2572,7 +2572,7 @@ int q6afe_audio_client_buf_alloc_contiguous(unsigned int dir, buf[cnt].used = dir ^ 1; buf[cnt].size = bufsz; buf[cnt].actual_size = bufsz; - pr_debug("%s: data[%p]phys[%pa][%p]\n", __func__, + pr_debug("%s: data[%pK]phys[%pK][%pK]\n", __func__, buf[cnt].data, &buf[cnt].phys, &buf[cnt].phys); @@ -2669,7 +2669,7 @@ int afe_cmd_memory_map(phys_addr_t dma_addr_p, u32 dma_buf_sz) mregion_pl->shm_addr_msw = upper_32_bits(dma_addr_p); mregion_pl->mem_size_bytes = dma_buf_sz; - pr_debug("%s: dma_addr_p 0x%pa , size %d\n", __func__, + pr_debug("%s: dma_addr_p 0x%pK , size %d\n", __func__, &dma_addr_p, dma_buf_sz); atomic_set(&this_afe.state, 1); atomic_set(&this_afe.status, 0); @@ -2793,7 +2793,7 @@ int q6afe_audio_client_buf_free_contiguous(unsigned int dir, cnt = port->max_buf_cnt - 1; if (port->buf[0].data) { - pr_debug("%s: data[%p]phys[%pa][%p] , client[%p] handle[%p]\n", + pr_debug("%s: data[%pK]phys[%pK][%pK] , client[%pK] handle[%pK]\n", __func__, port->buf[0].data, &port->buf[0].phys, @@ -4303,7 +4303,7 @@ static int afe_map_cal_data(int32_t cal_type, pr_err("%s: mmap did not work! size = %zd ret %d\n", __func__, cal_block->map_data.map_size, ret); - pr_debug("%s: mmap did not work! addr = 0x%pa, size = %zd\n", + pr_debug("%s: mmap did not work! addr = 0x%pK, size = %zd\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size); @@ -4438,7 +4438,7 @@ int afe_map_rtac_block(struct rtac_cal_block_data *cal_block) result = afe_cmd_memory_map(cal_block->cal_data.paddr, cal_block->map_data.map_size); if (result < 0) { - pr_err("%s: afe_cmd_memory_map failed for addr = 0x%pa, size = %d, err %d\n", + pr_err("%s: afe_cmd_memory_map failed for addr = 0x%pK, size = %d, err %d\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size, result); return result; diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index 4e38480ec1d22..209b857686e58 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -471,7 +471,7 @@ static int q6asm_map_cal_memory(struct cal_block_data *cal_block) pr_err("%s: mmap did not work! size = %zd result %d\n", __func__, cal_block->map_data.map_size, result); - pr_debug("%s: mmap did not work! addr = 0x%pa, size = %zd\n", + pr_debug("%s: mmap did not work! addr = 0x%pK, size = %zd\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size); @@ -604,7 +604,7 @@ int send_asm_custom_topology(struct audio_client *ac) asm_top.mem_map_handle = cal_block->map_data.q6map_handle; asm_top.payload_size = cal_block->cal_data.size; - pr_debug("%s: Sending ASM_CMD_ADD_TOPOLOGIES payload = %pa, size = %d, map handle = 0x%x\n", + pr_debug("%s: Sending ASM_CMD_ADD_TOPOLOGIES payload = %pK, size = %d, map handle = 0x%x\n", __func__, &cal_block->cal_data.paddr, asm_top.payload_size, asm_top.mem_map_handle); @@ -612,7 +612,7 @@ int send_asm_custom_topology(struct audio_client *ac) if (result < 0) { pr_err("%s: Set topologies failed result %d\n", __func__, result); - pr_debug("%s: Set topologies failed payload = 0x%pa\n", + pr_debug("%s: Set topologies failed payload = 0x%pK\n", __func__, &cal_block->cal_data.paddr); goto unmap; @@ -622,7 +622,7 @@ int send_asm_custom_topology(struct audio_client *ac) (atomic_read(&ac->mem_state) <= 0), 5*HZ); if (!result) { pr_err("%s: Set topologies failed timeout\n", __func__); - pr_debug("%s: Set topologies failed after timedout payload = 0x%pa\n", + pr_debug("%s: Set topologies failed after timedout payload = 0x%pK\n", __func__, &cal_block->cal_data.paddr); result = -ETIMEDOUT; goto unmap; @@ -698,7 +698,7 @@ int q6asm_map_rtac_block(struct rtac_cal_block_data *cal_block) pr_err("%s: mmap did not work! size = %d result %d\n", __func__, cal_block->map_data.map_size, result); - pr_debug("%s: mmap did not work! addr = 0x%pa, size = %d\n", + pr_debug("%s: mmap did not work! addr = 0x%pK, size = %d\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size); @@ -835,7 +835,7 @@ int q6asm_audio_client_buf_free_contiguous(unsigned int dir, } if (port->buf[0].data) { - pr_debug("%s: data[%p]phys[%pa][%p] , client[%p] handle[%p]\n", + pr_debug("%s: data[%pK]phys[%pK][%pK] , client[%pK] handle[%pK]\n", __func__, port->buf[0].data, &port->buf[0].phys, @@ -866,7 +866,7 @@ void q6asm_audio_client_free(struct audio_client *ac) int loopcnt; struct audio_port_data *port; if (!ac) { - pr_err("%s: ac %p\n", __func__, ac); + pr_err("%s: ac %pK\n", __func__, ac); return; } if (!ac->session) { @@ -1082,7 +1082,7 @@ int q6asm_audio_client_buf_alloc(unsigned int dir, size_t len; if (!(ac) || ((dir != IN) && (dir != OUT))) { - pr_err("%s: ac %p dir %d\n", __func__, ac, dir); + pr_err("%s: ac %pK dir %d\n", __func__, ac, dir); return -EINVAL; } @@ -1135,7 +1135,7 @@ int q6asm_audio_client_buf_alloc(unsigned int dir, buf[cnt].used = 1; buf[cnt].size = bufsz; buf[cnt].actual_size = bufsz; - pr_debug("%s: data[%p]phys[%pa][%p]\n", + pr_debug("%s: data[%pK]phys[%pK][%pK]\n", __func__, buf[cnt].data, &buf[cnt].phys, @@ -1172,7 +1172,7 @@ int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir, int bytes_to_alloc; if (!(ac) || ((dir != IN) && (dir != OUT))) { - pr_err("%s: ac %p dir %d\n", __func__, ac, dir); + pr_err("%s: ac %pK dir %d\n", __func__, ac, dir); return -EINVAL; } @@ -1241,7 +1241,7 @@ int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir, buf[cnt].used = dir ^ 1; buf[cnt].size = bufsz; buf[cnt].actual_size = bufsz; - pr_debug("%s: data[%p]phys[%pa][%p]\n", + pr_debug("%s: data[%pK]phys[%pK][%pK]\n", __func__, buf[cnt].data, &buf[cnt].phys, @@ -1284,7 +1284,7 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) payload = data->payload; if (data->opcode == RESET_EVENTS) { - pr_debug("%s: Reset event is received: %d %d apr[%p]\n", + pr_debug("%s: Reset event is received: %d %d apr[%pK]\n", __func__, data->reset_event, data->reset_proc, @@ -1450,7 +1450,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) return -EINVAL; } if (!q6asm_is_valid_audio_client(ac)) { - pr_err("%s: audio client pointer is invalid, ac = %p\n", + pr_err("%s: audio client pointer is invalid, ac = %pK\n", __func__, ac); return -EINVAL; } @@ -1476,7 +1476,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) atomic_set(&ac->reset, 1); if (ac->apr == NULL) ac->apr = ac->apr2; - pr_debug("%s: Reset event is received: %d %d apr[%p]\n", + pr_debug("%s: Reset event is received: %d %d apr[%pK]\n", __func__, data->reset_event, data->reset_proc, ac->apr); if (ac->cb) @@ -1619,7 +1619,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) payload[0] || upper_32_bits(port->buf[data->token].phys) != payload[1]) { - pr_debug("%s: Expected addr %pa\n", + pr_debug("%s: Expected addr %pK\n", __func__, &port->buf[data->token].phys); pr_err("%s: rxedl[0x%x] rxedu [0x%x]\n", __func__, payload[0], payload[1]); @@ -1694,7 +1694,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) payload[READDONE_IDX_BUFADD_LSW] || upper_32_bits(port->buf[token].phys) != payload[READDONE_IDX_BUFADD_MSW]) { - dev_vdbg(ac->dev, "%s: Expected addr %pa\n", + dev_vdbg(ac->dev, "%s: Expected addr %pK\n", __func__, &port->buf[token].phys); pr_err("%s: rxedl[0x%x] rxedu[0x%x]\n", __func__, @@ -1765,7 +1765,7 @@ void *q6asm_is_cpu_buf_avail(int dir, struct audio_client *ac, uint32_t *size, struct audio_port_data *port; if (!ac || ((dir != IN) && (dir != OUT))) { - pr_err("%s: ac %p dir %d\n", __func__, ac, dir); + pr_err("%s: ac %pK dir %d\n", __func__, ac, dir); return NULL; } @@ -1792,7 +1792,7 @@ void *q6asm_is_cpu_buf_avail(int dir, struct audio_client *ac, uint32_t *size, *size = port->buf[idx].actual_size; *index = port->cpu_buf; data = port->buf[idx].data; - dev_vdbg(ac->dev, "%s: session[%d]index[%d] data[%p]size[%d]\n", + dev_vdbg(ac->dev, "%s: session[%d]index[%d] data[%pK]size[%d]\n", __func__, ac->session, port->cpu_buf, @@ -1816,7 +1816,7 @@ void *q6asm_is_cpu_buf_avail_nolock(int dir, struct audio_client *ac, struct audio_port_data *port; if (!ac || ((dir != IN) && (dir != OUT))) { - pr_err("%s: ac %p dir %d\n", __func__, ac, dir); + pr_err("%s: ac %pK dir %d\n", __func__, ac, dir); return NULL; } @@ -1843,7 +1843,7 @@ void *q6asm_is_cpu_buf_avail_nolock(int dir, struct audio_client *ac, *size = port->buf[idx].actual_size; *index = port->cpu_buf; data = port->buf[idx].data; - dev_vdbg(ac->dev, "%s: session[%d]index[%d] data[%p]size[%d]\n", + dev_vdbg(ac->dev, "%s: session[%d]index[%d] data[%pK]size[%d]\n", __func__, ac->session, port->cpu_buf, data, *size); /* @@ -1863,7 +1863,7 @@ int q6asm_is_dsp_buf_avail(int dir, struct audio_client *ac) uint32_t idx; if (!ac || (dir != OUT)) { - pr_err("%s: ac %p dir %d\n", __func__, ac, dir); + pr_err("%s: ac %pK dir %d\n", __func__, ac, dir); return ret; } @@ -2129,13 +2129,13 @@ int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format, struct asm_stream_cmd_open_write_compressed open; if (ac == NULL) { - pr_err("%s: ac[%p] NULL\n", __func__, ac); + pr_err("%s: ac[%pK] NULL\n", __func__, ac); rc = -EINVAL; goto fail_cmd; } if (ac->apr == NULL) { - pr_err("%s: APR handle[%p] NULL\n", __func__, ac->apr); + pr_err("%s: APR handle[%pK] NULL\n", __func__, ac->apr); rc = -EINVAL; goto fail_cmd; } @@ -3931,7 +3931,7 @@ int q6asm_memory_map(struct audio_client *ac, phys_addr_t buf_add, int dir, ac->port[dir].tmp_hdl = 0; port = &ac->port[dir]; - pr_debug("%s: buf_add 0x%pa, bufsz: %d\n", __func__, + pr_debug("%s: buf_add 0x%pK, bufsz: %d\n", __func__, &buf_add, bufsz); mregions->shm_addr_lsw = lower_32_bits(buf_add); mregions->shm_addr_msw = upper_32_bits(buf_add); @@ -4117,7 +4117,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir, q6asm_add_mmaphdr(ac, &mmap_regions->hdr, cmd_size, TRUE, ((ac->session << 8) | dir)); atomic_set(&ac->mem_state, 1); - pr_debug("%s: mmap_region=0x%p token=0x%x\n", __func__, + pr_debug("%s: mmap_region=0x%pK token=0x%x\n", __func__, mmap_regions, ((ac->session << 8) | dir)); mmap_regions->hdr.opcode = ASM_CMD_SHARED_MEM_MAP_REGIONS; @@ -4173,7 +4173,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir, buffer_node[i].mmap_hdl = ac->port[dir].tmp_hdl; list_add_tail(&buffer_node[i].list, &ac->port[dir].mem_map_handle); - pr_debug("%s: i=%d, bufadd[i] = 0x%pa, maphdl[i] = 0x%x\n", + pr_debug("%s: i=%d, bufadd[i] = 0x%pK, maphdl[i] = 0x%x\n", __func__, i, &buffer_node[i].buf_phys_addr, buffer_node[i].mmap_hdl); } @@ -4405,7 +4405,7 @@ int q6asm_dts_eagle_set(struct audio_client *ac, int param_id, uint32_t size, } if (!ac || ac->apr == NULL || (size == 0) || !data) { - pr_err("DTS_EAGLE_ASM - %s: APR handle NULL, invalid size %u or pointer %p.\n", + pr_err("DTS_EAGLE_ASM - %s: APR handle NULL, invalid size %u or pointer %pK.\n", __func__, size, data); return -EINVAL; } @@ -4456,7 +4456,7 @@ int q6asm_dts_eagle_get(struct audio_client *ac, int param_id, uint32_t size, uint32_t sz; if (!ac || ac->apr == NULL || (size == 0) || !data) { - pr_err("DTS_EAGLE_ASM - %s: APR handle NULL, invalid size %u or pointer %p.\n", + pr_err("DTS_EAGLE_ASM - %s: APR handle NULL, invalid size %u or pointer %pK.\n", __func__, size, data); return -EINVAL; } @@ -4881,7 +4881,7 @@ static int __q6asm_read(struct audio_client *ac, bool is_custom_len_reqd, } ab = &port->buf[dsp_buf]; - dev_vdbg(ac->dev, "%s: session[%d]dsp-buf[%d][%p]cpu_buf[%d][%pa]\n", + dev_vdbg(ac->dev, "%s: session[%d]dsp-buf[%d][%pK]cpu_buf[%d][%pK]\n", __func__, ac->session, dsp_buf, @@ -4906,7 +4906,7 @@ static int __q6asm_read(struct audio_client *ac, bool is_custom_len_reqd, read.hdr.token = port->dsp_buf; port->dsp_buf = (port->dsp_buf + 1) & (port->max_buf_cnt - 1); mutex_unlock(&port->lock); - dev_vdbg(ac->dev, "%s: buf add[%pa] token[%d] uid[%d]\n", + dev_vdbg(ac->dev, "%s: buf add[%pK] token[%d] uid[%d]\n", __func__, &ab->phys, read.hdr.token, read.seq_id); rc = apr_send_pkt(ac->apr, (uint32_t *) &read); @@ -4958,7 +4958,7 @@ int q6asm_read_nolock(struct audio_client *ac) dsp_buf = port->dsp_buf; ab = &port->buf[dsp_buf]; - dev_vdbg(ac->dev, "%s: session[%d]dsp-buf[%d][%p]cpu_buf[%d][%pa]\n", + dev_vdbg(ac->dev, "%s: session[%d]dsp-buf[%d][%pK]cpu_buf[%d][%pK]\n", __func__, ac->session, dsp_buf, @@ -4983,7 +4983,7 @@ int q6asm_read_nolock(struct audio_client *ac) } port->dsp_buf = (port->dsp_buf + 1) & (port->max_buf_cnt - 1); - dev_vdbg(ac->dev, "%s: buf add[%pa] token[%d] uid[%d]\n", + dev_vdbg(ac->dev, "%s: buf add[%pK] token[%d] uid[%d]\n", __func__, &ab->phys, read.hdr.token, read.seq_id); rc = apr_send_pkt(ac->apr, (uint32_t *) &read); @@ -5046,7 +5046,7 @@ int q6asm_async_write(struct audio_client *ac, else lbuf_phys_addr = param->paddr; - dev_vdbg(ac->dev, "%s: token[0x%x], buf_addr[%pa], buf_size[0x%x], ts_msw[0x%x], ts_lsw[0x%x], lbuf_phys_addr: 0x[%pa]\n", + dev_vdbg(ac->dev, "%s: token[0x%x], buf_addr[%pK], buf_size[0x%x], ts_msw[0x%x], ts_lsw[0x%x], lbuf_phys_addr: 0x[%pK]\n", __func__, write.hdr.token, ¶m->paddr, write.buf_size, write.timestamp_msw, @@ -5193,7 +5193,7 @@ int q6asm_write(struct audio_client *ac, uint32_t len, uint32_t msw_ts, list); write.mem_map_handle = buf_node->mmap_hdl; - dev_vdbg(ac->dev, "%s: ab->phys[%pa]bufadd[0x%x] token[0x%x]buf_id[0x%x]buf_size[0x%x]mmaphdl[0x%x]" + dev_vdbg(ac->dev, "%s: ab->phys[%pK]bufadd[0x%x] token[0x%x]buf_id[0x%x]buf_size[0x%x]mmaphdl[0x%x]" , __func__, &ab->phys, write.buf_addr_lsw, @@ -5266,7 +5266,7 @@ int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts, write.flags = (0x80000000 | flags); port->dsp_buf = (port->dsp_buf + 1) & (port->max_buf_cnt - 1); - dev_vdbg(ac->dev, "%s: ab->phys[%pa]bufadd[0x%x]token[0x%x] buf_id[0x%x]buf_size[0x%x]mmaphdl[0x%x]" + dev_vdbg(ac->dev, "%s: ab->phys[%pK]bufadd[0x%x]token[0x%x] buf_id[0x%x]buf_size[0x%x]mmaphdl[0x%x]" , __func__, &ab->phys, write.buf_addr_lsw, diff --git a/sound/soc/msm/qdsp6v2/q6core.c b/sound/soc/msm/qdsp6v2/q6core.c index f9163bcce191c..2a28b47e02018 100644 --- a/sound/soc/msm/qdsp6v2/q6core.c +++ b/sound/soc/msm/qdsp6v2/q6core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -184,7 +184,7 @@ void ocm_core_open(void) if (q6core_lcl.core_handle_q == NULL) q6core_lcl.core_handle_q = apr_register("ADSP", "CORE", aprv2_core_fn_q, 0xFFFFFFFF, NULL); - pr_debug("%s: Open_q %p\n", __func__, q6core_lcl.core_handle_q); + pr_debug("%s: Open_q %pK\n", __func__, q6core_lcl.core_handle_q); if (q6core_lcl.core_handle_q == NULL) { if (__ratelimit(&rl)) pr_err("%s: Unable to register CORE\n", @@ -347,7 +347,7 @@ int core_dts_eagle_set(int size, char *data) pr_debug("DTS_EAGLE_CORE - %s\n", __func__); if (size <= 0 || !data) { - pr_err("DTS_EAGLE_CORE - %s: invalid size %i or pointer %p.\n", + pr_err("DTS_EAGLE_CORE - %s: invalid size %i or pointer %pK.\n", __func__, size, data); return -EINVAL; } @@ -393,7 +393,7 @@ int core_dts_eagle_get(int id, int size, char *data) pr_debug("DTS_EAGLE_CORE - %s\n", __func__); if (size <= 0 || !data) { - pr_err("DTS_EAGLE_CORE - %s: invalid size %i or pointer %p.\n", + pr_err("DTS_EAGLE_CORE - %s: invalid size %i or pointer %pK.\n", __func__, size, data); return -EINVAL; } diff --git a/sound/soc/msm/qdsp6v2/q6lsm.c b/sound/soc/msm/qdsp6v2/q6lsm.c index 04f37682dfe26..cde790a432791 100644 --- a/sound/soc/msm/qdsp6v2/q6lsm.c +++ b/sound/soc/msm/qdsp6v2/q6lsm.c @@ -134,7 +134,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) uint32_t *payload; if (!client || !data) { - pr_err("%s: client %p data %p\n", + pr_err("%s: client %pK data %pK\n", __func__, client, data); WARN_ON(1); return -EINVAL; @@ -942,7 +942,7 @@ int q6lsm_register_sound_model(struct lsm_client *client, rmb(); cmd.mem_map_handle = client->sound_model.mem_map_handle; - pr_debug("%s: addr %pa, size %d, handle 0x%x\n", __func__, + pr_debug("%s: addr %pK, size %d, handle 0x%x\n", __func__, &client->sound_model.phys, cmd.model_size, cmd.mem_map_handle); rc = q6lsm_apr_send_pkt(client, client->apr, &cmd, true, NULL); if (rc) @@ -1016,7 +1016,7 @@ static int q6lsm_memory_map_regions(struct lsm_client *client, int rc; int cmd_size = 0; - pr_debug("%s: dma_addr_p 0x%pa, dma_buf_sz %d, mmap_p 0x%p, session %d\n", + pr_debug("%s: dma_addr_p 0x%pK, dma_buf_sz %d, mmap_p 0x%pK, session %d\n", __func__, &dma_addr_p, dma_buf_sz, mmap_p, client->session); if (CHECK_SESSION(client->session)) { @@ -1296,7 +1296,7 @@ int q6lsm_snd_model_buf_alloc(struct lsm_client *client, size_t len, if (cal_block == NULL) goto fail; - pr_debug("%s:Snd Model len = %zd cal size %zd phys addr %pa", __func__, + pr_debug("%s:Snd Model len = %zd cal size %zd phys addr %pK", __func__, len, cal_block->cal_data.size, &cal_block->cal_data.paddr); if (!cal_block->cal_data.paddr) { @@ -1351,8 +1351,8 @@ int q6lsm_snd_model_buf_alloc(struct lsm_client *client, size_t len, memcpy((client->sound_model.data + pad_zero + client->sound_model.size), (uint32_t *)cal_block->cal_data.kvaddr, client->lsm_cal_size); - pr_debug("%s: Copy cal start virt_addr %p phy_addr %pa\n" - "Offset cal virtual Addr %p\n", __func__, + pr_debug("%s: Copy cal start virt_addr %pK phy_addr %pK\n" + "Offset cal virtual Addr %pK\n", __func__, client->sound_model.data, &client->sound_model.phys, (pad_zero + client->sound_model.data + client->sound_model.size)); @@ -1680,7 +1680,7 @@ int q6lsm_lab_control(struct lsm_client *client, u32 enable) u32 param_size; if (!client) { - pr_err("%s: invalid param client %p\n", __func__, client); + pr_err("%s: invalid param client %pK\n", __func__, client); return -EINVAL; } /* enable/disable lab on dsp */ @@ -1737,7 +1737,7 @@ int q6lsm_stop_lab(struct lsm_client *client) { int rc = 0; if (!client) { - pr_err("%s: invalid param client %p\n", __func__, client); + pr_err("%s: invalid param client %pK\n", __func__, client); return -EINVAL; } rc = q6lsm_cmd(client, LSM_SESSION_CMD_EOB, true); @@ -1750,7 +1750,7 @@ int q6lsm_read(struct lsm_client *client, struct lsm_cmd_read *read) { int rc = 0; if (!client || !read) { - pr_err("%s: Invalid params client %p read %p\n", __func__, + pr_err("%s: Invalid params client %pK read %pK\n", __func__, client, read); return -EINVAL; } @@ -1820,7 +1820,7 @@ int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc) kfree(client->lab_buffer); client->lab_buffer = NULL; } else { - pr_debug("%s: Memory map handle %x phys %pa size %d\n", + pr_debug("%s: Memory map handle %x phys %pK size %d\n", __func__, client->lab_buffer[0].mem_map_handle, &client->lab_buffer[0].phys, diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c index 828c796d662a0..5ba0ca45864d5 100644 --- a/sound/soc/msm/qdsp6v2/q6voice.c +++ b/sound/soc/msm/qdsp6v2/q6voice.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -326,7 +326,7 @@ static struct voice_data *voice_get_session(u32 session_id) break; } - pr_debug("%s:session_id 0x%x session handle %p\n", + pr_debug("%s:session_id 0x%x session handle %pK\n", __func__, session_id, v); return v; @@ -2978,7 +2978,7 @@ static int voice_map_cal_memory(struct cal_block_data *cal_block, cal_block->map_data.map_size, VOC_CAL_MEM_MAP_TOKEN); if (result < 0) { - pr_err("%s: Mmap did not work! addr = 0x%pa, size = %zd\n", + pr_err("%s: Mmap did not work! addr = 0x%pK, size = %zd\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size); @@ -3011,7 +3011,7 @@ static int remap_cal_data(struct cal_block_data *cal_block, goto done; } } else { - pr_debug("%s: Cal block 0x%pa, size %zd already mapped. Q6 map handle = %d\n", + pr_debug("%s: Cal block 0x%pK, size %zd already mapped. Q6 map handle = %d\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size, cal_block->map_data.q6map_handle); @@ -3209,7 +3209,7 @@ int voc_map_rtac_block(struct rtac_cal_block_data *cal_block) if (!is_rtac_memory_allocated()) { result = voice_alloc_rtac_mem_map_table(); if (result < 0) { - pr_err("%s: RTAC alloc mem map table did not work! addr = 0x%pa, size = %d\n", + pr_err("%s: RTAC alloc mem map table did not work! addr = 0x%pK, size = %d\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size); @@ -3224,7 +3224,7 @@ int voc_map_rtac_block(struct rtac_cal_block_data *cal_block) cal_block->map_data.map_size, VOC_RTAC_MEM_MAP_TOKEN); if (result < 0) { - pr_err("%s: RTAC mmap did not work! addr = 0x%pa, size = %d\n", + pr_err("%s: RTAC mmap did not work! addr = 0x%pK, size = %d\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size); @@ -3915,7 +3915,7 @@ static int voice_send_cvs_packet_exchange_config_cmd(struct voice_data *v) packet_exchange_config_pkt.enc_buf_addr = (uint32_t)enc_buf; packet_exchange_config_pkt.enc_buf_size = 4096; - pr_debug("%s: dec buf: add %pa, size %d, enc buf: add %pa, size %d\n", + pr_debug("%s: dec buf: add %pK, size %d, enc buf: add %pK, size %d\n", __func__, &dec_buf, packet_exchange_config_pkt.dec_buf_size, @@ -4328,7 +4328,7 @@ int voc_start_record(uint32_t port_id, uint32_t set, uint32_t session_id) break; } - pr_debug("%s: port_id: %d, set: %d, v: %p\n", + pr_debug("%s: port_id: %d, set: %d, v: %pK\n", __func__, port_id, set, v); mutex_lock(&v->lock); @@ -6400,12 +6400,12 @@ static int voice_alloc_oob_shared_mem(void) cnt++; } - pr_debug("%s buf[0].data:[%p], buf[0].phys:[%pa], &buf[0].phys:[%p],\n", + pr_debug("%s buf[0].data:[%pK], buf[0].phys:[%pK], &buf[0].phys:[%pK],\n", __func__, (void *)v->shmem_info.sh_buf.buf[0].data, &v->shmem_info.sh_buf.buf[0].phys, (void *)&v->shmem_info.sh_buf.buf[0].phys); - pr_debug("%s: buf[1].data:[%p], buf[1].phys[%pa], &buf[1].phys[%p]\n", + pr_debug("%s: buf[1].data:[%pK], buf[1].phys[%pK], &buf[1].phys[%pK]\n", __func__, (void *)v->shmem_info.sh_buf.buf[1].data, &v->shmem_info.sh_buf.buf[1].phys, @@ -6447,7 +6447,7 @@ static int voice_alloc_oob_mem_table(void) } v->shmem_info.memtbl.size = sizeof(struct vss_imemory_table_t); - pr_debug("%s data[%p]phys[%pa][%p]\n", __func__, + pr_debug("%s data[%pK]phys[%pK][%pK]\n", __func__, (void *)v->shmem_info.memtbl.data, &v->shmem_info.memtbl.phys, (void *)&v->shmem_info.memtbl.phys); @@ -6799,7 +6799,7 @@ static int voice_alloc_cal_mem_map_table(void) } common.cal_mem_map_table.size = sizeof(struct vss_imemory_table_t); - pr_debug("%s: data %p phys %pa\n", __func__, + pr_debug("%s: data %pK phys %pK\n", __func__, common.cal_mem_map_table.data, &common.cal_mem_map_table.phys); @@ -6826,7 +6826,7 @@ static int voice_alloc_rtac_mem_map_table(void) } common.rtac_mem_map_table.size = sizeof(struct vss_imemory_table_t); - pr_debug("%s: data %p phys %pa\n", __func__, + pr_debug("%s: data %pK phys %pK\n", __func__, common.rtac_mem_map_table.data, &common.rtac_mem_map_table.phys); @@ -7427,7 +7427,7 @@ static int voice_alloc_source_tracking_shared_memory(void) memset((void *)(common.source_tracking_sh_mem.sh_mem_block.data), 0, common.source_tracking_sh_mem.sh_mem_block.size); - pr_debug("%s: sh_mem_block: phys:[%pa], data:[0x%p], size:[%zd]\n", + pr_debug("%s: sh_mem_block: phys:[%pK], data:[0x%pK], size:[%zd]\n", __func__, &(common.source_tracking_sh_mem.sh_mem_block.phys), (void *)(common.source_tracking_sh_mem.sh_mem_block.data), @@ -7458,7 +7458,7 @@ static int voice_alloc_source_tracking_shared_memory(void) memset((void *)(common.source_tracking_sh_mem.sh_mem_table.data), 0, common.source_tracking_sh_mem.sh_mem_table.size); - pr_debug("%s sh_mem_table: phys:[%pa], data:[0x%p], size:[%zd],\n", + pr_debug("%s sh_mem_table: phys:[%pK], data:[0x%pK], size:[%zd],\n", __func__, &(common.source_tracking_sh_mem.sh_mem_table.phys), (void *)(common.source_tracking_sh_mem.sh_mem_table.data), diff --git a/sound/soc/msm/qdsp6v2/rtac.c b/sound/soc/msm/qdsp6v2/rtac.c index fcae47f6355c9..f1705897b18e6 100644 --- a/sound/soc/msm/qdsp6v2/rtac.c +++ b/sound/soc/msm/qdsp6v2/rtac.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -174,7 +174,7 @@ int rtac_allocate_cal_buffer(uint32_t cal_type) } if (rtac_cal[cal_type].cal_data.paddr != 0) { - pr_err("%s: memory already allocated! cal_type %d, paddr 0x%pa\n", + pr_err("%s: memory already allocated! cal_type %d, paddr 0x%pK\n", __func__, cal_type, &rtac_cal[cal_type].cal_data.paddr); result = -EPERM; goto done; @@ -193,7 +193,7 @@ int rtac_allocate_cal_buffer(uint32_t cal_type) goto done; } - pr_debug("%s: cal_type %d, paddr 0x%pa, kvaddr 0x%p, map_size 0x%x\n", + pr_debug("%s: cal_type %d, paddr 0x%pK, kvaddr 0x%pK, map_size 0x%x\n", __func__, cal_type, &rtac_cal[cal_type].cal_data.paddr, rtac_cal[cal_type].cal_data.kvaddr, @@ -223,7 +223,7 @@ int rtac_free_cal_buffer(uint32_t cal_type) result = msm_audio_ion_free(rtac_cal[cal_type].map_data.ion_client, rtac_cal[cal_type].map_data.ion_handle); if (result < 0) { - pr_err("%s: ION free for RTAC failed! cal_type %d, paddr 0x%pa\n", + pr_err("%s: ION free for RTAC failed! cal_type %d, paddr 0x%pK\n", __func__, cal_type, &rtac_cal[cal_type].cal_data.paddr); goto done; } @@ -657,7 +657,7 @@ static int get_voice_index(u32 mode, u32 handle) /* ADM APR */ void rtac_set_adm_handle(void *handle) { - pr_debug("%s: handle = %p\n", __func__, handle); + pr_debug("%s: handle = %pK\n", __func__, handle); mutex_lock(&rtac_adm_apr_mutex); rtac_adm_apr_data.apr_handle = handle; @@ -715,7 +715,7 @@ u32 send_adm_apr(void *buf, u32 opcode) if (copy_from_user(&user_buf_size, (void *)buf, sizeof(user_buf_size))) { - pr_err("%s: Copy from user failed! buf = 0x%p\n", + pr_err("%s: Copy from user failed! buf = 0x%pK\n", __func__, buf); goto done; } @@ -810,7 +810,7 @@ u32 send_adm_apr(void *buf, u32 opcode) memcpy(rtac_adm_buffer, &adm_params, sizeof(adm_params)); atomic_set(&rtac_adm_apr_data.cmd_state, 1); - pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pa\n", + pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n", __func__, opcode, &rtac_cal[ADM_RTAC_CAL].cal_data.paddr); @@ -921,7 +921,7 @@ u32 send_rtac_asm_apr(void *buf, u32 opcode) if (copy_from_user(&user_buf_size, (void *)buf, sizeof(user_buf_size))) { - pr_err("%s: Copy from user failed! buf = 0x%p\n", + pr_err("%s: Copy from user failed! buf = 0x%pK\n", __func__, buf); goto done; } @@ -1016,7 +1016,7 @@ u32 send_rtac_asm_apr(void *buf, u32 opcode) memcpy(rtac_asm_buffer, &asm_params, sizeof(asm_params)); atomic_set(&rtac_asm_apr_data[session_id].cmd_state, 1); - pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pa\n", + pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n", __func__, opcode, &rtac_cal[ASM_RTAC_CAL].cal_data.paddr); @@ -1148,7 +1148,7 @@ static u32 send_rtac_afe_apr(void *buf, uint32_t opcode) if (copy_from_user(&user_afe_buf, (void *)buf, sizeof(struct rtac_afe_user_data))) { - pr_err("%s: Copy from user failed! buf = 0x%p\n", + pr_err("%s: Copy from user failed! buf = 0x%pK\n", __func__, buf); goto done; } @@ -1256,7 +1256,7 @@ static u32 send_rtac_afe_apr(void *buf, uint32_t opcode) atomic_set(&rtac_afe_apr_data.cmd_state, 1); - pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pa\n", + pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n", __func__, opcode, &rtac_cal[AFE_RTAC_CAL].cal_data.paddr); @@ -1372,7 +1372,7 @@ u32 send_voice_apr(u32 mode, void *buf, u32 opcode) if (copy_from_user(&user_buf_size, (void *)buf, sizeof(user_buf_size))) { - pr_err("%s: Copy from user failed! buf = 0x%p\n", + pr_err("%s: Copy from user failed! buf = 0x%pK\n", __func__, buf); goto done; } @@ -1468,7 +1468,7 @@ u32 send_voice_apr(u32 mode, void *buf, u32 opcode) memcpy(rtac_voice_buffer, &voice_params, sizeof(voice_params)); atomic_set(&rtac_voice_apr_data[mode].cmd_state, 1); - pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pa\n", + pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n", __func__, opcode, &rtac_cal[VOICE_RTAC_CAL].cal_data.paddr); From ebbcb5753157f8ce0b32dc74a18761ef50855254 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Mon, 20 Jun 2016 19:28:13 -0700 Subject: [PATCH 074/320] diag: Update msg, log and event codes Update the msg, log and event codes to match the definitions in the mainline. CRs-Fixed: 1031959 Change-Id: Ia297eaab9abe2d36ce7c0a5084e2a77edfbf2286 Signed-off-by: Chris Lew --- include/linux/diagchar.h | 98 +++++++++++++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 17 deletions(-) diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h index 548b79e00f763..ea58a3d28754c 100644 --- a/include/linux/diagchar.h +++ b/include/linux/diagchar.h @@ -139,10 +139,10 @@ the appropriate macros. */ /* This needs to be modified manually now, when we add a new RANGE of SSIDs to the msg_mask_tbl */ #define MSG_MASK_TBL_CNT 25 -#define APPS_EVENT_LAST_ID 0x0A70 +#define APPS_EVENT_LAST_ID 0x0B14 #define MSG_SSID_0 0 -#define MSG_SSID_0_LAST 111 +#define MSG_SSID_0_LAST 118 #define MSG_SSID_1 500 #define MSG_SSID_1_LAST 506 #define MSG_SSID_2 1000 @@ -154,15 +154,15 @@ the appropriate macros. */ #define MSG_SSID_5 4000 #define MSG_SSID_5_LAST 4010 #define MSG_SSID_6 4500 -#define MSG_SSID_6_LAST 4526 +#define MSG_SSID_6_LAST 4573 #define MSG_SSID_7 4600 #define MSG_SSID_7_LAST 4615 #define MSG_SSID_8 5000 -#define MSG_SSID_8_LAST 5031 +#define MSG_SSID_8_LAST 5032 #define MSG_SSID_9 5500 #define MSG_SSID_9_LAST 5516 #define MSG_SSID_10 6000 -#define MSG_SSID_10_LAST 6080 +#define MSG_SSID_10_LAST 6081 #define MSG_SSID_11 6500 #define MSG_SSID_11_LAST 6521 #define MSG_SSID_12 7000 @@ -174,7 +174,7 @@ the appropriate macros. */ #define MSG_SSID_15 8000 #define MSG_SSID_15_LAST 8000 #define MSG_SSID_16 8500 -#define MSG_SSID_16_LAST 8524 +#define MSG_SSID_16_LAST 8529 #define MSG_SSID_17 9000 #define MSG_SSID_17_LAST 9008 #define MSG_SSID_18 9500 @@ -321,7 +321,17 @@ static const uint32_t msg_bld_masks_0[] = { MSG_LVL_HIGH, MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, - MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW, + MSG_LVL_MED, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_MED, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_HIGH }; static const uint32_t msg_bld_masks_1[] = { @@ -392,13 +402,60 @@ static const uint32_t msg_bld_masks_5[] = { }; static const uint32_t msg_bld_masks_6[] = { - MSG_LVL_MED, - MSG_LVL_MED, - MSG_LVL_MED, - MSG_LVL_MED, - MSG_LVL_MED, - MSG_LVL_MED, - MSG_LVL_MED, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, MSG_LVL_LOW, MSG_LVL_LOW, MSG_LVL_LOW, @@ -472,6 +529,7 @@ static const uint32_t msg_bld_masks_8[] = { MSG_LVL_MED, MSG_LVL_MED, MSG_LVL_MED, + MSG_LVL_MED, MSG_LVL_MED }; @@ -581,7 +639,8 @@ static const uint32_t msg_bld_masks_10[] = { MSG_LVL_LOW, MSG_LVL_LOW, MSG_LVL_LOW, - MSG_LVL_LOW + MSG_LVL_LOW, + MSG_LVL_MED }; static const uint32_t msg_bld_masks_11[] = { @@ -666,6 +725,11 @@ static const uint32_t msg_bld_masks_16[] = { MSG_LVL_LOW, MSG_LVL_LOW, MSG_LVL_LOW, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL }; static const uint32_t msg_bld_masks_17[] = { @@ -785,7 +849,7 @@ static const uint32_t msg_bld_masks_23[] = { /* LOG CODES */ static const uint32_t log_code_last_tbl[] = { 0x0, /* EQUIP ID 0 */ - 0x18A4, /* EQUIP ID 1 */ + 0x1966, /* EQUIP ID 1 */ 0x0, /* EQUIP ID 2 */ 0x0, /* EQUIP ID 3 */ 0x4910, /* EQUIP ID 4 */ @@ -797,7 +861,7 @@ static const uint32_t log_code_last_tbl[] = { 0xA38A, /* EQUIP ID 10 */ 0xB201, /* EQUIP ID 11 */ 0x0, /* EQUIP ID 12 */ - 0x0, /* EQUIP ID 13 */ + 0xD1FF, /* EQUIP ID 13 */ 0x0, /* EQUIP ID 14 */ 0x0, /* EQUIP ID 15 */ }; From 2c4fdce1ec6df1c05e17f96ab93220356a780b83 Mon Sep 17 00:00:00 2001 From: Xiaogang Cui Date: Wed, 15 Jun 2016 17:09:58 +0800 Subject: [PATCH 075/320] ARM: dts: msm: Add initial support for msm8909 QRD SKUQ board Add initial device trees for msm8909 QRD SKUQ board. Change-Id: Ib4ecec16676301fea3a1977147a4fa10d34f993d Signed-off-by: Xiaogang Cui --- arch/arm/boot/dts/qcom/Makefile | 1 + .../boot/dts/qcom/msm8909-pm8916-qrd-skuq.dts | 20 ++++++++++++ .../dts/qcom/msm8909-pm8916-qrd-skuq.dtsi | 31 +++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dts create mode 100644 arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile index 2dbdeb2063fa4..4d488acf20c31 100644 --- a/arch/arm/boot/dts/qcom/Makefile +++ b/arch/arm/boot/dts/qcom/Makefile @@ -53,6 +53,7 @@ dtb-$(CONFIG_ARCH_MSM8909) += msm8909-sim.dtb \ msm8909-pm8916-qhd-rcm.dtb \ msm8909-pm8916-qrd-skut-evt.dtb \ msm8909-pm8916-qrd-skut-dvt.dtb \ + msm8909-pm8916-qrd-skuq.dtb \ msm8208-cdp.dtb \ msm8208-mtp.dtb \ msm8208-1gb-cdp.dtb \ diff --git a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dts b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dts new file mode 100644 index 0000000000000..b3e2128eed3ea --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/dts-v1/; + +#include "msm8909-pm8916-qrd-skuq.dtsi" + +/ { + qcom,board-id= <0x6040b 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi new file mode 100644 index 0000000000000..6d46889487c89 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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 "msm8909-pm8916-qrd.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM8909-PM8916 QSIP SKUQ"; + compatible = "qcom,msm8909-qrd", "qcom,msm8909", "qcom,qrd"; + qcom,msm-id = <245 0>, + <258 0>, + <275 0>, + <300 0>; +}; + +&pm8916_chg { + status = "ok"; +}; + +&pm8916_bms { + status = "ok"; +}; From d540ee581b7ac5835a7dbad503e26e34d0aa9756 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 16 Jun 2015 22:11:06 +0100 Subject: [PATCH 076/320] pipe: iovec: Fix memory corruption when retrying atomic copy as non-atomic pipe_iov_copy_{from,to}_user() may be tried twice with the same iovec, the first time atomically and the second time not. The second attempt needs to continue from the iovec position, pipe buffer offset and remaining length where the first attempt failed, but currently the pipe buffer offset and remaining length are reset. This will corrupt the piped data (possibly also leading to an information leak between processes) and may also corrupt kernel memory. This was fixed upstream by commits f0d1bec9d58d ("new helper: copy_page_from_iter()") and 637b58c2887e ("switch pipe_read() to copy_page_to_iter()"), but those aren't suitable for stable. This fix for older kernel versions was made by Seth Jennings for RHEL and I have extracted it from their update. CVE-2015-1805 Change-Id: I4a18eab0e46f35b1d72f178138d50e1b3eb867cd References: https://bugzilla.redhat.com/show_bug.cgi?id=1202855 Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman Git-repo: http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git Git-commit: 14f81062f365fa9e3839bb2a16862217b71a553c Signed-off-by: Srinivasa Rao Kuppala --- fs/pipe.c | 55 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/fs/pipe.c b/fs/pipe.c index 0e0752ef27159..3e7ab278bb0c0 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -117,25 +117,27 @@ void pipe_wait(struct pipe_inode_info *pipe) } static int -pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len, - int atomic) +pipe_iov_copy_from_user(void *addr, int *offset, struct iovec *iov, + size_t *remaining, int atomic) { unsigned long copy; - while (len > 0) { + while (*remaining > 0) { while (!iov->iov_len) iov++; - copy = min_t(unsigned long, len, iov->iov_len); + copy = min_t(unsigned long, *remaining, iov->iov_len); if (atomic) { - if (__copy_from_user_inatomic(to, iov->iov_base, copy)) + if (__copy_from_user_inatomic(addr + *offset, + iov->iov_base, copy)) return -EFAULT; } else { - if (copy_from_user(to, iov->iov_base, copy)) + if (copy_from_user(addr + *offset, + iov->iov_base, copy)) return -EFAULT; } - to += copy; - len -= copy; + *offset += copy; + *remaining -= copy; iov->iov_base += copy; iov->iov_len -= copy; } @@ -143,25 +145,27 @@ pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len, } static int -pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len, - int atomic) +pipe_iov_copy_to_user(struct iovec *iov, void *addr, int *offset, + size_t *remaining, int atomic) { unsigned long copy; - while (len > 0) { + while (*remaining > 0) { while (!iov->iov_len) iov++; - copy = min_t(unsigned long, len, iov->iov_len); + copy = min_t(unsigned long, *remaining, iov->iov_len); if (atomic) { - if (__copy_to_user_inatomic(iov->iov_base, from, copy)) + if (__copy_to_user_inatomic(iov->iov_base, + addr + *offset, copy)) return -EFAULT; } else { - if (copy_to_user(iov->iov_base, from, copy)) + if (copy_to_user(iov->iov_base, + addr + *offset, copy)) return -EFAULT; } - from += copy; - len -= copy; + *offset += copy; + *remaining -= copy; iov->iov_base += copy; iov->iov_len -= copy; } @@ -395,7 +399,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, struct pipe_buffer *buf = pipe->bufs + curbuf; const struct pipe_buf_operations *ops = buf->ops; void *addr; - size_t chars = buf->len; + size_t chars = buf->len, remaining; int error, atomic; if (chars > total_len) @@ -409,9 +413,11 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, } atomic = !iov_fault_in_pages_write(iov, chars); + remaining = chars; redo: addr = ops->map(pipe, buf, atomic); - error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars, atomic); + error = pipe_iov_copy_to_user(iov, addr, &buf->offset, + &remaining, atomic); ops->unmap(pipe, buf, addr); if (unlikely(error)) { /* @@ -426,7 +432,6 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, break; } ret += chars; - buf->offset += chars; buf->len -= chars; /* Was it a packet buffer? Clean up and exit */ @@ -531,6 +536,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, if (ops->can_merge && offset + chars <= PAGE_SIZE) { int error, atomic = 1; void *addr; + size_t remaining = chars; error = ops->confirm(pipe, buf); if (error) @@ -539,8 +545,8 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, iov_fault_in_pages_read(iov, chars); redo1: addr = ops->map(pipe, buf, atomic); - error = pipe_iov_copy_from_user(offset + addr, iov, - chars, atomic); + error = pipe_iov_copy_from_user(addr, &offset, iov, + &remaining, atomic); ops->unmap(pipe, buf, addr); ret = error; do_wakeup = 1; @@ -575,6 +581,8 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, struct page *page = pipe->tmp_page; char *src; int error, atomic = 1; + int offset = 0; + size_t remaining; if (!page) { page = alloc_page(GFP_HIGHUSER); @@ -595,14 +603,15 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, chars = total_len; iov_fault_in_pages_read(iov, chars); + remaining = chars; redo2: if (atomic) src = kmap_atomic(page); else src = kmap(page); - error = pipe_iov_copy_from_user(src, iov, chars, - atomic); + error = pipe_iov_copy_from_user(src, &offset, iov, + &remaining, atomic); if (atomic) kunmap_atomic(src); else From c5f269d28bdb4725a1a95a6597187174cac8a8f9 Mon Sep 17 00:00:00 2001 From: Surendar karka Date: Thu, 23 Jun 2016 15:22:48 +0530 Subject: [PATCH 077/320] mfd: wcd9xxx-slimslave: Change slim driver to use %pK Change slimslave driver to use %pK instead of %p. %pK hides addresses when the users doesn't have kernel permissions. If address information is needed echo 0 > /proc/sys/kernel/kptr_restrict. Change-Id: I319f7a4f71e779963c4d31eb5a0f91637cf805d2 Signed-off-by: Surendar karka --- drivers/mfd/wcd9xxx-slimslave.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/mfd/wcd9xxx-slimslave.c b/drivers/mfd/wcd9xxx-slimslave.c index ac113e5f65a5b..4076e93a4b0c4 100644 --- a/drivers/mfd/wcd9xxx-slimslave.c +++ b/drivers/mfd/wcd9xxx-slimslave.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -266,7 +266,7 @@ int wcd9xxx_cfg_slim_sch_rx(struct wcd9xxx *wcd9xxx, list_for_each_entry(rx, wcd9xxx_ch_list, list) { codec_port = rx->port; - pr_debug("%s: codec_port %d rx 0x%p, payload %d\n" + pr_debug("%s: codec_port %d rx 0x%pK, payload %d\n" "sh_ch.rx_port_ch_reg_base0 0x%x\n" "sh_ch.port_rx_cfg_reg_base 0x%x\n", __func__, codec_port, rx, payload, @@ -373,7 +373,7 @@ int wcd9xxx_cfg_slim_sch_tx(struct wcd9xxx *wcd9xxx, pr_debug("%s: ch_cnt[%d] rate[%d]\n", __func__, ch_cnt, rate); list_for_each_entry(tx, wcd9xxx_ch_list, list) { codec_port = tx->port; - pr_debug("%s: codec_port %d tx 0x%p, payload 0x%x\n", + pr_debug("%s: codec_port %d tx 0x%pK, payload 0x%x\n", __func__, codec_port, tx, payload); /* write to interface device */ ret = wcd9xxx_interface_reg_write(wcd9xxx, @@ -595,7 +595,7 @@ int wcd9xxx_slim_ch_master_open(struct wcd9xxx *wcd9xxx, __func__, rate, bit_sz); if (wcd9xxx == NULL || handle == NULL) { - pr_err("%s: Invalid params, wcd9xxx(%p) handle(%p)\n", + pr_err("%s: Invalid params, wcd9xxx(%pK) handle(%pK)\n", __func__, wcd9xxx, handle); return -EINVAL; } @@ -658,12 +658,12 @@ int wcd9xxx_slim_ch_master_open(struct wcd9xxx *wcd9xxx, *handle = (struct wcd9xxx_master_cfg *)tx_master; tx_master->slim_s.handle = *handle; init_completion(&tx_master->slim_s.sb_comp); - pr_debug("%s: Handle %p slim_cfg->ph1 %x slim grp handle %x\n" + pr_debug("%s: Handle %pK slim_cfg->ph1 %x slim grp handle %x\n" "chanh %x\n", __func__, tx_master->slim_s.handle, tx_master->slim_cfg->ph1, tx_master->slim_cfg->grph, tx_master->slim_cfg->chanh); mutex_unlock(&tx_master->lock); - pr_debug("%s: Handle %p slim_cfg->ph1 %x slim grp\n" + pr_debug("%s: Handle %pK slim_cfg->ph1 %x slim grp\n" "handle %x chanh %x ref count %x\n", __func__, tx_master->slim_s.handle, tx_master->slim_cfg->ph1, @@ -687,14 +687,14 @@ int wcd9xxx_slim_ch_master_close(struct wcd9xxx *wcd9xxx, void **handle) struct wcd9xxx_slim_master_prop *slim_cfg; if (wcd9xxx == NULL || handle == NULL) { - pr_err("%s: Invalid params, wcd9xxx(%p) handle(%p)\n", + pr_err("%s: Invalid params, wcd9xxx(%pK) handle(%pK)\n", __func__, wcd9xxx, handle); return -EINVAL; } tx_master = &slim_tx_master; if (*handle != tx_master->slim_s.handle) { - pr_err("%s: handle(%p) not matching slim_hdl(%p)\n", + pr_err("%s: handle(%pK) not matching slim_hdl(%pK)\n", __func__, *handle, tx_master->slim_s.handle); return -EINVAL; } @@ -751,7 +751,7 @@ int wcd9xxx_slim_ch_master_status(struct wcd9xxx *wcd9xxx, void *handle, } tx_master = &slim_tx_master; if (handle != tx_master->slim_s.handle) { - pr_err("%s: handle(%p) not matching slim_hdl(%p)\n", + pr_err("%s: handle(%pK) not matching slim_hdl(%pK)\n", __func__, handle, tx_master->slim_s.handle); return -EINVAL; } @@ -775,17 +775,17 @@ int wcd9xxx_slim_ch_master_enable_read(struct wcd9xxx *wcd9xxx, void *handle) int rc = 0; struct wcd9xxx_master_cfg *tx_master; struct wcd9xxx_slim_master_prop *slim_cfg; - pr_debug("%s:handle = %p\n", __func__, handle); + pr_debug("%s:handle = %pK\n", __func__, handle); if (wcd9xxx == NULL || handle == NULL) { - pr_err("%s: Invalid params, wcd9xxx(%p) handle(%p)\n", + pr_err("%s: Invalid params, wcd9xxx(%pK) handle(%pK)\n", __func__, wcd9xxx, handle); return -EINVAL; } tx_master = &slim_tx_master; if (handle != tx_master->slim_s.handle) { - pr_err("%s: handle(%p) not matching slim_hdl(%p)\n", + pr_err("%s: handle(%pK) not matching slim_hdl(%pK)\n", __func__, handle, tx_master->slim_s.handle); return -EINVAL; } @@ -822,7 +822,7 @@ int wcd9xxx_slim_ch_master_read(struct wcd9xxx *wcd9xxx, void *handle, struct wcd9xxx_slim_master_prop *slim_cfg; struct completion *sb_comp; - pr_debug("%s: handle %p len %x\n", + pr_debug("%s: handle %pK len %x\n", __func__, handle, read_len); if (wcd9xxx == NULL || handle == NULL) { @@ -832,7 +832,7 @@ int wcd9xxx_slim_ch_master_read(struct wcd9xxx *wcd9xxx, void *handle, tx_master = &slim_tx_master; if (handle != tx_master->slim_s.handle) { - pr_err("%s: handle(%p) not matching slim_hdl(%p)\n", + pr_err("%s: handle(%pK) not matching slim_hdl(%pK)\n", __func__, handle, tx_master->slim_s.handle); return -EINVAL; } From 4b2de15e6f86050c2f733769159021f84f42373e Mon Sep 17 00:00:00 2001 From: Subash Abhinov Kasiviswanathan Date: Thu, 14 Jan 2016 10:51:04 -0700 Subject: [PATCH 078/320] msm_rmnet_bam: Move open operation to probe Rather than relying on userspace to open the hardware channel, open it directly from the probe callback. Change-Id: I5aee656f8a01cc7f91fe8ea17efc30366bdaf1bd Signed-off-by: Subash Abhinov Kasiviswanathan --- drivers/net/ethernet/msm/msm_rmnet_bam.c | 36 +++++++++++------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/drivers/net/ethernet/msm/msm_rmnet_bam.c b/drivers/net/ethernet/msm/msm_rmnet_bam.c index 94e25db91ab75..5c05a003172d2 100644 --- a/drivers/net/ethernet/msm/msm_rmnet_bam.c +++ b/drivers/net/ethernet/msm/msm_rmnet_bam.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -358,21 +358,6 @@ static void bam_notify(void *dev, int event, unsigned long data) static int __rmnet_open(struct net_device *dev) { - int r; - struct rmnet_private *p = netdev_priv(dev); - - DBG0("[%s] __rmnet_open()\n", dev->name); - - if (p->device_up == DEVICE_UNINITIALIZED) { - r = msm_bam_dmux_open(p->ch_id, dev, bam_notify); - if (r < 0) { - DBG0("%s: ch=%d failed with rc %d\n", - __func__, p->ch_id, r); - return -ENODEV; - } - } - - p->device_up = DEVICE_ACTIVE; return 0; } @@ -382,10 +367,7 @@ static int rmnet_open(struct net_device *dev) DBG0("[%s] rmnet_open()\n", dev->name); - rc = __rmnet_open(dev); - - if (rc == 0) - netif_start_queue(dev); + netif_start_queue(dev); return rc; } @@ -838,6 +820,20 @@ static int bam_rmnet_probe(struct platform_device *pdev) rmnet_debug_init(dev); + DBG0("[%s] OPEN()\n", dev->name); + + if (p->device_up == DEVICE_UNINITIALIZED) { + ret = msm_bam_dmux_open(p->ch_id, dev, bam_notify); + if (ret < 0) { + DBG0("%s: ch=%d failed with rc %d\n", + __func__, p->ch_id, ret); + unregister_netdev(dev); + free_netdev(dev); + return -EPROBE_DEFER; + } + } + + p->device_up = DEVICE_ACTIVE; return 0; } From 377c97c7d9153290f9c6f5fff8727cf6885877af Mon Sep 17 00:00:00 2001 From: Gaurav Singhal Date: Mon, 27 Jun 2016 18:37:19 +0530 Subject: [PATCH 079/320] NFC: Fix crash due to invalid use of ese gpio Some of the targets are not having ese gpio so if we try to access this pin on these targets, crash is observed. Change-Id: Ib5a2d7879f1b493bc445ab4a2d32a89f98d872b4 Signed-off-by: Gaurav Singhal --- drivers/nfc/nq-nci.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c index ed163bb7a6d80..04d72420cf773 100644 --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -324,8 +324,10 @@ static int nqx_ese_pwr(struct nqx_dev *nqx_dev, unsigned long int arg) } else if (arg == 3) { if (!nqx_dev->nfc_ven_enabled) r = 0; - else - r = gpio_get_value(nqx_dev->ese_gpio); + else { + if (gpio_is_valid(nqx_dev->ese_gpio)) + r = gpio_get_value(nqx_dev->ese_gpio); + } } return r; } @@ -373,11 +375,14 @@ int nfc_ioctl_power_states(struct file *filp, unsigned long arg) __func__, nqx_dev); if (gpio_is_valid(nqx_dev->firm_gpio)) gpio_set_value(nqx_dev->firm_gpio, 0); - if (!gpio_get_value(nqx_dev->ese_gpio)) { - dev_dbg(&nqx_dev->client->dev, "disabling en_gpio\n"); - gpio_set_value(nqx_dev->en_gpio, 0); - } else { - dev_dbg(&nqx_dev->client->dev, "keeping en_gpio high\n"); + + if (gpio_is_valid(nqx_dev->ese_gpio)) { + if (!gpio_get_value(nqx_dev->ese_gpio)) { + dev_dbg(&nqx_dev->client->dev, "disabling en_gpio\n"); + gpio_set_value(nqx_dev->en_gpio, 0); + } else { + dev_dbg(&nqx_dev->client->dev, "keeping en_gpio high\n"); + } } r = nqx_clock_deselect(nqx_dev); if (r < 0) @@ -402,9 +407,11 @@ int nfc_ioctl_power_states(struct file *filp, unsigned long arg) /* We are switching to Dowload Mode, toggle the enable pin * in order to set the NFCC in the new mode */ - if (gpio_get_value(nqx_dev->ese_gpio)) { - dev_err(&nqx_dev->client->dev, "FW download forbidden while ese is on\n"); - return -EBUSY; /* Device or resource busy */ + if (gpio_is_valid(nqx_dev->ese_gpio)) { + if (gpio_get_value(nqx_dev->ese_gpio)) { + dev_err(&nqx_dev->client->dev, "FW download forbidden while ese is on\n"); + return -EBUSY; /* Device or resource busy */ + } } gpio_set_value(nqx_dev->en_gpio, 1); msleep(20); @@ -824,6 +831,7 @@ static int nqx_probe(struct i2c_client *client, nqx_dev->en_gpio = platform_data->en_gpio; nqx_dev->irq_gpio = platform_data->irq_gpio; nqx_dev->firm_gpio = platform_data->firm_gpio; + nqx_dev->ese_gpio = platform_data->ese_gpio; nqx_dev->clkreq_gpio = platform_data->clkreq_gpio; nqx_dev->pdata = platform_data; From 11a09b79d911fd3d7e63669d7d1ee724c57bc1e8 Mon Sep 17 00:00:00 2001 From: Jayant Shekhar Date: Mon, 27 Apr 2015 17:25:43 +0530 Subject: [PATCH 080/320] msm: mdss: Add support to select max MDP bandwidth MDSS currently has fixed maximum bandwidth enabled in DT file. But there are scenarios where this maximum bandwidth support can change to enhance performance. Based on scenarios such as camera use, or flip involved declare the max bandwidth for usecase in DT and change accordingly based on the usecase. Change-Id: Icc85d75d7a60fe6f934a1fbd9d5077b620b2993d Signed-off-by: Jayant Shekhar Signed-off-by: Raghavendra Ambadas --- .../devicetree/bindings/fb/mdss-mdp.txt | 21 +++++ drivers/video/msm/mdss/mdss.h | 9 +++ drivers/video/msm/mdss/mdss_mdp.c | 64 +++++++++++++++ drivers/video/msm/mdss/mdss_mdp_ctl.c | 80 ++++++++++++++++++- include/uapi/linux/msm_mdp.h | 7 ++ 5 files changed, 180 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt index 7ad5888dd815b..d0b34e7851da6 100644 --- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt +++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt @@ -404,6 +404,22 @@ Fudge Factors: Fudge factors are used to boost demand for command mode panels. - qcom,max-bandwidth-per-pipe-kbps: This value indicates the max bandwidth in KB that a single pipe can support without underflow. +- qcom,max-bw-settings: This two dimension array indicates the max bandwidth + in KB that has to be supported when particular + scenarios are involved such as camera, flip. + The first parameter indicate the + scenario/usecase and second paramter indicate + the maximum bandwidth for that usecase. + Following are the enum values for modes in different + cases: + For default case, mode = 1 + camera usecase, mode = 2 + hflip usecase, mode = 4 + vflip usecase, mode = 8 + First parameter/mode value need to match enum, + mdss_mdp_max_bw_mode, present in + include/uapi/linux/msm_mdp.h. + - qcom,mdss-has-panic-ctrl: Boolean property to indicate if panic/robust signal control feature is available or not. - qcom,mdss-pipe-vig-panic-ctrl-offsets: Array of panic/robust signal offsets @@ -523,6 +539,11 @@ Example: qcom,max-bandwidth-low-kbps = <2300000>; qcom,max-bandwidth-high-kbps = <3000000>; + qcom,max-bw-settings = <1 2300000>, + <2 1700000>, + <4 2300000>, + <8 2000000>; + qcom,max-mixer-width = <2048>; qcom,max-clk-rate = <320000000>; qcom,vbif-settings = <0x0004 0x00000001>, diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h index 5308acbdd7b5a..a3e47474ae850 100644 --- a/drivers/video/msm/mdss/mdss.h +++ b/drivers/video/msm/mdss/mdss.h @@ -60,6 +60,11 @@ struct mdss_hw_settings { u32 val; }; +struct mdss_max_bw_settings { + u32 mdss_max_bw_mode; + u32 mdss_max_bw_val; +}; + struct mdss_debug_inf { void *debug_data; void (*debug_enable_clock)(int on); @@ -258,6 +263,10 @@ struct mdss_data_type { u64 ab[MDSS_MAX_BUS_CLIENTS]; u64 ib[MDSS_MAX_BUS_CLIENTS]; + + struct mdss_max_bw_settings *max_bw_settings; + u32 bw_mode_bitmap; + u32 max_bw_settings_cnt; }; extern struct mdss_data_type *mdss_res; diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c index 4d9f3bf7f5edb..d1e50fc8ab0b2 100644 --- a/drivers/video/msm/mdss/mdss_mdp.c +++ b/drivers/video/msm/mdss/mdss_mdp.c @@ -1423,10 +1423,29 @@ static ssize_t mdss_mdp_show_capabilities(struct device *dev, return cnt; } +static ssize_t mdss_mdp_store_max_limit_bw(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct mdss_data_type *mdata = dev_get_drvdata(dev); + u32 data = 0; + + if (1 != sscanf(buf, "%d", &data)) { + pr_info("Not able scan to bw_mode_bitmap\n"); + } else { + mdata->bw_mode_bitmap = data; + pr_debug("limit use case, bw_mode_bitmap = %d\n", data); + } + + return len; +} + static DEVICE_ATTR(caps, S_IRUGO, mdss_mdp_show_capabilities, NULL); +static DEVICE_ATTR(bw_mode_bitmap, S_IRUGO | S_IWUSR | S_IWGRP, NULL, + mdss_mdp_store_max_limit_bw); static struct attribute *mdp_fs_attrs[] = { &dev_attr_caps.attr, + &dev_attr_bw_mode_bitmap.attr, NULL }; @@ -2574,6 +2593,48 @@ static void mdss_mdp_parse_vbif_qos(struct platform_device *pdev) } } +static void mdss_mdp_parse_max_bw_array(const u32 *arr, + struct mdss_max_bw_settings *max_bw_settings, int count) +{ + int i; + for (i = 0; i < count; i++) { + max_bw_settings->mdss_max_bw_mode = be32_to_cpu(arr[i*2]); + max_bw_settings->mdss_max_bw_val = be32_to_cpu(arr[(i*2)+1]); + max_bw_settings++; + } +} + +static void mdss_mdp_parse_max_bandwidth(struct platform_device *pdev) +{ + struct mdss_data_type *mdata = platform_get_drvdata(pdev); + struct mdss_max_bw_settings *max_bw_settings; + int max_bw_settings_cnt = 0; + const u32 *max_bw; + + max_bw = of_get_property(pdev->dev.of_node, "qcom,max-bw-settings", + &max_bw_settings_cnt); + + if (!max_bw && !max_bw_settings_cnt) { + pr_debug("MDSS max bandwidth settings not found\n"); + return; + } + + max_bw_settings_cnt /= 2 * sizeof(u32); + + max_bw_settings = devm_kzalloc(&pdev->dev, sizeof(*max_bw_settings) + * max_bw_settings_cnt, GFP_KERNEL); + if (!max_bw_settings) { + pr_err("Memory allocation failed for max_bw_settings\n"); + return; + } + + mdss_mdp_parse_max_bw_array(max_bw, max_bw_settings, + max_bw_settings_cnt); + + mdata->max_bw_settings = max_bw_settings; + mdata->max_bw_settings_cnt = max_bw_settings_cnt; +} + static int mdss_mdp_parse_dt_misc(struct platform_device *pdev) { struct mdss_data_type *mdata = platform_get_drvdata(pdev); @@ -2697,6 +2758,9 @@ static int mdss_mdp_parse_dt_misc(struct platform_device *pdev) if (rc) pr_debug("max bandwidth (per pipe) property not specified\n"); + + mdss_mdp_parse_max_bandwidth(pdev); + mdata->nclk_lvl = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-clk-levels"); diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c index 491f3eb3d4573..cb33e4ebb0b5c 100644 --- a/drivers/video/msm/mdss/mdss_mdp_ctl.c +++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c @@ -908,13 +908,83 @@ static void __mdss_mdp_perf_calc_ctl_helper(struct mdss_mdp_ctl *ctl, *(perf->bw_vote_mode)); } +static u32 mdss_check_for_flip(struct mdss_mdp_ctl *ctl) +{ + u32 i, panel_orientation; + struct mdss_mdp_pipe *pipe; + u32 flags = 0; + + panel_orientation = ctl->mfd->panel_orientation; + if (panel_orientation & MDP_FLIP_LR) + flags |= MDSS_MAX_BW_LIMIT_HFLIP; + if (panel_orientation & MDP_FLIP_UD) + flags |= MDSS_MAX_BW_LIMIT_VFLIP; + + for (i = 0; i < MAX_PIPES_PER_LM; i++) { + if ((flags & MDSS_MAX_BW_LIMIT_HFLIP) && + (flags & MDSS_MAX_BW_LIMIT_VFLIP)) + return flags; + + if (ctl->mixer_left && ctl->mixer_left->stage_pipe[i]) { + pipe = ctl->mixer_left->stage_pipe[i]; + if (pipe->flags & MDP_FLIP_LR) + flags |= MDSS_MAX_BW_LIMIT_HFLIP; + if (pipe->flags & MDP_FLIP_UD) + flags |= MDSS_MAX_BW_LIMIT_VFLIP; + } + + if (ctl->mixer_right && ctl->mixer_right->stage_pipe[i]) { + pipe = ctl->mixer_right->stage_pipe[i]; + if (pipe->flags & MDP_FLIP_LR) + flags |= MDSS_MAX_BW_LIMIT_HFLIP; + if (pipe->flags & MDP_FLIP_UD) + flags |= MDSS_MAX_BW_LIMIT_VFLIP; + } + } + + return flags; +} + +static int mdss_mdp_set_threshold_max_bandwidth(struct mdss_mdp_ctl *ctl) +{ + u32 mode, threshold = 0, max = INT_MAX; + u32 i = 0; + struct mdss_max_bw_settings *max_bw_settings = + ctl->mdata->max_bw_settings; + + if (!ctl->mdata->max_bw_settings_cnt && !ctl->mdata->max_bw_settings) + return 0; + + mode = ctl->mdata->bw_mode_bitmap; + + if (!((mode & MDSS_MAX_BW_LIMIT_HFLIP) && + (mode & MDSS_MAX_BW_LIMIT_VFLIP))) + mode |= mdss_check_for_flip(ctl); + + pr_debug("final mode = %d, bw_mode_bitmap = %d\n", mode, + ctl->mdata->bw_mode_bitmap); + + /* Select BW mode with smallest limit */ + while (mode) { + if (mode & BIT(0)) { + threshold = max_bw_settings[i].mdss_max_bw_val; + if (threshold < max) + max = threshold; + } + mode >>= 1; + i++; + } + + return max; +} + int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl, struct mdss_mdp_pipe **left_plist, int left_cnt, struct mdss_mdp_pipe **right_plist, int right_cnt) { struct mdss_data_type *mdata = ctl->mdata; struct mdss_mdp_perf_params perf; - u32 bw, threshold; + u32 bw, threshold, max_bw; /* we only need bandwidth check on real-time clients (interfaces) */ if (ctl->intf_type == MDSS_MDP_NO_INTF) @@ -929,6 +999,14 @@ int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl, pr_debug("calculated bandwidth=%uk\n", bw); threshold = ctl->is_video_mode ? mdata->max_bw_low : mdata->max_bw_high; + + max_bw = mdss_mdp_set_threshold_max_bandwidth(ctl); + + if (max_bw && (max_bw < threshold)) + threshold = max_bw; + + pr_debug("final threshold bw limit = %d\n", threshold); + if (bw > threshold) { pr_debug("exceeds bandwidth: %ukb > %ukb\n", bw, threshold); return -E2BIG; diff --git a/include/uapi/linux/msm_mdp.h b/include/uapi/linux/msm_mdp.h index 8298116d8912c..9013ebfb9be5f 100644 --- a/include/uapi/linux/msm_mdp.h +++ b/include/uapi/linux/msm_mdp.h @@ -182,6 +182,13 @@ enum { NUM_HSIC_PARAM, }; +enum mdss_mdp_max_bw_mode { + MDSS_MAX_BW_LIMIT_DEFAULT = 0x1, + MDSS_MAX_BW_LIMIT_CAMERA = 0x2, + MDSS_MAX_BW_LIMIT_HFLIP = 0x4, + MDSS_MAX_BW_LIMIT_VFLIP = 0x8, +}; + #define MDSS_MDP_ROT_ONLY 0x80 #define MDSS_MDP_RIGHT_MIXER 0x100 #define MDSS_MDP_DUAL_PIPE 0x200 From f1a1df9e13b99a1eb0ba212d3137ed82ccb3ea9e Mon Sep 17 00:00:00 2001 From: Jayant Shekhar Date: Fri, 1 May 2015 15:04:34 +0530 Subject: [PATCH 081/320] msm: mdss: Add debugfs support to change MDP max bandwidth Based on various use-cases such as camera and flip, MDP bandwidth limit can be changed. For debug purpose add support to change these paramaters via debugfs. First parameter takes mode and second paramter takes bandwidth limit for that particular mode. E.g. echo 2 1700000 > /mdp/perf/threshold_bw_limit Change-Id: I98456f4f00223136628b2d2300b5785af386b134 Signed-off-by: Jayant Shekhar Signed-off-by: Raghavendra Ambadas --- drivers/video/msm/mdss/mdss_debug.c | 86 +++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c index 93b2a213f5f8f..76d65044be8f2 100644 --- a/drivers/video/msm/mdss/mdss_debug.c +++ b/drivers/video/msm/mdss/mdss_debug.c @@ -857,6 +857,89 @@ static int mdss_debugfs_cleanup(struct mdss_debug_data *mdd) return 0; } +static ssize_t mdss_debug_perf_bw_limit_read(struct file *file, + char __user *buff, size_t count, loff_t *ppos) +{ + struct mdss_data_type *mdata = file->private_data; + struct mdss_max_bw_settings *temp_settings = mdata->max_bw_settings; + int len = 0, i; + char buf[256]; + + if (!mdata) + return -ENODEV; + + if (*ppos) + return 0; /* the end */ + + pr_debug("mdata->max_bw_settings_cnt = %d\n", + mdata->max_bw_settings_cnt); + + for (i = 0; i < mdata->max_bw_settings_cnt; i++) { + len += snprintf(buf + len, sizeof(buf), "%d %d\n", + temp_settings->mdss_max_bw_mode, + temp_settings->mdss_max_bw_val); + temp_settings++; + } + + if (len < 0) + return 0; + + if (copy_to_user(buff, buf, len)) + return -EFAULT; + + *ppos += len; /* increase offset */ + + return len; +} + +static ssize_t mdss_debug_perf_bw_limit_write(struct file *file, + const char __user *user_buf, size_t count, loff_t *ppos) +{ + struct mdss_data_type *mdata = file->private_data; + char buf[32]; + u32 mode, val; + u32 cnt = mdata->max_bw_settings_cnt; + struct mdss_max_bw_settings *temp_settings = mdata->max_bw_settings; + + if (!mdata) + return -ENODEV; + + + if (count >= sizeof(buf)) + return -EFAULT; + + if (copy_from_user(buf, user_buf, count)) + return -EFAULT; + + buf[count] = 0; /* end of string */ + + if (strnchr(buf, count, ' ')) { + /* Parsing buf */ + if (sscanf(buf, "%d %d", &mode, &val) != 2) + return -EFAULT; + } + + while (cnt--) { + if (mode == temp_settings->mdss_max_bw_mode) { + temp_settings->mdss_max_bw_val = val; + break; + } else { + temp_settings++; + } + } + + if (cnt == 0) + pr_err("Input mode is invalid\n"); + + return count; +} + +static const struct file_operations mdss_perf_bw_limit_fops = { + .open = simple_open, + .read = mdss_debug_perf_bw_limit_read, + .write = mdss_debug_perf_bw_limit_write, +}; + static int mdss_debugfs_perf_init(struct mdss_debug_data *mdd, struct mdss_data_type *mdata) { @@ -910,6 +993,9 @@ static int mdss_debugfs_perf_init(struct mdss_debug_data *mdd, debugfs_create_u32("latency_buff_per", 0644, mdd->perf, (u32 *)&mdata->latency_buff_per); + debugfs_create_file("threshold_bw_limit", 0644, mdd->perf, + (struct mdss_data_type *)mdata, &mdss_perf_bw_limit_fops); + return 0; } From 10c39a5da0c08d6d14081e32372f93c9e7d86fbb Mon Sep 17 00:00:00 2001 From: Jayant Shekhar Date: Thu, 21 May 2015 15:49:25 +0530 Subject: [PATCH 082/320] msm: mdss: Fix potential NULL pointer dereference issues Fix to prevent potential NULL pointer dereferences in max bandwidth limit implementation. Change-Id: I2b132e75f2254265ea1179ef7822743d53861954 Signed-off-by: Jayant Shekhar Signed-off-by: Raghavendra Ambadas --- drivers/video/msm/mdss/mdss_debug.c | 10 ++++++---- drivers/video/msm/mdss/mdss_mdp.c | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c index 76d65044be8f2..a03e194f64975 100644 --- a/drivers/video/msm/mdss/mdss_debug.c +++ b/drivers/video/msm/mdss/mdss_debug.c @@ -861,7 +861,7 @@ static ssize_t mdss_debug_perf_bw_limit_read(struct file *file, char __user *buff, size_t count, loff_t *ppos) { struct mdss_data_type *mdata = file->private_data; - struct mdss_max_bw_settings *temp_settings = mdata->max_bw_settings; + struct mdss_max_bw_settings *temp_settings; int len = 0, i; char buf[256]; @@ -874,6 +874,7 @@ static ssize_t mdss_debug_perf_bw_limit_read(struct file *file, pr_debug("mdata->max_bw_settings_cnt = %d\n", mdata->max_bw_settings_cnt); + temp_settings = mdata->max_bw_settings; for (i = 0; i < mdata->max_bw_settings_cnt; i++) { len += snprintf(buf + len, sizeof(buf), "%d %d\n", temp_settings->mdss_max_bw_mode, @@ -897,9 +898,8 @@ static ssize_t mdss_debug_perf_bw_limit_write(struct file *file, { struct mdss_data_type *mdata = file->private_data; char buf[32]; - u32 mode, val; - u32 cnt = mdata->max_bw_settings_cnt; - struct mdss_max_bw_settings *temp_settings = mdata->max_bw_settings; + u32 mode, val, cnt; + struct mdss_max_bw_settings *temp_settings; if (!mdata) return -ENODEV; @@ -912,6 +912,8 @@ static ssize_t mdss_debug_perf_bw_limit_write(struct file *file, return -EFAULT; buf[count] = 0; /* end of string */ + cnt = mdata->max_bw_settings_cnt; + temp_settings = mdata->max_bw_settings; if (strnchr(buf, count, ' ')) { /* Parsing buf */ diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c index d1e50fc8ab0b2..4594489a0d55b 100644 --- a/drivers/video/msm/mdss/mdss_mdp.c +++ b/drivers/video/msm/mdss/mdss_mdp.c @@ -2614,7 +2614,7 @@ static void mdss_mdp_parse_max_bandwidth(struct platform_device *pdev) max_bw = of_get_property(pdev->dev.of_node, "qcom,max-bw-settings", &max_bw_settings_cnt); - if (!max_bw && !max_bw_settings_cnt) { + if (!max_bw || !max_bw_settings_cnt) { pr_debug("MDSS max bandwidth settings not found\n"); return; } From 8e1b3064682d0294ab0a1bd384d44f0c1cf45dc4 Mon Sep 17 00:00:00 2001 From: Jayant Shekhar Date: Mon, 24 Aug 2015 14:34:26 +0530 Subject: [PATCH 083/320] msm: mdss: Correct max threshold bandwidth selection logic Max threshold Bandwidth selection logic should be independent of number of entries in max bandwidth limit DT property. Correct the logic to make it independent . Change-Id: I6510ad7095560b25bbada7c63c44ae88a6d955f1 Signed-off-by: Jayant Shekhar Signed-off-by: Raghavendra Ambadas --- drivers/video/msm/mdss/mdss_mdp_ctl.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c index cb33e4ebb0b5c..f2ef8b4311752 100644 --- a/drivers/video/msm/mdss/mdss_mdp_ctl.c +++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c @@ -964,15 +964,13 @@ static int mdss_mdp_set_threshold_max_bandwidth(struct mdss_mdp_ctl *ctl) pr_debug("final mode = %d, bw_mode_bitmap = %d\n", mode, ctl->mdata->bw_mode_bitmap); - /* Select BW mode with smallest limit */ - while (mode) { - if (mode & BIT(0)) { + /* Return minimum bandwidth limit */ + for (i = 0; i < ctl->mdata->max_bw_settings_cnt; i++) { + if (max_bw_settings[i].mdss_max_bw_mode & mode) { threshold = max_bw_settings[i].mdss_max_bw_val; if (threshold < max) max = threshold; } - mode >>= 1; - i++; } return max; From 94047135cb0acb999701f1d05349da4c94bc21ba Mon Sep 17 00:00:00 2001 From: raghavendra ambadas Date: Mon, 12 Oct 2015 13:58:19 +0530 Subject: [PATCH 084/320] ARM: dts: msm: Enable max bandwidth limit in msm8939 MDSS Based on scenarios such as camera use, or flip involved declare the max bandwidth and per pipe bandwidth settings in DT and change accordingly based on usecase. Usecase is identified based on modes and each mode has a particular maximum bandwidth limit. Change-Id: Ic432b6f2f3522fd1befd3ed62e1fb907b81ede5d Signed-off-by: Raghavendra Ambadas --- arch/arm/boot/dts/qcom/msm8939-mdss.dtsi | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/qcom/msm8939-mdss.dtsi b/arch/arm/boot/dts/qcom/msm8939-mdss.dtsi index 9332e6e49e625..4e8e8ec1dd33d 100644 --- a/arch/arm/boot/dts/qcom/msm8939-mdss.dtsi +++ b/arch/arm/boot/dts/qcom/msm8939-mdss.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -34,9 +34,16 @@ qcom,mdss-ib-factor = <2 1>; /* 2 times */ qcom,mdss-ib-factor-cmd = <10 6>; /* 1.6 times */ qcom,mdss-clk-factor = <105 100>; /* 1.05 times */ - qcom,max-bandwidth-low-kbps = <2000000>; - qcom,max-bandwidth-high-kbps = <2000000>; - qcom,max-bandwidth-per-pipe-kbps = <1500000>; + qcom,max-bandwidth-low-kbps = <2500000>; + qcom,max-bandwidth-high-kbps = <2500000>; + qcom,max-bandwidth-per-pipe-kbps = <1 2100000>, /* Default */ + <2 1500000>; /* Camera */ + + /* Bandwidth limit settings */ + qcom,max-bw-settings = <1 2500000>, /* Default */ + <2 2100000>, /* Camera */ + <4 1900000>, /* HFlip */ + <8 1900000>; /* VFlip */ /* VBIF QoS remapper settings*/ qcom,mdss-vbif-qos-rt-setting = <2 2 2 2>; From d902a23f5ec34ae44bbbcf0940ebb2fdccf1629e Mon Sep 17 00:00:00 2001 From: Anusha Koduru Date: Fri, 24 Jul 2015 15:27:23 +0530 Subject: [PATCH 085/320] msm: mdss: specify HFlip and VFlip per pipe BW limit Apply per pipe BW limit check based on HFlip/VFlip. Some targets have different limits for BW based on usecase. Change-Id: Ie23dba396b47ffb3fb910e746e4a992fe6d78ab9 Signed-off-by: Anusha Koduru Signed-off-by: Jayant Shekhar Signed-off-by: Raghavendra Ambadas --- .../devicetree/bindings/fb/mdss-mdp.txt | 18 +++++- drivers/video/msm/mdss/mdss.h | 4 ++ drivers/video/msm/mdss/mdss_mdp.c | 63 +++++++++++++++++-- drivers/video/msm/mdss/mdss_mdp_ctl.c | 62 +++++++++++++++++- 4 files changed, 139 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt index d0b34e7851da6..c92d4e40f820a 100644 --- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt +++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt @@ -402,8 +402,20 @@ Fudge Factors: Fudge factors are used to boost demand for applied in scenarios where panel interface can be more tolerant to memory latency such as command mode panels. -- qcom,max-bandwidth-per-pipe-kbps: This value indicates the max bandwidth in KB - that a single pipe can support without underflow. +- qcom,max-bandwidth-per-pipe-kbps: A two dimensional array indicating the max + bandwidth in KB that a single pipe can support + without underflow for various usecases. The + first parameter indicates the usecase and the + second parameter gives the max bw allowed for + the usecase. Following are the enum values for + modes in different cases: + For default case, mode = 1 + camera usecase, mode = 2 + hflip usecase, mode = 4 + vflip usecase, mode = 8 + First parameter/mode value need to match enum, + mdss_mdp_max_bw_mode, present in + include/uapi/linux/msm_mdp.h. - qcom,max-bw-settings: This two dimension array indicates the max bandwidth in KB that has to be supported when particular scenarios are involved such as camera, flip. @@ -539,6 +551,8 @@ Example: qcom,max-bandwidth-low-kbps = <2300000>; qcom,max-bandwidth-high-kbps = <3000000>; + qcom,max-bandwidth-per-pipe-kbps = <4 2100000>, + <8 1800000>; qcom,max-bw-settings = <1 2300000>, <2 1700000>, <4 2300000>, diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h index a3e47474ae850..e25f0630df054 100644 --- a/drivers/video/msm/mdss/mdss.h +++ b/drivers/video/msm/mdss/mdss.h @@ -267,6 +267,10 @@ struct mdss_data_type { struct mdss_max_bw_settings *max_bw_settings; u32 bw_mode_bitmap; u32 max_bw_settings_cnt; + + struct mdss_max_bw_settings *max_per_pipe_bw_settings; + u32 mdss_per_pipe_bw_cnt; + u32 min_bw_per_pipe; }; extern struct mdss_data_type *mdss_res; diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c index 4594489a0d55b..7cfe38d1bc455 100644 --- a/drivers/video/msm/mdss/mdss_mdp.c +++ b/drivers/video/msm/mdss/mdss_mdp.c @@ -2635,6 +2635,63 @@ static void mdss_mdp_parse_max_bandwidth(struct platform_device *pdev) mdata->max_bw_settings_cnt = max_bw_settings_cnt; } +static void mdss_mdp_parse_per_pipe_bandwidth(struct platform_device *pdev) +{ + + struct mdss_data_type *mdata = platform_get_drvdata(pdev); + struct mdss_max_bw_settings *max_bw_per_pipe_settings; + int max_bw_settings_cnt = 0; + const u32 *max_bw_settings; + u32 max_bw, min_bw, threshold, i = 0; + + max_bw_settings = of_get_property(pdev->dev.of_node, + "qcom,max-bandwidth-per-pipe-kbps", + &max_bw_settings_cnt); + + if (!max_bw_settings || !max_bw_settings_cnt) { + pr_debug("MDSS per pipe max bandwidth settings not found\n"); + return; + } + + /* Support targets where a common per pipe max bw is provided */ + if ((max_bw_settings_cnt / sizeof(u32)) == 1) { + mdata->max_bw_per_pipe = be32_to_cpu(max_bw_settings[0]); + mdata->max_per_pipe_bw_settings = NULL; + pr_debug("Common per pipe max bandwidth provided\n"); + return; + } + + max_bw_settings_cnt /= 2 * sizeof(u32); + + max_bw_per_pipe_settings = devm_kzalloc(&pdev->dev, + sizeof(struct mdss_max_bw_settings) * max_bw_settings_cnt, + GFP_KERNEL); + if (!max_bw_per_pipe_settings) { + pr_err("Memory allocation failed for max_bw_settings\n"); + return; + } + + mdss_mdp_parse_max_bw_array(max_bw_settings, max_bw_per_pipe_settings, + max_bw_settings_cnt); + mdata->max_per_pipe_bw_settings = max_bw_per_pipe_settings; + mdata->mdss_per_pipe_bw_cnt = max_bw_settings_cnt; + + /* Calculate min and max allowed per pipe BW */ + min_bw = mdata->max_bw_high; + max_bw = 0; + + while (i < max_bw_settings_cnt) { + threshold = mdata->max_per_pipe_bw_settings[i].mdss_max_bw_val; + if (threshold > max_bw) + max_bw = threshold; + if (threshold < min_bw) + min_bw = threshold; + ++i; + } + mdata->max_bw_per_pipe = max_bw; + mdata->min_bw_per_pipe = min_bw; +} + static int mdss_mdp_parse_dt_misc(struct platform_device *pdev) { struct mdss_data_type *mdata = platform_get_drvdata(pdev); @@ -2753,11 +2810,7 @@ static int mdss_mdp_parse_dt_misc(struct platform_device *pdev) if (rc) pr_debug("max bandwidth (high) property not specified\n"); - rc = of_property_read_u32(pdev->dev.of_node, - "qcom,max-bandwidth-per-pipe-kbps", &mdata->max_bw_per_pipe); - if (rc) - pr_debug("max bandwidth (per pipe) property not specified\n"); - + mdss_mdp_parse_per_pipe_bandwidth(pdev); mdss_mdp_parse_max_bandwidth(pdev); diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c index f2ef8b4311752..fb75564388b6d 100644 --- a/drivers/video/msm/mdss/mdss_mdp_ctl.c +++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c @@ -1013,6 +1013,61 @@ int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl, return 0; } +static u32 mdss_mdp_get_bw_by_mode(struct mdss_max_bw_settings *settings, + int count, int key) +{ + u32 value = 0, i = 0; + + while (i < count) { + if (settings[i].mdss_max_bw_mode == key) { + value = settings[i].mdss_max_bw_val; + break; + } + ++i; + } + return value; +} + +static u32 mdss_mdp_get_max_pipe_bw(struct mdss_mdp_pipe *pipe) +{ + + struct mdss_data_type *mdata = pipe->mixer_left->ctl->mdata; + struct mdss_mdp_ctl *ctl = pipe->mixer_left->ctl; + u32 flags = 0, threshold = 0, panel_orientation; + + panel_orientation = ctl->mfd->panel_orientation; + + /* Check for panel orienatation */ + panel_orientation = ctl->mfd->panel_orientation; + if (panel_orientation & MDP_FLIP_LR) + flags |= MDSS_MAX_BW_LIMIT_HFLIP; + if (panel_orientation & MDP_FLIP_UD) + flags |= MDSS_MAX_BW_LIMIT_VFLIP; + + /* check for Hflip/Vflip in pipe */ + if (pipe->flags & MDP_FLIP_LR) + flags |= MDSS_MAX_BW_LIMIT_HFLIP; + if (pipe->flags & MDP_FLIP_UD) + flags |= MDSS_MAX_BW_LIMIT_VFLIP; + + if ((flags & MDSS_MAX_BW_LIMIT_HFLIP) && + (flags & MDSS_MAX_BW_LIMIT_VFLIP)) { + threshold = mdata->min_bw_per_pipe; + } else if (flags & MDSS_MAX_BW_LIMIT_HFLIP) { + threshold = mdss_mdp_get_bw_by_mode( + mdata->max_per_pipe_bw_settings, + mdata->mdss_per_pipe_bw_cnt, + MDSS_MAX_BW_LIMIT_HFLIP); + } else if (flags & MDSS_MAX_BW_LIMIT_VFLIP) { + threshold = mdss_mdp_get_bw_by_mode( + mdata->max_per_pipe_bw_settings, + mdata->mdss_per_pipe_bw_cnt, + MDSS_MAX_BW_LIMIT_VFLIP); + } + + return threshold ? threshold : mdata->max_bw_per_pipe; +} + int mdss_mdp_perf_bw_check_pipe(struct mdss_mdp_perf_params *perf, struct mdss_mdp_pipe *pipe) { @@ -1034,7 +1089,12 @@ int mdss_mdp_perf_bw_check_pipe(struct mdss_mdp_perf_params *perf, /* convert bandwidth to kb */ pipe_bw = DIV_ROUND_UP_ULL(pipe_bw, 1000); - threshold = mdata->max_bw_per_pipe; + + if (!mdata->max_per_pipe_bw_settings) + threshold = mdata->max_bw_per_pipe; + else + threshold = mdss_mdp_get_max_pipe_bw(pipe); + pr_debug("bw=%llu threshold=%u\n", pipe_bw, threshold); if (threshold && pipe_bw > threshold) { From de705be0738e073eacd94d76b575cedea6967b0b Mon Sep 17 00:00:00 2001 From: Jayant Shekhar Date: Wed, 23 Sep 2015 12:06:50 +0530 Subject: [PATCH 086/320] msm: mdss: Generalize per pipe bw limit implementation Currently per pipe bandwidth limit implementation takes care of only HFLip and VFLip case. Make it generic such that it takes care of camera usecase as well. Change-Id: I6642bdb0611aa973a7563df019bf2dcdd5e4e584 Signed-off-by: Jayant Shekhar Signed-off-by: Raghavendra Ambadas --- drivers/video/msm/mdss/mdss_mdp_ctl.c | 56 ++++++++++----------------- 1 file changed, 21 insertions(+), 35 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c index fb75564388b6d..100f5b4c6d24c 100644 --- a/drivers/video/msm/mdss/mdss_mdp_ctl.c +++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c @@ -1013,29 +1013,20 @@ int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl, return 0; } -static u32 mdss_mdp_get_bw_by_mode(struct mdss_max_bw_settings *settings, - int count, int key) -{ - u32 value = 0, i = 0; - - while (i < count) { - if (settings[i].mdss_max_bw_mode == key) { - value = settings[i].mdss_max_bw_val; - break; - } - ++i; - } - return value; -} - static u32 mdss_mdp_get_max_pipe_bw(struct mdss_mdp_pipe *pipe) { - struct mdss_data_type *mdata = pipe->mixer_left->ctl->mdata; struct mdss_mdp_ctl *ctl = pipe->mixer_left->ctl; + struct mdss_max_bw_settings *max_per_pipe_bw_settings; u32 flags = 0, threshold = 0, panel_orientation; + u32 i, max = INT_MAX; + + if (!ctl->mdata->mdss_per_pipe_bw_cnt + && !ctl->mdata->max_per_pipe_bw_settings) + return 0; panel_orientation = ctl->mfd->panel_orientation; + max_per_pipe_bw_settings = ctl->mdata->max_per_pipe_bw_settings; /* Check for panel orienatation */ panel_orientation = ctl->mfd->panel_orientation; @@ -1050,22 +1041,17 @@ static u32 mdss_mdp_get_max_pipe_bw(struct mdss_mdp_pipe *pipe) if (pipe->flags & MDP_FLIP_UD) flags |= MDSS_MAX_BW_LIMIT_VFLIP; - if ((flags & MDSS_MAX_BW_LIMIT_HFLIP) && - (flags & MDSS_MAX_BW_LIMIT_VFLIP)) { - threshold = mdata->min_bw_per_pipe; - } else if (flags & MDSS_MAX_BW_LIMIT_HFLIP) { - threshold = mdss_mdp_get_bw_by_mode( - mdata->max_per_pipe_bw_settings, - mdata->mdss_per_pipe_bw_cnt, - MDSS_MAX_BW_LIMIT_HFLIP); - } else if (flags & MDSS_MAX_BW_LIMIT_VFLIP) { - threshold = mdss_mdp_get_bw_by_mode( - mdata->max_per_pipe_bw_settings, - mdata->mdss_per_pipe_bw_cnt, - MDSS_MAX_BW_LIMIT_VFLIP); + flags |= ctl->mdata->bw_mode_bitmap; + + for (i = 0; i < ctl->mdata->mdss_per_pipe_bw_cnt; i++) { + if (max_per_pipe_bw_settings[i].mdss_max_bw_mode & flags) { + threshold = max_per_pipe_bw_settings[i].mdss_max_bw_val; + if (threshold < max) + max = threshold; + } } - return threshold ? threshold : mdata->max_bw_per_pipe; + return max; } int mdss_mdp_perf_bw_check_pipe(struct mdss_mdp_perf_params *perf, @@ -1074,7 +1060,7 @@ int mdss_mdp_perf_bw_check_pipe(struct mdss_mdp_perf_params *perf, struct mdss_data_type *mdata = pipe->mixer_left->ctl->mdata; struct mdss_mdp_ctl *ctl = pipe->mixer_left->ctl; u32 vbp_fac, threshold; - u64 prefill_bw, pipe_bw; + u64 prefill_bw, pipe_bw, max_pipe_bw; /* we only need bandwidth check on real-time clients (interfaces) */ if (ctl->intf_type == MDSS_MDP_NO_INTF) @@ -1089,11 +1075,11 @@ int mdss_mdp_perf_bw_check_pipe(struct mdss_mdp_perf_params *perf, /* convert bandwidth to kb */ pipe_bw = DIV_ROUND_UP_ULL(pipe_bw, 1000); + threshold = mdata->max_bw_per_pipe; + max_pipe_bw = mdss_mdp_get_max_pipe_bw(pipe); - if (!mdata->max_per_pipe_bw_settings) - threshold = mdata->max_bw_per_pipe; - else - threshold = mdss_mdp_get_max_pipe_bw(pipe); + if (max_pipe_bw && (max_pipe_bw < threshold)) + threshold = max_pipe_bw; pr_debug("bw=%llu threshold=%u\n", pipe_bw, threshold); From 495a0d0416fb2619a7e27b7b84003aa9e6da08b6 Mon Sep 17 00:00:00 2001 From: Ashish Jain Date: Mon, 20 Jun 2016 18:09:07 +0530 Subject: [PATCH 087/320] ASoC: msm: qdsp6v2: DAP: Add check to validate data length Validate input data length to ensure only relevant data is copied. CRs-Fixed: 1027585 Change-Id: I67eb4f162f944bbf4d9e55fb8fe93759e6b8ff91 Signed-off-by: Ashish Jain --- sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c index aac11f3084980..3f741e3261c91 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c @@ -1522,6 +1522,14 @@ static int msm_ds2_dap_get_param(u32 cmd, void *arg) goto end; } + /* Return if invalid length */ + if (dolby_data->length > + (DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM - DOLBY_PARAM_PAYLOAD_SIZE)) { + pr_err("Invalid length %d", dolby_data->length); + rc = -EINVAL; + goto end; + } + for (i = 0; i < DS2_DEVICES_ALL; i++) { if ((dev_map[i].active) && (dev_map[i].device_id & dolby_data->device_id)) { From 4722f2f736e7624b3984a094baf62e07be454ced Mon Sep 17 00:00:00 2001 From: Josh Kirsch Date: Mon, 2 May 2016 14:55:04 -0700 Subject: [PATCH 088/320] drivers: soc: Add buffer overflow check for svc send request Add buffer overflow check in voice_svc_send_req. CRs-fixed: 1010081 Change-Id: I4ae703334b0cf04f327b392bc9cd6febd4ad32f2 Signed-off-by: Josh Kirsch --- drivers/soc/qcom/qdsp6v2/voice_svc.c | 46 +++++++++++++++++++--------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/drivers/soc/qcom/qdsp6v2/voice_svc.c b/drivers/soc/qcom/qdsp6v2/voice_svc.c index 23b8292c8db5b..67c58d1e6d4cd 100644 --- a/drivers/soc/qcom/qdsp6v2/voice_svc.c +++ b/drivers/soc/qcom/qdsp6v2/voice_svc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -188,7 +188,8 @@ static int voice_svc_send_req(struct voice_svc_cmd_request *apr_request, int ret = 0; void *apr_handle = NULL; struct apr_data *aprdata = NULL; - uint32_t user_payload_size = 0; + uint32_t user_payload_size; + uint32_t payload_size; pr_debug("%s\n", __func__); @@ -200,15 +201,19 @@ static int voice_svc_send_req(struct voice_svc_cmd_request *apr_request, } user_payload_size = apr_request->payload_size; + payload_size = sizeof(struct apr_data) + user_payload_size; - aprdata = kmalloc(sizeof(struct apr_data) + user_payload_size, - GFP_KERNEL); - - if (aprdata == NULL) { - pr_err("%s: aprdata kmalloc failed.\n", __func__); - - ret = -ENOMEM; + if (payload_size <= user_payload_size) { + pr_err("%s: invalid payload size ( 0x%x ).\n", + __func__, user_payload_size); + ret = -EINVAL; goto done; + } else { + aprdata = kmalloc(payload_size, GFP_KERNEL); + if (aprdata == NULL) { + ret = -ENOMEM; + goto done; + } } voice_svc_update_hdr(apr_request, aprdata); @@ -388,18 +393,31 @@ static ssize_t voice_svc_write(struct file *file, const char __user *buf, switch (cmd) { case MSG_REGISTER: - ret = process_reg_cmd( + if (count >= + (sizeof(struct voice_svc_register) + + sizeof(*data))) { + ret = process_reg_cmd( (struct voice_svc_register *)data->payload, prtd); - if (!ret) - ret = count; - + if (!ret) + ret = count; + } else { + pr_err("%s: invalid payload size\n", __func__); + ret = -EINVAL; + goto done; + } break; case MSG_REQUEST: + if (count >= (sizeof(struct voice_svc_cmd_request) + + sizeof(*data))) { ret = voice_svc_send_req( (struct voice_svc_cmd_request *)data->payload, prtd); if (!ret) ret = count; - + } else { + pr_err("%s: invalid payload size\n", __func__); + ret = -EINVAL; + goto done; + } break; default: pr_debug("%s: Invalid command: %u\n", __func__, cmd); From 9ca67fd9740985f22a2d6272e9790eb9579df524 Mon Sep 17 00:00:00 2001 From: Trishansh Bhardwaj Date: Wed, 29 Jun 2016 14:34:31 +0530 Subject: [PATCH 089/320] msm: camera: Fix memory read security flaw Adds bound check on reg_cfg_cmd->u.dmi_info.hi_tbl_offset. IOCTL VIDIOC_MSM_VFE_REG_CFG uses usersupplied value without performing bounds check for following cmd_type. VFE_READ_DMI_16BIT VFE_READ_DMI_32BIT VFE_READ_DMI_64BIT Change-Id: I554c45ef3a172f5b5891b67a7e8e7a1f3f3882ed Signed-off-by: Trishansh Bhardwaj --- drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c index dafc76e3205cd..baf95a5f50d37 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c @@ -953,7 +953,8 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev, case VFE_READ_DMI_16BIT: case VFE_READ_DMI_32BIT: case VFE_READ_DMI_64BIT: { - if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT) { + if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT || + reg_cfg_cmd->cmd_type == VFE_READ_DMI_64BIT) { if ((reg_cfg_cmd->u.dmi_info.hi_tbl_offset <= reg_cfg_cmd->u.dmi_info.lo_tbl_offset) || (reg_cfg_cmd->u.dmi_info.hi_tbl_offset - From a421980d7abb8ae2abb2f7384022d5f10cbdd749 Mon Sep 17 00:00:00 2001 From: Dibyendu Roy Date: Mon, 4 Jul 2016 15:21:42 +0530 Subject: [PATCH 090/320] Bluetooth: Replace %p with %pK The %pK restrictions are used to eliminate exposing kernel addresses. When kptr_restrict is set to "0" there are no restrictions. When kptr_restrict is set to "1", kernel pointers printed using the %pK format specifier will be replaced with 0's unless the user has CAP_SYSLOG. When kptr_restrict is set to "2", kernel pointers printed using %pK will be replaced with 0's regardless of privileges. Change-Id: Ie56b7f253a55d4402c434502932a7c5fe56b2c00 Signed-off-by: Dibyendu Roy --- drivers/bluetooth/hci_ibs.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/bluetooth/hci_ibs.c b/drivers/bluetooth/hci_ibs.c index 0d732184f274c..b97287058fbec 100644 --- a/drivers/bluetooth/hci_ibs.c +++ b/drivers/bluetooth/hci_ibs.c @@ -231,7 +231,7 @@ static int send_hci_ibs_cmd(u8 cmd, struct hci_uart *hu) struct ibs_struct *ibs = hu->priv; struct hci_ibs_cmd *hci_ibs_packet; - BT_DBG("hu %p cmd 0x%x", hu, cmd); + BT_DBG("hu %pK cmd 0x%x", hu, cmd); /* allocate packet */ skb = bt_skb_alloc(1, GFP_ATOMIC); @@ -259,7 +259,7 @@ static void ibs_wq_awake_device(struct work_struct *work) struct hci_uart *hu = (struct hci_uart *)ibs->ibs_hu; unsigned long flags; - BT_DBG(" %p ", hu); + BT_DBG(" %pK ", hu); /* Vote for serial clock */ ibs_msm_serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_ON, hu); @@ -286,7 +286,7 @@ static void ibs_wq_awake_rx(struct work_struct *work) struct hci_uart *hu = (struct hci_uart *)ibs->ibs_hu; unsigned long flags; - BT_DBG(" %p ", hu); + BT_DBG(" %pK ", hu); ibs_msm_serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_ON, hu); @@ -314,7 +314,7 @@ static void ibs_wq_serial_rx_clock_vote_off(struct work_struct *work) ws_rx_vote_off); struct hci_uart *hu = (struct hci_uart *)ibs->ibs_hu; - BT_DBG(" %p ", hu); + BT_DBG(" %pK ", hu); ibs_msm_serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_OFF, hu); @@ -326,7 +326,7 @@ static void ibs_wq_serial_tx_clock_vote_off(struct work_struct *work) ws_tx_vote_off); struct hci_uart *hu = (struct hci_uart *)ibs->ibs_hu; - BT_DBG(" %p ", hu); + BT_DBG(" %pK ", hu); hci_uart_tx_wakeup(hu); /* run HCI tx handling unlocked */ @@ -342,7 +342,7 @@ static void hci_ibs_tx_idle_timeout(unsigned long arg) struct ibs_struct *ibs = hu->priv; unsigned long flags; - BT_DBG("hu %p idle timeout in %lu state", hu, ibs->tx_ibs_state); + BT_DBG("hu %pK idle timeout in %lu state", hu, ibs->tx_ibs_state); spin_lock_irqsave_nested(&ibs->hci_ibs_lock, flags, SINGLE_DEPTH_NESTING); @@ -376,8 +376,8 @@ static void hci_ibs_wake_retrans_timeout(unsigned long arg) unsigned long flags; unsigned long retransmit = 0; - BT_DBG("hu %p wake retransmit timeout in %lu state", - hu, ibs->tx_ibs_state); + BT_DBG("hu %pK wake retransmit timeout in %lu state", + hu, ibs->tx_ibs_state); spin_lock_irqsave_nested(&ibs->hci_ibs_lock, flags, SINGLE_DEPTH_NESTING); @@ -409,7 +409,7 @@ static int ibs_open(struct hci_uart *hu) { struct ibs_struct *ibs; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); ibs = kzalloc(sizeof(*ibs), GFP_ATOMIC); if (!ibs) @@ -505,7 +505,7 @@ static int ibs_flush(struct hci_uart *hu) { struct ibs_struct *ibs = hu->priv; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); skb_queue_purge(&ibs->tx_wait_q); skb_queue_purge(&ibs->txq); @@ -518,7 +518,7 @@ static int ibs_close(struct hci_uart *hu) { struct ibs_struct *ibs = hu->priv; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); ibs_msm_serial_clock_vote(HCI_IBS_VOTE_STATS_UPDATE, hu); ibs_log_local_stats(ibs); @@ -547,7 +547,7 @@ static void ibs_device_want_to_wakeup(struct hci_uart *hu) unsigned long flags; struct ibs_struct *ibs = hu->priv; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); /* lock hci_ibs state */ spin_lock_irqsave(&ibs->hci_ibs_lock, flags); @@ -596,7 +596,7 @@ static void ibs_device_want_to_sleep(struct hci_uart *hu) unsigned long flags; struct ibs_struct *ibs = hu->priv; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); /* lock hci_ibs state */ spin_lock_irqsave(&ibs->hci_ibs_lock, flags); @@ -632,7 +632,7 @@ static void ibs_device_woke_up(struct hci_uart *hu) struct ibs_struct *ibs = hu->priv; struct sk_buff *skb = NULL; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); /* lock hci_ibs state */ spin_lock_irqsave(&ibs->hci_ibs_lock, flags); @@ -677,7 +677,7 @@ static int ibs_enqueue(struct hci_uart *hu, struct sk_buff *skb) unsigned long flags = 0; struct ibs_struct *ibs = hu->priv; - BT_DBG("hu %p skb %p", hu, skb); + BT_DBG("hu %pK skb %pK", hu, skb); /* Prepend skb with frame type */ memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); @@ -756,8 +756,8 @@ static int ibs_recv(struct hci_uart *hu, void *data, int count) struct hci_sco_hdr *sh; register int len, type, dlen; - BT_DBG("hu %p count %d rx_state %ld rx_count %ld", - hu, count, ibs->rx_state, ibs->rx_count); + BT_DBG("hu %pK count %d rx_state %ld rx_count %ld", + hu, count, ibs->rx_state, ibs->rx_count); ptr = data; while (count) { From e6c5c200ee39edfbf1545bda8af729c9422322d3 Mon Sep 17 00:00:00 2001 From: VijayaKumar T M Date: Tue, 5 Jul 2016 10:58:35 +0530 Subject: [PATCH 091/320] ARM: dts: msm: adding top ahb clock to ispif for 8909 Adding missing camss top ahb clock to ispif node for 8909 Change-Id: I1aa840c9dc92922a1adc7aa87d29204f44ad1bf3 Signed-off-by: Shilpa Mamidi Signed-off-by: VijayaKumar T M --- arch/arm/boot/dts/qcom/msm8909-camera.dtsi | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/qcom/msm8909-camera.dtsi b/arch/arm/boot/dts/qcom/msm8909-camera.dtsi index 5e96cb1abaa6e..8c7a22c40e04f 100644 --- a/arch/arm/boot/dts/qcom/msm8909-camera.dtsi +++ b/arch/arm/boot/dts/qcom/msm8909-camera.dtsi @@ -98,6 +98,8 @@ interrupt-names = "ispif"; clocks = <&clock_gcc clk_gcc_camss_ispif_ahb_clk>, <&clock_gcc clk_gcc_camss_ahb_clk>, + <&clock_gcc clk_gcc_camss_top_ahb_clk>, + <&clock_gcc clk_camss_top_ahb_clk_src>, <&clock_gcc clk_csi0_clk_src>, <&clock_gcc clk_gcc_camss_csi0_clk>, <&clock_gcc clk_gcc_camss_csi0pix_clk>, @@ -110,12 +112,13 @@ <&clock_gcc clk_gcc_camss_vfe0_clk>, <&clock_gcc clk_gcc_camss_csi_vfe0_clk>; clock-names = "ispif_ahb_clk","camss_ahb_clk", + "camss_top_ahb_clk", "camss_ahb_src", "csi0_src_clk", "csi0_clk", "csi0_pix_clk","csi0_rdi_clk", "csi1_src_clk", "csi1_clk", "csi1_pix_clk", "csi1_rdi_clk", "vfe0_clk_src", "camss_vfe_vfe0_clk", "camss_csi_vfe0_clk"; - qcom,clock-rates = <40000000 0 0 0 0 0 0 0 0 0 0 0 0>; + qcom,clock-rates = <40000000 0 0 0 0 0 0 0 0 0 0 0 0 0 0>; }; qcom,vfe@1b10000 { From 238b58fd38b4e8143cd42dafd9c916a01c096c44 Mon Sep 17 00:00:00 2001 From: VijayaKumar T M Date: Tue, 5 Jul 2016 12:24:02 +0530 Subject: [PATCH 092/320] msm: ispif: Remove CSID version check for ahb clock As part of open AHB clocks are currently enabled based on CSID version check. But CSID version is updated as part of INIT IOCTL call. Due to this AHB clocks are not enabled and this is causing unclocked register access. Now every target have AHB clocks for ISPIF which needs to be enabled always. Change-Id: I576ac20650ac081175942b7d94b6f2b9711b14c8 Signed-off-by: Shilpa Mamidi Signed-off-by: VijayaKumar T M --- drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c index 1fd8da1e50ead..04acb08eba5dd 100644 --- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c +++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c @@ -258,11 +258,6 @@ static int msm_ispif_clk_ahb_enable(struct ispif_device *ispif, int enable) { int rc = 0; - if (ispif->csid_version < CSID_VERSION_V30) { - /* Older ISPIF versiond don't need ahb clokc */ - return 0; - } - rc = msm_ispif_get_ahb_clk_info(ispif, ispif->pdev, ispif_8974_ahb_clk_info); if (rc < 0) { From 365757b9133f37792bb58143e2e41c53c0ada35d Mon Sep 17 00:00:00 2001 From: Suyog Sarda Date: Tue, 7 Jun 2016 21:15:42 +0530 Subject: [PATCH 093/320] lowmemorykiller: Introduce sysfs node for ALMK and PPR adj threshold The grouping of tasks based on oom_score_adj values change from one framework to another. This requires corresponding changes in the threshold values set for almk and per process reclaim. Introduce sysfs nodes to set threshold adj for process reclaim and adaptive LMK dynamically. Change-Id: Ib7565bfd5d2e93aa4ff8fdd20414cac0a0f38bf7 Signed-off-by: Suyog Sarda Signed-off-by: Vinayak Menon --- drivers/staging/android/lowmemorykiller.c | 2 ++ mm/process_reclaim.c | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index c5d6fa7e353c3..3ce8d95f25bd1 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -83,6 +83,8 @@ static unsigned long lowmem_deathpending_timeout; static atomic_t shift_adj = ATOMIC_INIT(0); static short adj_max_shift = 353; +module_param_named(adj_max_shift, adj_max_shift, short, + S_IRUGO | S_IWUSR); /* User knob to enable/disable adaptive lmk feature */ static int enable_adaptive_lmk; diff --git a/mm/process_reclaim.c b/mm/process_reclaim.c index 5afd106998dc3..0b6aea811d61c 100644 --- a/mm/process_reclaim.c +++ b/mm/process_reclaim.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -48,6 +48,10 @@ static unsigned long pressure_max = 90; module_param_named(pressure_min, pressure_min, ulong, S_IRUGO | S_IWUSR); module_param_named(pressure_max, pressure_max, ulong, S_IRUGO | S_IWUSR); +static short min_score_adj = 360; +module_param_named(min_score_adj, min_score_adj, short, + S_IRUGO | S_IWUSR); + /* * Scheduling process reclaim workqueue unecessarily * when the reclaim efficiency is low does not make @@ -114,7 +118,6 @@ static void swap_fn(struct work_struct *work) int i; int tasksize; int total_sz = 0; - short min_score_adj = 360; int total_scan = 0; int total_reclaimed = 0; int nr_to_reclaim; From f0e2c13e4f77d465d1223bf4323e0cc576f4f270 Mon Sep 17 00:00:00 2001 From: Arun Kumar Neelakantam Date: Fri, 1 Jul 2016 14:52:21 +0530 Subject: [PATCH 094/320] char: msm_smd_pkt: Fix the TIOCMSET IOCTL argument reading In the TIOCMSET IOCTL call the user passed argument is used incorrectly to update the SMD channel DTR/CTS signals which results in unexpected flow control on the SMD channel. Use the get_user() API to get the user passed value and use the same value to update SMD channel signals. CRs-Fixed: 1036867 Change-Id: Ia814892a626b7a291d07ba3670e144f6f09fd41a Signed-off-by: Arun Kumar Neelakantam --- drivers/char/msm_smd_pkt.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/char/msm_smd_pkt.c b/drivers/char/msm_smd_pkt.c index 8de52593d892b..7502d8cb769c0 100644 --- a/drivers/char/msm_smd_pkt.c +++ b/drivers/char/msm_smd_pkt.c @@ -359,6 +359,7 @@ static long smd_pkt_ioctl(struct file *file, unsigned int cmd, { int ret; struct smd_pkt_dev *smd_pkt_devp; + uint32_t val; smd_pkt_devp = file->private_data; if (!smd_pkt_devp) @@ -372,9 +373,15 @@ static long smd_pkt_ioctl(struct file *file, unsigned int cmd, ret = smd_tiocmget(smd_pkt_devp->ch); break; case TIOCMSET: - D_STATUS("%s TIOCSET command on smd_pkt_dev id:%d\n", - __func__, smd_pkt_devp->i); - ret = smd_tiocmset(smd_pkt_devp->ch, arg, ~arg); + ret = get_user(val, (uint32_t *)arg); + if (ret) { + pr_err("Error getting TIOCMSET value\n"); + mutex_unlock(&smd_pkt_devp->ch_lock); + return ret; + } + D_STATUS("%s TIOCSET command on smd_pkt_dev id:%d arg[0x%x]\n", + __func__, smd_pkt_devp->i, val); + ret = smd_tiocmset(smd_pkt_devp->ch, val, ~val); break; case SMD_PKT_IOCTL_BLOCKING_WRITE: ret = get_user(smd_pkt_devp->blocking_write, (int *)arg); From e2c9809ba1a8037fc89ada4ea3a4624ace101471 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Tue, 5 Jul 2016 12:43:44 +0800 Subject: [PATCH 095/320] ARM: dts: msm: add sound node for 8909 QSIP SKUQ Add audio codec node and relevant device properties. Add support for sound card on QSIP SKUQ device. CRs-Fixed: 1037568 Change-Id: Iaa9d4718a097044fa3ee0e0b00d38d24cbe8b155 Signed-off-by: Xiaojun Sang --- .../dts/qcom/msm8909-pm8916-qrd-skuq.dtsi | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi index 6d46889487c89..1c856f03e82ce 100644 --- a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi +++ b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi @@ -29,3 +29,58 @@ &pm8916_bms { status = "ok"; }; + +&soc { + sound { + compatible = "qcom,msm8x16-audio-codec"; + qcom,model = "msm8909-skuq-snd-card"; + qcom,msm-snd-card-id = <0>; + qcom,msm-codec-type = "internal"; + qcom,msm-ext-pa = "primary"; + qcom,msm-mclk-freq = <9600000>; + qcom,msm-mbhc-hphl-swh = <1>; + qcom,msm-mbhc-gnd-swh = <0>; + qcom,msm-hs-micbias-type = "internal"; + qcom,msm-micbias1-ext-cap; + qcom,audio-routing = + "RX_BIAS", "MCLK", + "SPK_RX_BIAS", "MCLK", + "INT_LDO_H", "MCLK", + "MIC BIAS External", "Handset Mic", + "MIC BIAS Internal2", "Headset Mic", + "MIC BIAS External", "Secondary Mic", + "AMIC1", "MIC BIAS External", + "AMIC2", "MIC BIAS Internal2", + "AMIC3", "MIC BIAS External"; + pinctrl-names = "cdc_lines_act", + "cdc_lines_sus"; + pinctrl-0 = <&cdc_pdm_lines_act>; + pinctrl-1 = <&cdc_pdm_lines_sus>; + asoc-platform = <&pcm0>, <&pcm1>, <&voip>, <&voice>, + <&loopback>, <&compress>, <&hostless>, + <&afe>, <&lsm>, <&routing>, <&lpa>, + <&voice_svc>; + asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1", + "msm-voip-dsp", "msm-pcm-voice", "msm-pcm-loopback", + "msm-compress-dsp", "msm-pcm-hostless", "msm-pcm-afe", + "msm-lsm-client", "msm-pcm-routing", "msm-pcm-lpa", + "msm-voice-svc"; + asoc-cpu = <&dai_pri_auxpcm>, <&dai_mi2s0>, <&dai_mi2s1>, <&dai_mi2s2>, + <&dai_mi2s3>, <&bt_sco_rx>, <&bt_sco_tx>, <&bt_a2dp_rx>, + <&int_fm_rx>, <&int_fm_tx>, <&afe_pcm_rx>, <&afe_pcm_tx>, + <&afe_proxy_rx>, <&afe_proxy_tx>, <&incall_record_rx>, + <&incall_record_tx>, <&incall_music_rx>, <&incall_music_2_rx>; + asoc-cpu-names = "msm-dai-q6-auxpcm.1", + "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", + "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3", + "msm-dai-q6-dev.12288", "msm-dai-q6-dev.12289", + "msm-dai-q6-dev.12290", + "msm-dai-q6-dev.12292", "msm-dai-q6-dev.12293", + "msm-dai-q6-dev.224", "msm-dai-q6-dev.225", + "msm-dai-q6-dev.241", "msm-dai-q6-dev.240", + "msm-dai-q6-dev.32771", "msm-dai-q6-dev.32772", + "msm-dai-q6-dev.32773", "msm-dai-q6-dev.32770"; + asoc-codec = <&stub_codec>, <&pm8916_tombak_dig>; + asoc-codec-names = "msm-stub-codec.1", "tombak_codec"; + }; +}; From 3ba39d4aa7f59ce3b5deab5931105a11a0976799 Mon Sep 17 00:00:00 2001 From: Ashish Jain Date: Thu, 30 Jun 2016 18:28:37 +0530 Subject: [PATCH 096/320] ASoC: msm: qdsp6v2: DAP: Allocate param buffer with correct size Size of param buffer should be big enough to hold param length of data and param payload. CRs-Fixed: 1033525 Change-Id: I6fa58f87a7c7df5f0485ea5b368ea090eb8bedb4 Signed-off-by: Ashish Jain --- sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c index 3f741e3261c91..28659a2184aac 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c @@ -1554,7 +1554,8 @@ static int msm_ds2_dap_get_param(u32 cmd, void *arg) pr_debug("%s: port_id 0x%x, copp_idx %d, dev_map[i].device_id %x\n", __func__, port_id, copp_idx, dev_map[i].device_id); - params_value = kzalloc(params_length, GFP_KERNEL); + params_value = kzalloc(params_length + param_payload_len, + GFP_KERNEL); if (!params_value) { pr_err("%s: params memory alloc failed\n", __func__); rc = -ENOMEM; @@ -1578,9 +1579,9 @@ static int msm_ds2_dap_get_param(u32 cmd, void *arg) rc = -EINVAL; goto end; } else { - params_length = (ds2_dap_params_length[i] + - DOLBY_PARAM_PAYLOAD_SIZE) * - sizeof(uint32_t); + params_length = + ds2_dap_params_length[i] * sizeof(uint32_t); + rc = adm_get_params(port_id, copp_idx, DOLBY_BUNDLE_MODULE_ID, ds2_dap_params_id[i], From c1ab6f3d04b3926c357e9a69a5b993571a4aa6f9 Mon Sep 17 00:00:00 2001 From: Ashish Jain Date: Fri, 1 Jul 2016 12:31:21 +0530 Subject: [PATCH 097/320] ASoC: msm: qdsp6v2: DAP: Add check to validate param length To avoid buffer overflow, validate input length used to fetch visualizer data. CRs-Fixed: 1033540 Change-Id: I445d1ba3bce47308bc31ae24a70d5ee358f22a2d Signed-off-by: Ashish Jain --- sound/soc/msm/qdsp6v2/msm-dolby-common.h | 3 ++- sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/sound/soc/msm/qdsp6v2/msm-dolby-common.h b/sound/soc/msm/qdsp6v2/msm-dolby-common.h index c34a95f78e40d..c510812e4b2bb 100644 --- a/sound/soc/msm/qdsp6v2/msm-dolby-common.h +++ b/sound/soc/msm/qdsp6v2/msm-dolby-common.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2014, 2016 The Linux Foundation. All rights reserved. * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. @@ -232,6 +232,7 @@ #define TOTAL_LENGTH_DOLBY_PARAM 745 #define DOLBY_VIS_PARAM_HEADER_SIZE 25 +#define DOLBY_PARAM_VCNB_MAX_LENGTH 40 #define DOLBY_INVALID_PORT_ID -1 diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c index 3f741e3261c91..8c84c0dcc6c70 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c @@ -1635,6 +1635,13 @@ static int msm_ds2_dap_param_visualizer_control_get(u32 cmd, void *arg) } length = ds2_dap_params[cache_dev].params_val[DOLBY_PARAM_VCNB_OFFSET]; + + if (length > DOLBY_PARAM_VCNB_MAX_LENGTH || length <= 0) { + ret = 0; + dolby_data->length = 0; + pr_err("%s Incorrect VCNB length", __func__); + } + params_length = (2*length + DOLBY_VIS_PARAM_HEADER_SIZE) * sizeof(uint32_t); From 78160f6593c7d3f01aa95e491414756507eb431b Mon Sep 17 00:00:00 2001 From: Sunil Khatri Date: Wed, 22 Jun 2016 14:45:31 +0530 Subject: [PATCH 098/320] ashmem: Validate ashmem memory with fops pointer Validate the ashmem memory entry against f_op pointer rather then comparing its name with path of the dentry. This is to avoid any invalid access to ashmem area in cases where some one deliberately set the dentry name to /ashmem. Change-Id: I74e50cd244f68cb13009cf2355e528485f4de34b Signed-off-by: Sunil Khatri --- drivers/staging/android/ashmem.c | 42 +++++++++++++++----------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 5661711b9f554..94a9cc8ff77ec 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -766,11 +766,28 @@ static long compat_ashmem_ioctl(struct file *file, unsigned int cmd, unsigned lo } #endif +static const struct file_operations ashmem_fops = { + .owner = THIS_MODULE, + .open = ashmem_open, + .release = ashmem_release, + .read = ashmem_read, + .llseek = ashmem_llseek, + .mmap = ashmem_mmap, + .unlocked_ioctl = ashmem_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = compat_ashmem_ioctl, +#endif +}; + +static struct miscdevice ashmem_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "ashmem", + .fops = &ashmem_fops, +}; + static int is_ashmem_file(struct file *file) { - char fname[256], *name; - name = dentry_path(file->f_dentry, fname, 256); - return strcmp(name, "/ashmem") ? 0 : 1; + return (file->f_op == &ashmem_fops); } int get_ashmem_file(int fd, struct file **filp, struct file **vm_file, @@ -819,25 +836,6 @@ void put_ashmem_file(struct file *file) } EXPORT_SYMBOL(put_ashmem_file); -static const struct file_operations ashmem_fops = { - .owner = THIS_MODULE, - .open = ashmem_open, - .release = ashmem_release, - .read = ashmem_read, - .llseek = ashmem_llseek, - .mmap = ashmem_mmap, - .unlocked_ioctl = ashmem_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = compat_ashmem_ioctl, -#endif -}; - -static struct miscdevice ashmem_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "ashmem", - .fops = &ashmem_fops, -}; - static int __init ashmem_init(void) { int ret; From 7554a1c06cc77c651661d503dc07695f7af72c00 Mon Sep 17 00:00:00 2001 From: Mao Flynn Date: Tue, 5 Jul 2016 17:22:43 +0800 Subject: [PATCH 099/320] ARM: dts: msm: add hx8394f panel for msm8909 SKUQ For msm8909 SKUQ, add a device tree file for DDIC hx8394f, and enable it in the board dtsi file. Change-Id: I481be5646e3d1d5153a7a21e164814d330496916 Signed-off-by: Mao Flynn Signed-off-by: c_yinbin --- .../qcom/dsi-panel-hx8394f-720p-video.dtsi | 122 ++++++++++++++++++ .../dts/qcom/msm8909-pm8916-qrd-skuq.dtsi | 40 ++++++ 2 files changed, 162 insertions(+) create mode 100644 arch/arm/boot/dts/qcom/dsi-panel-hx8394f-720p-video.dtsi diff --git a/arch/arm/boot/dts/qcom/dsi-panel-hx8394f-720p-video.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-hx8394f-720p-video.dtsi new file mode 100644 index 0000000000000..2c6688fd4c87b --- /dev/null +++ b/arch/arm/boot/dts/qcom/dsi-panel-hx8394f-720p-video.dtsi @@ -0,0 +1,122 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +&mdss_mdp { + dsi_hx8394f_720p_video: qcom,mdss_dsi_hx8394f_720p_video { + qcom,mdss-dsi-panel-name = "hx8394f 720p video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <720>; + qcom,mdss-dsi-panel-height = <1280>; + qcom,mdss-dsi-h-front-porch = <16>; + qcom,mdss-dsi-h-back-porch = <16>; + qcom,mdss-dsi-h-pulse-width = <8>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <12>; + qcom,mdss-dsi-v-front-porch = <15>; + qcom,mdss-dsi-v-pulse-width = <4>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [39 01 00 00 00 00 04 b9 ff 83 94 + 39 01 00 00 00 00 0b + b1 50 14 74 09 31 24 71 31 55 + 2f + 39 01 00 00 00 00 07 + ba 63 03 68 6b b2 c0 + 39 01 00 00 00 00 02 + d2 77 + 39 01 00 00 00 00 06 + b2 00 80 64 10 07 + 39 01 00 00 00 00 16 + b4 01 74 01 74 01 74 01 0c 86 + 75 00 3f 01 74 01 74 01 74 01 + 0c 86 + 39 01 00 00 00 00 22 + d3 00 00 07 07 40 1e 08 00 32 + 10 08 00 08 54 15 10 05 04 02 + 12 10 05 07 23 23 0c 0c 27 10 + 07 07 10 40 + 39 01 00 00 00 00 2d + d5 19 19 18 18 1b 1b 1a 1a 04 + 05 06 07 00 01 02 03 20 21 18 + 18 22 23 18 18 18 18 18 18 18 + 18 18 18 18 18 18 18 18 18 18 + 18 18 18 18 18 + 39 01 00 00 00 00 2d + d6 18 18 19 19 1b 1b 1a 1a 03 + 02 01 00 07 06 05 04 23 22 18 + 18 21 20 18 18 18 18 18 18 18 + 18 18 18 18 18 18 18 18 18 18 + 18 18 18 18 18 + 39 01 00 00 00 00 3b + e0 00 03 09 11 11 14 18 16 2e + 3d 4d 4d 58 6c 72 78 88 8b 86 + a4 b2 58 55 59 5b 5d 60 64 7f + 00 03 09 0f 11 14 18 16 2e 3d + 4d 4d 58 6d 73 78 88 8b 87 a5 + b2 58 55 58 5b 5d 61 65 7f + 39 01 00 00 00 00 02 + cc 0b + 39 01 00 00 00 00 03 + c0 1f 31 + 39 01 00 00 00 00 03 + b6 92 92 + 39 01 00 00 00 00 02 + bd 01 + 39 01 00 00 00 00 02 + b1 00 + 39 01 00 00 00 00 02 + bd 00 + 39 01 00 00 00 00 08 + bf 40 81 50 00 1a fc 01 + 39 01 00 00 00 00 02 + c6 ef + 05 01 00 00 78 00 02 + 11 00 + 05 01 00 00 14 00 02 + 29 00]; + qcom,mdss-dsi-off-command = [05 01 00 00 14 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <1>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-lane-map = "lane_map_0123"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-timings + = [6a 16 0e 00 38 3c 12 1a 10 03 04 00]; + qcom,mdss-dsi-t-clk-post = <0x04>; + qcom,mdss-dsi-t-clk-pre = <0x17>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <255>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm"; + qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>; + qcom,mdss-dsi-bl-pmic-bank-select = <0>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-reset-sequence = <1 20>, <0 2>, <1 20>; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi index 1c856f03e82ce..e2e0f2fc9db9e 100644 --- a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi +++ b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi @@ -84,3 +84,43 @@ asoc-codec-names = "msm-stub-codec.1", "tombak_codec"; }; }; +&pm8916_mpps { + mpp@a300 { /* MPP 4 */ + /* Backlight PWM */ + qcom,mode = <1>; /* Digital output */ + qcom,invert = <0>; /* Disable invert */ + qcom,src-sel = <4>; /* DTEST1 */ + qcom,vin-sel = <0>; /* VPH_PWR */ + qcom,master-en = <1>; /* Enable MPP */ + }; +}; + +#include "dsi-panel-hx8394f-720p-video.dtsi" + +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&dsi_hx8394f_720p_video { + qcom,cont-splash-enabled; + qcom,mdss-dsi-pwm-gpio = <&pm8916_mpps 4 0>; +}; + +&pmx_mdss { + qcom,num-grp-pins = <3>; + qcom,pins = <&gp 25>, <&gp 11>, <&gp 10>; +}; + +&pmx_mdss_te { + qcom,num-grp-pins = <1>; + qcom,pins = <&gp 24>; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_hx8394f_720p_video>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + + qcom,platform-reset-gpio = <&msm_gpio 25 0>; +}; From f25bbce90bf28ec9c303d18a19355af2519efc30 Mon Sep 17 00:00:00 2001 From: Divya Ponnusamy Date: Wed, 15 Jun 2016 16:22:11 +0530 Subject: [PATCH 100/320] staging: android: Change %p to %pK in debug messages The format specifier %p can leak kernel addresses while not valuing the kptr_restrict system settings. Use %pK instead of %p, which also evaluates whether kptr_restrict is set. Change-Id: Ib1adf14e9620ad7b1bd3e962001c852610210d46 Signed-off-by: Divya Ponnusamy --- drivers/staging/android/oneshot_sync.c | 4 ++-- drivers/staging/android/sync.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/android/oneshot_sync.c b/drivers/staging/android/oneshot_sync.c index bc1aad908aa09..6a56ee9d6b062 100644 --- a/drivers/staging/android/oneshot_sync.c +++ b/drivers/staging/android/oneshot_sync.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -286,7 +286,7 @@ int oneshot_fence_signal(struct oneshot_sync_timeline *timeline, } spin_unlock(&timeline->lock); if (ret == -EINVAL) - pr_debug("fence: %p not from this timeline\n", fence); + pr_debug("fence: %pK not from this timeline\n", fence); if (signaled) sync_timeline_signal(&timeline->obj); diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index bcb311b63193d..da8211d1bdfdd 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -696,14 +696,14 @@ int sync_fence_wait(struct sync_fence *fence, long timeout) return err; if (fence->status < 0) { - pr_info("fence error %d on [%p]\n", fence->status, fence); + pr_info("fence error %d on [%pK]\n", fence->status, fence); _sync_fence_log(fence, true); return fence->status; } if (fence->status == 0) { if (timeout > 0) { - pr_info("fence timeout on [%p] after %dms\n", fence, + pr_info("fence timeout on [%pK] after %dms\n", fence, jiffies_to_msecs(timeout)); _sync_fence_log(fence, true); } @@ -989,7 +989,7 @@ static void sync_print_fence(struct seq_file *s, struct sync_fence *fence) struct list_head *pos; unsigned long flags; - seq_printf(s, "[%p] %s: %s\n", fence, fence->name, + seq_printf(s, "[%pK] %s: %s\n", fence, fence->name, sync_status_str(fence->status)); list_for_each(pos, &fence->pt_list_head) { From e5e07d660b880419047e12cad4ebca8b946fbc8f Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Tue, 22 Dec 2015 12:24:37 -0800 Subject: [PATCH 101/320] diag: Change to update the range correctly on a range mismatch Setting message masks with tools outside of the initial range causes a reallocation of the structure with the wrong size. This change updates the sizes to the correct values. CRs-Fixed: 965686 Change-Id: I8bb0d0b77cd4d2417b10345b6e4b09ff29ba5f8c Signed-off-by: Christopher Lew Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_masks.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c index 7c0f103b2fbe9..860b93e836e4f 100644 --- a/drivers/char/diag/diag_masks.c +++ b/drivers/char/diag/diag_masks.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -546,7 +546,8 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, mask = (struct diag_msg_mask_t *)msg_mask.ptr; for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { if ((req->ssid_first < mask->ssid_first) || - (req->ssid_first > mask->ssid_last_tools)) { + (req->ssid_first > (mask->ssid_first + + MAX_SSID_PER_RANGE))) { continue; } found = 1; @@ -564,8 +565,10 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, pr_debug("diag: Msg SSID range mismatch\n"); if (mask_size != MAX_SSID_PER_RANGE) mask->ssid_last_tools = req->ssid_last; + mask->range_tools = + mask->ssid_last_tools - mask->ssid_first + 1; temp = krealloc(mask->ptr, - mask_size * sizeof(uint32_t), + mask->range_tools * sizeof(uint32_t), GFP_KERNEL); if (!temp) { pr_err_ratelimited("diag: In %s, unable to allocate memory for msg mask ptr, mask_size: %d\n", @@ -573,7 +576,6 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, return -ENOMEM; } mask->ptr = temp; - mask->range_tools = mask_size; } offset = req->ssid_first - mask->ssid_first; From 1848cf2595699bf88062a6ba1d68a7aee123175f Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Mon, 13 Jun 2016 18:27:47 +0530 Subject: [PATCH 102/320] diag: Fix possible mask pointer corruption This patch updates the stale pointer corrupted at specific ssid ranges. CRs-Fixed: 980487 Change-Id: I2b8afcef25dceb76118b803c67f4c5656feae82b Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_masks.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c index 860b93e836e4f..87493380af219 100644 --- a/drivers/char/diag/diag_masks.c +++ b/drivers/char/diag/diag_masks.c @@ -532,6 +532,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, struct diag_msg_mask_t *mask = NULL; struct diag_msg_build_mask_t *req = NULL; struct diag_msg_build_mask_t rsp; + struct diag_msg_mask_t *mask_next = NULL; uint32_t *temp = NULL; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { @@ -545,11 +546,18 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, mutex_lock(&msg_mask.lock); mask = (struct diag_msg_mask_t *)msg_mask.ptr; for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { + if (i < (driver->msg_mask_tbl_count - 1)) { + mask_next = mask; + mask_next++; + } else + mask_next = NULL; + if ((req->ssid_first < mask->ssid_first) || - (req->ssid_first > (mask->ssid_first + - MAX_SSID_PER_RANGE))) { + (req->ssid_first > mask->ssid_first + MAX_SSID_PER_RANGE) || + (mask_next && (req->ssid_first >= mask_next->ssid_first))) { continue; } + mask_next = NULL; found = 1; mask_size = req->ssid_last - req->ssid_first + 1; if (mask_size > MAX_SSID_PER_RANGE) { From b33705ece23506a08dc3fbfedc1e29a67b3ee43f Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Mon, 9 Mar 2015 23:11:12 +0200 Subject: [PATCH 103/320] BACKPORT: pagemap: do not leak physical addresses to non-privileged userspace (cherry pick from commit ab676b7d6fbf4b294bf198fb27ade5b0e865c7ce) As pointed by recent post[1] on exploiting DRAM physical imperfection, /proc/PID/pagemap exposes sensitive information which can be used to do attacks. This disallows anybody without CAP_SYS_ADMIN to read the pagemap. [1] http://googleprojectzero.blogspot.com/2015/03/exploiting-dram-rowhammer-bug-to-gain.html [ Eventually we might want to do anything more finegrained, but for now this is the simple model. - Linus ] Signed-off-by: Kirill A. Shutemov Acked-by: Konstantin Khlebnikov Acked-by: Andy Lutomirski Cc: Pavel Emelyanov Cc: Andrew Morton Cc: Mark Seaborn Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds Signed-off-by: Mark Salyzyn Bug: 25739721 Git-commit: 19dc2c8b1ccfe130a8d2fc4093acacdf2ed1395f Git-repo: https://android.googlesource.com/kernel/common Change-Id: I5582c993dbeb0b7287e6d41b57e494d123d33083 Signed-off-by: Nirmal Abraham --- fs/proc/task_mmu.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index c70bb56e9ebd8..d78cf827b8ddf 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -1166,9 +1166,18 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, return ret; } +static int pagemap_open(struct inode *inode, struct file *file) +{ + /* do not disclose physical addresses: attack vector */ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + return 0; +} + const struct file_operations proc_pagemap_operations = { .llseek = mem_lseek, /* borrow this */ .read = pagemap_read, + .open = pagemap_open, }; #endif /* CONFIG_PROC_PAGE_MONITOR */ From 4d818fa8119014ddfb58b6a543ff7f7adc88d115 Mon Sep 17 00:00:00 2001 From: Ashish Jain Date: Mon, 20 Jun 2016 18:09:07 +0530 Subject: [PATCH 104/320] ASoC: msm: qdsp6v2: DAP: Add check to validate data length Validate input data length to ensure only relevant data is copied. CRs-Fixed: 1027585 Change-Id: I67eb4f162f944bbf4d9e55fb8fe93759e6b8ff91 Signed-off-by: Ashish Jain --- sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c index 51f8b8c9e4086..9467e8cefcc3e 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c @@ -1522,6 +1522,14 @@ static int msm_ds2_dap_get_param(u32 cmd, void *arg) goto end; } + /* Return if invalid length */ + if (dolby_data->length > + (DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM - DOLBY_PARAM_PAYLOAD_SIZE)) { + pr_err("Invalid length %d", dolby_data->length); + rc = -EINVAL; + goto end; + } + for (i = 0; i < DS2_DEVICES_ALL; i++) { if ((dev_map[i].active) && (dev_map[i].device_id & dolby_data->device_id)) { From 4fd79d7cc1107896234b5c0b4e94d01768bd641b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 16 Jun 2015 22:11:06 +0100 Subject: [PATCH 105/320] pipe: iovec: Fix memory corruption when retrying atomic copy as non-atomic pipe_iov_copy_{from,to}_user() may be tried twice with the same iovec, the first time atomically and the second time not. The second attempt needs to continue from the iovec position, pipe buffer offset and remaining length where the first attempt failed, but currently the pipe buffer offset and remaining length are reset. This will corrupt the piped data (possibly also leading to an information leak between processes) and may also corrupt kernel memory. This was fixed upstream by commits f0d1bec9d58d ("new helper: copy_page_from_iter()") and 637b58c2887e ("switch pipe_read() to copy_page_to_iter()"), but those aren't suitable for stable. This fix for older kernel versions was made by Seth Jennings for RHEL and I have extracted it from their update. CVE-2015-1805 Change-Id: I4a18eab0e46f35b1d72f178138d50e1b3eb867cd References: https://bugzilla.redhat.com/show_bug.cgi?id=1202855 Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman Git-repo: http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git Git-commit: 14f81062f365fa9e3839bb2a16862217b71a553c Signed-off-by: Srinivasa Rao Kuppala --- fs/pipe.c | 55 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/fs/pipe.c b/fs/pipe.c index 0e0752ef27159..3e7ab278bb0c0 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -117,25 +117,27 @@ void pipe_wait(struct pipe_inode_info *pipe) } static int -pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len, - int atomic) +pipe_iov_copy_from_user(void *addr, int *offset, struct iovec *iov, + size_t *remaining, int atomic) { unsigned long copy; - while (len > 0) { + while (*remaining > 0) { while (!iov->iov_len) iov++; - copy = min_t(unsigned long, len, iov->iov_len); + copy = min_t(unsigned long, *remaining, iov->iov_len); if (atomic) { - if (__copy_from_user_inatomic(to, iov->iov_base, copy)) + if (__copy_from_user_inatomic(addr + *offset, + iov->iov_base, copy)) return -EFAULT; } else { - if (copy_from_user(to, iov->iov_base, copy)) + if (copy_from_user(addr + *offset, + iov->iov_base, copy)) return -EFAULT; } - to += copy; - len -= copy; + *offset += copy; + *remaining -= copy; iov->iov_base += copy; iov->iov_len -= copy; } @@ -143,25 +145,27 @@ pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len, } static int -pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len, - int atomic) +pipe_iov_copy_to_user(struct iovec *iov, void *addr, int *offset, + size_t *remaining, int atomic) { unsigned long copy; - while (len > 0) { + while (*remaining > 0) { while (!iov->iov_len) iov++; - copy = min_t(unsigned long, len, iov->iov_len); + copy = min_t(unsigned long, *remaining, iov->iov_len); if (atomic) { - if (__copy_to_user_inatomic(iov->iov_base, from, copy)) + if (__copy_to_user_inatomic(iov->iov_base, + addr + *offset, copy)) return -EFAULT; } else { - if (copy_to_user(iov->iov_base, from, copy)) + if (copy_to_user(iov->iov_base, + addr + *offset, copy)) return -EFAULT; } - from += copy; - len -= copy; + *offset += copy; + *remaining -= copy; iov->iov_base += copy; iov->iov_len -= copy; } @@ -395,7 +399,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, struct pipe_buffer *buf = pipe->bufs + curbuf; const struct pipe_buf_operations *ops = buf->ops; void *addr; - size_t chars = buf->len; + size_t chars = buf->len, remaining; int error, atomic; if (chars > total_len) @@ -409,9 +413,11 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, } atomic = !iov_fault_in_pages_write(iov, chars); + remaining = chars; redo: addr = ops->map(pipe, buf, atomic); - error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars, atomic); + error = pipe_iov_copy_to_user(iov, addr, &buf->offset, + &remaining, atomic); ops->unmap(pipe, buf, addr); if (unlikely(error)) { /* @@ -426,7 +432,6 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, break; } ret += chars; - buf->offset += chars; buf->len -= chars; /* Was it a packet buffer? Clean up and exit */ @@ -531,6 +536,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, if (ops->can_merge && offset + chars <= PAGE_SIZE) { int error, atomic = 1; void *addr; + size_t remaining = chars; error = ops->confirm(pipe, buf); if (error) @@ -539,8 +545,8 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, iov_fault_in_pages_read(iov, chars); redo1: addr = ops->map(pipe, buf, atomic); - error = pipe_iov_copy_from_user(offset + addr, iov, - chars, atomic); + error = pipe_iov_copy_from_user(addr, &offset, iov, + &remaining, atomic); ops->unmap(pipe, buf, addr); ret = error; do_wakeup = 1; @@ -575,6 +581,8 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, struct page *page = pipe->tmp_page; char *src; int error, atomic = 1; + int offset = 0; + size_t remaining; if (!page) { page = alloc_page(GFP_HIGHUSER); @@ -595,14 +603,15 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, chars = total_len; iov_fault_in_pages_read(iov, chars); + remaining = chars; redo2: if (atomic) src = kmap_atomic(page); else src = kmap(page); - error = pipe_iov_copy_from_user(src, iov, chars, - atomic); + error = pipe_iov_copy_from_user(src, &offset, iov, + &remaining, atomic); if (atomic) kunmap_atomic(src); else From 7e3372dea87f8fe8cf91da61578d33f580d3c509 Mon Sep 17 00:00:00 2001 From: Dilip Kota Date: Tue, 9 Feb 2016 17:14:38 +0530 Subject: [PATCH 106/320] ARM: dts: msm: Register slimbus with modem subsystem on msm8939 On 8939 slimbus master is present on modem, so register slimbus driver with modem subsystem to receive subsystem restart notification. Change-Id: I2195dab59524a41dd8fabd4653ee0032ed193652 Signed-off-by: Dilip Kota --- arch/arm/boot/dts/qcom/msm8939-common.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/qcom/msm8939-common.dtsi b/arch/arm/boot/dts/qcom/msm8939-common.dtsi index 91bafb56e4ecb..d641aa37d1e19 100644 --- a/arch/arm/boot/dts/qcom/msm8939-common.dtsi +++ b/arch/arm/boot/dts/qcom/msm8939-common.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -578,6 +578,7 @@ interrupt-names = "slimbus_irq", "slimbus_bam_irq"; qcom,apps-ch-pipes = <0x600000>; qcom,ea-pc = <0x140>; + qcom,subsys-name = "modem"; status = "disabled"; }; From 58b7aa3d9a89668a70250337a0ff9c5d54b4444d Mon Sep 17 00:00:00 2001 From: Subash Abhinov Kasiviswanathan Date: Thu, 17 Mar 2016 10:57:38 -0600 Subject: [PATCH 107/320] net: core: neighbour: Change the print format for addresses Print format %p displays the kernel address while bypassing the kptr_restrict sysctl settings. Change the print format for addresses from %p to %pK. If kptr_restrict is enabled, addresses are printed as zeroes. To view the actual addresses, disable kptr_restrict by - echo 0 > /proc/sys/kernel/kptr_restrict CRs-Fixed: 987041 Change-Id: I2eb33c63168ab26818dfdb3e11315f2ce8f24fa5 Signed-off-by: Subash Abhinov Kasiviswanathan Signed-off-by: Arun Padma --- net/core/neighbour.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/core/neighbour.c b/net/core/neighbour.c index cdd77161e99f2..2bc6c11134027 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -700,7 +700,7 @@ void neigh_destroy(struct neighbour *neigh) NEIGH_CACHE_STAT_INC(neigh->tbl, destroys); if (!neigh->dead) { - pr_warn("Destroying alive neighbour %p\n", neigh); + pr_warn("Destroying alive neighbour %pK\n", neigh); dump_stack(); return; } @@ -1317,7 +1317,7 @@ int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb) out: return rc; discard: - neigh_dbg(1, "%s: dst=%p neigh=%p\n", __func__, dst, neigh); + neigh_dbg(1, "%s: dst=%pK neigh=%pK\n", __func__, dst, neigh); out_kfree_skb: rc = -EINVAL; kfree_skb(skb); From 03e6ed92944295ab3b8c0ae23e9fec1914404f77 Mon Sep 17 00:00:00 2001 From: Dibyendu Roy Date: Wed, 23 Mar 2016 14:00:19 +0530 Subject: [PATCH 108/320] Bluetooth : Replace %p with %pK The %pK restrictions are used to eliminate exposing kernel addresses. When kptr_restrict is set to "0" there are no restrictions. When kptr_restrict is set to "1", kernel pointers printed using the %pK format specifier will be replaced with 0's unless the user has CAP_SYSLOG. When kptr_restrict is set to "2", kernel pointers printed using %pK will be replaced with 0's regardless of privileges. Change-Id: Iacd8f7b7cdafed3a111507d3da899be9261ff09f Signed-off-by: Dibyendu Roy --- drivers/bluetooth/hci_h4.c | 8 +- drivers/bluetooth/hci_ldisc.c | 10 +- net/bluetooth/af_bluetooth.c | 16 +-- net/bluetooth/bnep/core.c | 2 +- net/bluetooth/bnep/netdev.c | 4 +- net/bluetooth/bnep/sock.c | 4 +- net/bluetooth/cmtp/capi.c | 31 +++--- net/bluetooth/cmtp/core.c | 10 +- net/bluetooth/cmtp/sock.c | 4 +- net/bluetooth/hci_conn.c | 46 ++++----- net/bluetooth/hci_core.c | 48 ++++----- net/bluetooth/hci_event.c | 10 +- net/bluetooth/hci_sock.c | 20 ++-- net/bluetooth/hci_sysfs.c | 8 +- net/bluetooth/hidp/core.c | 21 ++-- net/bluetooth/hidp/sock.c | 4 +- net/bluetooth/l2cap_core.c | 185 +++++++++++++++++----------------- net/bluetooth/l2cap_sock.c | 38 +++---- net/bluetooth/lib.c | 4 +- net/bluetooth/mgmt.c | 12 +-- net/bluetooth/rfcomm/core.c | 128 +++++++++++------------ net/bluetooth/rfcomm/sock.c | 47 ++++----- net/bluetooth/rfcomm/tty.c | 50 ++++----- net/bluetooth/sco.c | 64 ++++++------ net/bluetooth/smp.c | 20 ++-- 25 files changed, 399 insertions(+), 395 deletions(-) diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index 8ae9f1ea2bb5e..3bbaa9828c09e 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c @@ -67,7 +67,7 @@ static int h4_open(struct hci_uart *hu) { struct h4_struct *h4; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); h4 = kzalloc(sizeof(*h4), GFP_KERNEL); if (!h4) @@ -84,7 +84,7 @@ static int h4_flush(struct hci_uart *hu) { struct h4_struct *h4 = hu->priv; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); skb_queue_purge(&h4->txq); @@ -98,7 +98,7 @@ static int h4_close(struct hci_uart *hu) hu->priv = NULL; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); skb_queue_purge(&h4->txq); @@ -115,7 +115,7 @@ static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb) { struct h4_struct *h4 = hu->priv; - BT_DBG("hu %p skb %p", hu, skb); + BT_DBG("hu %pK skb %pK", hu, skb); /* Prepend skb with frame type */ memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 8b49b56dc4d5e..c5975ca87ec14 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -200,7 +200,7 @@ int hci_uart_init_ready(struct hci_uart *hu) /* Initialize device */ static int hci_uart_open(struct hci_dev *hdev) { - BT_DBG("%s %p", hdev->name, hdev); + BT_DBG("%s %pK", hdev->name, hdev); /* Nothing to do for UART driver */ @@ -215,7 +215,7 @@ static int hci_uart_flush(struct hci_dev *hdev) struct hci_uart *hu = hci_get_drvdata(hdev); struct tty_struct *tty = hu->tty; - BT_DBG("hdev %p tty %p", hdev, tty); + BT_DBG("hdev %pK tty %pK", hdev, tty); if (hu->tx_skb) { kfree_skb(hu->tx_skb); hu->tx_skb = NULL; @@ -234,7 +234,7 @@ static int hci_uart_flush(struct hci_dev *hdev) /* Close device */ static int hci_uart_close(struct hci_dev *hdev) { - BT_DBG("hdev %p", hdev); + BT_DBG("hdev %pK", hdev); if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) return 0; @@ -283,7 +283,7 @@ static int hci_uart_tty_open(struct tty_struct *tty) { struct hci_uart *hu; - BT_DBG("tty %p", tty); + BT_DBG("tty %pK", tty); /* Error if the tty has no write op instead of leaving an exploitable hole */ @@ -326,7 +326,7 @@ static void hci_uart_tty_close(struct tty_struct *tty) struct hci_uart *hu = (void *)tty->disc_data; struct hci_dev *hdev; - BT_DBG("tty %p", tty); + BT_DBG("tty %pK", tty); /* Detach from the tty */ tty->disc_data = NULL; diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index f7c36826f3f4d..3b6e2439f7ab5 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -185,7 +185,7 @@ EXPORT_SYMBOL(bt_sock_unlink); void bt_accept_enqueue(struct sock *parent, struct sock *sk) { - BT_DBG("parent %p, sk %p", parent, sk); + BT_DBG("parent %pK, sk %pK", parent, sk); sock_hold(sk); list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q); @@ -196,7 +196,7 @@ EXPORT_SYMBOL(bt_accept_enqueue); void bt_accept_unlink(struct sock *sk) { - BT_DBG("sk %p state %d", sk, sk->sk_state); + BT_DBG("sk %pK state %d", sk, sk->sk_state); list_del_init(&bt_sk(sk)->accept_q); bt_sk(sk)->parent->sk_ack_backlog--; @@ -210,7 +210,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock) struct list_head *p, *n; struct sock *sk; - BT_DBG("parent %p", parent); + BT_DBG("parent %pK", parent); list_for_each_safe(p, n, &bt_sk(parent)->accept_q) { sk = (struct sock *) list_entry(p, struct bt_sock, accept_q); @@ -250,7 +250,7 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, size_t copied; int err; - BT_DBG("sock %p sk %p len %zu", sock, sk, len); + BT_DBG("sock %pK sk %pK len %zu", sock, sk, len); if (flags & (MSG_OOB)) return -EOPNOTSUPP; @@ -319,7 +319,7 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, if (flags & MSG_OOB) return -EOPNOTSUPP; - BT_DBG("sk %p size %zu", sk, size); + BT_DBG("sk %pK size %zu", sk, size); lock_sock(sk); @@ -435,7 +435,7 @@ unsigned int bt_sock_poll(struct file *file, struct socket *sock, struct sock *sk = sock->sk; unsigned int mask = 0; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); poll_wait(file, sk_sleep(sk), wait); @@ -479,7 +479,7 @@ int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) long amount; int err; - BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg); + BT_DBG("sk %pK cmd %x arg %lx", sk, cmd, arg); switch (cmd) { case TIOCOUTQ: @@ -525,7 +525,7 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) DECLARE_WAITQUEUE(wait, current); int err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); add_wait_queue(sk_sleep(sk), &wait); set_current_state(TASK_INTERRUPTIBLE); diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index e430b1abcd2fa..13f3b1ff245d9 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -393,7 +393,7 @@ static int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb) int len = 0, il = 0; u8 type = 0; - BT_DBG("skb %p dev %p type %d", skb, skb->dev, skb->pkt_type); + BT_DBG("skb %pK dev %pK type %d", skb, skb->dev, skb->pkt_type); if (!skb->dev) { /* Control frame sent by us */ diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c index 4b488ec261054..601b7b21ab581 100644 --- a/net/bluetooth/bnep/netdev.c +++ b/net/bluetooth/bnep/netdev.c @@ -156,7 +156,7 @@ static int bnep_net_proto_filter(struct sk_buff *skb, struct bnep_session *s) return 0; } - BT_DBG("BNEP: filtered skb %p, proto 0x%.4x", skb, proto); + BT_DBG("BNEP: filtered skb %pK, proto 0x%.4x", skb, proto); return 1; } #endif @@ -167,7 +167,7 @@ static netdev_tx_t bnep_net_xmit(struct sk_buff *skb, struct bnep_session *s = netdev_priv(dev); struct sock *sk = s->sock->sk; - BT_DBG("skb %p, dev %p", skb, dev); + BT_DBG("skb %pK, dev %pK", skb, dev); #ifdef CONFIG_BT_BNEP_MC_FILTER if (bnep_net_mc_filter(skb, s)) { diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c index 5f051290dabab..9340bf18063ce 100644 --- a/net/bluetooth/bnep/sock.c +++ b/net/bluetooth/bnep/sock.c @@ -37,7 +37,7 @@ static int bnep_sock_release(struct socket *sock) { struct sock *sk = sock->sk; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (!sk) return 0; @@ -190,7 +190,7 @@ static int bnep_sock_create(struct net *net, struct socket *sock, int protocol, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index cd75e4d64b909..d09f976f35970 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c @@ -74,7 +74,7 @@ static struct cmtp_application *cmtp_application_add(struct cmtp_session *sessio { struct cmtp_application *app = kzalloc(sizeof(*app), GFP_KERNEL); - BT_DBG("session %p application %p appl %d", session, app, appl); + BT_DBG("session %pK application %pK appl %d", session, app, appl); if (!app) return NULL; @@ -89,7 +89,7 @@ static struct cmtp_application *cmtp_application_add(struct cmtp_session *sessio static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app) { - BT_DBG("session %p application %p", session, app); + BT_DBG("session %pK application %pK", session, app); if (app) { list_del(&app->list); @@ -137,7 +137,7 @@ static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb) { struct cmtp_scb *scb = (void *) skb->cb; - BT_DBG("session %p skb %p len %d", session, skb, skb->len); + BT_DBG("session %pK skb %pK len %d", session, skb, skb->len); scb->id = -1; scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3); @@ -154,7 +154,8 @@ static void cmtp_send_interopmsg(struct cmtp_session *session, struct sk_buff *skb; unsigned char *s; - BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum); + BT_DBG("session %pK subcmd 0x%02x appl %d msgnum %d", + session, subcmd, appl, msgnum); skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC); if (!skb) { @@ -190,7 +191,7 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s __u16 appl, msgnum, func, info; __u32 controller; - BT_DBG("session %p skb %p len %d", session, skb, skb->len); + BT_DBG("session %pK skb %pK len %d", session, skb, skb->len); switch (CAPIMSG_SUBCOMMAND(skb->data)) { case CAPI_CONF: @@ -329,7 +330,7 @@ void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb) __u16 appl; __u32 contr; - BT_DBG("session %p skb %p len %d", session, skb, skb->len); + BT_DBG("session %pK skb %pK len %d", session, skb, skb->len); if (skb->len < CAPI_MSG_BASELEN) return; @@ -373,7 +374,7 @@ void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb) static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) { - BT_DBG("ctrl %p data %p", ctrl, data); + BT_DBG("ctrl %pK data %pK", ctrl, data); return 0; } @@ -382,7 +383,7 @@ static void cmtp_reset_ctr(struct capi_ctr *ctrl) { struct cmtp_session *session = ctrl->driverdata; - BT_DBG("ctrl %p", ctrl); + BT_DBG("ctrl %pK", ctrl); capi_ctr_down(ctrl); @@ -399,8 +400,8 @@ static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_ unsigned char buf[8]; int err = 0, nconn, want = rp->level3cnt; - BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d", - ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen); + BT_DBG("ctrl %pK appl %d level3cnt %d datablkcnt %d datablklen %d", + ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen); application = cmtp_application_add(session, appl); if (!application) { @@ -464,7 +465,7 @@ static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl) struct cmtp_session *session = ctrl->driverdata; struct cmtp_application *application; - BT_DBG("ctrl %p appl %d", ctrl, appl); + BT_DBG("ctrl %pK appl %d", ctrl, appl); application = cmtp_application_get(session, CMTP_APPLID, appl); if (!application) { @@ -490,7 +491,7 @@ static u16 cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) __u16 appl; __u32 contr; - BT_DBG("ctrl %p skb %p", ctrl, skb); + BT_DBG("ctrl %pK skb %pK", ctrl, skb); appl = CAPIMSG_APPID(skb->data); contr = CAPIMSG_CONTROL(skb->data); @@ -555,7 +556,7 @@ int cmtp_attach_device(struct cmtp_session *session) unsigned char buf[4]; long ret; - BT_DBG("session %p", session); + BT_DBG("session %pK", session); capimsg_setu32(buf, 0, 0); @@ -597,7 +598,7 @@ int cmtp_attach_device(struct cmtp_session *session) session->num = session->ctrl.cnr; - BT_DBG("session %p num %d", session, session->num); + BT_DBG("session %pK num %d", session, session->num); capimsg_setu32(buf, 0, 1); @@ -618,7 +619,7 @@ int cmtp_attach_device(struct cmtp_session *session) void cmtp_detach_device(struct cmtp_session *session) { - BT_DBG("session %p", session); + BT_DBG("session %pK", session); detach_capi_ctr(&session->ctrl); } diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index e0a6ebf2baa6f..d74d9fe541189 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -108,7 +108,7 @@ static inline void cmtp_add_msgpart(struct cmtp_session *session, int id, const struct sk_buff *skb = session->reassembly[id], *nskb; int size; - BT_DBG("session %p buf %p count %d", session, buf, count); + BT_DBG("session %pK buf %pK count %d", session, buf, count); size = (skb) ? skb->len + count : count; @@ -133,7 +133,7 @@ static inline int cmtp_recv_frame(struct cmtp_session *session, struct sk_buff * __u8 hdr, hdrlen, id; __u16 len; - BT_DBG("session %p skb %p len %d", session, skb, skb->len); + BT_DBG("session %pK skb %pK len %d", session, skb, skb->len); while (skb->len > 0) { hdr = skb->data[0]; @@ -196,7 +196,7 @@ static int cmtp_send_frame(struct cmtp_session *session, unsigned char *data, in struct kvec iv = { data, len }; struct msghdr msg; - BT_DBG("session %p data %p len %d", session, data, len); + BT_DBG("session %pK data %pK len %d", session, data, len); if (!len) return 0; @@ -212,7 +212,7 @@ static void cmtp_process_transmit(struct cmtp_session *session) unsigned char *hdr; unsigned int size, tail; - BT_DBG("session %p", session); + BT_DBG("session %pK", session); nskb = alloc_skb(session->mtu, GFP_ATOMIC); if (!nskb) { @@ -282,7 +282,7 @@ static int cmtp_session(void *arg) struct sk_buff *skb; wait_queue_t wait; - BT_DBG("session %p", session); + BT_DBG("session %pK", session); set_user_nice(current, -15); diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c index d82787d417bdc..8d7d3c16c8b6f 100644 --- a/net/bluetooth/cmtp/sock.c +++ b/net/bluetooth/cmtp/sock.c @@ -50,7 +50,7 @@ static int cmtp_sock_release(struct socket *sock) { struct sock *sk = sock->sk; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (!sk) return 0; @@ -200,7 +200,7 @@ static int cmtp_sock_create(struct net *net, struct socket *sock, int protocol, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 44ed20c84745f..600a8acc61496 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -66,7 +66,7 @@ static void hci_acl_create_connection(struct hci_conn *conn) struct inquiry_entry *ie; struct hci_cp_create_conn cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); conn->state = BT_CONNECT; conn->out = true; @@ -110,7 +110,7 @@ static void hci_acl_create_connection_cancel(struct hci_conn *conn) { struct hci_cp_create_conn_cancel cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (conn->hdev->hci_ver < BLUETOOTH_VER_1_2) return; @@ -133,7 +133,7 @@ void hci_disconnect(struct hci_conn *conn, __u8 reason) { struct hci_cp_disconnect cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); conn->state = BT_DISCONN; @@ -146,7 +146,7 @@ static void hci_amp_disconn(struct hci_conn *conn, __u8 reason) { struct hci_cp_disconn_phy_link cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); conn->state = BT_DISCONN; @@ -161,7 +161,7 @@ static void hci_add_sco(struct hci_conn *conn, __u16 handle) struct hci_dev *hdev = conn->hdev; struct hci_cp_add_sco cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); conn->state = BT_CONNECT; conn->out = true; @@ -179,7 +179,7 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle) struct hci_dev *hdev = conn->hdev; struct hci_cp_setup_sync_conn cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); conn->state = BT_CONNECT; conn->out = true; @@ -223,7 +223,7 @@ void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], struct hci_dev *hdev = conn->hdev; struct hci_cp_le_start_enc cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); memset(&cp, 0, sizeof(cp)); @@ -243,7 +243,7 @@ void hci_sco_setup(struct hci_conn *conn, __u8 status) if (!sco) return; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (!status) { if (lmp_esco_capable(conn->hdev)) @@ -275,7 +275,7 @@ static void hci_conn_timeout(struct work_struct *work) struct hci_conn *conn = container_of(work, struct hci_conn, disc_work.work); - BT_DBG("hcon %p state %s", conn, state_to_string(conn->state)); + BT_DBG("hcon %pK state %s", conn, state_to_string(conn->state)); if (atomic_read(&conn->refcnt)) return; @@ -307,7 +307,7 @@ static void hci_conn_enter_sniff_mode(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; - BT_DBG("hcon %p mode %d", conn, conn->mode); + BT_DBG("hcon %pK mode %d", conn, conn->mode); if (test_bit(HCI_RAW, &hdev->flags)) return; @@ -345,7 +345,7 @@ static void hci_conn_idle(unsigned long arg) { struct hci_conn *conn = (void *) arg; - BT_DBG("hcon %p mode %d", conn, conn->mode); + BT_DBG("hcon %pK mode %d", conn, conn->mode); hci_conn_enter_sniff_mode(conn); } @@ -433,7 +433,7 @@ int hci_conn_del(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; - BT_DBG("%s hcon %p handle %d", hdev->name, conn, conn->handle); + BT_DBG("%s hcon %pK handle %d", hdev->name, conn, conn->handle); del_timer(&conn->idle_timer); @@ -650,7 +650,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, /* Check link security requirement */ int hci_conn_check_link_mode(struct hci_conn *conn) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (hci_conn_ssp_enabled(conn) && !(conn->link_mode & HCI_LM_ENCRYPT)) return 0; @@ -661,7 +661,7 @@ int hci_conn_check_link_mode(struct hci_conn *conn) /* Authenticate remote device */ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (conn->pending_sec_level > sec_level) sec_level = conn->pending_sec_level; @@ -698,7 +698,7 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) /* Encrypt the the link */ static void hci_conn_encrypt(struct hci_conn *conn) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) { struct hci_cp_set_conn_encrypt cp; @@ -712,7 +712,7 @@ static void hci_conn_encrypt(struct hci_conn *conn) /* Enable security */ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (conn->type == LE_LINK) return smp_conn_security(conn, sec_level); @@ -768,7 +768,7 @@ EXPORT_SYMBOL(hci_conn_security); /* Check secure link requirement */ int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (sec_level != BT_SECURITY_HIGH) return 1; /* Accept if non-secure is required */ @@ -783,7 +783,7 @@ EXPORT_SYMBOL(hci_conn_check_secure); /* Change link key */ int hci_conn_change_link_key(struct hci_conn *conn) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { struct hci_cp_change_conn_link_key cp; @@ -798,7 +798,7 @@ int hci_conn_change_link_key(struct hci_conn *conn) /* Switch role */ int hci_conn_switch_role(struct hci_conn *conn, __u8 role) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (!role && conn->link_mode & HCI_LM_MASTER) return 1; @@ -837,7 +837,7 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active) { struct hci_dev *hdev = conn->hdev; - BT_DBG("hcon %p mode %d", conn, conn->mode); + BT_DBG("hcon %pK mode %d", conn, conn->mode); if (test_bit(HCI_RAW, &hdev->flags)) return; @@ -1019,7 +1019,7 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn) struct hci_dev *hdev = conn->hdev; struct hci_chan *chan; - BT_DBG("%s hcon %p", hdev->name, conn); + BT_DBG("%s hcon %pK", hdev->name, conn); chan = kzalloc(sizeof(struct hci_chan), GFP_KERNEL); if (!chan) @@ -1039,7 +1039,7 @@ void hci_chan_del(struct hci_chan *chan) struct hci_conn *conn = chan->conn; struct hci_dev *hdev = conn->hdev; - BT_DBG("%s hcon %p chan %p", hdev->name, conn, chan); + BT_DBG("%s hcon %pK chan %pK", hdev->name, conn, chan); list_del_rcu(&chan->list); @@ -1055,7 +1055,7 @@ void hci_chan_list_flush(struct hci_conn *conn) { struct hci_chan *chan, *n; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); list_for_each_entry_safe(chan, n, &conn->chan_list, list) hci_chan_del(chan); diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index f91b3baf3e14a..3d8e183a5c3cf 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -771,7 +771,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *e; - BT_DBG("cache %p, %pMR", cache, bdaddr); + BT_DBG("cache %pK, %pMR", cache, bdaddr); list_for_each_entry(e, &cache->all, all) { if (!bacmp(&e->data.bdaddr, bdaddr)) @@ -787,7 +787,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *e; - BT_DBG("cache %p, %pMR", cache, bdaddr); + BT_DBG("cache %pK, %pMR", cache, bdaddr); list_for_each_entry(e, &cache->unknown, list) { if (!bacmp(&e->data.bdaddr, bdaddr)) @@ -804,7 +804,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *e; - BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); + BT_DBG("cache %pK bdaddr %pMR state %d", cache, bdaddr, state); list_for_each_entry(e, &cache->resolve, list) { if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) @@ -841,7 +841,7 @@ bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *ie; - BT_DBG("cache %p, %pMR", cache, &data->bdaddr); + BT_DBG("cache %pK, %pMR", cache, &data->bdaddr); hci_remove_remote_oob_data(hdev, &data->bdaddr); @@ -917,7 +917,7 @@ static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) copied++; } - BT_DBG("cache %p, copied %d", cache, copied); + BT_DBG("cache %pK, copied %d", cache, copied); return copied; } @@ -1114,7 +1114,7 @@ int hci_dev_open(__u16 dev) if (!hdev) return -ENODEV; - BT_DBG("%s %p", hdev->name, hdev); + BT_DBG("%s %pK", hdev->name, hdev); hci_req_lock(hdev); @@ -1203,7 +1203,7 @@ int hci_dev_open(__u16 dev) static int hci_dev_do_close(struct hci_dev *hdev) { - BT_DBG("%s %p", hdev->name, hdev); + BT_DBG("%s %pK", hdev->name, hdev); cancel_work_sync(&hdev->le_scan); @@ -1546,7 +1546,7 @@ static int hci_rfkill_set_block(void *data, bool blocked) { struct hci_dev *hdev = data; - BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); + BT_DBG("%pK name %s blocked %d", hdev, hdev->name, blocked); if (blocked) { set_bit(HCI_RFKILLED, &hdev->dev_flags); @@ -2215,7 +2215,7 @@ int hci_register_dev(struct hci_dev *hdev) snprintf(hdev->name, sizeof(hdev->name), "hci%d", id); hdev->id = id; - BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); + BT_DBG("%pK name %s bus %d", hdev, hdev->name, hdev->bus); write_lock(&hci_dev_list_lock); list_add(&hdev->list, &hci_dev_list); @@ -2284,7 +2284,7 @@ void hci_unregister_dev(struct hci_dev *hdev) { int i, id; - BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); + BT_DBG("%pK name %s bus %d", hdev, hdev->name, hdev->bus); set_bit(HCI_UNREGISTER, &hdev->dev_flags); @@ -2545,7 +2545,7 @@ EXPORT_SYMBOL(hci_recv_stream_fragment); int hci_register_cb(struct hci_cb *cb) { - BT_DBG("%p name %s", cb, cb->name); + BT_DBG("%pK name %s", cb, cb->name); write_lock(&hci_cb_list_lock); list_add(&cb->list, &hci_cb_list); @@ -2557,7 +2557,7 @@ EXPORT_SYMBOL(hci_register_cb); int hci_unregister_cb(struct hci_cb *cb) { - BT_DBG("%p name %s", cb, cb->name); + BT_DBG("%pK name %s", cb, cb->name); write_lock(&hci_cb_list_lock); list_del(&cb->list); @@ -2780,12 +2780,12 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, list = skb_shinfo(skb)->frag_list; if (!list) { /* Non fragmented */ - BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); + BT_DBG("%s nonfrag skb %pK len %d", hdev->name, skb, skb->len); skb_queue_tail(queue, skb); } else { /* Fragmented */ - BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); + BT_DBG("%s frag %pK len %d", hdev->name, skb, skb->len); skb_shinfo(skb)->frag_list = NULL; @@ -2803,7 +2803,7 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; hci_add_acl_hdr(skb, conn->handle, flags); - BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); + BT_DBG("%s frag %pK len %d", hdev->name, skb, skb->len); __skb_queue_tail(queue, skb); } while (list); @@ -2816,7 +2816,7 @@ void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) { struct hci_dev *hdev = chan->conn->hdev; - BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); + BT_DBG("%s chan %pK flags 0x%4.4x", hdev->name, chan, flags); skb->dev = (void *) hdev; @@ -2906,7 +2906,7 @@ static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, } else *quote = 0; - BT_DBG("conn %p quote %d", conn, *quote); + BT_DBG("conn %pK quote %d", conn, *quote); return conn; } @@ -3009,7 +3009,7 @@ static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, q = cnt / num; *quote = q ? q : 1; - BT_DBG("chan %p quote %d", chan, *quote); + BT_DBG("chan %pK quote %d", chan, *quote); return chan; } @@ -3051,7 +3051,7 @@ static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) skb->priority = HCI_PRIO_MAX - 1; - BT_DBG("chan %p skb %p promoted to %d", chan, skb, + BT_DBG("chan %pK skb %pK promoted to %d", chan, skb, skb->priority); } @@ -3093,7 +3093,7 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev) (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { u32 priority = (skb_peek(&chan->data_q))->priority; while (quote-- && (skb = skb_peek(&chan->data_q))) { - BT_DBG("chan %p skb %p len %d priority %u", chan, skb, + BT_DBG("chan %pK skb %pK len %d priority %u", chan, skb, skb->len, skb->priority); /* Stop if priority has changed */ @@ -3141,7 +3141,7 @@ static void hci_sched_acl_blk(struct hci_dev *hdev) while (quote > 0 && (skb = skb_peek(&chan->data_q))) { int blocks; - BT_DBG("chan %p skb %p len %d priority %u", chan, skb, + BT_DBG("chan %pK skb %pK len %d priority %u", chan, skb, skb->len, skb->priority); /* Stop if priority has changed */ @@ -3209,7 +3209,7 @@ static void hci_sched_sco(struct hci_dev *hdev) while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { while (quote-- && (skb = skb_dequeue(&conn->data_q))) { - BT_DBG("skb %p len %d", skb, skb->len); + BT_DBG("skb %pK len %d", skb, skb->len); hci_send_frame(skb); conn->sent++; @@ -3233,7 +3233,7 @@ static void hci_sched_esco(struct hci_dev *hdev) while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, "e))) { while (quote-- && (skb = skb_dequeue(&conn->data_q))) { - BT_DBG("skb %p len %d", skb, skb->len); + BT_DBG("skb %pK len %d", skb, skb->len); hci_send_frame(skb); conn->sent++; @@ -3267,7 +3267,7 @@ static void hci_sched_le(struct hci_dev *hdev) while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { u32 priority = (skb_peek(&chan->data_q))->priority; while (quote-- && (skb = skb_peek(&chan->data_q))) { - BT_DBG("chan %p skb %p len %d priority %u", chan, skb, + BT_DBG("chan %pK skb %pK len %d priority %u", chan, skb, skb->len, skb->priority); /* Stop if priority has changed */ diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 9918688c78995..39f900d199ff1 100755 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1106,7 +1106,7 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); - BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn); + BT_DBG("%s bdaddr %pMR hcon %pK", hdev->name, &cp->bdaddr, conn); if (status) { if (conn && conn->state == BT_CONNECT) { @@ -1535,7 +1535,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) return; } - BT_DBG("%s bdaddr %pMR conn %p", hdev->name, &conn->dst, conn); + BT_DBG("%s bdaddr %pMR conn %pK", hdev->name, &conn->dst, conn); conn->state = BT_CLOSED; mgmt_connect_failed(hdev, &conn->dst, conn->type, @@ -2533,7 +2533,7 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) break; default: - BT_ERR("Unknown type %d conn %p", conn->type, conn); + BT_ERR("Unknown type %d conn %pK", conn->type, conn); break; } } @@ -2604,7 +2604,7 @@ static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) break; default: - BT_ERR("Unknown type %d conn %p", conn->type, conn); + BT_ERR("Unknown type %d conn %pK", conn->type, conn); break; } } @@ -3488,7 +3488,7 @@ static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hchan->handle = le16_to_cpu(ev->handle); - BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan); + BT_DBG("hcon %pK mgr %pK hchan %pK", hcon, hcon->amp_mgr, hchan); mgr = hcon->amp_mgr; if (mgr && mgr->bredr_chan) { diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index fa4bf66314255..4f5acc0247025 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -72,7 +72,7 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) struct sock *sk; struct sk_buff *skb_copy = NULL; - BT_DBG("hdev %p len %d", hdev, skb->len); + BT_DBG("hdev %pK len %d", hdev, skb->len); read_lock(&hci_sk_list.lock); @@ -180,7 +180,7 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb) if (!atomic_read(&monitor_promisc)) return; - BT_DBG("hdev %p len %d", hdev, skb->len); + BT_DBG("hdev %pK len %d", hdev, skb->len); switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: @@ -413,7 +413,7 @@ static int hci_sock_release(struct socket *sock) struct sock *sk = sock->sk; struct hci_dev *hdev; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (!sk) return 0; @@ -590,7 +590,7 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, struct hci_dev *hdev = NULL; int len, err = 0; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (!addr) return -EINVAL; @@ -679,7 +679,7 @@ static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, struct sock *sk = sock->sk; struct hci_dev *hdev = hci_pi(sk)->hdev; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (!hdev) return -EBADFD; @@ -740,7 +740,7 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct sk_buff *skb; int copied, err; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (flags & (MSG_OOB)) return -EOPNOTSUPP; @@ -784,7 +784,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct sk_buff *skb; int err; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (msg->msg_flags & MSG_OOB) return -EOPNOTSUPP; @@ -888,7 +888,7 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname, struct sock *sk = sock->sk; int err = 0, opt = 0; - BT_DBG("sk %p, opt %d", sk, optname); + BT_DBG("sk %pK, opt %d", sk, optname); lock_sock(sk); @@ -971,7 +971,7 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname, struct sock *sk = sock->sk; int len, opt, err = 0; - BT_DBG("sk %p, opt %d", sk, optname); + BT_DBG("sk %pK, opt %d", sk, optname); if (get_user(len, optlen)) return -EFAULT; @@ -1061,7 +1061,7 @@ static int hci_sock_create(struct net *net, struct socket *sock, int protocol, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 7ad6ecf36f20a..1c207bf0afec4 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -103,7 +103,7 @@ void hci_conn_init_sysfs(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); conn->dev.type = &bt_link; conn->dev.class = bt_class; @@ -116,7 +116,7 @@ void hci_conn_add_sysfs(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); @@ -547,7 +547,7 @@ int hci_add_sysfs(struct hci_dev *hdev) struct device *dev = &hdev->dev; int err; - BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); + BT_DBG("%pK name %s bus %d", hdev, hdev->name, hdev->bus); dev_set_name(dev, "%s", hdev->name); @@ -577,7 +577,7 @@ int hci_add_sysfs(struct hci_dev *hdev) void hci_del_sysfs(struct hci_dev *hdev) { - BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); + BT_DBG("%pK name %s bus %d", hdev, hdev->name, hdev->bus); debugfs_remove_recursive(hdev->debugfs); diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index b5cfba13bd379..5afd337cfa075 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -106,7 +106,7 @@ static int hidp_send_message(struct hidp_session *session, struct socket *sock, struct sk_buff *skb; struct sock *sk = sock->sk; - BT_DBG("session %p data %p size %d", session, data, size); + BT_DBG("session %pK data %pK size %d", session, data, size); if (atomic_read(&session->terminate)) return -EIO; @@ -150,7 +150,7 @@ static int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned char newleds; unsigned char hdr, data[2]; - BT_DBG("session %p type %d code %d value %d", + BT_DBG("session %pK type %d code %d value %d", session, type, code, value); if (type != EV_LED) @@ -414,7 +414,7 @@ static void hidp_del_timer(struct hidp_session *session) static void hidp_process_handshake(struct hidp_session *session, unsigned char param) { - BT_DBG("session %p param 0x%02x", session, param); + BT_DBG("session %pK param 0x%02x", session, param); session->output_report_success = 0; /* default condition */ switch (param) { @@ -457,7 +457,7 @@ static void hidp_process_handshake(struct hidp_session *session, static void hidp_process_hid_control(struct hidp_session *session, unsigned char param) { - BT_DBG("session %p param 0x%02x", session, param); + BT_DBG("session %pK param 0x%02x", session, param); if (param == HIDP_CTRL_VIRTUAL_CABLE_UNPLUG) { /* Flush the transmit queues */ @@ -473,7 +473,8 @@ static int hidp_process_data(struct hidp_session *session, struct sk_buff *skb, unsigned char param) { int done_with_skb = 1; - BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param); + BT_DBG("session %pK skb %pK len %d param 0x%02x", + session, skb, skb->len, param); switch (param) { case HIDP_DATA_RTYPE_INPUT: @@ -517,7 +518,7 @@ static void hidp_recv_ctrl_frame(struct hidp_session *session, unsigned char hdr, type, param; int free_skb = 1; - BT_DBG("session %p skb %p len %d", session, skb, skb->len); + BT_DBG("session %pK skb %pK len %d", session, skb, skb->len); hdr = skb->data[0]; skb_pull(skb, 1); @@ -553,7 +554,7 @@ static void hidp_recv_intr_frame(struct hidp_session *session, { unsigned char hdr; - BT_DBG("session %p skb %p len %d", session, skb, skb->len); + BT_DBG("session %pK skb %pK len %d", session, skb, skb->len); hdr = skb->data[0]; skb_pull(skb, 1); @@ -580,7 +581,7 @@ static int hidp_send_frame(struct socket *sock, unsigned char *data, int len) struct kvec iv = { data, len }; struct msghdr msg; - BT_DBG("sock %p data %p len %d", sock, data, len); + BT_DBG("sock %pK data %pK len %d", sock, data, len); if (!len) return 0; @@ -598,7 +599,7 @@ static void hidp_process_transmit(struct hidp_session *session, struct sk_buff *skb; int ret; - BT_DBG("session %p", session); + BT_DBG("session %pK", session); while ((skb = skb_dequeue(transmit))) { ret = hidp_send_frame(sock, skb->data, skb->len); @@ -1192,7 +1193,7 @@ static int hidp_session_thread(void *arg) struct hidp_session *session = arg; wait_queue_t ctrl_wait, intr_wait; - BT_DBG("session %p", session); + BT_DBG("session %pK", session); /* initialize runtime environment */ hidp_session_get(session); diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c index cb3fdde1968a0..5b7abfad038b3 100644 --- a/net/bluetooth/hidp/sock.c +++ b/net/bluetooth/hidp/sock.c @@ -33,7 +33,7 @@ static int hidp_sock_release(struct socket *sock) { struct sock *sk = sock->sk; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (!sk) return 0; @@ -230,7 +230,7 @@ static int hidp_sock_create(struct net *net, struct socket *sock, int protocol, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 79a680a122691..03c52804c3dcf 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -212,7 +212,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn) static void __l2cap_state_change(struct l2cap_chan *chan, int state) { - BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state), + BT_DBG("chan %pK %s -> %s", chan, state_to_string(chan->state), state_to_string(state)); chan->state = state; @@ -400,7 +400,7 @@ static void l2cap_chan_timeout(struct work_struct *work) struct l2cap_conn *conn = chan->conn; int reason; - BT_DBG("chan %p state %s", chan, state_to_string(chan->state)); + BT_DBG("chan %pK state %s", chan, state_to_string(chan->state)); mutex_lock(&conn->chan_lock); l2cap_chan_lock(chan); @@ -446,7 +446,7 @@ struct l2cap_chan *l2cap_chan_create(void) /* This flag is cleared in l2cap_chan_ready() */ set_bit(CONF_NOT_COMPLETE, &chan->conf_state); - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); return chan; } @@ -455,7 +455,7 @@ static void l2cap_chan_destroy(struct kref *kref) { struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref); - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); write_lock(&chan_list_lock); list_del(&chan->global_l); @@ -466,14 +466,14 @@ static void l2cap_chan_destroy(struct kref *kref) void l2cap_chan_hold(struct l2cap_chan *c) { - BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount)); + BT_DBG("chan %pK orig refcnt %d", c, atomic_read(&c->kref.refcount)); kref_get(&c->kref); } void l2cap_chan_put(struct l2cap_chan *c) { - BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount)); + BT_DBG("chan %pK orig refcnt %d", c, atomic_read(&c->kref.refcount)); kref_put(&c->kref, l2cap_chan_destroy); } @@ -492,7 +492,7 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan) void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) { - BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, + BT_DBG("conn %pK, psm 0x%2.2x, dcid 0x%4.4x", conn, __le16_to_cpu(chan->psm), chan->dcid); conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM; @@ -559,7 +559,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) __clear_chan_timer(chan); - BT_DBG("chan %p, conn %p, err %d", chan, conn, err); + BT_DBG("chan %pK, conn %pK, err %d", chan, conn, err); if (conn) { struct amp_mgr *mgr = conn->hcon->amp_mgr; @@ -580,7 +580,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) if (chan->hs_hchan) { struct hci_chan *hs_hchan = chan->hs_hchan; - BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan); + BT_DBG("chan %pK disconnect hs_hchan %pK", chan, hs_hchan); amp_disconnect_logical_link(hs_hchan); } @@ -618,7 +618,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) struct l2cap_conn *conn = chan->conn; struct sock *sk = chan->sk; - BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state), + BT_DBG("chan %pK state %s sk %pK", chan, state_to_string(chan->state), sk); switch (chan->state) { @@ -770,7 +770,7 @@ static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) struct hci_conn *hcon = chan->conn->hcon; u16 flags; - BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len, + BT_DBG("chan %pK, skb %pK len %d priority %u", chan, skb, skb->len, skb->priority); if (chan->hs_hcon && !__chan_is_moving(chan)) { @@ -952,7 +952,7 @@ static void l2cap_send_sframe(struct l2cap_chan *chan, struct sk_buff *skb; u32 control_field; - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); if (!control->sframe) return; @@ -991,7 +991,7 @@ static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll) { struct l2cap_ctrl control; - BT_DBG("chan %p, poll %d", chan, poll); + BT_DBG("chan %pK, poll %d", chan, poll); memset(&control, 0, sizeof(control)); control.sframe = 1; @@ -1062,7 +1062,7 @@ static void l2cap_move_setup(struct l2cap_chan *chan) { struct sk_buff *skb; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); if (chan->mode != L2CAP_MODE_ERTM) return; @@ -1096,7 +1096,7 @@ static void l2cap_move_setup(struct l2cap_chan *chan) static void l2cap_move_done(struct l2cap_chan *chan) { u8 move_role = chan->move_role; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); chan->move_state = L2CAP_MOVE_STABLE; chan->move_role = L2CAP_MOVE_ROLE_NONE; @@ -1129,7 +1129,7 @@ static void l2cap_chan_ready(struct l2cap_chan *chan) static void l2cap_start_connection(struct l2cap_chan *chan) { if (__amp_capable(chan)) { - BT_DBG("chan %p AMP capable: discover AMPs", chan); + BT_DBG("chan %pK AMP capable: discover AMPs", chan); a2mp_discover_amp(chan); } else { l2cap_send_conn_req(chan); @@ -1219,7 +1219,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) { struct l2cap_chan *chan, *tmp; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); mutex_lock(&conn->chan_lock); @@ -1381,7 +1381,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) struct l2cap_chan *chan; struct hci_conn *hcon = conn->hcon; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); if (!hcon->out && hcon->type == LE_LINK) l2cap_le_conn_ready(conn); @@ -1426,7 +1426,7 @@ static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err) { struct l2cap_chan *chan; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); mutex_lock(&conn->chan_lock); @@ -1540,7 +1540,7 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) if (!conn) return; - BT_DBG("hcon %p conn %p, err %d", hcon, conn, err); + BT_DBG("hcon %pK conn %pK, err %d", hcon, conn, err); kfree_skb(conn->rx_skb); @@ -1583,7 +1583,7 @@ static void security_timeout(struct work_struct *work) struct l2cap_conn *conn = container_of(work, struct l2cap_conn, security_timer.work); - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) { smp_chan_destroy(conn); @@ -1615,7 +1615,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon) hci_conn_get(conn->hcon); conn->hchan = hchan; - BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan); + BT_DBG("hcon %pK conn %pK hchan %pK", hcon, conn, hchan); switch (hcon->type) { case LE_LINK: @@ -1891,7 +1891,7 @@ static void l2cap_monitor_timeout(struct work_struct *work) struct l2cap_chan *chan = container_of(work, struct l2cap_chan, monitor_timer.work); - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); l2cap_chan_lock(chan); @@ -1912,7 +1912,7 @@ static void l2cap_retrans_timeout(struct work_struct *work) struct l2cap_chan *chan = container_of(work, struct l2cap_chan, retrans_timer.work); - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); l2cap_chan_lock(chan); @@ -1933,7 +1933,7 @@ static void l2cap_streaming_send(struct l2cap_chan *chan, struct sk_buff *skb; struct l2cap_ctrl *control; - BT_DBG("chan %p, skbs %p", chan, skbs); + BT_DBG("chan %pK, skbs %pK", chan, skbs); if (__chan_is_moving(chan)) return; @@ -1972,7 +1972,7 @@ static int l2cap_ertm_send(struct l2cap_chan *chan) struct l2cap_ctrl *control; int sent = 0; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); if (chan->state != BT_CONNECTED) return -ENOTCONN; @@ -2043,7 +2043,7 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan) struct sk_buff *tx_skb; u16 seq; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) return; @@ -2118,7 +2118,7 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan) static void l2cap_retransmit(struct l2cap_chan *chan, struct l2cap_ctrl *control) { - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); l2cap_seq_list_append(&chan->retrans_list, control->reqseq); l2cap_ertm_resend(chan); @@ -2129,7 +2129,7 @@ static void l2cap_retransmit_all(struct l2cap_chan *chan, { struct sk_buff *skb; - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); if (control->poll) set_bit(CONN_SEND_FBIT, &chan->conn_state); @@ -2165,7 +2165,7 @@ static void l2cap_send_ack(struct l2cap_chan *chan) chan->last_acked_seq); int threshold; - BT_DBG("chan %p last_acked_seq %d buffer_seq %d", + BT_DBG("chan %pK last_acked_seq %d buffer_seq %d", chan, chan->last_acked_seq, chan->buffer_seq); memset(&control, 0, sizeof(control)); @@ -2262,7 +2262,7 @@ static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE; struct l2cap_hdr *lh; - BT_DBG("chan %p len %zu priority %u", chan, len, priority); + BT_DBG("chan %pK len %zu priority %u", chan, len, priority); count = min_t(unsigned int, (conn->mtu - hlen), len); @@ -2296,7 +2296,7 @@ static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, int err, count; struct l2cap_hdr *lh; - BT_DBG("chan %p len %zu", chan, len); + BT_DBG("chan %pK len %zu", chan, len); count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len); @@ -2329,7 +2329,7 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, int err, count, hlen; struct l2cap_hdr *lh; - BT_DBG("chan %p len %zu", chan, len); + BT_DBG("chan %pK len %zu", chan, len); if (!conn) return ERR_PTR(-ENOTCONN); @@ -2383,7 +2383,7 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, size_t pdu_len; u8 sar; - BT_DBG("chan %p, msg %p, len %zu", chan, msg, len); + BT_DBG("chan %pK, msg %pK, len %zu", chan, msg, len); /* It is critical that ERTM PDUs fit in a single HCI fragment, * so fragmented skbs are not used. The HCI layer's handling @@ -2529,7 +2529,7 @@ static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq) struct l2cap_ctrl control; u16 seq; - BT_DBG("chan %p, txseq %u", chan, txseq); + BT_DBG("chan %pK, txseq %u", chan, txseq); memset(&control, 0, sizeof(control)); control.sframe = 1; @@ -2551,7 +2551,7 @@ static void l2cap_send_srej_tail(struct l2cap_chan *chan) { struct l2cap_ctrl control; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR) return; @@ -2569,7 +2569,7 @@ static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq) u16 initial_head; u16 seq; - BT_DBG("chan %p, txseq %u", chan, txseq); + BT_DBG("chan %pK, txseq %u", chan, txseq); memset(&control, 0, sizeof(control)); control.sframe = 1; @@ -2594,7 +2594,7 @@ static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq) struct sk_buff *acked_skb; u16 ackseq; - BT_DBG("chan %p, reqseq %u", chan, reqseq); + BT_DBG("chan %pK, reqseq %u", chan, reqseq); if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq) return; @@ -2623,7 +2623,7 @@ static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq) static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan) { - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); chan->expected_tx_seq = chan->buffer_seq; l2cap_seq_list_clear(&chan->srej_list); @@ -2635,7 +2635,7 @@ static void l2cap_tx_state_xmit(struct l2cap_chan *chan, struct l2cap_ctrl *control, struct sk_buff_head *skbs, u8 event) { - BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs, + BT_DBG("chan %pK, control %pK, skbs %pK, event %d", chan, control, skbs, event); switch (event) { @@ -2707,7 +2707,7 @@ static void l2cap_tx_state_wait_f(struct l2cap_chan *chan, struct l2cap_ctrl *control, struct sk_buff_head *skbs, u8 event) { - BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs, + BT_DBG("chan %pK, control %pK, skbs %pK, event %d", chan, control, skbs, event); switch (event) { @@ -2784,7 +2784,7 @@ static void l2cap_tx_state_wait_f(struct l2cap_chan *chan, static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, struct sk_buff_head *skbs, u8 event) { - BT_DBG("chan %p, control %p, skbs %p, event %d, state %d", + BT_DBG("chan %pK, control %pK, skbs %pK, event %d, state %d", chan, control, skbs, event, chan->tx_state); switch (chan->tx_state) { @@ -2803,14 +2803,14 @@ static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, static void l2cap_pass_to_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control) { - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT); } static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan, struct l2cap_ctrl *control) { - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT); } @@ -2820,7 +2820,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) struct sk_buff *nskb; struct l2cap_chan *chan; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); mutex_lock(&conn->chan_lock); @@ -2852,7 +2852,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code, struct l2cap_hdr *lh; int len, count; - BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u", + BT_DBG("conn %pK, code 0x%2.2x, ident 0x%2.2x, len %u", conn, code, ident, dlen); if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE) @@ -3011,7 +3011,7 @@ static void l2cap_ack_timeout(struct work_struct *work) ack_timer.work); u16 frames_to_ack; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); l2cap_chan_lock(chan); @@ -3153,7 +3153,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) void *ptr = req->data; u16 size; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); if (chan->num_conf_req || chan->num_conf_rsp) goto done; @@ -3279,7 +3279,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) u16 result = L2CAP_CONF_SUCCESS; u16 size; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); while (len >= L2CAP_CONF_OPT_SIZE) { len -= l2cap_get_conf_opt(&req, &type, &olen, &val); @@ -3488,7 +3488,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; struct l2cap_conf_efs efs; - BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data); + BT_DBG("chan %pK, rsp %pK, len %d, req %pK", chan, rsp, len, data); while (len >= L2CAP_CONF_OPT_SIZE) { len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); @@ -3593,7 +3593,7 @@ static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, struct l2cap_conf_rsp *rsp = data; void *ptr = rsp->data; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); rsp->scid = cpu_to_le16(chan->dcid); rsp->result = cpu_to_le16(result); @@ -3619,7 +3619,7 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan) else rsp_code = L2CAP_CONN_RSP; - BT_DBG("chan %p rsp_code %u", chan, rsp_code); + BT_DBG("chan %pK rsp_code %u", chan, rsp_code); l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp); @@ -3647,7 +3647,7 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW), }; - BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len); + BT_DBG("chan %pK, rsp %pK, len %d", chan, rsp, len); if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING)) return; @@ -3948,7 +3948,7 @@ static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data, { struct l2cap_conn *conn = chan->conn; - BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident, + BT_DBG("conn %pK chan %pK ident %d flags 0x%4.4x", conn, chan, ident, flags); clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state); @@ -4442,7 +4442,8 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn, return -EFAULT; } - BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon); + BT_DBG("mgr %pK bredr_chan %pK hs_hcon %pK", + mgr, chan, hs_hcon); mgr->bredr_chan = chan; chan->hs_hcon = hs_hcon; @@ -4471,7 +4472,7 @@ static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id) struct l2cap_move_chan_req req; u8 ident; - BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id); + BT_DBG("chan %pK, dest_amp_id %d", chan, dest_amp_id); ident = l2cap_get_ident(chan->conn); chan->ident = ident; @@ -4489,7 +4490,7 @@ static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result) { struct l2cap_move_chan_rsp rsp; - BT_DBG("chan %p, result 0x%4.4x", chan, result); + BT_DBG("chan %pK, result 0x%4.4x", chan, result); rsp.icid = cpu_to_le16(chan->dcid); rsp.result = cpu_to_le16(result); @@ -4502,7 +4503,7 @@ static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result) { struct l2cap_move_chan_cfm cfm; - BT_DBG("chan %p, result 0x%4.4x", chan, result); + BT_DBG("chan %pK, result 0x%4.4x", chan, result); chan->ident = l2cap_get_ident(chan->conn); @@ -4519,7 +4520,7 @@ static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid) { struct l2cap_move_chan_cfm cfm; - BT_DBG("conn %p, icid 0x%4.4x", conn, icid); + BT_DBG("conn %pK, icid 0x%4.4x", conn, icid); cfm.icid = cpu_to_le16(icid); cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED); @@ -4639,7 +4640,7 @@ static void l2cap_logical_finish_move(struct l2cap_chan *chan, void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, u8 status) { - BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status); + BT_DBG("chan %pK, hchan %pK, status %d", chan, hchan, status); if (status) { l2cap_logical_fail(chan); @@ -4658,7 +4659,7 @@ void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, void l2cap_move_start(struct l2cap_chan *chan) { - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); if (chan->local_amp_id == HCI_BREDR_ID) { if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED) @@ -4678,7 +4679,7 @@ void l2cap_move_start(struct l2cap_chan *chan) static void l2cap_do_create(struct l2cap_chan *chan, int result, u8 local_amp_id, u8 remote_amp_id) { - BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state), + BT_DBG("chan %pK state %s %u -> %u", chan, state_to_string(chan->state), local_amp_id, remote_amp_id); chan->fcs = L2CAP_FCS_NONE; @@ -4787,7 +4788,7 @@ void __l2cap_physical_cfm(struct l2cap_chan *chan, int result) u8 local_amp_id = chan->local_amp_id; u8 remote_amp_id = chan->remote_amp_id; - BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d", + BT_DBG("chan %pK, result %d, local_amp_id %d, remote_amp_id %d", chan, result, local_amp_id, remote_amp_id); if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) { @@ -5369,7 +5370,7 @@ static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) { struct l2cap_ctrl control; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); memset(&control, 0, sizeof(control)); control.sframe = 1; @@ -5524,7 +5525,7 @@ static int l2cap_rx_queued_iframes(struct l2cap_chan *chan) * until a gap is encountered. */ - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { struct sk_buff *skb; @@ -5556,7 +5557,7 @@ static void l2cap_handle_srej(struct l2cap_chan *chan, { struct sk_buff *skb; - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); if (control->reqseq == chan->next_tx_seq) { BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq); @@ -5614,7 +5615,7 @@ static void l2cap_handle_rej(struct l2cap_chan *chan, { struct sk_buff *skb; - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); if (control->reqseq == chan->next_tx_seq) { BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq); @@ -5648,7 +5649,7 @@ static void l2cap_handle_rej(struct l2cap_chan *chan, static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq) { - BT_DBG("chan %p, txseq %d", chan, txseq); + BT_DBG("chan %pK, txseq %d", chan, txseq); BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq, chan->expected_tx_seq); @@ -5739,7 +5740,7 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan, int err = 0; bool skb_in_use = 0; - BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb, + BT_DBG("chan %pK, control %pK, skb %pK, event %d", chan, control, skb, event); switch (event) { @@ -5795,7 +5796,7 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan, */ skb_queue_tail(&chan->srej_q, skb); skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, + BT_DBG("Queued %pK (queue len %d)", skb, skb_queue_len(&chan->srej_q)); clear_bit(CONN_SREJ_ACT, &chan->conn_state); @@ -5859,7 +5860,7 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan, } if (skb && !skb_in_use) { - BT_DBG("Freeing %p", skb); + BT_DBG("Freeing %pK", skb); kfree_skb(skb); } @@ -5874,7 +5875,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, u16 txseq = control->txseq; bool skb_in_use = 0; - BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb, + BT_DBG("chan %pK, control %pK, skb %pK, event %d", chan, control, skb, event); switch (event) { @@ -5885,7 +5886,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, l2cap_pass_to_tx(chan, control); skb_queue_tail(&chan->srej_q, skb); skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, + BT_DBG("Queued %pK (queue len %d)", skb, skb_queue_len(&chan->srej_q)); chan->expected_tx_seq = __next_seq(chan, txseq); @@ -5896,7 +5897,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, l2cap_pass_to_tx(chan, control); skb_queue_tail(&chan->srej_q, skb); skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, + BT_DBG("Queued %pK (queue len %d)", skb, skb_queue_len(&chan->srej_q)); err = l2cap_rx_queued_iframes(chan); @@ -5911,7 +5912,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, */ skb_queue_tail(&chan->srej_q, skb); skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, + BT_DBG("Queued %pK (queue len %d)", skb, skb_queue_len(&chan->srej_q)); l2cap_pass_to_tx(chan, control); @@ -5925,7 +5926,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, */ skb_queue_tail(&chan->srej_q, skb); skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, + BT_DBG("Queued %pK (queue len %d)", skb, skb_queue_len(&chan->srej_q)); l2cap_pass_to_tx(chan, control); @@ -6002,7 +6003,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, } if (skb && !skb_in_use) { - BT_DBG("Freeing %p", skb); + BT_DBG("Freeing %pK", skb); kfree_skb(skb); } @@ -6011,7 +6012,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, static int l2cap_finish_move(struct l2cap_chan *chan) { - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); chan->rx_state = L2CAP_RX_STATE_RECV; @@ -6029,7 +6030,7 @@ static int l2cap_rx_state_wait_p(struct l2cap_chan *chan, { int err; - BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb, + BT_DBG("chan %pK, control %pK, skb %pK, event %d", chan, control, skb, event); if (!control->poll) @@ -6113,7 +6114,7 @@ static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, { int err = 0; - BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan, + BT_DBG("chan %pK, control %pK, skb %pK, event %d, state %d", chan, control, skb, event, chan->rx_state); if (__valid_reqseq(chan, control->reqseq)) { @@ -6150,7 +6151,7 @@ static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, { int err = 0; - BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb, + BT_DBG("chan %pK, control %pK, skb %pK, state %d", chan, control, skb, chan->rx_state); if (l2cap_classify_txseq(chan, control->txseq) == @@ -6172,7 +6173,7 @@ static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, chan->sdu_len = 0; if (skb) { - BT_DBG("Freeing %p", skb); + BT_DBG("Freeing %pK", skb); kfree_skb(skb); } } @@ -6294,7 +6295,7 @@ static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid, } } - BT_DBG("chan %p, len %d", chan, skb->len); + BT_DBG("chan %pK, len %d", chan, skb->len); if (chan->state != BT_CONNECTED) goto drop; @@ -6319,7 +6320,7 @@ static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid, goto done; default: - BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode); + BT_DBG("chan %pK: bad mode 0x%2.2x", chan, chan->mode); break; } @@ -6339,7 +6340,7 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, if (!chan) goto drop; - BT_DBG("chan %p, len %d", chan, skb->len); + BT_DBG("chan %pK, len %d", chan, skb->len); if (chan->state != BT_BOUND && chan->state != BT_CONNECTED) goto drop; @@ -6364,7 +6365,7 @@ static void l2cap_att_channel(struct l2cap_conn *conn, if (!chan) goto drop; - BT_DBG("chan %p, len %d", chan, skb->len); + BT_DBG("chan %pK, len %d", chan, skb->len); if (chan->state != BT_BOUND && chan->state != BT_CONNECTED) goto drop; @@ -6460,7 +6461,7 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status) { struct l2cap_conn *conn; - BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status); + BT_DBG("hcon %pK bdaddr %pMR status %d", hcon, &hcon->dst, status); if (!status) { conn = l2cap_conn_add(hcon); @@ -6475,7 +6476,7 @@ int l2cap_disconn_ind(struct hci_conn *hcon) { struct l2cap_conn *conn = hcon->l2cap_data; - BT_DBG("hcon %p", hcon); + BT_DBG("hcon %pK", hcon); if (!conn) return HCI_ERROR_REMOTE_USER_TERM; @@ -6484,7 +6485,7 @@ int l2cap_disconn_ind(struct hci_conn *hcon) void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason) { - BT_DBG("hcon %p reason %d", hcon, reason); + BT_DBG("hcon %pK reason %d", hcon, reason); l2cap_conn_del(hcon, bt_to_errno(reason)); } @@ -6513,7 +6514,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) if (!conn) return 0; - BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt); + BT_DBG("conn %pK status 0x%2.2x encrypt %u", conn, status, encrypt); if (hcon->type == LE_LINK) { if (!status && encrypt) @@ -6526,7 +6527,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) list_for_each_entry(chan, &conn->chan_l, list) { l2cap_chan_lock(chan); - BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid, + BT_DBG("chan %pK scid 0x%4.4x state %s", chan, chan->scid, state_to_string(chan->state)); if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) { @@ -6637,7 +6638,7 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) if (!conn) goto drop; - BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags); + BT_DBG("conn %pK len %d flags 0x%x", conn, skb->len, flags); switch (flags) { case ACL_START: diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 302d29b3744d4..c676811c25797 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -56,7 +56,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) struct sockaddr_l2 la; int len, err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (!addr || addr->sa_family != AF_BLUETOOTH) return -EINVAL; @@ -121,7 +121,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, struct sockaddr_l2 la; int len, err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (!addr || alen < sizeof(addr->sa_family) || addr->sa_family != AF_BLUETOOTH) @@ -155,7 +155,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog) struct l2cap_chan *chan = l2cap_pi(sk)->chan; int err = 0; - BT_DBG("sk %p backlog %d", sk, backlog); + BT_DBG("sk %pK backlog %d", sk, backlog); lock_sock(sk); @@ -205,7 +205,7 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); - BT_DBG("sk %p timeo %ld", sk, timeo); + BT_DBG("sk %pK timeo %ld", sk, timeo); /* Wait for an incoming connection. (wake-one). */ add_wait_queue_exclusive(sk_sleep(sk), &wait); @@ -243,7 +243,7 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, newsock->state = SS_CONNECTED; - BT_DBG("new socket %p", nsk); + BT_DBG("new socket %pK", nsk); done: release_sock(sk); @@ -257,7 +257,7 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, struct sock *sk = sock->sk; struct l2cap_chan *chan = l2cap_pi(sk)->chan; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); memset(la, 0, sizeof(struct sockaddr_l2)); addr->sa_family = AF_BLUETOOTH; @@ -286,7 +286,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, int len, err = 0; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (get_user(len, optlen)) return -EFAULT; @@ -373,7 +373,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, struct bt_power pwr; int len, err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (level == SOL_L2CAP) return l2cap_sock_getsockopt_old(sock, optname, optval, optlen); @@ -488,7 +488,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, int len, err = 0; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); lock_sock(sk); @@ -590,7 +590,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, int len, err = 0; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (level == SOL_L2CAP) return l2cap_sock_setsockopt_old(sock, optname, optval, optlen); @@ -765,7 +765,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct l2cap_chan *chan = l2cap_pi(sk)->chan; int err; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); err = sock_error(sk); if (err) @@ -847,7 +847,7 @@ static void l2cap_sock_kill(struct sock *sk) if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) return; - BT_DBG("sk %p state %s", sk, state_to_string(sk->sk_state)); + BT_DBG("sk %pK state %s", sk, state_to_string(sk->sk_state)); /* Kill poor orphan */ @@ -863,7 +863,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) struct l2cap_conn *conn; int err = 0; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (!sk) return 0; @@ -909,7 +909,7 @@ static int l2cap_sock_release(struct socket *sock) struct sock *sk = sock->sk; int err; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (!sk) return 0; @@ -927,7 +927,7 @@ static void l2cap_sock_cleanup_listen(struct sock *parent) { struct sock *sk; - BT_DBG("parent %p", parent); + BT_DBG("parent %pK", parent); /* Close not yet accepted channels */ while ((sk = bt_accept_dequeue(parent, NULL))) { @@ -1085,7 +1085,7 @@ static void l2cap_sock_ready_cb(struct l2cap_chan *chan) parent = bt_sk(sk)->parent; - BT_DBG("sk %p, parent %p", sk, parent); + BT_DBG("sk %pK, parent %pK", sk, parent); sk->sk_state = BT_CONNECTED; sk->sk_state_change(sk); @@ -1119,7 +1119,7 @@ static struct l2cap_ops l2cap_chan_ops = { static void l2cap_sock_destruct(struct sock *sk) { - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (l2cap_pi(sk)->chan) l2cap_chan_put(l2cap_pi(sk)->chan); @@ -1137,7 +1137,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) struct l2cap_pinfo *pi = l2cap_pi(sk); struct l2cap_chan *chan = pi->chan; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (parent) { struct l2cap_chan *pchan = l2cap_pi(parent)->chan; @@ -1239,7 +1239,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); sock->state = SS_UNCONNECTED; diff --git a/net/bluetooth/lib.c b/net/bluetooth/lib.c index b3fbc73516c41..79c8f55d695ea 100644 --- a/net/bluetooth/lib.c +++ b/net/bluetooth/lib.c @@ -145,7 +145,7 @@ int bt_info(const char *format, ...) vaf.fmt = format; vaf.va = &args; - r = pr_info("%pV", &vaf); + r = pr_info("%pKV", &vaf); va_end(args); @@ -164,7 +164,7 @@ int bt_err(const char *format, ...) vaf.fmt = format; vaf.va = &args; - r = pr_err("%pV", &vaf); + r = pr_err("%pKV", &vaf); va_end(args); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 3e574540b2c2f..b21964051ef81 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -213,7 +213,7 @@ static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) struct mgmt_ev_cmd_status *ev; int err; - BT_DBG("sock %p, index %u, cmd %u, status %u", sk, index, cmd, status); + BT_DBG("sock %pK, index %u, cmd %u, status %u", sk, index, cmd, status); skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_KERNEL); if (!skb) @@ -244,7 +244,7 @@ static int cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, struct mgmt_ev_cmd_complete *ev; int err; - BT_DBG("sock %p", sk); + BT_DBG("sock %pK", sk); skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_KERNEL); if (!skb) @@ -275,7 +275,7 @@ static int read_version(struct sock *sk, struct hci_dev *hdev, void *data, { struct mgmt_rp_read_version rp; - BT_DBG("sock %p", sk); + BT_DBG("sock %pK", sk); rp.version = MGMT_VERSION; rp.revision = __constant_cpu_to_le16(MGMT_REVISION); @@ -294,7 +294,7 @@ static int read_commands(struct sock *sk, struct hci_dev *hdev, void *data, size_t rp_size; int i, err; - BT_DBG("sock %p", sk); + BT_DBG("sock %pK", sk); rp_size = sizeof(*rp) + ((num_commands + num_events) * sizeof(u16)); @@ -327,7 +327,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, u16 count; int err; - BT_DBG("sock %p", sk); + BT_DBG("sock %pK", sk); read_lock(&hci_dev_list_lock); @@ -698,7 +698,7 @@ static int read_controller_info(struct sock *sk, struct hci_dev *hdev, { struct mgmt_rp_read_info rp; - BT_DBG("sock %p %s", sk, hdev->name); + BT_DBG("sock %pK %s", sk, hdev->name); hci_dev_lock(hdev); diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 0c77476d33d20..03a9c68e6c833 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -182,13 +182,13 @@ static inline int __check_fcs(u8 *data, int type, u8 fcs) /* ---- L2CAP callbacks ---- */ static void rfcomm_l2state_change(struct sock *sk) { - BT_DBG("%p state %d", sk, sk->sk_state); + BT_DBG("%pK state %d", sk, sk->sk_state); rfcomm_schedule(); } static void rfcomm_l2data_ready(struct sock *sk, int bytes) { - BT_DBG("%p bytes %d", sk, bytes); + BT_DBG("%pK bytes %d", sk, bytes); rfcomm_schedule(); } @@ -233,7 +233,7 @@ static void rfcomm_session_timeout(unsigned long arg) { struct rfcomm_session *s = (void *) arg; - BT_DBG("session %p state %ld", s, s->state); + BT_DBG("session %pK state %ld", s, s->state); set_bit(RFCOMM_TIMED_OUT, &s->flags); rfcomm_schedule(); @@ -241,14 +241,14 @@ static void rfcomm_session_timeout(unsigned long arg) static void rfcomm_session_set_timer(struct rfcomm_session *s, long timeout) { - BT_DBG("session %p state %ld timeout %ld", s, s->state, timeout); + BT_DBG("session %pK state %ld timeout %ld", s, s->state, timeout); mod_timer(&s->timer, jiffies + timeout); } static void rfcomm_session_clear_timer(struct rfcomm_session *s) { - BT_DBG("session %p state %ld", s, s->state); + BT_DBG("session %pK state %ld", s, s->state); del_timer_sync(&s->timer); } @@ -258,7 +258,7 @@ static void rfcomm_dlc_timeout(unsigned long arg) { struct rfcomm_dlc *d = (void *) arg; - BT_DBG("dlc %p state %ld", d, d->state); + BT_DBG("dlc %pK state %ld", d, d->state); set_bit(RFCOMM_TIMED_OUT, &d->flags); rfcomm_dlc_put(d); @@ -267,7 +267,7 @@ static void rfcomm_dlc_timeout(unsigned long arg) static void rfcomm_dlc_set_timer(struct rfcomm_dlc *d, long timeout) { - BT_DBG("dlc %p state %ld timeout %ld", d, d->state, timeout); + BT_DBG("dlc %pK state %ld timeout %ld", d, d->state, timeout); if (!mod_timer(&d->timer, jiffies + timeout)) rfcomm_dlc_hold(d); @@ -275,7 +275,7 @@ static void rfcomm_dlc_set_timer(struct rfcomm_dlc *d, long timeout) static void rfcomm_dlc_clear_timer(struct rfcomm_dlc *d) { - BT_DBG("dlc %p state %ld", d, d->state); + BT_DBG("dlc %pK state %ld", d, d->state); if (del_timer(&d->timer)) rfcomm_dlc_put(d); @@ -283,7 +283,7 @@ static void rfcomm_dlc_clear_timer(struct rfcomm_dlc *d) static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d) { - BT_DBG("%p", d); + BT_DBG("%pK", d); d->state = BT_OPEN; d->flags = 0; @@ -311,14 +311,14 @@ struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio) rfcomm_dlc_clear_state(d); - BT_DBG("%p", d); + BT_DBG("%pK", d); return d; } void rfcomm_dlc_free(struct rfcomm_dlc *d) { - BT_DBG("%p", d); + BT_DBG("%pK", d); skb_queue_purge(&d->tx_queue); kfree(d); @@ -326,7 +326,7 @@ void rfcomm_dlc_free(struct rfcomm_dlc *d) static void rfcomm_dlc_link(struct rfcomm_session *s, struct rfcomm_dlc *d) { - BT_DBG("dlc %p session %p", d, s); + BT_DBG("dlc %pK session %pK", d, s); rfcomm_session_clear_timer(s); rfcomm_dlc_hold(d); @@ -338,7 +338,7 @@ static void rfcomm_dlc_unlink(struct rfcomm_dlc *d) { struct rfcomm_session *s = d->session; - BT_DBG("dlc %p refcnt %d session %p", d, atomic_read(&d->refcnt), s); + BT_DBG("dlc %pK refcnt %d session %pK", d, atomic_read(&d->refcnt), s); list_del(&d->list); d->session = NULL; @@ -365,7 +365,7 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, int err = 0; u8 dlci; - BT_DBG("dlc %p state %ld %pMR -> %pMR channel %d", + BT_DBG("dlc %pK state %ld %pMR -> %pMR channel %d", d, d->state, src, dst, channel); if (channel < 1 || channel > 30) @@ -431,8 +431,8 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err) if (!s) return 0; - BT_DBG("dlc %p state %ld dlci %d err %d session %p", - d, d->state, d->dlci, err, s); + BT_DBG("dlc %pK state %ld dlci %d err %d session %pK", + d, d->state, d->dlci, err, s); switch (d->state) { case BT_CONNECT: @@ -484,7 +484,7 @@ int rfcomm_dlc_close(struct rfcomm_dlc *d, int err) struct rfcomm_dlc *d_list; struct rfcomm_session *s, *s_list; - BT_DBG("dlc %p state %ld dlci %d err %d", d, d->state, d->dlci, err); + BT_DBG("dlc %pK state %ld dlci %d err %d", d, d->state, d->dlci, err); rfcomm_lock(); @@ -519,7 +519,7 @@ int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb) if (d->state != BT_CONNECTED) return -ENOTCONN; - BT_DBG("dlc %p mtu %d len %d", d, d->mtu, len); + BT_DBG("dlc %pK mtu %d len %d", d, d->mtu, len); if (len > d->mtu) return -EINVAL; @@ -534,7 +534,7 @@ int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb) void __rfcomm_dlc_throttle(struct rfcomm_dlc *d) { - BT_DBG("dlc %p state %ld", d, d->state); + BT_DBG("dlc %pK state %ld", d, d->state); if (!d->cfc) { d->v24_sig |= RFCOMM_V24_FC; @@ -545,7 +545,7 @@ void __rfcomm_dlc_throttle(struct rfcomm_dlc *d) void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d) { - BT_DBG("dlc %p state %ld", d, d->state); + BT_DBG("dlc %pK state %ld", d, d->state); if (!d->cfc) { d->v24_sig &= ~RFCOMM_V24_FC; @@ -561,8 +561,8 @@ void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d) */ int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig) { - BT_DBG("dlc %p state %ld v24_sig 0x%x", - d, d->state, v24_sig); + BT_DBG("dlc %pK state %ld v24_sig 0x%x", + d, d->state, v24_sig); if (test_bit(RFCOMM_RX_THROTTLED, &d->flags)) v24_sig |= RFCOMM_V24_FC; @@ -579,8 +579,8 @@ int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig) int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig) { - BT_DBG("dlc %p state %ld v24_sig 0x%x", - d, d->state, d->v24_sig); + BT_DBG("dlc %pK state %ld v24_sig 0x%x", + d, d->state, d->v24_sig); *v24_sig = d->v24_sig; return 0; @@ -594,7 +594,7 @@ static struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state) if (!s) return NULL; - BT_DBG("session %p sock %p", s, sock); + BT_DBG("session %pK sock %pK", s, sock); setup_timer(&s->timer, rfcomm_session_timeout, (unsigned long) s); @@ -622,7 +622,7 @@ static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s) { int state = s->state; - BT_DBG("session %p state %ld", s, s->state); + BT_DBG("session %pK state %ld", s, s->state); list_del(&s->list); @@ -660,7 +660,7 @@ static struct rfcomm_session *rfcomm_session_close(struct rfcomm_session *s, s->state = BT_CLOSED; - BT_DBG("session %p state %ld err %d", s, s->state, err); + BT_DBG("session %pK state %ld err %d", s, s->state, err); /* Close all dlcs */ list_for_each_safe(p, n, &s->dlcs) { @@ -744,7 +744,7 @@ static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len) struct kvec iv = { data, len }; struct msghdr msg; - BT_DBG("session %p len %d", s, len); + BT_DBG("session %pK len %d", s, len); memset(&msg, 0, sizeof(msg)); @@ -753,7 +753,7 @@ static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len) static int rfcomm_send_cmd(struct rfcomm_session *s, struct rfcomm_cmd *cmd) { - BT_DBG("%p cmd %u", s, cmd->ctrl); + BT_DBG("%pK cmd %u", s, cmd->ctrl); return rfcomm_send_frame(s, (void *) cmd, sizeof(*cmd)); } @@ -762,7 +762,7 @@ static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci) { struct rfcomm_cmd cmd; - BT_DBG("%p dlci %d", s, dlci); + BT_DBG("%pK dlci %d", s, dlci); cmd.addr = __addr(s->initiator, dlci); cmd.ctrl = __ctrl(RFCOMM_SABM, 1); @@ -776,7 +776,7 @@ static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci) { struct rfcomm_cmd cmd; - BT_DBG("%p dlci %d", s, dlci); + BT_DBG("%pK dlci %d", s, dlci); cmd.addr = __addr(!s->initiator, dlci); cmd.ctrl = __ctrl(RFCOMM_UA, 1); @@ -790,7 +790,7 @@ static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci) { struct rfcomm_cmd cmd; - BT_DBG("%p dlci %d", s, dlci); + BT_DBG("%pK dlci %d", s, dlci); cmd.addr = __addr(s->initiator, dlci); cmd.ctrl = __ctrl(RFCOMM_DISC, 1); @@ -805,7 +805,7 @@ static int rfcomm_queue_disc(struct rfcomm_dlc *d) struct rfcomm_cmd *cmd; struct sk_buff *skb; - BT_DBG("dlc %p dlci %d", d, d->dlci); + BT_DBG("dlc %pK dlci %d", d, d->dlci); skb = alloc_skb(sizeof(*cmd), GFP_KERNEL); if (!skb) @@ -826,7 +826,7 @@ static int rfcomm_send_dm(struct rfcomm_session *s, u8 dlci) { struct rfcomm_cmd cmd; - BT_DBG("%p dlci %d", s, dlci); + BT_DBG("%pK dlci %d", s, dlci); cmd.addr = __addr(!s->initiator, dlci); cmd.ctrl = __ctrl(RFCOMM_DM, 1); @@ -842,7 +842,7 @@ static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type) struct rfcomm_mcc *mcc; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d type %d", s, cr, type); + BT_DBG("%pK cr %d type %d", s, cr, type); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -868,7 +868,7 @@ static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d struct rfcomm_pn *pn; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d dlci %d mtu %d", s, cr, d->dlci, d->mtu); + BT_DBG("%pK cr %d dlci %d mtu %d", s, cr, d->dlci, d->mtu); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -913,10 +913,9 @@ int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci, struct rfcomm_rpn *rpn; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d dlci %d bit_r 0x%x data_b 0x%x stop_b 0x%x parity 0x%x" - " flwc_s 0x%x xon_c 0x%x xoff_c 0x%x p_mask 0x%x", - s, cr, dlci, bit_rate, data_bits, stop_bits, parity, - flow_ctrl_settings, xon_char, xoff_char, param_mask); + BT_DBG("%pK cr %d dlci %d bit_r 0x%x data_b 0x%x stop_b 0x%x parity 0x%x flwc_s 0x%x xon_c 0x%x xoff_c 0x%x p_mask 0x%x", + s, cr, dlci, bit_rate, data_bits, stop_bits, parity, + flow_ctrl_settings, xon_char, xoff_char, param_mask); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -948,7 +947,7 @@ static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status) struct rfcomm_rls *rls; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d status 0x%x", s, cr, status); + BT_DBG("%pK cr %d status 0x%x", s, cr, status); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -975,7 +974,7 @@ static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig struct rfcomm_msc *msc; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d v24 0x%x", s, cr, v24_sig); + BT_DBG("%pK cr %d v24 0x%x", s, cr, v24_sig); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -1001,7 +1000,7 @@ static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr) struct rfcomm_mcc *mcc; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d", s, cr); + BT_DBG("%pK cr %d", s, cr); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -1023,7 +1022,7 @@ static int rfcomm_send_fcon(struct rfcomm_session *s, int cr) struct rfcomm_mcc *mcc; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d", s, cr); + BT_DBG("%pK cr %d", s, cr); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -1049,7 +1048,7 @@ static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int l if (len > 125) return -EINVAL; - BT_DBG("%p cr %d", s, cr); + BT_DBG("%pK cr %d", s, cr); hdr[0] = __addr(s->initiator, 0); hdr[1] = __ctrl(RFCOMM_UIH, 0); @@ -1076,7 +1075,7 @@ static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits) struct rfcomm_hdr *hdr; u8 buf[16], *ptr = buf; - BT_DBG("%p addr %d credits %d", s, addr, credits); + BT_DBG("%pK addr %d credits %d", s, addr, credits); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = addr; @@ -1113,7 +1112,7 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr) /* ---- RFCOMM frame reception ---- */ static struct rfcomm_session *rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci) { - BT_DBG("session %p state %ld dlci %d", s, s->state, dlci); + BT_DBG("session %pK state %ld dlci %d", s, s->state, dlci); if (dlci) { /* Data channel */ @@ -1167,7 +1166,7 @@ static struct rfcomm_session *rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci) { int err = 0; - BT_DBG("session %p state %ld dlci %d", s, s->state, dlci); + BT_DBG("session %pK state %ld dlci %d", s, s->state, dlci); if (dlci) { /* Data DLC */ @@ -1197,7 +1196,7 @@ static struct rfcomm_session *rfcomm_recv_disc(struct rfcomm_session *s, { int err = 0; - BT_DBG("session %p state %ld dlci %d", s, s->state, dlci); + BT_DBG("session %pK state %ld dlci %d", s, s->state, dlci); if (dlci) { struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci); @@ -1232,7 +1231,7 @@ void rfcomm_dlc_accept(struct rfcomm_dlc *d) struct sock *sk = d->session->sock->sk; struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn; - BT_DBG("dlc %p", d); + BT_DBG("dlc %pK", d); rfcomm_send_ua(d->session, d->dlci); @@ -1273,7 +1272,7 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci) struct rfcomm_dlc *d; u8 channel; - BT_DBG("session %p state %ld dlci %d", s, s->state, dlci); + BT_DBG("session %pK state %ld dlci %d", s, s->state, dlci); if (!dlci) { rfcomm_send_ua(s, 0); @@ -1314,8 +1313,8 @@ static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn) { struct rfcomm_session *s = d->session; - BT_DBG("dlc %p state %ld dlci %d mtu %d fc 0x%x credits %d", - d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits); + BT_DBG("dlc %pK state %ld dlci %d mtu %d fc 0x%x credits %d", + d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits); if ((pn->flow_ctrl == 0xf0 && s->cfc != RFCOMM_CFC_DISABLED) || pn->flow_ctrl == 0xe0) { @@ -1345,7 +1344,7 @@ static int rfcomm_recv_pn(struct rfcomm_session *s, int cr, struct sk_buff *skb) struct rfcomm_dlc *d; u8 dlci = pn->dlci; - BT_DBG("session %p state %ld dlci %d", s, s->state, dlci); + BT_DBG("session %pK state %ld dlci %d", s, s->state, dlci); if (!dlci) return 0; @@ -1561,7 +1560,7 @@ static int rfcomm_recv_mcc(struct rfcomm_session *s, struct sk_buff *skb) type = __get_mcc_type(mcc->type); len = __get_mcc_len(mcc->len); - BT_DBG("%p type 0x%x cr %d", s, type, cr); + BT_DBG("%pK type 0x%x cr %d", s, type, cr); skb_pull(skb, 2); @@ -1616,7 +1615,7 @@ static int rfcomm_recv_data(struct rfcomm_session *s, u8 dlci, int pf, struct sk { struct rfcomm_dlc *d; - BT_DBG("session %p state %ld dlci %d pf %d", s, s->state, dlci, pf); + BT_DBG("session %pK state %ld dlci %d pf %d", s, s->state, dlci, pf); d = rfcomm_dlc_get(s, dlci); if (!d) { @@ -1718,7 +1717,7 @@ static void rfcomm_process_connect(struct rfcomm_session *s) struct rfcomm_dlc *d; struct list_head *p, *n; - BT_DBG("session %p state %ld", s, s->state); + BT_DBG("session %pK state %ld", s, s->state); list_for_each_safe(p, n, &s->dlcs) { d = list_entry(p, struct rfcomm_dlc, list); @@ -1742,8 +1741,8 @@ static int rfcomm_process_tx(struct rfcomm_dlc *d) struct sk_buff *skb; int err; - BT_DBG("dlc %p state %ld cfc %d rx_credits %d tx_credits %d", - d, d->state, d->cfc, d->rx_credits, d->tx_credits); + BT_DBG("dlc %pK state %ld cfc %d rx_credits %d tx_credits %d", + d, d->state, d->cfc, d->rx_credits, d->tx_credits); /* Send pending MSC */ if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags)) @@ -1790,7 +1789,7 @@ static void rfcomm_process_dlcs(struct rfcomm_session *s) struct rfcomm_dlc *d; struct list_head *p, *n; - BT_DBG("session %p state %ld", s, s->state); + BT_DBG("session %pK state %ld", s, s->state); list_for_each_safe(p, n, &s->dlcs) { d = list_entry(p, struct rfcomm_dlc, list); @@ -1851,7 +1850,8 @@ static struct rfcomm_session *rfcomm_process_rx(struct rfcomm_session *s) struct sock *sk = sock->sk; struct sk_buff *skb; - BT_DBG("session %p state %ld qlen %d", s, s->state, skb_queue_len(&sk->sk_receive_queue)); + BT_DBG("session %pK state %ld qlen %d", s, s->state, + skb_queue_len(&sk->sk_receive_queue)); /* Get data directly from socket receive queue without copying it. */ while ((skb = skb_dequeue(&sk->sk_receive_queue))) { @@ -1878,7 +1878,7 @@ static void rfcomm_accept_connection(struct rfcomm_session *s) if (list_empty(&bt_sk(sock->sk)->accept_q)) return; - BT_DBG("session %p", s); + BT_DBG("session %pK", s); err = kernel_accept(sock, &nsock, O_NONBLOCK); if (err < 0) @@ -1904,7 +1904,7 @@ static struct rfcomm_session *rfcomm_check_connection(struct rfcomm_session *s) { struct sock *sk = s->sock->sk; - BT_DBG("%p state %ld", s, s->state); + BT_DBG("%pK state %ld", s, s->state); switch (sk->sk_state) { case BT_CONNECTED: @@ -2059,7 +2059,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt) struct rfcomm_dlc *d; struct list_head *p, *n; - BT_DBG("conn %p status 0x%02x encrypt 0x%02x", conn, status, encrypt); + BT_DBG("conn %pK status 0x%02x encrypt 0x%02x", conn, status, encrypt); s = rfcomm_session_get(&conn->hdev->bdaddr, &conn->dst); if (!s) diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index c1c6028e389ad..75f10eee71f01 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -68,7 +68,7 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) if (!sk) return; - BT_DBG("dlc %p state %ld err %d", d, d->state, err); + BT_DBG("dlc %pK state %ld err %d", d, d->state, err); local_irq_save(flags); bh_lock_sock(sk); @@ -150,7 +150,7 @@ static void rfcomm_sock_destruct(struct sock *sk) { struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; - BT_DBG("sk %p dlc %p", sk, d); + BT_DBG("sk %pK dlc %pK", sk, d); skb_queue_purge(&sk->sk_receive_queue); skb_queue_purge(&sk->sk_write_queue); @@ -170,7 +170,7 @@ static void rfcomm_sock_cleanup_listen(struct sock *parent) { struct sock *sk; - BT_DBG("parent %p", parent); + BT_DBG("parent %pK", parent); /* Close not yet accepted dlcs */ while ((sk = bt_accept_dequeue(parent, NULL))) { @@ -190,7 +190,8 @@ static void rfcomm_sock_kill(struct sock *sk) if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) return; - BT_DBG("sk %p state %d refcnt %d", sk, sk->sk_state, atomic_read(&sk->sk_refcnt)); + BT_DBG("sk %pK state %d refcnt %d", sk, sk->sk_state, + atomic_read(&sk->sk_refcnt)); /* Kill poor orphan */ bt_sock_unlink(&rfcomm_sk_list, sk); @@ -202,7 +203,7 @@ static void __rfcomm_sock_close(struct sock *sk) { struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; - BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); + BT_DBG("sk %pK state %d socket %pK", sk, sk->sk_state, sk->sk_socket); switch (sk->sk_state) { case BT_LISTEN: @@ -235,7 +236,7 @@ static void rfcomm_sock_init(struct sock *sk, struct sock *parent) { struct rfcomm_pinfo *pi = rfcomm_pi(sk); - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (parent) { sk->sk_type = parent->sk_type; @@ -300,7 +301,7 @@ static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock, int bt_sock_link(&rfcomm_sk_list, sk); - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); return sk; } @@ -309,7 +310,7 @@ static int rfcomm_sock_create(struct net *net, struct socket *sock, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); sock->state = SS_UNCONNECTED; @@ -332,7 +333,7 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr struct sock *sk = sock->sk; int err = 0; - BT_DBG("sk %p %pMR", sk, &sa->rc_bdaddr); + BT_DBG("sk %pK %pMR", sk, &sa->rc_bdaddr); if (!addr || addr->sa_family != AF_BLUETOOTH) return -EINVAL; @@ -374,7 +375,7 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; int err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (alen < sizeof(struct sockaddr_rc) || addr->sa_family != AF_BLUETOOTH) @@ -414,7 +415,7 @@ static int rfcomm_sock_listen(struct socket *sock, int backlog) struct sock *sk = sock->sk; int err = 0; - BT_DBG("sk %p backlog %d", sk, backlog); + BT_DBG("sk %pK backlog %d", sk, backlog); lock_sock(sk); @@ -474,7 +475,7 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); - BT_DBG("sk %p timeo %ld", sk, timeo); + BT_DBG("sk %pK timeo %ld", sk, timeo); /* Wait for an incoming connection. (wake-one). */ add_wait_queue_exclusive(sk_sleep(sk), &wait); @@ -512,7 +513,7 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f newsock->state = SS_CONNECTED; - BT_DBG("new socket %p", nsk); + BT_DBG("new socket %pK", nsk); done: release_sock(sk); @@ -524,7 +525,7 @@ static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int * struct sockaddr_rc *sa = (struct sockaddr_rc *) addr; struct sock *sk = sock->sk; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); memset(sa, 0, sizeof(*sa)); sa->rc_family = AF_BLUETOOTH; @@ -555,7 +556,7 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, if (sk->sk_shutdown & SEND_SHUTDOWN) return -EPIPE; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); lock_sock(sk); @@ -630,7 +631,7 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __u int err = 0; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); lock_sock(sk); @@ -668,7 +669,7 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c size_t len; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (level == SOL_RFCOMM) return rfcomm_sock_setsockopt_old(sock, optname, optval, optlen); @@ -736,7 +737,7 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u int len, err = 0; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (get_user(len, optlen)) return -EFAULT; @@ -800,7 +801,7 @@ static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, c struct bt_security sec; int len, err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (level == SOL_RFCOMM) return rfcomm_sock_getsockopt_old(sock, optname, optval, optlen); @@ -855,7 +856,7 @@ static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned lon struct sock *sk __maybe_unused = sock->sk; int err; - BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg); + BT_DBG("sk %pK cmd %x arg %lx", sk, cmd, arg); err = bt_sock_ioctl(sock, cmd, arg); @@ -877,7 +878,7 @@ static int rfcomm_sock_shutdown(struct socket *sock, int how) struct sock *sk = sock->sk; int err = 0; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (!sk) return 0; @@ -899,7 +900,7 @@ static int rfcomm_sock_release(struct socket *sock) struct sock *sk = sock->sk; int err; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (!sk) return 0; @@ -921,7 +922,7 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc * bdaddr_t src, dst; int result = 0; - BT_DBG("session %p channel %d", s, channel); + BT_DBG("session %pK channel %d", s, channel); rfcomm_session_getaddr(s, &src, &dst); diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index b6e44ad6cca6e..d2ce585a3c152 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -88,7 +88,7 @@ static void rfcomm_dev_destruct(struct tty_port *port) struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port); struct rfcomm_dlc *dlc = dev->dlc; - BT_DBG("dev %p dlc %p", dev, dlc); + BT_DBG("dev %pK dlc %pK", dev, dlc); /* Refcount should only hit zero when called from rfcomm_dev_del() which will have taken us off the list. Everything else are @@ -304,7 +304,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) static void rfcomm_dev_del(struct rfcomm_dev *dev) { unsigned long flags; - BT_DBG("dev %p", dev); + BT_DBG("dev %pK", dev); BUG_ON(test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags)); @@ -373,7 +373,7 @@ static int rfcomm_create_dev(struct sock *sk, void __user *arg) if (copy_from_user(&req, arg, sizeof(req))) return -EFAULT; - BT_DBG("sk %p dev_id %d flags 0x%x", sk, req.dev_id, req.flags); + BT_DBG("sk %pK dev_id %d flags 0x%x", sk, req.dev_id, req.flags); if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) return -EPERM; @@ -518,7 +518,7 @@ static int rfcomm_get_dev_info(void __user *arg) int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) { - BT_DBG("cmd %d arg %p", cmd, arg); + BT_DBG("cmd %d arg %pK", cmd, arg); switch (cmd) { case RFCOMMCREATEDEV: @@ -552,7 +552,7 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb) return; } - BT_DBG("dlc %p len %d", dlc, skb->len); + BT_DBG("dlc %pK len %d", dlc, skb->len); tty_insert_flip_string(&dev->port, skb->data, skb->len); tty_flip_buffer_push(&dev->port); @@ -566,7 +566,7 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err) if (!dev) return; - BT_DBG("dlc %p dev %p err %d", dlc, dev, err); + BT_DBG("dlc %pK dev %pK err %d", dlc, dev, err); dev->err = err; wake_up_interruptible(&dev->wait); @@ -602,7 +602,7 @@ static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig) if (!dev) return; - BT_DBG("dlc %p dev %p v24_sig 0x%02x", dlc, dev, v24_sig); + BT_DBG("dlc %pK dev %pK v24_sig 0x%02x", dlc, dev, v24_sig); if ((dev->modem_status & TIOCM_CD) && !(v24_sig & RFCOMM_V24_DV)) { if (dev->port.tty && !C_CLOCAL(dev->port.tty)) @@ -622,7 +622,7 @@ static void rfcomm_tty_copy_pending(struct rfcomm_dev *dev) struct sk_buff *skb; int inserted = 0; - BT_DBG("dev %p", dev); + BT_DBG("dev %pK", dev); rfcomm_dlc_lock(dev->dlc); @@ -648,7 +648,7 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) id = tty->index; - BT_DBG("tty %p id %d", tty, id); + BT_DBG("tty %pK id %d", tty, id); /* We don't leak this refcount. For reasons which are not entirely clear, the TTY layer will call our ->close() method even if the @@ -658,7 +658,7 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) if (!dev) return -ENODEV; - BT_DBG("dev %p dst %pMR channel %d opened %d", dev, &dev->dst, + BT_DBG("dev %pK dst %pMR channel %d opened %d", dev, &dev->dst, dev->channel, dev->port.count); spin_lock_irqsave(&dev->port.lock, flags); @@ -726,8 +726,8 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp) if (!dev) return; - BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc, - dev->port.count); + BT_DBG("tty %pK dev %pK dlc %pK opened %d", tty, dev, dev->dlc, + dev->port.count); spin_lock_irqsave(&dev->port.lock, flags); if (!--dev->port.count) { @@ -765,7 +765,7 @@ static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, in struct sk_buff *skb; int err = 0, sent = 0, size; - BT_DBG("tty %p count %d", tty, count); + BT_DBG("tty %pK count %d", tty, count); while (count) { size = min_t(uint, count, dlc->mtu); @@ -797,7 +797,7 @@ static int rfcomm_tty_write_room(struct tty_struct *tty) struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; int room; - BT_DBG("tty %p", tty); + BT_DBG("tty %pK", tty); if (!dev || !dev->dlc) return 0; @@ -811,7 +811,7 @@ static int rfcomm_tty_write_room(struct tty_struct *tty) static int rfcomm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { - BT_DBG("tty %p cmd 0x%02x", tty, cmd); + BT_DBG("tty %pK cmd 0x%02x", tty, cmd); switch (cmd) { case TCGETS: @@ -865,7 +865,7 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old) struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p termios %p", tty, old); + BT_DBG("tty %pK termios %pK", tty, old); if (!dev || !dev->dlc || !dev->dlc->session) return; @@ -997,7 +997,7 @@ static void rfcomm_tty_throttle(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p dev %p", tty, dev); + BT_DBG("tty %pK dev %pK", tty, dev); rfcomm_dlc_throttle(dev->dlc); } @@ -1006,7 +1006,7 @@ static void rfcomm_tty_unthrottle(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p dev %p", tty, dev); + BT_DBG("tty %pK dev %pK", tty, dev); rfcomm_dlc_unthrottle(dev->dlc); } @@ -1015,7 +1015,7 @@ static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p dev %p", tty, dev); + BT_DBG("tty %pK dev %pK", tty, dev); if (!dev || !dev->dlc) return 0; @@ -1030,7 +1030,7 @@ static void rfcomm_tty_flush_buffer(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p dev %p", tty, dev); + BT_DBG("tty %pK dev %pK", tty, dev); if (!dev || !dev->dlc) return; @@ -1041,19 +1041,19 @@ static void rfcomm_tty_flush_buffer(struct tty_struct *tty) static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch) { - BT_DBG("tty %p ch %c", tty, ch); + BT_DBG("tty %pK ch %c", tty, ch); } static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout) { - BT_DBG("tty %p timeout %d", tty, timeout); + BT_DBG("tty %pK timeout %d", tty, timeout); } static void rfcomm_tty_hangup(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p dev %p", tty, dev); + BT_DBG("tty %pK dev %pK", tty, dev); if (!dev) return; @@ -1072,7 +1072,7 @@ static int rfcomm_tty_tiocmget(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p dev %p", tty, dev); + BT_DBG("tty %pK dev %pK", tty, dev); return dev->modem_status; } @@ -1083,7 +1083,7 @@ static int rfcomm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigne struct rfcomm_dlc *dlc = dev->dlc; u8 v24_sig; - BT_DBG("tty %p dev %p set 0x%02x clear 0x%02x", tty, dev, set, clear); + BT_DBG("tty %pK dev %pK set 0x%02x clear 0x%02x", tty, dev, set, clear); rfcomm_dlc_get_modem_status(dlc, &v24_sig); diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 11797c13a0c37..5bf2937fd1509 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -51,7 +51,7 @@ static void sco_sock_timeout(unsigned long arg) { struct sock *sk = (struct sock *) arg; - BT_DBG("sock %p state %d", sk, sk->sk_state); + BT_DBG("sock %pK state %d", sk, sk->sk_state); bh_lock_sock(sk); sk->sk_err = ETIMEDOUT; @@ -64,13 +64,13 @@ static void sco_sock_timeout(unsigned long arg) static void sco_sock_set_timer(struct sock *sk, long timeout) { - BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout); + BT_DBG("sock %pK state %d timeout %ld", sk, sk->sk_state, timeout); sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout); } static void sco_sock_clear_timer(struct sock *sk) { - BT_DBG("sock %p state %d", sk, sk->sk_state); + BT_DBG("sock %pK state %d", sk, sk->sk_state); sk_stop_timer(sk, &sk->sk_timer); } @@ -100,7 +100,7 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon) else conn->mtu = 60; - BT_DBG("hcon %p conn %p", hcon, conn); + BT_DBG("hcon %pK conn %pK", hcon, conn); return conn; } @@ -122,7 +122,7 @@ static int sco_conn_del(struct hci_conn *hcon, int err) if (!conn) return 0; - BT_DBG("hcon %p conn %p, err %d", hcon, conn, err); + BT_DBG("hcon %pK conn %pK, err %d", hcon, conn, err); /* Kill socket */ sk = sco_chan_get(conn); @@ -224,7 +224,7 @@ static int sco_send_frame(struct sock *sk, struct msghdr *msg, int len) if (len > conn->mtu) return -EINVAL; - BT_DBG("sk %p len %d", sk, len); + BT_DBG("sk %pK len %d", sk, len); skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err); if (!skb) @@ -247,7 +247,7 @@ static void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb) if (!sk) goto drop; - BT_DBG("sk %p len %d", sk, skb->len); + BT_DBG("sk %pK len %d", sk, skb->len); if (sk->sk_state != BT_CONNECTED) goto drop; @@ -304,7 +304,7 @@ static struct sock *sco_get_sock_listen(bdaddr_t *src) static void sco_sock_destruct(struct sock *sk) { - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); skb_queue_purge(&sk->sk_receive_queue); skb_queue_purge(&sk->sk_write_queue); @@ -314,7 +314,7 @@ static void sco_sock_cleanup_listen(struct sock *parent) { struct sock *sk; - BT_DBG("parent %p", parent); + BT_DBG("parent %pK", parent); /* Close not yet accepted channels */ while ((sk = bt_accept_dequeue(parent, NULL))) { @@ -334,7 +334,7 @@ static void sco_sock_kill(struct sock *sk) if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) return; - BT_DBG("sk %p state %d", sk, sk->sk_state); + BT_DBG("sk %pK state %d", sk, sk->sk_state); /* Kill poor orphan */ bt_sock_unlink(&sco_sk_list, sk); @@ -344,7 +344,7 @@ static void sco_sock_kill(struct sock *sk) static void __sco_sock_close(struct sock *sk) { - BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); + BT_DBG("sk %pK state %d socket %pK", sk, sk->sk_state, sk->sk_socket); switch (sk->sk_state) { case BT_LISTEN: @@ -388,7 +388,7 @@ static void sco_sock_close(struct sock *sk) static void sco_sock_init(struct sock *sk, struct sock *parent) { - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (parent) { sk->sk_type = parent->sk_type; @@ -433,7 +433,7 @@ static int sco_sock_create(struct net *net, struct socket *sock, int protocol, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); sock->state = SS_UNCONNECTED; @@ -456,7 +456,7 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) struct sock *sk = sock->sk; int len, err = 0; - BT_DBG("sk %p %pMR", sk, &sa.sco_bdaddr); + BT_DBG("sk %pK %pMR", sk, &sa.sco_bdaddr); if (!addr || addr->sa_family != AF_BLUETOOTH) return -EINVAL; @@ -493,7 +493,7 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen struct sockaddr_sco sa; int len, err; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (!addr || addr->sa_family != AF_BLUETOOTH) return -EINVAL; @@ -536,7 +536,7 @@ static int sco_sock_listen(struct socket *sock, int backlog) bdaddr_t *src = &bt_sk(sk)->src; int err = 0; - BT_DBG("sk %p backlog %d", sk, backlog); + BT_DBG("sk %pK backlog %d", sk, backlog); lock_sock(sk); @@ -581,7 +581,7 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); - BT_DBG("sk %p timeo %ld", sk, timeo); + BT_DBG("sk %pK timeo %ld", sk, timeo); /* Wait for an incoming connection. (wake-one). */ add_wait_queue_exclusive(sk_sleep(sk), &wait); @@ -619,7 +619,7 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag newsock->state = SS_CONNECTED; - BT_DBG("new socket %p", ch); + BT_DBG("new socket %pK", ch); done: release_sock(sk); @@ -631,7 +631,7 @@ static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len struct sockaddr_sco *sa = (struct sockaddr_sco *) addr; struct sock *sk = sock->sk; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); addr->sa_family = AF_BLUETOOTH; *len = sizeof(struct sockaddr_sco); @@ -651,7 +651,7 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct sock *sk = sock->sk; int err; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); err = sock_error(sk); if (err) @@ -675,7 +675,7 @@ static void sco_conn_defer_accept(struct hci_conn *conn, int mask) { struct hci_dev *hdev = conn->hdev; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); conn->state = BT_CONFIG; @@ -735,7 +735,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char int err = 0; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); lock_sock(sk); @@ -774,7 +774,7 @@ static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user struct sco_conninfo cinfo; int len, err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (get_user(len, optlen)) return -EFAULT; @@ -828,7 +828,7 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char struct sock *sk = sock->sk; int len, err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (level == SOL_SCO) return sco_sock_getsockopt_old(sock, optname, optval, optlen); @@ -866,7 +866,7 @@ static int sco_sock_shutdown(struct socket *sock, int how) struct sock *sk = sock->sk; int err = 0; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (!sk) return 0; @@ -890,7 +890,7 @@ static int sco_sock_release(struct socket *sock) struct sock *sk = sock->sk; int err = 0; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (!sk) return 0; @@ -910,7 +910,7 @@ static int sco_sock_release(struct socket *sock) static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent) { - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); sco_pi(sk)->conn = conn; conn->sk = sk; @@ -927,7 +927,7 @@ static void sco_chan_del(struct sock *sk, int err) conn = sco_pi(sk)->conn; - BT_DBG("sk %p, conn %p, err %d", sk, conn, err); + BT_DBG("sk %pK, conn %pK, err %d", sk, conn, err); if (conn) { sco_conn_lock(conn); @@ -951,7 +951,7 @@ static void sco_conn_ready(struct sco_conn *conn) struct sock *parent; struct sock *sk = conn->sk; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); if (sk) { sco_sock_clear_timer(sk); @@ -1030,7 +1030,7 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) void sco_connect_cfm(struct hci_conn *hcon, __u8 status) { - BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status); + BT_DBG("hcon %pK bdaddr %pMR status %d", hcon, &hcon->dst, status); if (!status) { struct sco_conn *conn; @@ -1043,7 +1043,7 @@ void sco_connect_cfm(struct hci_conn *hcon, __u8 status) void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason) { - BT_DBG("hcon %p reason %d", hcon, reason); + BT_DBG("hcon %pK reason %d", hcon, reason); sco_conn_del(hcon, bt_to_errno(reason)); } @@ -1055,7 +1055,7 @@ int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb) if (!conn) goto drop; - BT_DBG("conn %p len %d", conn, skb->len); + BT_DBG("conn %pK len %d", conn, skb->len); if (skb->len) { sco_recv_frame(conn, skb); diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 3c66c2922c21f..d937dd0821803 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -56,7 +56,7 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r) unsigned char iv[128]; if (tfm == NULL) { - BT_ERR("tfm %p", tfm); + BT_ERR("tfm %pK", tfm); return -EINVAL; } @@ -375,7 +375,7 @@ static void confirm_work(struct work_struct *work) int ret; u8 res[16], reason; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); tfm = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm)) { @@ -422,7 +422,7 @@ static void random_work(struct work_struct *work) goto error; } - BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); + BT_DBG("conn %pK %s", conn, conn->hcon->out ? "master" : "slave"); if (hcon->out) ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp, 0, @@ -574,7 +574,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) u8 auth = SMP_AUTH_NONE; int ret; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); if (conn->hcon->link_mode & HCI_LM_MASTER) return SMP_CMD_NOTSUPP; @@ -628,7 +628,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) u8 key_size, auth = SMP_AUTH_NONE; int ret; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); if (!(conn->hcon->link_mode & HCI_LM_MASTER)) return SMP_CMD_NOTSUPP; @@ -674,7 +674,7 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) struct smp_chan *smp = conn->smp_chan; struct hci_dev *hdev = conn->hcon->hdev; - BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); + BT_DBG("conn %pK %s", conn, conn->hcon->out ? "master" : "slave"); memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); skb_pull(skb, sizeof(smp->pcnf)); @@ -699,7 +699,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) struct smp_chan *smp = conn->smp_chan; struct hci_dev *hdev = conn->hcon->hdev; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); swap128(skb->data, smp->rrnd); skb_pull(skb, sizeof(smp->rrnd)); @@ -737,7 +737,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) struct hci_conn *hcon = conn->hcon; struct smp_chan *smp; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req); @@ -770,7 +770,7 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) struct smp_chan *smp = conn->smp_chan; __u8 authreq; - BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); + BT_DBG("conn %pK hcon %pK level 0x%2.2x", conn, hcon, sec_level); if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) return 1; @@ -938,7 +938,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force) struct smp_chan *smp = conn->smp_chan; __u8 *keydist; - BT_DBG("conn %p force %d", conn, force); + BT_DBG("conn %pK force %d", conn, force); if (!test_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) return 0; From c9f7083a4edfe5061767e63367a02e60c6157b4a Mon Sep 17 00:00:00 2001 From: Dibyendu Roy Date: Mon, 4 Jul 2016 15:21:42 +0530 Subject: [PATCH 109/320] Bluetooth: Replace %p with %pK The %pK restrictions are used to eliminate exposing kernel addresses. When kptr_restrict is set to "0" there are no restrictions. When kptr_restrict is set to "1", kernel pointers printed using the %pK format specifier will be replaced with 0's unless the user has CAP_SYSLOG. When kptr_restrict is set to "2", kernel pointers printed using %pK will be replaced with 0's regardless of privileges. Change-Id: Ie56b7f253a55d4402c434502932a7c5fe56b2c00 Signed-off-by: Dibyendu Roy --- drivers/bluetooth/hci_ibs.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/bluetooth/hci_ibs.c b/drivers/bluetooth/hci_ibs.c index 0d732184f274c..b97287058fbec 100644 --- a/drivers/bluetooth/hci_ibs.c +++ b/drivers/bluetooth/hci_ibs.c @@ -231,7 +231,7 @@ static int send_hci_ibs_cmd(u8 cmd, struct hci_uart *hu) struct ibs_struct *ibs = hu->priv; struct hci_ibs_cmd *hci_ibs_packet; - BT_DBG("hu %p cmd 0x%x", hu, cmd); + BT_DBG("hu %pK cmd 0x%x", hu, cmd); /* allocate packet */ skb = bt_skb_alloc(1, GFP_ATOMIC); @@ -259,7 +259,7 @@ static void ibs_wq_awake_device(struct work_struct *work) struct hci_uart *hu = (struct hci_uart *)ibs->ibs_hu; unsigned long flags; - BT_DBG(" %p ", hu); + BT_DBG(" %pK ", hu); /* Vote for serial clock */ ibs_msm_serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_ON, hu); @@ -286,7 +286,7 @@ static void ibs_wq_awake_rx(struct work_struct *work) struct hci_uart *hu = (struct hci_uart *)ibs->ibs_hu; unsigned long flags; - BT_DBG(" %p ", hu); + BT_DBG(" %pK ", hu); ibs_msm_serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_ON, hu); @@ -314,7 +314,7 @@ static void ibs_wq_serial_rx_clock_vote_off(struct work_struct *work) ws_rx_vote_off); struct hci_uart *hu = (struct hci_uart *)ibs->ibs_hu; - BT_DBG(" %p ", hu); + BT_DBG(" %pK ", hu); ibs_msm_serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_OFF, hu); @@ -326,7 +326,7 @@ static void ibs_wq_serial_tx_clock_vote_off(struct work_struct *work) ws_tx_vote_off); struct hci_uart *hu = (struct hci_uart *)ibs->ibs_hu; - BT_DBG(" %p ", hu); + BT_DBG(" %pK ", hu); hci_uart_tx_wakeup(hu); /* run HCI tx handling unlocked */ @@ -342,7 +342,7 @@ static void hci_ibs_tx_idle_timeout(unsigned long arg) struct ibs_struct *ibs = hu->priv; unsigned long flags; - BT_DBG("hu %p idle timeout in %lu state", hu, ibs->tx_ibs_state); + BT_DBG("hu %pK idle timeout in %lu state", hu, ibs->tx_ibs_state); spin_lock_irqsave_nested(&ibs->hci_ibs_lock, flags, SINGLE_DEPTH_NESTING); @@ -376,8 +376,8 @@ static void hci_ibs_wake_retrans_timeout(unsigned long arg) unsigned long flags; unsigned long retransmit = 0; - BT_DBG("hu %p wake retransmit timeout in %lu state", - hu, ibs->tx_ibs_state); + BT_DBG("hu %pK wake retransmit timeout in %lu state", + hu, ibs->tx_ibs_state); spin_lock_irqsave_nested(&ibs->hci_ibs_lock, flags, SINGLE_DEPTH_NESTING); @@ -409,7 +409,7 @@ static int ibs_open(struct hci_uart *hu) { struct ibs_struct *ibs; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); ibs = kzalloc(sizeof(*ibs), GFP_ATOMIC); if (!ibs) @@ -505,7 +505,7 @@ static int ibs_flush(struct hci_uart *hu) { struct ibs_struct *ibs = hu->priv; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); skb_queue_purge(&ibs->tx_wait_q); skb_queue_purge(&ibs->txq); @@ -518,7 +518,7 @@ static int ibs_close(struct hci_uart *hu) { struct ibs_struct *ibs = hu->priv; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); ibs_msm_serial_clock_vote(HCI_IBS_VOTE_STATS_UPDATE, hu); ibs_log_local_stats(ibs); @@ -547,7 +547,7 @@ static void ibs_device_want_to_wakeup(struct hci_uart *hu) unsigned long flags; struct ibs_struct *ibs = hu->priv; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); /* lock hci_ibs state */ spin_lock_irqsave(&ibs->hci_ibs_lock, flags); @@ -596,7 +596,7 @@ static void ibs_device_want_to_sleep(struct hci_uart *hu) unsigned long flags; struct ibs_struct *ibs = hu->priv; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); /* lock hci_ibs state */ spin_lock_irqsave(&ibs->hci_ibs_lock, flags); @@ -632,7 +632,7 @@ static void ibs_device_woke_up(struct hci_uart *hu) struct ibs_struct *ibs = hu->priv; struct sk_buff *skb = NULL; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); /* lock hci_ibs state */ spin_lock_irqsave(&ibs->hci_ibs_lock, flags); @@ -677,7 +677,7 @@ static int ibs_enqueue(struct hci_uart *hu, struct sk_buff *skb) unsigned long flags = 0; struct ibs_struct *ibs = hu->priv; - BT_DBG("hu %p skb %p", hu, skb); + BT_DBG("hu %pK skb %pK", hu, skb); /* Prepend skb with frame type */ memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); @@ -756,8 +756,8 @@ static int ibs_recv(struct hci_uart *hu, void *data, int count) struct hci_sco_hdr *sh; register int len, type, dlen; - BT_DBG("hu %p count %d rx_state %ld rx_count %ld", - hu, count, ibs->rx_state, ibs->rx_count); + BT_DBG("hu %pK count %d rx_state %ld rx_count %ld", + hu, count, ibs->rx_state, ibs->rx_count); ptr = data; while (count) { From 70d3bad7f7d99c06d23d76bc85bb11e4bb9b1a58 Mon Sep 17 00:00:00 2001 From: Abhijeet Dharmapurikar Date: Thu, 28 Jan 2016 12:09:51 -0800 Subject: [PATCH 110/320] spmi: qpnp-int: prevent a race condition in mask/unmask of interrupts Currently the accesses to the peripheral data's irq enable count is unprotected. The ACC bit in the spmi arbiter represents if any of the eight interrupts in the peripheral is enabled. The counts are used to ensure that the ACC bit for that peripheral is enabled when the first interrupt in the peripheral is unmasked and is disabled when the last interrupt in the peripheral is masked. A race like this could happen. Initial condition: Only two interrupts are enabled in the peripheral. cpu0 cpu1 1. Mask 1st 2. Handle 1st 3. Unmask 1st. Sees that 2nd is unmasked 3. Mask 2nd. Disables ACC 4. Handle 2nd 5. Unmask 1st continues. Skips enabling ACC since it sees that this is not the first interrupt being unmasked. Although it is, since 2nd interrupt was masked after enabled counts were read. 6. Unmask 2nd, sees that 1st is enabled and skips enabling ACC bit 7. After this, the ACC bit for that peripheral remains disabled even when interrupts are in unmasked state at the peripheral. Fix this by ensuring 3 and 5 happen atomically, i.e. the reading of the masked state and the action of enabling/disabling ACC bit should be atomic. CRs-Fixed: 968643 Change-Id: I02cb7b3350d73c9b24b6445a5008f52cbc32cecf Signed-off-by: Abhijeet Dharmapurikar --- drivers/spmi/qpnp-int.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/spmi/qpnp-int.c b/drivers/spmi/qpnp-int.c index 6379528f963d0..5c8d0c8676c64 100644 --- a/drivers/spmi/qpnp-int.c +++ b/drivers/spmi/qpnp-int.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -53,6 +53,7 @@ struct q_perip_data { uint8_t pol_low; /* bitmap */ uint8_t int_en; /* bitmap */ uint8_t use_count; + spinlock_t lock; }; struct q_irq_data { @@ -205,7 +206,7 @@ static void qpnpint_irq_mask(struct irq_data *d) struct q_chip_data *chip_d = irq_d->chip_d; struct q_perip_data *per_d = irq_d->per_d; int rc; - uint8_t prev_int_en = per_d->int_en; + uint8_t prev_int_en; pr_debug("hwirq %lu irq: %d\n", d->hwirq, d->irq); @@ -216,6 +217,8 @@ static void qpnpint_irq_mask(struct irq_data *d) return; } + spin_lock(&per_d->lock); + prev_int_en = per_d->int_en; per_d->int_en &= ~irq_d->mask_shift; if (prev_int_en && !(per_d->int_en)) { @@ -225,6 +228,7 @@ static void qpnpint_irq_mask(struct irq_data *d) */ qpnpint_arbiter_op(d, irq_d, chip_d->cb->mask); } + spin_unlock(&per_d->lock); rc = qpnpint_spmi_write(irq_d, QPNPINT_REG_EN_CLR, (u8 *)&irq_d->mask_shift, 1); @@ -251,7 +255,7 @@ static void qpnpint_irq_unmask(struct irq_data *d) struct q_perip_data *per_d = irq_d->per_d; int rc; uint8_t buf[2]; - uint8_t prev_int_en = per_d->int_en; + uint8_t prev_int_en; pr_debug("hwirq %lu irq: %d\n", d->hwirq, d->irq); @@ -262,6 +266,8 @@ static void qpnpint_irq_unmask(struct irq_data *d) return; } + spin_lock(&per_d->lock); + prev_int_en = per_d->int_en; per_d->int_en |= irq_d->mask_shift; if (!prev_int_en && per_d->int_en) { /* @@ -271,6 +277,7 @@ static void qpnpint_irq_unmask(struct irq_data *d) */ qpnpint_arbiter_op(d, irq_d, chip_d->cb->unmask); } + spin_unlock(&per_d->lock); /* Check the current state of the interrupt enable bit. */ rc = qpnpint_spmi_read(irq_d, QPNPINT_REG_EN_SET, buf, 1); @@ -429,6 +436,7 @@ static struct q_irq_data *qpnpint_alloc_irq_data( rc = -ENOMEM; goto alloc_fail; } + spin_lock_init(&per_d->lock); rc = radix_tree_preload(GFP_KERNEL); if (rc) goto alloc_fail; From 6e6e57c15e7c9284c6e064dd323bac982d4b9493 Mon Sep 17 00:00:00 2001 From: Ping Li Date: Fri, 15 Apr 2016 15:27:36 -0700 Subject: [PATCH 111/320] msm: mdss: Correct block id check for mdss_mdp_misr_table DISPLAY_MISR_LCDC block doesn't have corresponding mdss_mdp_misr_table, this change corrects the block id check for mdss_mdp_misr_table. CRs-Fixed: 1001224 Change-Id: I74b03c31542d4b239eb2ffdc4dc6345dff5eab86 Signed-off-by: Ping Li --- drivers/video/msm/mdss/mdss_debug.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c index 389125e603de5..93b2a213f5f8f 100644 --- a/drivers/video/msm/mdss/mdss_debug.c +++ b/drivers/video/msm/mdss/mdss_debug.c @@ -1058,7 +1058,7 @@ static inline struct mdss_mdp_misr_map *mdss_misr_get_map(u32 block_id, char *ctrl_reg = NULL, *value_reg = NULL; char *intf_base = NULL; - if (block_id > DISPLAY_MISR_MDP) { + if (block_id > DISPLAY_MISR_HDMI && block_id != DISPLAY_MISR_MDP) { pr_err("MISR Block id (%d) out of range\n", block_id); return NULL; } @@ -1146,6 +1146,12 @@ int mdss_misr_set(struct mdss_data_type *mdata, bool is_valid_wb_mixer = true; bool use_mdp_up_misr = false; + if (!mdata || !req || !ctl) { + pr_err("Invalid input params: mdata = %p req = %p ctl = %p", + mdata, req, ctl); + return -EINVAL; + } + map = mdss_misr_get_map(req->block_id, ctl, mdata); if (!map) { From 4aac45ba571eb05d708ee16cd635d754e74a9f5c Mon Sep 17 00:00:00 2001 From: Arumuga Durai A Date: Fri, 27 May 2016 16:36:01 +0530 Subject: [PATCH 112/320] USB: gadget: serial: Fix debugfs crash Serial function driver creates debugfs files even though ports are not allocated. Fetching/reading those files without allocation of ports leads to crash. Check port allocation before creating the files. CRs-Fixed: 1003498 Change-Id: I85b050a261cca6f961d5d9058efb8b7facf242ce Signed-off-by: Arumuga Durai A --- drivers/usb/gadget/u_serial.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 030a47ed55985..7f0c734100a38 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c @@ -1258,6 +1258,9 @@ static ssize_t debug_read_status(struct file *file, char __user *ubuf, int ret; int result = 0; + if (!ui_dev) + return -EINVAL; + tty = ui_dev->port.tty; gser = ui_dev->port_usb; @@ -1310,6 +1313,9 @@ static ssize_t debug_write_reset(struct file *file, const char __user *buf, struct gs_port *ui_dev = file->private_data; unsigned long flags; + if (!ui_dev) + return -EINVAL; + spin_lock_irqsave(&ui_dev->port_lock, flags); ui_dev->nbytes_from_host = ui_dev->nbytes_to_tty = ui_dev->nbytes_from_tty = ui_dev->nbytes_to_host = 0; @@ -1339,6 +1345,9 @@ static void usb_debugfs_init(struct gs_port *ui_dev, int port_num) { char buf[48]; + if (!ui_dev) + return; + snprintf(buf, 48, "usb_serial%d", port_num); gs_dent = debugfs_create_dir(buf, 0); if (!gs_dent || IS_ERR(gs_dent)) From b5742a15f0a6c87e72cc2340140e5c4d45cebe30 Mon Sep 17 00:00:00 2001 From: Sunil Khatri Date: Wed, 27 Apr 2016 18:08:08 +0530 Subject: [PATCH 113/320] msm: kgsl: Check the address range before mapping to GPU Validate the GPU address range for memory mapping request for user allocated buffers before setting the bitmap. This is applicable to the memory mapping specifically when user have used USE_CPU_MAP flag. Change-Id: I7fd30789329939f89b5486d59bdee920616cc6df Signed-off-by: Sunil Khatri --- drivers/gpu/msm/kgsl_mmu.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c index 7a87a3ee27c0b..e68e86b5fc98d 100644 --- a/drivers/gpu/msm/kgsl_mmu.c +++ b/drivers/gpu/msm/kgsl_mmu.c @@ -712,6 +712,10 @@ kgsl_mmu_get_gpuaddr(struct kgsl_pagetable *pagetable, if (kgsl_memdesc_has_guard_page(memdesc)) size += PAGE_SIZE; + if (size < memdesc->size) { + memdesc->size = 0; + return -EINVAL; + } /* * Allocate aligned virtual addresses for iommu. This allows * more efficient pagetable entries if the physical memory @@ -719,8 +723,19 @@ kgsl_mmu_get_gpuaddr(struct kgsl_pagetable *pagetable, */ if (kgsl_memdesc_use_cpu_map(memdesc)) { + uint64_t end = memdesc->gpuaddr + size; if (memdesc->gpuaddr == 0) return -EINVAL; + + /* + * Validate the GPU address range for memory mapping request + * for user allocated buffers before setting the bitmap. + */ + if ((end >= (KGSL_MMU_GLOBAL_MEM_BASE - SZ_1M)) || + (end < memdesc->gpuaddr)) { + memdesc->gpuaddr = 0; + return -EINVAL; + } bitmap_set(pagetable->mem_bitmap, (int) (memdesc->gpuaddr >> PAGE_SHIFT), (int) (size >> PAGE_SHIFT)); From fe16bb01bf192a7f2c4b5f96e894c6cc7e6659d0 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 20 Jan 2015 09:07:05 +1030 Subject: [PATCH 114/320] module: remove mod arg from module_free, rename module_memfree(). Nothing needs the module pointer any more, and the next patch will call it from RCU, where the module itself might no longer exist. Removing the arg is the safest approach. This just codifies the use of the module_alloc/module_free pattern which ftrace and bpf use. Change-Id: I5aaa9922e36ce7eef43b89cfdd803ee3b8434819 Signed-off-by: Rusty Russell Acked-by: Alexei Starovoitov Cc: Mikael Starvik Cc: Jesper Nilsson Cc: Ralf Baechle Cc: Ley Foon Tan Cc: Benjamin Herrenschmidt Cc: Chris Metcalf Cc: Steven Rostedt Cc: x86@kernel.org Cc: Ananth N Mavinakayanahalli Cc: Anil S Keshavamurthy Cc: Masami Hiramatsu Cc: linux-cris-kernel@axis.com Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Cc: nios2-dev@lists.rocketboards.org Cc: linuxppc-dev@lists.ozlabs.org Cc: sparclinux@vger.kernel.org Cc: netdev@vger.kernel.org Git-commit: be1f221c0445a4157d177197c236f888d3581914 Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git [psodagud@codeaurora.org: resolved context conflicts in module.c. Also dropped changes in arch/nios2/kernel/module.c and arch/x86/kernel/ftrace.c files because of dependencies] Signed-off-by: Prasad Sodagudi [neeraju@codeaurora.org: Resolved context conflicts in arch/powerpc/net/ bpf_jit_comp.c, arch/sparc/net/bpf_jit_comp.c. Also, dropped changes in arch/mips/net/bpf_jit.c, kernel/bpf/core.c and updated arch/arm/net/ bpf_jit_32.c] Signed-off-by: Neeraj Upadhyay --- arch/arm/net/bpf_jit_32.c | 2 +- arch/cris/kernel/module.c | 2 +- arch/powerpc/net/bpf_jit_comp.c | 4 ++-- arch/sparc/net/bpf_jit_comp.c | 6 +++--- arch/tile/kernel/module.c | 2 +- include/linux/moduleloader.h | 2 +- kernel/kprobes.c | 2 +- kernel/module.c | 14 +++++++------- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index 6de423dbd3859..6d94cb5a16cc9 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -929,7 +929,7 @@ void bpf_jit_compile(struct sk_filter *fp) static void bpf_jit_free_worker(struct work_struct *work) { - module_free(NULL, work); + module_memfree(work); } void bpf_jit_free(struct sk_filter *fp) diff --git a/arch/cris/kernel/module.c b/arch/cris/kernel/module.c index 51123f985eb58..af04cb6b6dc9a 100644 --- a/arch/cris/kernel/module.c +++ b/arch/cris/kernel/module.c @@ -36,7 +36,7 @@ void *module_alloc(unsigned long size) } /* Free memory returned from module_alloc */ -void module_free(struct module *mod, void *module_region) +void module_memfree(void *module_region) { kfree(module_region); } diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index a012a9747cddb..1a89dfd1c09de 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -691,11 +691,11 @@ void bpf_jit_compile(struct sk_filter *fp) static void jit_free_defer(struct work_struct *arg) { - module_free(NULL, arg); + module_memfree(arg); } /* run from softirq, we must use a work_struct to call - * module_free() from process context + * module_memfree() from process context */ void bpf_jit_free(struct sk_filter *fp) { diff --git a/arch/sparc/net/bpf_jit_comp.c b/arch/sparc/net/bpf_jit_comp.c index 224fc0c71b8a0..7bfb9079a5b84 100644 --- a/arch/sparc/net/bpf_jit_comp.c +++ b/arch/sparc/net/bpf_jit_comp.c @@ -773,7 +773,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf]; if (unlikely(proglen + ilen > oldproglen)) { pr_err("bpb_jit_compile fatal error\n"); kfree(addrs); - module_free(NULL, image); + module_memfree(image); return; } memcpy(image + proglen, temp, ilen); @@ -819,11 +819,11 @@ cond_branch: f_offset = addrs[i + filter[i].jf]; static void jit_free_defer(struct work_struct *arg) { - module_free(NULL, arg); + module_memfree(arg); } /* run from softirq, we must use a work_struct to call - * module_free() from process context + * module_memfree() from process context */ void bpf_jit_free(struct sk_filter *fp) { diff --git a/arch/tile/kernel/module.c b/arch/tile/kernel/module.c index 4918d91bc3a66..0ecbfbc9d3915 100644 --- a/arch/tile/kernel/module.c +++ b/arch/tile/kernel/module.c @@ -74,7 +74,7 @@ void *module_alloc(unsigned long size) /* Free memory returned from module_alloc */ -void module_free(struct module *mod, void *module_region) +void module_memfree(void *module_region) { vfree(module_region); diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h index 560ca53a75fa6..b5b20165ccfea 100644 --- a/include/linux/moduleloader.h +++ b/include/linux/moduleloader.h @@ -26,7 +26,7 @@ unsigned int arch_mod_section_prepend(struct module *mod, unsigned int section); void *module_alloc(unsigned long size); /* Free memory returned from module_alloc. */ -void module_free(struct module *mod, void *module_region); +void module_memfree(void *module_region); /* * Apply the given relocation to the (simplified) ELF. Return -error diff --git a/kernel/kprobes.c b/kernel/kprobes.c index bddf3b201a480..f011c0b9dae34 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -225,7 +225,7 @@ static int __kprobes collect_one_slot(struct kprobe_insn_page *kip, int idx) */ if (!list_is_singular(&kip->list)) { list_del(&kip->list); - module_free(NULL, kip->insns); + module_memfree(kip->insns); kfree(kip); } return 1; diff --git a/kernel/module.c b/kernel/module.c index 49fce4f990a3f..40eda2909a523 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1851,7 +1851,7 @@ static void unset_module_core_ro_nx(struct module *mod) { } static void unset_module_init_ro_nx(struct module *mod) { } #endif -void __weak module_free(struct module *mod, void *module_region) +void __weak module_memfree(void *module_region) { vfree(module_region); } @@ -1890,7 +1890,7 @@ static void free_module(struct module *mod) /* This may be NULL, but that's OK */ unset_module_init_ro_nx(mod); - module_free(mod, mod->module_init); + module_memfree(mod->module_init); kfree(mod->args); percpu_modfree(mod); @@ -1899,7 +1899,7 @@ static void free_module(struct module *mod) /* Finally, free the core (containing the module structure) */ unset_module_core_ro_nx(mod); - module_free(mod, mod->module_core); + module_memfree(mod->module_core); #ifdef CONFIG_MPU update_protections(current->mm); @@ -2848,7 +2848,7 @@ static int move_module(struct module *mod, struct load_info *info) */ kmemleak_ignore(ptr); if (!ptr) { - module_free(mod, mod->module_core); + module_memfree(mod->module_core); return -ENOMEM; } memset(ptr, 0, mod->init_size); @@ -3003,8 +3003,8 @@ static int alloc_module_percpu(struct module *mod, struct load_info *info) static void module_deallocate(struct module *mod, struct load_info *info) { percpu_modfree(mod); - module_free(mod, mod->module_init); - module_free(mod, mod->module_core); + module_memfree(mod->module_init); + module_memfree(mod->module_core); } int __weak module_finalize(const Elf_Ehdr *hdr, @@ -3141,7 +3141,7 @@ static int do_init_module(struct module *mod) rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms); #endif unset_module_init_ro_nx(mod); - module_free(mod, mod->module_init); + module_memfree(mod->module_init); mod->module_init = NULL; mod->init_size = 0; mod->init_ro_size = 0; From 08d914ab254d78cb973a77dd8ce9806188f167b1 Mon Sep 17 00:00:00 2001 From: Rajesh Kemisetti Date: Tue, 31 May 2016 14:41:35 +0530 Subject: [PATCH 115/320] msm: kgsl: Check for integer overflow before allocating memory In _kgsl_sharedmem_page_alloc(), if the requested size is very large then there could be a possibility of integer overflow during memory allocation for scatterlist. To fix this, check for integer overflow condition before allocating the memory. CRs-Fixed: 1005344 Change-Id: I6e0015ab67d6b13fc94d94dafec41788f53820d3 Signed-off-by: Rajesh Kemisetti --- drivers/gpu/msm/kgsl_sharedmem.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c index 45c1cc866a876..f26023d7dcf95 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.c +++ b/drivers/gpu/msm/kgsl_sharedmem.c @@ -621,6 +621,9 @@ _kgsl_sharedmem_page_alloc(struct kgsl_memdesc *memdesc, memdesc->pagetable = pagetable; memdesc->ops = &kgsl_page_alloc_ops; + /* Check for integer overflow */ + if (sglen_alloc && (sizeof(struct scatterlist) > INT_MAX / sglen_alloc)) + return -EINVAL; memdesc->sg = kgsl_malloc(sglen_alloc * sizeof(struct scatterlist)); if (memdesc->sg == NULL) { From 0924e7ceb4d07dc91d548ade7c50d8a15006f0ce Mon Sep 17 00:00:00 2001 From: Josh Kirsch Date: Mon, 2 May 2016 14:55:04 -0700 Subject: [PATCH 116/320] drivers: soc: Add buffer overflow check for svc send request Add buffer overflow check in voice_svc_send_req. CRs-fixed: 1010081 Change-Id: I4ae703334b0cf04f327b392bc9cd6febd4ad32f2 Signed-off-by: Josh Kirsch --- drivers/soc/qcom/qdsp6v2/voice_svc.c | 46 +++++++++++++++++++--------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/drivers/soc/qcom/qdsp6v2/voice_svc.c b/drivers/soc/qcom/qdsp6v2/voice_svc.c index 23b8292c8db5b..67c58d1e6d4cd 100644 --- a/drivers/soc/qcom/qdsp6v2/voice_svc.c +++ b/drivers/soc/qcom/qdsp6v2/voice_svc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -188,7 +188,8 @@ static int voice_svc_send_req(struct voice_svc_cmd_request *apr_request, int ret = 0; void *apr_handle = NULL; struct apr_data *aprdata = NULL; - uint32_t user_payload_size = 0; + uint32_t user_payload_size; + uint32_t payload_size; pr_debug("%s\n", __func__); @@ -200,15 +201,19 @@ static int voice_svc_send_req(struct voice_svc_cmd_request *apr_request, } user_payload_size = apr_request->payload_size; + payload_size = sizeof(struct apr_data) + user_payload_size; - aprdata = kmalloc(sizeof(struct apr_data) + user_payload_size, - GFP_KERNEL); - - if (aprdata == NULL) { - pr_err("%s: aprdata kmalloc failed.\n", __func__); - - ret = -ENOMEM; + if (payload_size <= user_payload_size) { + pr_err("%s: invalid payload size ( 0x%x ).\n", + __func__, user_payload_size); + ret = -EINVAL; goto done; + } else { + aprdata = kmalloc(payload_size, GFP_KERNEL); + if (aprdata == NULL) { + ret = -ENOMEM; + goto done; + } } voice_svc_update_hdr(apr_request, aprdata); @@ -388,18 +393,31 @@ static ssize_t voice_svc_write(struct file *file, const char __user *buf, switch (cmd) { case MSG_REGISTER: - ret = process_reg_cmd( + if (count >= + (sizeof(struct voice_svc_register) + + sizeof(*data))) { + ret = process_reg_cmd( (struct voice_svc_register *)data->payload, prtd); - if (!ret) - ret = count; - + if (!ret) + ret = count; + } else { + pr_err("%s: invalid payload size\n", __func__); + ret = -EINVAL; + goto done; + } break; case MSG_REQUEST: + if (count >= (sizeof(struct voice_svc_cmd_request) + + sizeof(*data))) { ret = voice_svc_send_req( (struct voice_svc_cmd_request *)data->payload, prtd); if (!ret) ret = count; - + } else { + pr_err("%s: invalid payload size\n", __func__); + ret = -EINVAL; + goto done; + } break; default: pr_debug("%s: Invalid command: %u\n", __func__, cmd); From 9a758d8bc94770327df7f07236b0710cdfbf4526 Mon Sep 17 00:00:00 2001 From: Anand Kumar Date: Tue, 21 Jun 2016 17:36:05 +0530 Subject: [PATCH 117/320] wcnss: Avoid user buffer overloading for write cal data compare size of allocated cal data buffer from heap and count bytes provided to write by user to avoid heap overflow for write cal data. Change-Id: Id70c3230f761385489e5e94c613f4519239dfb1f CRs-Fixed: 1032174 Signed-off-by: Anand Kumar --- drivers/net/wireless/wcnss/wcnss_wlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c index 9f3db5c2d6135..0b7c15cf991d9 100644 --- a/drivers/net/wireless/wcnss/wcnss_wlan.c +++ b/drivers/net/wireless/wcnss/wcnss_wlan.c @@ -3206,7 +3206,7 @@ static ssize_t wcnss_wlan_write(struct file *fp, const char __user return -EFAULT; if ((UINT32_MAX - count < penv->user_cal_rcvd) || - MAX_CALIBRATED_DATA_SIZE < count + penv->user_cal_rcvd) { + (penv->user_cal_exp_size < count + penv->user_cal_rcvd)) { pr_err(DEVICE " invalid size to write %zu\n", count + penv->user_cal_rcvd); rc = -ENOMEM; From d3bafe9f0d53c369c241b8b072a511693246b6a7 Mon Sep 17 00:00:00 2001 From: Sunil Khatri Date: Wed, 22 Jun 2016 14:45:31 +0530 Subject: [PATCH 118/320] ashmem: Validate ashmem memory with fops pointer Validate the ashmem memory entry against f_op pointer rather then comparing its name with path of the dentry. This is to avoid any invalid access to ashmem area in cases where some one deliberately set the dentry name to /ashmem. Change-Id: I74e50cd244f68cb13009cf2355e528485f4de34b Signed-off-by: Sunil Khatri --- drivers/staging/android/ashmem.c | 42 +++++++++++++++----------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 5661711b9f554..94a9cc8ff77ec 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -766,11 +766,28 @@ static long compat_ashmem_ioctl(struct file *file, unsigned int cmd, unsigned lo } #endif +static const struct file_operations ashmem_fops = { + .owner = THIS_MODULE, + .open = ashmem_open, + .release = ashmem_release, + .read = ashmem_read, + .llseek = ashmem_llseek, + .mmap = ashmem_mmap, + .unlocked_ioctl = ashmem_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = compat_ashmem_ioctl, +#endif +}; + +static struct miscdevice ashmem_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "ashmem", + .fops = &ashmem_fops, +}; + static int is_ashmem_file(struct file *file) { - char fname[256], *name; - name = dentry_path(file->f_dentry, fname, 256); - return strcmp(name, "/ashmem") ? 0 : 1; + return (file->f_op == &ashmem_fops); } int get_ashmem_file(int fd, struct file **filp, struct file **vm_file, @@ -819,25 +836,6 @@ void put_ashmem_file(struct file *file) } EXPORT_SYMBOL(put_ashmem_file); -static const struct file_operations ashmem_fops = { - .owner = THIS_MODULE, - .open = ashmem_open, - .release = ashmem_release, - .read = ashmem_read, - .llseek = ashmem_llseek, - .mmap = ashmem_mmap, - .unlocked_ioctl = ashmem_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = compat_ashmem_ioctl, -#endif -}; - -static struct miscdevice ashmem_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "ashmem", - .fops = &ashmem_fops, -}; - static int __init ashmem_init(void) { int ret; From b3320048b24a8b515b1d98adfe6d6a6fabd2f263 Mon Sep 17 00:00:00 2001 From: Rajesh Kemisetti Date: Mon, 9 May 2016 22:12:20 +0530 Subject: [PATCH 119/320] msm: kgsl: Add missing checks for alloc size and sglen In _kgsl_sharedmem_page_alloc(), check for boundary limits of requested alloc size before honoring and make sure sglen is greater than zero before marking it as end of sg list. Change-Id: I8b9e225e515a0f31593df6f4cad253236475d0ae Signed-off-by: Rajesh Kemisetti --- drivers/gpu/msm/kgsl_sharedmem.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c index 45c1cc866a876..a4c584b0e3518 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.c +++ b/drivers/gpu/msm/kgsl_sharedmem.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -599,6 +599,10 @@ _kgsl_sharedmem_page_alloc(struct kgsl_memdesc *memdesc, unsigned int align; int step = ((VMALLOC_END - VMALLOC_START)/8) >> PAGE_SHIFT; + size = PAGE_ALIGN(size); + if (size == 0 || size > UINT_MAX) + return -EINVAL; + align = (memdesc->flags & KGSL_MEMALIGN_MASK) >> KGSL_MEMALIGN_SHIFT; page_size = get_page_size(size, align); @@ -702,7 +706,9 @@ _kgsl_sharedmem_page_alloc(struct kgsl_memdesc *memdesc, memdesc->sglen = sglen; memdesc->size = size; - sg_mark_end(&memdesc->sg[sglen - 1]); + + if (sglen > 0) + sg_mark_end(&memdesc->sg[sglen - 1]); /* * All memory that goes to the user has to be zeroed out before it gets From 33e48d1ce31a6a5e33a6e55f862eb947d15c92fe Mon Sep 17 00:00:00 2001 From: Trishansh Bhardwaj Date: Wed, 29 Jun 2016 14:34:31 +0530 Subject: [PATCH 120/320] msm: camera: Fix memory read security flaw Adds bound check on reg_cfg_cmd->u.dmi_info.hi_tbl_offset. IOCTL VIDIOC_MSM_VFE_REG_CFG uses usersupplied value without performing bounds check for following cmd_type. VFE_READ_DMI_16BIT VFE_READ_DMI_32BIT VFE_READ_DMI_64BIT Change-Id: I554c45ef3a172f5b5891b67a7e8e7a1f3f3882ed Signed-off-by: Trishansh Bhardwaj --- drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c index 529757ac48244..74d2eac64d8c0 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c @@ -946,7 +946,8 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev, case VFE_READ_DMI_16BIT: case VFE_READ_DMI_32BIT: case VFE_READ_DMI_64BIT: { - if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT) { + if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT || + reg_cfg_cmd->cmd_type == VFE_READ_DMI_64BIT) { if ((reg_cfg_cmd->u.dmi_info.hi_tbl_offset <= reg_cfg_cmd->u.dmi_info.lo_tbl_offset) || (reg_cfg_cmd->u.dmi_info.hi_tbl_offset - From 8391ff512e893e62396068bf97eeeb1be9bb719a Mon Sep 17 00:00:00 2001 From: Ashish Jain Date: Thu, 30 Jun 2016 18:28:37 +0530 Subject: [PATCH 121/320] ASoC: msm: qdsp6v2: DAP: Allocate param buffer with correct size Size of param buffer should be big enough to hold param length of data and param payload. CRs-Fixed: 1033525 Change-Id: I6fa58f87a7c7df5f0485ea5b368ea090eb8bedb4 Signed-off-by: Ashish Jain --- sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c index 51f8b8c9e4086..f5fa33be19903 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c @@ -1546,7 +1546,8 @@ static int msm_ds2_dap_get_param(u32 cmd, void *arg) pr_debug("%s: port_id 0x%x, copp_idx %d, dev_map[i].device_id %x\n", __func__, port_id, copp_idx, dev_map[i].device_id); - params_value = kzalloc(params_length, GFP_KERNEL); + params_value = kzalloc(params_length + param_payload_len, + GFP_KERNEL); if (!params_value) { pr_err("%s: params memory alloc failed\n", __func__); rc = -ENOMEM; @@ -1570,9 +1571,9 @@ static int msm_ds2_dap_get_param(u32 cmd, void *arg) rc = -EINVAL; goto end; } else { - params_length = (ds2_dap_params_length[i] + - DOLBY_PARAM_PAYLOAD_SIZE) * - sizeof(uint32_t); + params_length = + ds2_dap_params_length[i] * sizeof(uint32_t); + rc = adm_get_params(port_id, copp_idx, DOLBY_BUNDLE_MODULE_ID, ds2_dap_params_id[i], From 999ee5f57bd5bada98d89a025933a38d03b61939 Mon Sep 17 00:00:00 2001 From: Ashish Jain Date: Fri, 1 Jul 2016 12:31:21 +0530 Subject: [PATCH 122/320] ASoC: msm: qdsp6v2: DAP: Add check to validate param length To avoid buffer overflow, validate input length used to fetch visualizer data. CRs-Fixed: 1033540 Change-Id: I445d1ba3bce47308bc31ae24a70d5ee358f22a2d Signed-off-by: Ashish Jain --- sound/soc/msm/qdsp6v2/msm-dolby-common.h | 3 ++- sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/sound/soc/msm/qdsp6v2/msm-dolby-common.h b/sound/soc/msm/qdsp6v2/msm-dolby-common.h index c34a95f78e40d..c510812e4b2bb 100644 --- a/sound/soc/msm/qdsp6v2/msm-dolby-common.h +++ b/sound/soc/msm/qdsp6v2/msm-dolby-common.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2014, 2016 The Linux Foundation. All rights reserved. * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. @@ -232,6 +232,7 @@ #define TOTAL_LENGTH_DOLBY_PARAM 745 #define DOLBY_VIS_PARAM_HEADER_SIZE 25 +#define DOLBY_PARAM_VCNB_MAX_LENGTH 40 #define DOLBY_INVALID_PORT_ID -1 diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c index 51f8b8c9e4086..a18045e8bb86b 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c @@ -1627,6 +1627,13 @@ static int msm_ds2_dap_param_visualizer_control_get(u32 cmd, void *arg) } length = ds2_dap_params[cache_dev].params_val[DOLBY_PARAM_VCNB_OFFSET]; + + if (length > DOLBY_PARAM_VCNB_MAX_LENGTH || length <= 0) { + ret = 0; + dolby_data->length = 0; + pr_err("%s Incorrect VCNB length", __func__); + } + params_length = (2*length + DOLBY_VIS_PARAM_HEADER_SIZE) * sizeof(uint32_t); From 3c09a6105431cfa7f6ec8ce025c002b752e3134d Mon Sep 17 00:00:00 2001 From: Divya Ponnusamy Date: Wed, 15 Jun 2016 16:22:11 +0530 Subject: [PATCH 123/320] staging: android: Change %p to %pK in debug messages The format specifier %p can leak kernel addresses while not valuing the kptr_restrict system settings. Use %pK instead of %p, which also evaluates whether kptr_restrict is set. Change-Id: Ib1adf14e9620ad7b1bd3e962001c852610210d46 Signed-off-by: Divya Ponnusamy --- drivers/staging/android/oneshot_sync.c | 4 ++-- drivers/staging/android/sync.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/android/oneshot_sync.c b/drivers/staging/android/oneshot_sync.c index bc1aad908aa09..6a56ee9d6b062 100644 --- a/drivers/staging/android/oneshot_sync.c +++ b/drivers/staging/android/oneshot_sync.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -286,7 +286,7 @@ int oneshot_fence_signal(struct oneshot_sync_timeline *timeline, } spin_unlock(&timeline->lock); if (ret == -EINVAL) - pr_debug("fence: %p not from this timeline\n", fence); + pr_debug("fence: %pK not from this timeline\n", fence); if (signaled) sync_timeline_signal(&timeline->obj); diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index bcb311b63193d..da8211d1bdfdd 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -696,14 +696,14 @@ int sync_fence_wait(struct sync_fence *fence, long timeout) return err; if (fence->status < 0) { - pr_info("fence error %d on [%p]\n", fence->status, fence); + pr_info("fence error %d on [%pK]\n", fence->status, fence); _sync_fence_log(fence, true); return fence->status; } if (fence->status == 0) { if (timeout > 0) { - pr_info("fence timeout on [%p] after %dms\n", fence, + pr_info("fence timeout on [%pK] after %dms\n", fence, jiffies_to_msecs(timeout)); _sync_fence_log(fence, true); } @@ -989,7 +989,7 @@ static void sync_print_fence(struct seq_file *s, struct sync_fence *fence) struct list_head *pos; unsigned long flags; - seq_printf(s, "[%p] %s: %s\n", fence, fence->name, + seq_printf(s, "[%pK] %s: %s\n", fence, fence->name, sync_status_str(fence->status)); list_for_each(pos, &fence->pt_list_head) { From 326d684627cd8fdd1ad462bd7344245f42764510 Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Fri, 15 Jul 2016 15:57:18 +0530 Subject: [PATCH 124/320] diag: Fix possible kernel addresses leak This patch addresses kernel addresses leak by changing the format specifier to adhere to kptr_restrict system setting. CRs-Fixed: 987013 Change-Id: I32649a26f54d96c56d80aa2a1bd5f5d9dd0dd9d3 Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_dci.c | 16 ++++---- drivers/char/diag/diag_debugfs.c | 54 +++++++++++++-------------- drivers/char/diag/diag_masks.c | 26 ++++++------- drivers/char/diag/diag_memorydevice.c | 4 +- drivers/char/diag/diagchar_core.c | 4 +- drivers/char/diag/diagchar_hdlc.c | 4 +- drivers/char/diag/diagfwd.c | 10 ++--- drivers/char/diag/diagfwd_bridge.c | 4 +- drivers/char/diag/diagfwd_cntl.c | 4 +- drivers/char/diag/diagfwd_hsic.c | 4 +- drivers/char/diag/diagfwd_mhi.c | 10 ++--- 11 files changed, 70 insertions(+), 70 deletions(-) diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index 25b89dd9be3da..cb188b2f49601 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -405,7 +405,7 @@ static int diag_process_single_dci_pkt(unsigned char *buf, int len, uint8_t cmd_code = 0; if (!buf || len < 0) { - pr_err("diag: Invalid input in %s, buf: %p, len: %d\n", + pr_err("diag: Invalid input in %s, buf: %pK, len: %d\n", __func__, buf, len); return -EIO; } @@ -749,7 +749,7 @@ static int diag_dci_remove_req_entry(unsigned char *buf, int len, { uint16_t rsp_count = 0, delayed_rsp_id = 0; if (!buf || len <= 0 || !entry) { - pr_err("diag: In %s, invalid input buf: %p, len: %d, entry: %p\n", + pr_err("diag: In %s, invalid input buf: %pK, len: %d, entry: %pK\n", __func__, buf, len, entry); return -EIO; } @@ -803,7 +803,7 @@ static void dci_process_ctrl_status(unsigned char *buf, int len, int token) int peripheral_mask, status; if (!buf || (len < sizeof(struct diag_ctrl_dci_status))) { - pr_err("diag: In %s, invalid buf %p or length: %d\n", + pr_err("diag: In %s, invalid buf %pK or length: %d\n", __func__, buf, len); return; } @@ -1937,7 +1937,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len) __func__); return -ENOMEM; } - pr_debug("diag: head of dci log mask %p\n", head_log_mask_ptr); + pr_debug("diag: head of dci log mask %pK\n", head_log_mask_ptr); count = 0; /* iterator for extracting log codes */ while (count < num_codes) { @@ -1965,7 +1965,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len) while (log_mask_ptr && (offset < DCI_LOG_MASK_SIZE)) { if (*log_mask_ptr == equip_id) { found = 1; - pr_debug("diag: find equip id = %x at %p\n", + pr_debug("diag: find equip id = %x at %pK\n", equip_id, log_mask_ptr); break; } else { @@ -2043,7 +2043,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len) __func__); return -ENOMEM; } - pr_debug("diag: head of dci event mask %p\n", event_mask_ptr); + pr_debug("diag: head of dci event mask %pK\n", event_mask_ptr); count = 0; /* iterator for extracting log codes */ while (count < num_codes) { if (read_len >= USER_SPACE_DATA) { @@ -3096,7 +3096,7 @@ int diag_dci_write_proc(int peripheral, int pkt_type, char *buf, int len) if (!buf || (peripheral < 0 || peripheral >= NUM_SMD_DCI_CHANNELS) || !driver->rcvd_feature_mask[peripheral] || len < 0) { - pr_err("diag: In %s, invalid data 0x%p, peripheral: %d, len: %d\n", + pr_err("diag: In %s, invalid data 0x%pK, peripheral: %d, len: %d\n", __func__, buf, peripheral, len); return -EINVAL; } diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c index 6916507ec2b15..0812576732321 100644 --- a/drivers/char/diag/diag_debugfs.c +++ b/drivers/char/diag/diag_debugfs.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -50,26 +50,26 @@ static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf, } buf_size = ksize(buf); ret = scnprintf(buf, buf_size, - "modem ch: 0x%p\n" - "lpass ch: 0x%p\n" - "riva ch: 0x%p\n" - "sensors ch: 0x%p\n" - "modem dci ch: 0x%p\n" - "lpass dci ch: 0x%p\n" - "riva dci ch: 0x%p\n" - "sensors dci ch: 0x%p\n" - "modem cntl_ch: 0x%p\n" - "lpass cntl_ch: 0x%p\n" - "riva cntl_ch: 0x%p\n" - "sensors cntl_ch: 0x%p\n" - "modem cmd ch: 0x%p\n" - "adsp cmd ch: 0x%p\n" - "riva cmd ch: 0x%p\n" - "sensors cmd ch: 0x%p\n" - "modem dci cmd ch: 0x%p\n" - "lpass dci cmd ch: 0x%p\n" - "riva dci cmd ch: 0x%p\n" - "sensors dci cmd ch: 0x%p\n" + "modem ch: 0x%pK\n" + "lpass ch: 0x%pK\n" + "riva ch: 0x%pK\n" + "sensors ch: 0x%pK\n" + "modem dci ch: 0x%pK\n" + "lpass dci ch: 0x%pK\n" + "riva dci ch: 0x%pK\n" + "sensors dci ch: 0x%pK\n" + "modem cntl_ch: 0x%pK\n" + "lpass cntl_ch: 0x%pK\n" + "riva cntl_ch: 0x%pK\n" + "sensors cntl_ch: 0x%pK\n" + "modem cmd ch: 0x%pK\n" + "adsp cmd ch: 0x%pK\n" + "riva cmd ch: 0x%pK\n" + "sensors cmd ch: 0x%pK\n" + "modem dci cmd ch: 0x%pK\n" + "lpass dci cmd ch: 0x%pK\n" + "riva dci cmd ch: 0x%pK\n" + "sensors dci cmd ch: 0x%pK\n" "CPU Tools id: %d\n" "Apps only: %d\n" "Apps master: %d\n" @@ -723,7 +723,7 @@ static ssize_t diag_dbgfs_read_usbinfo(struct file *file, char __user *ubuf, bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining, "id: %d\n" "name: %s\n" - "hdl: %p\n" + "hdl: %pK\n" "connected: %d\n" "enabled: %d\n" "mempool: %s\n" @@ -865,9 +865,9 @@ static ssize_t diag_dbgfs_read_mhiinfo(struct file *file, char __user *ubuf, "bridge index: %s\n" "mempool: %s\n" "read ch opened: %d\n" - "read ch hdl: %p\n" + "read ch hdl: %pK\n" "write ch opened: %d\n" - "write ch hdl: %p\n" + "write ch hdl: %pK\n" "read work pending: %d\n" "read done work pending: %d\n" "open work pending: %d\n" @@ -936,9 +936,9 @@ static ssize_t diag_dbgfs_read_bridge(struct file *file, char __user *ubuf, "type: %d\n" "inited: %d\n" "ctxt: %d\n" - "dev_ops: %p\n" - "dci_read_buf: %p\n" - "dci_read_ptr: %p\n" + "dev_ops: %pK\n" + "dci_read_buf: %pK\n" + "dci_read_ptr: %pK\n" "dci_read_len: %d\n\n", info->id, info->name, diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c index 7c0f103b2fbe9..c007cb568fd48 100644 --- a/drivers/char/diag/diag_masks.c +++ b/drivers/char/diag/diag_masks.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -386,7 +386,7 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len, struct diag_ssid_range_t ssid_range; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -430,7 +430,7 @@ static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len, struct diag_msg_build_mask_t rsp; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -483,7 +483,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len, struct diag_msg_build_mask_t rsp; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -535,7 +535,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, uint32_t *temp = NULL; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -628,7 +628,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len, struct diag_msg_mask_t *mask = (struct diag_msg_mask_t *)msg_mask.ptr; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -674,7 +674,7 @@ static int diag_cmd_get_event_mask(unsigned char *src_buf, int src_len, struct diag_event_mask_config_t rsp; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -712,7 +712,7 @@ static int diag_cmd_update_event_mask(unsigned char *src_buf, int src_len, struct diag_event_mask_config_t *req; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -759,7 +759,7 @@ static int diag_cmd_toggle_events(unsigned char *src_buf, int src_len, struct diag_event_report_t header; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -805,7 +805,7 @@ static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len, struct diag_log_config_rsp_t rsp; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -875,7 +875,7 @@ static int diag_cmd_get_log_range(unsigned char *src_buf, int src_len, return 0; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -913,7 +913,7 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len, struct diag_log_config_set_rsp_t rsp; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -992,7 +992,7 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len, int i; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } diff --git a/drivers/char/diag/diag_memorydevice.c b/drivers/char/diag/diag_memorydevice.c index f00f2a9bc0103..53982079b90dd 100644 --- a/drivers/char/diag/diag_memorydevice.c +++ b/drivers/char/diag/diag_memorydevice.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -142,7 +142,7 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx) if (ch->tbl[i].buf != buf) continue; found = 1; - pr_err_ratelimited("diag: trying to write the same buffer buf: %p, ctxt: %d len: %d at i: %d back to the table, proc: %d, mode: %d\n", + pr_err_ratelimited("diag: trying to write the same buffer buf: %pK, ctxt: %d len: %d at i: %d back to the table, proc: %d, mode: %d\n", buf, ctx, ch->tbl[i].len, i, id, driver->logging_mode); } diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index bb14523f2ec3a..ffb34fb54a6a7 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -706,7 +706,7 @@ static int diag_process_userspace_remote(int proc, void *buf, int len) int bridge_index = proc - 1; if (!buf || len < 0) { - pr_err("diag: Invalid input in %s, buf: %p, len: %d\n", + pr_err("diag: Invalid input in %s, buf: %pK, len: %d\n", __func__, buf, len); return -EINVAL; } diff --git a/drivers/char/diag/diagchar_hdlc.c b/drivers/char/diag/diagchar_hdlc.c index 39f1f4487467c..4a6de7381793c 100644 --- a/drivers/char/diag/diagchar_hdlc.c +++ b/drivers/char/diag/diagchar_hdlc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2009, 2012-2013, The Linux Foundation. +/* Copyright (c) 2008-2009, 2012-2013, 2016, The Linux Foundation. * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -242,7 +242,7 @@ int crc_check(uint8_t *buf, uint16_t len) * of data and 3 bytes for CRC */ if (!buf || len < 4) { - pr_err_ratelimited("diag: In %s, invalid packet or length, buf: 0x%p, len: %d", + pr_err_ratelimited("diag: In %s, invalid packet or length, buf: 0x%pK, len: %d", __func__, buf, len); return -EIO; } diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c index cbb9dbc2db1ae..19e38d4800a07 100644 --- a/drivers/char/diag/diagfwd.c +++ b/drivers/char/diag/diagfwd.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -810,7 +810,7 @@ void diag_update_pkt_buffer(unsigned char *buf, int type) } if (!ptr || length == 0) { - pr_err("diag: Invalid ptr %p and length %d in %s", + pr_err("diag: Invalid ptr %pK and length %d in %s", ptr, length, __func__); return; } @@ -923,7 +923,7 @@ int diag_process_stm_cmd(unsigned char *buf, unsigned char *dest_buf) int i; if (!buf || !dest_buf) { - pr_err("diag: Invalid pointers buf: %p, dest_buf %p in %s\n", + pr_err("diag: Invalid pointers buf: %pK, dest_buf %pK in %s\n", buf, dest_buf, __func__); return -EIO; } @@ -1011,7 +1011,7 @@ int diag_cmd_log_on_demand(unsigned char *src_buf, int src_len, return 0; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -2038,7 +2038,7 @@ int diag_smd_write(struct diag_smd_info *smd_info, void *buf, int len) int max_retries = 3; if (!smd_info || !buf || len <= 0) { - pr_err_ratelimited("diag: In %s, invalid params, smd_info: %p, buf: %p, len: %d\n", + pr_err_ratelimited("diag: In %s, invalid params, smd_info: %pK, buf: %pK, len: %d\n", __func__, smd_info, buf, len); return -EINVAL; } diff --git a/drivers/char/diag/diagfwd_bridge.c b/drivers/char/diag/diagfwd_bridge.c index f6aa7962d5167..633cd9983e018 100644 --- a/drivers/char/diag/diagfwd_bridge.c +++ b/drivers/char/diag/diagfwd_bridge.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -133,7 +133,7 @@ int diagfwd_bridge_register(int id, int ctxt, struct diag_remote_dev_ops *ops) char wq_name[DIAG_BRIDGE_NAME_SZ + 10]; if (!ops) { - pr_err("diag: Invalid pointers ops: %p ctxt: %d\n", ops, ctxt); + pr_err("diag: Invalid pointers ops: %pK ctxt: %d\n", ops, ctxt); return -EINVAL; } diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c index 55ce976da9876..cf7284401b6ba 100644 --- a/drivers/char/diag/diagfwd_cntl.c +++ b/drivers/char/diag/diagfwd_cntl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -836,7 +836,7 @@ int diag_send_diag_mode_update_by_smd(struct diag_smd_info *smd_info, int err = 0; if (!smd_info || smd_info->type != SMD_CNTL_TYPE) { - pr_err("diag: In %s, invalid channel info, smd_info: %p type: %d\n", + pr_err("diag: In %s, invalid channel info, smd_info: %pK type: %d\n", __func__, smd_info, ((smd_info) ? smd_info->type : -1)); return -EIO; diff --git a/drivers/char/diag/diagfwd_hsic.c b/drivers/char/diag/diagfwd_hsic.c index 987931fdc7626..df9b9a6e37d1d 100644 --- a/drivers/char/diag/diagfwd_hsic.c +++ b/drivers/char/diag/diagfwd_hsic.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -354,7 +354,7 @@ static int hsic_write(int id, unsigned char *buf, int len, int ctxt) return -EINVAL; } if (!buf || len <= 0) { - pr_err_ratelimited("diag: In %s, ch %d, invalid buf %p len %d\n", + pr_err_ratelimited("diag: In %s, ch %d, invalid buf %pK len %d\n", __func__, id, buf, len); return -EINVAL; } diff --git a/drivers/char/diag/diagfwd_mhi.c b/drivers/char/diag/diagfwd_mhi.c index a2bea81449161..0178153db8b6a 100644 --- a/drivers/char/diag/diagfwd_mhi.c +++ b/drivers/char/diag/diagfwd_mhi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -133,7 +133,7 @@ static int mhi_buf_tbl_add(struct diag_mhi_info *mhi_info, int type, item = kzalloc(sizeof(struct diag_mhi_buf_tbl_t), GFP_KERNEL); if (!item) { - pr_err_ratelimited("diag: In %s, unable to allocate new item for buf tbl, ch: %p, type: %d, buf: %p, len: %d\n", + pr_err_ratelimited("diag: In %s, unable to allocate new item for buf tbl, ch: %pK, type: %d, buf: %pK, len: %d\n", __func__, ch, ch->type, buf, len); return -ENOMEM; } @@ -187,7 +187,7 @@ static void mhi_buf_tbl_remove(struct diag_mhi_info *mhi_info, int type, spin_unlock_irqrestore(&ch->lock, flags); if (!found) { - pr_err_ratelimited("diag: In %s, unable to find buffer, ch: %p, type: %d, buf: %p\n", + pr_err_ratelimited("diag: In %s, unable to find buffer, ch: %pK, type: %d, buf: %pK\n", __func__, ch, ch->type, buf); } } @@ -443,7 +443,7 @@ static int mhi_write(int id, unsigned char *buf, int len, int ctxt) } if (!buf || len <= 0) { - pr_err("diag: In %s, ch %d, invalid buf %p len %d\n", + pr_err("diag: In %s, ch %d, invalid buf %pK len %d\n", __func__, id, buf, len); return -EINVAL; } @@ -473,7 +473,7 @@ static int mhi_write(int id, unsigned char *buf, int len, int ctxt) err = mhi_queue_xfer(ch->hdl, dma_addr, len, flags); if (err) { - pr_err_ratelimited("diag: In %s, cannot write to MHI channel %p, len %d, err: %d\n", + pr_err_ratelimited("diag: In %s, cannot write to MHI channel %pK, len %d, err: %d\n", __func__, diag_mhi[id].name, len, err); dma_unmap_single(NULL, (dma_addr_t)dma_addr, len, DMA_TO_DEVICE); From f2ac394643b6ecc55d9e8d33ea1a5991d7cabadc Mon Sep 17 00:00:00 2001 From: Adrian Salido-Moreno Date: Sat, 15 Nov 2014 19:06:06 -0800 Subject: [PATCH 125/320] msm: mdss: avoid any hdmi update during cont splash screen handoff While continuous splash screen is in progress need to ensure that other display devices such as HDMI don't come in and modify state of clocks and votes before handoff completed. Change-Id: Ia85c4805b38080adecc5025affea37c392b11071 Signed-off-by: Adrian Salido-Moreno --- drivers/video/msm/mdss/mdss_mdp_overlay.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c index 5976753e111f3..af5864b156bde 100644 --- a/drivers/video/msm/mdss/mdss_mdp_overlay.c +++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c @@ -1224,6 +1224,10 @@ int mdss_mdp_overlay_start(struct msm_fb_data_type *mfd) mfd->index); return 0; } + } else if (mdata->handoff_pending) { + pr_warn("fb%d: commit while splash handoff pending\n", + mfd->index); + return -EPERM; } pr_debug("starting fb%d overlay\n", mfd->index); From 926373d9d67d3d4aff593c9cbc7c81070d779b12 Mon Sep 17 00:00:00 2001 From: Nikhilesh Reddy Date: Fri, 15 May 2015 16:03:01 -0700 Subject: [PATCH 126/320] fuse: Add support for shortcircuited read/write for files Add support for shortcircuited read/write for files when enabled through a userspace init option of FUSE_SHORTCIRCUIT. When FUSE_SHORTCIRCUIT is enabled all the reads and writes to the fuse mount point go directly to the native filesystem rather than through the fuse daemon. All requsts that aren't read/write still go thought the userspace code. This allows for significantly better performance on read and writes and the difference between fuse and the native lower filesystem is negligible. Change-Id: I8258f356963505a2f8499f38879e9e36aba43ad4 Signed-off-by: Nikhilesh Reddy --- fs/fuse/Makefile | 2 +- fs/fuse/dev.c | 3 ++ fs/fuse/dir.c | 3 ++ fs/fuse/file.c | 33 ++++++++++-- fs/fuse/fuse_i.h | 9 ++++ fs/fuse/fuse_shortcircuit.h | 33 ++++++++++++ fs/fuse/inode.c | 4 ++ fs/fuse/shortcircuit.c | 105 ++++++++++++++++++++++++++++++++++++ include/uapi/linux/fuse.h | 4 +- 9 files changed, 191 insertions(+), 5 deletions(-) create mode 100644 fs/fuse/fuse_shortcircuit.h create mode 100644 fs/fuse/shortcircuit.c diff --git a/fs/fuse/Makefile b/fs/fuse/Makefile index e95eeb445e587..15b0b7edbec01 100644 --- a/fs/fuse/Makefile +++ b/fs/fuse/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_FUSE_FS) += fuse.o obj-$(CONFIG_CUSE) += cuse.o -fuse-objs := dev.o dir.o file.o inode.o control.o +fuse-objs := dev.o dir.o file.o inode.o control.o shortcircuit.o diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index f4e875a29e7aa..8121e6aa3fa67 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -7,6 +7,7 @@ */ #include "fuse_i.h" +#include "fuse_shortcircuit.h" #include #include @@ -1876,6 +1877,8 @@ static ssize_t fuse_dev_do_write(struct fuse_conn *fc, err = copy_out_args(cs, &req->out, nbytes); fuse_copy_finish(cs); + fuse_setup_shortcircuit(fc, req); + spin_lock(&fc->lock); req->locked = 0; if (!err) { diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 28fa6811f6a6d..5f7df9946785e 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -472,6 +472,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, if (err) goto out_free_ff; + if (req->private_lower_rw_file != NULL) + ff->rw_lower_file = req->private_lower_rw_file; + err = -EIO; if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid)) goto out_free_ff; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 8282b423e18e0..540d50d131f22 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -7,6 +7,7 @@ */ #include "fuse_i.h" +#include "fuse_shortcircuit.h" #include #include @@ -21,7 +22,8 @@ static const struct file_operations fuse_direct_io_file_operations; static int fuse_send_open(struct fuse_conn *fc, u64 nodeid, struct file *file, - int opcode, struct fuse_open_out *outargp) + int opcode, struct fuse_open_out *outargp, + struct file **lower_file) { struct fuse_open_in inarg; struct fuse_req *req; @@ -45,6 +47,10 @@ static int fuse_send_open(struct fuse_conn *fc, u64 nodeid, struct file *file, req->out.args[0].value = outargp; fuse_request_send(fc, req); err = req->out.h.error; + + if (!err && req->private_lower_rw_file != NULL) + *lower_file = req->private_lower_rw_file; + fuse_put_request(fc, req); return err; @@ -58,6 +64,7 @@ struct fuse_file *fuse_file_alloc(struct fuse_conn *fc) if (unlikely(!ff)) return NULL; + ff->rw_lower_file = NULL; ff->fc = fc; ff->reserved_req = fuse_request_alloc(0); if (unlikely(!ff->reserved_req)) { @@ -153,7 +160,8 @@ int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file, if (!ff) return -ENOMEM; - err = fuse_send_open(fc, nodeid, file, opcode, &outarg); + err = fuse_send_open(fc, nodeid, file, opcode, &outarg, + &(ff->rw_lower_file)); if (err) { fuse_file_free(ff); return err; @@ -261,6 +269,8 @@ void fuse_release_common(struct file *file, int opcode) if (unlikely(!ff)) return; + fuse_shortcircuit_release(ff); + req = ff->reserved_req; fuse_prepare_release(ff, file->f_flags, opcode); @@ -959,8 +969,10 @@ static int fuse_readpages(struct file *file, struct address_space *mapping, static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos) { + ssize_t ret_val; struct inode *inode = iocb->ki_filp->f_mapping->host; struct fuse_conn *fc = get_fuse_conn(inode); + struct fuse_file *ff = iocb->ki_filp->private_data; /* * In auto invalidate mode, always update attributes on read. @@ -975,7 +987,12 @@ static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov, return err; } - return generic_file_aio_read(iocb, iov, nr_segs, pos); + if (ff && ff->rw_lower_file) + ret_val = fuse_shortcircuit_aio_read(iocb, iov, nr_segs, pos); + else + ret_val = generic_file_aio_read(iocb, iov, nr_segs, pos); + + return ret_val; } static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff, @@ -1213,6 +1230,7 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, { struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; + struct fuse_file *ff = file->private_data; size_t count = 0; size_t ocount = 0; ssize_t written = 0; @@ -1222,6 +1240,15 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, struct iov_iter i; loff_t endbyte = 0; + if (ff && ff->rw_lower_file) { + /* Update size (EOF optimization) and mode (SUID clearing) */ + err = fuse_update_attributes(mapping->host, NULL, file, NULL); + if (err) + return err; + + return fuse_shortcircuit_aio_write(iocb, iov, nr_segs, pos); + } + if (get_fuse_conn(inode)->writeback_cache) { /* Update size (EOF optimization) and mode (SUID clearing) */ err = fuse_update_attributes(mapping->host, NULL, file, NULL); diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index fba925b6a7bd5..e4457b68c58a4 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -157,6 +157,9 @@ struct fuse_file { /** Has flock been performed on this file? */ bool flock:1; + + /* the read write file */ + struct file *rw_lower_file; }; /** One input argument of a request */ @@ -361,6 +364,9 @@ struct fuse_req { /** Request is stolen from fuse_file->reserved_req */ struct file *stolen_file; + + /** fuse shortcircuit file */ + struct file *private_lower_rw_file; }; /** @@ -483,6 +489,9 @@ struct fuse_conn { /** write-back cache policy (default is write-through) */ unsigned writeback_cache:1; + /** Shortcircuited IO. */ + unsigned shortcircuit_io:1; + /* * The following bitfields are only for optimization purposes * and hence races in setting them will not cause malfunction diff --git a/fs/fuse/fuse_shortcircuit.h b/fs/fuse/fuse_shortcircuit.h new file mode 100644 index 0000000000000..5f269f9667f24 --- /dev/null +++ b/fs/fuse/fuse_shortcircuit.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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 _FS_FUSE_SHORCIRCUIT_H +#define _FS_FUSE_SHORCIRCUIT_H + +#include "fuse_i.h" + +#include +#include + +void fuse_setup_shortcircuit(struct fuse_conn *fc, struct fuse_req *req); + +ssize_t fuse_shortcircuit_aio_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos); + +ssize_t fuse_shortcircuit_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos); + +void fuse_shortcircuit_release(struct fuse_file *ff); + +#endif /* _FS_FUSE_SHORCIRCUIT_H */ diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 7db940568fb04..7cf8dcc9e03cf 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -891,6 +891,10 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) fc->async_dio = 1; if (arg->flags & FUSE_WRITEBACK_CACHE) fc->writeback_cache = 1; + if (arg->flags & FUSE_SHORTCIRCUIT) { + fc->writeback_cache = 0; + fc->shortcircuit_io = 1; + } if (arg->time_gran && arg->time_gran <= 1000000000) fc->sb->s_time_gran = arg->time_gran; else diff --git a/fs/fuse/shortcircuit.c b/fs/fuse/shortcircuit.c new file mode 100644 index 0000000000000..f24d2fbf6237c --- /dev/null +++ b/fs/fuse/shortcircuit.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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 "fuse_shortcircuit.h" + +#include + +void fuse_setup_shortcircuit(struct fuse_conn *fc, struct fuse_req *req) +{ + int daemon_fd; + struct file *rw_lower_file = NULL; + struct fuse_open_out *open_out; + int open_out_index; + + req->private_lower_rw_file = NULL; + + if (!(fc->shortcircuit_io)) + return; + + if ((req->in.h.opcode != FUSE_OPEN) && + (req->in.h.opcode != FUSE_CREATE)) + return; + + open_out_index = req->in.numargs - 1; + + BUG_ON(open_out_index != 0 && open_out_index != 1); + BUG_ON(req->out.args[open_out_index].size != sizeof(*open_out)); + + open_out = req->out.args[open_out_index].value; + + daemon_fd = (int)open_out->lower_fd; + if (daemon_fd < 0) + return; + + rw_lower_file = fget_raw(daemon_fd); + if (!rw_lower_file) + return; + req->private_lower_rw_file = rw_lower_file; +} + +static ssize_t fuse_shortcircuit_aio_read_write(struct kiocb *iocb, + const struct iovec *iov, + unsigned long nr_segs, + loff_t pos, int do_write) +{ + ssize_t ret_val; + struct fuse_file *ff = iocb->ki_filp->private_data; + struct file *fuse_file, *lower_file; + + fuse_file = iocb->ki_filp; + lower_file = ff->rw_lower_file; + + /* lock lower file to prevent it from being released */ + get_file(lower_file); + iocb->ki_filp = lower_file; + + if (do_write) { + if (!lower_file->f_op->aio_write) + return -EIO; + ret_val = lower_file->f_op->aio_write(iocb, iov, nr_segs, pos); + } else { + if (!lower_file->f_op->aio_read) + return -EIO; + ret_val = lower_file->f_op->aio_read(iocb, iov, nr_segs, pos); + } + + iocb->ki_filp = fuse_file; + fput(lower_file); + /* unlock lower file */ + + return ret_val; +} + +ssize_t fuse_shortcircuit_aio_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) +{ + return fuse_shortcircuit_aio_read_write(iocb, iov, nr_segs, pos, 0); +} + +ssize_t fuse_shortcircuit_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) +{ + return fuse_shortcircuit_aio_read_write(iocb, iov, nr_segs, pos, 1); +} + +void fuse_shortcircuit_release(struct fuse_file *ff) +{ + if (!(ff->rw_lower_file)) + return; + + /* Release the lower file. */ + fput(ff->rw_lower_file); + ff->rw_lower_file = NULL; +} diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h index d1b4e2ca9672e..bafd0d840bb7f 100644 --- a/include/uapi/linux/fuse.h +++ b/include/uapi/linux/fuse.h @@ -244,6 +244,8 @@ struct fuse_file_lock { #define FUSE_ASYNC_DIO (1 << 15) #define FUSE_WRITEBACK_CACHE (1 << 16) +#define FUSE_SHORTCIRCUIT (1 << 31) + /** * CUSE INIT request/reply flags * @@ -466,7 +468,7 @@ struct fuse_create_in { struct fuse_open_out { uint64_t fh; uint32_t open_flags; - uint32_t padding; + int32_t lower_fd;/* lower layer file descriptor */ }; struct fuse_release_in { From a435e227b717d5bc5fc91a271030d0c369247d84 Mon Sep 17 00:00:00 2001 From: Nikhilesh Reddy Date: Sun, 28 Jun 2015 20:53:30 -0700 Subject: [PATCH 127/320] fs:fuse: Ensure update of fuse inode attributes in shortcircuit Ensure that in shortcircuit mode the fuse inode attributes always reflect those of the native filesystem by forcing an attribute copy. Change-Id: Ie4d322c9b8e0d3b49d195801dab4cc86d8df11e2 Signed-off-by: Nikhilesh Reddy --- fs/fuse/file.c | 14 +++++--------- fs/fuse/inode.c | 2 ++ fs/fuse/shortcircuit.c | 16 +++++++++++++++- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 540d50d131f22..b70aca3ca350e 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1240,15 +1240,6 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, struct iov_iter i; loff_t endbyte = 0; - if (ff && ff->rw_lower_file) { - /* Update size (EOF optimization) and mode (SUID clearing) */ - err = fuse_update_attributes(mapping->host, NULL, file, NULL); - if (err) - return err; - - return fuse_shortcircuit_aio_write(iocb, iov, nr_segs, pos); - } - if (get_fuse_conn(inode)->writeback_cache) { /* Update size (EOF optimization) and mode (SUID clearing) */ err = fuse_update_attributes(mapping->host, NULL, file, NULL); @@ -1286,6 +1277,11 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, if (err) goto out; + if (ff && ff->rw_lower_file) { + written = fuse_shortcircuit_aio_write(iocb, iov, nr_segs, pos); + goto out; + } + if (file->f_flags & O_DIRECT) { written = generic_file_direct_write(iocb, iov, &nr_segs, pos, &iocb->ki_pos, diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 7cf8dcc9e03cf..190647eeaa95e 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -894,6 +894,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) if (arg->flags & FUSE_SHORTCIRCUIT) { fc->writeback_cache = 0; fc->shortcircuit_io = 1; + pr_info("FUSE: SHORTCIRCUIT enabled [%s : %d]!\n", + current->comm, current->pid); } if (arg->time_gran && arg->time_gran <= 1000000000) fc->sb->s_time_gran = arg->time_gran; diff --git a/fs/fuse/shortcircuit.c b/fs/fuse/shortcircuit.c index f24d2fbf6237c..cf13c38d4a2e3 100644 --- a/fs/fuse/shortcircuit.c +++ b/fs/fuse/shortcircuit.c @@ -15,6 +15,7 @@ #include "fuse_shortcircuit.h" #include +#include void fuse_setup_shortcircuit(struct fuse_conn *fc, struct fuse_req *req) { @@ -55,24 +56,37 @@ static ssize_t fuse_shortcircuit_aio_read_write(struct kiocb *iocb, loff_t pos, int do_write) { ssize_t ret_val; - struct fuse_file *ff = iocb->ki_filp->private_data; + struct fuse_file *ff; struct file *fuse_file, *lower_file; + struct inode *fuse_inode, *lower_inode; + ff = iocb->ki_filp->private_data; fuse_file = iocb->ki_filp; lower_file = ff->rw_lower_file; /* lock lower file to prevent it from being released */ get_file(lower_file); iocb->ki_filp = lower_file; + fuse_inode = fuse_file->f_path.dentry->d_inode; + lower_inode = file_inode(lower_file); if (do_write) { if (!lower_file->f_op->aio_write) return -EIO; + ret_val = lower_file->f_op->aio_write(iocb, iov, nr_segs, pos); + + if (ret_val >= 0 || ret_val == -EIOCBQUEUED) { + fsstack_copy_inode_size(fuse_inode, lower_inode); + fsstack_copy_attr_times(fuse_inode, lower_inode); + } } else { if (!lower_file->f_op->aio_read) return -EIO; + ret_val = lower_file->f_op->aio_read(iocb, iov, nr_segs, pos); + if (ret_val >= 0 || ret_val == -EIOCBQUEUED) + fsstack_copy_attr_atime(fuse_inode, lower_inode); } iocb->ki_filp = fuse_file; From ee0fc760f2f32c53d19174e34893a20fd29365ac Mon Sep 17 00:00:00 2001 From: Nikhilesh Reddy Date: Sat, 22 Aug 2015 11:47:56 -0700 Subject: [PATCH 128/320] fuse: Use iocb->ki_pos instead of pos for shortcircuit writes Use iocb->ki_pos instead of pos to handle the cases of files that are opened with O_APPEND. For example if multiple processes open the same file with O_APPEND then the iocb->ki_pos will not be equal to the new pos value that is updated with the file size(to guarantee appends even when the file has grown due to the writes by another process). We should use iocb->pos here since the lower filesystem is expected to adjust for O_APPEND anyway and may need to adjust the size for the file changes that occur due to some processes writing directly to the lower filesystem. Change-Id: I279e3ea96cdfd020c45f4cd348f6e1b4bd48a3fb Signed-off-by: Nikhilesh Reddy --- fs/fuse/file.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index b70aca3ca350e..33f9c5471a8a7 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1278,7 +1278,20 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, goto out; if (ff && ff->rw_lower_file) { - written = fuse_shortcircuit_aio_write(iocb, iov, nr_segs, pos); + /* Use iocb->ki_pos instead of pos to handle the cases of files + * that are opened with O_APPEND. For example if multiple + * processes open the same file with O_APPEND then the + * iocb->ki_pos will not be equal to the new pos value that is + * updated with the file size(to guarantee appends even when + * the file has grown due to the writes by another process). + * We should use iocb->pos here since the lower filesystem + * is expected to adjust for O_APPEND anyway and may need to + * adjust the size for the file changes that occur due to + * some processes writing directly to the lower filesystem + * without using fuse. + */ + written = fuse_shortcircuit_aio_write(iocb, iov, nr_segs, + iocb->ki_pos); goto out; } From 15f6f377f97b51238104d6c690398704e8a91806 Mon Sep 17 00:00:00 2001 From: Nikhilesh Reddy Date: Fri, 21 Aug 2015 18:24:51 -0700 Subject: [PATCH 129/320] fuse: Use BUG_ON to check pos validity in fuse_aio_write Change the check that iocb->ki_pos should be equal to pos to a BUG_ON from a WARN_ON to ensure we actually catch the bug before it propagates down and causes other errors. Change-Id: Ie6d537f3182f638a50166b456226e9c10bb1e3d4 Signed-off-by: Nikhilesh Reddy --- fs/fuse/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 33f9c5471a8a7..c1a4eb8052ff3 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1249,7 +1249,7 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, return generic_file_aio_write(iocb, iov, nr_segs, pos); } - WARN_ON(iocb->ki_pos != pos); + BUG_ON(iocb->ki_pos != pos); ocount = 0; err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); From 8007aebb6810f901cea866b7987d5fee9cef067c Mon Sep 17 00:00:00 2001 From: Nikhilesh Reddy Date: Thu, 20 Aug 2015 17:39:21 -0700 Subject: [PATCH 130/320] fs: Workaround the compiler's bad optimization When compiling the kernel with the compiler "aarch64-linux-android-gcc (GCC) 4.9.x-google 20140827 (prerelease)" The compiler seems to be optimizing a value out in the do_sync_write function and is incorrectly passing the pointer instead of the dereferenced value. Force the compiler to use the right value by passing the dereferenced pointer instead of another variable that is assigned with the dereferenced value. Change-Id: I60505ffe39393f6323dcc7c6f912c74ea6aca6cd Signed-off-by: Nikhilesh Reddy --- fs/read_write.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/read_write.c b/fs/read_write.c index 1653768438362..d77987d787e95 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -411,7 +411,7 @@ ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, lof kiocb.ki_left = len; kiocb.ki_nbytes = len; - ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); + ret = filp->f_op->aio_write(&kiocb, &iov, 1, *ppos); if (-EIOCBQUEUED == ret) ret = wait_on_sync_kiocb(&kiocb); *ppos = kiocb.ki_pos; From cb57cc59db92f4db1df6bddf617b9c5b4a22f4a9 Mon Sep 17 00:00:00 2001 From: Anand Kumar Date: Tue, 21 Jun 2016 17:36:05 +0530 Subject: [PATCH 131/320] wcnss: Avoid user buffer overloading for write cal data compare size of allocated cal data buffer from heap and count bytes provided to write by user to avoid heap overflow for write cal data. Change-Id: Id70c3230f761385489e5e94c613f4519239dfb1f CRs-Fixed: 1032174 Signed-off-by: Anand Kumar --- drivers/net/wireless/wcnss/wcnss_wlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c index 9f3db5c2d6135..0b7c15cf991d9 100644 --- a/drivers/net/wireless/wcnss/wcnss_wlan.c +++ b/drivers/net/wireless/wcnss/wcnss_wlan.c @@ -3206,7 +3206,7 @@ static ssize_t wcnss_wlan_write(struct file *fp, const char __user return -EFAULT; if ((UINT32_MAX - count < penv->user_cal_rcvd) || - MAX_CALIBRATED_DATA_SIZE < count + penv->user_cal_rcvd) { + (penv->user_cal_exp_size < count + penv->user_cal_rcvd)) { pr_err(DEVICE " invalid size to write %zu\n", count + penv->user_cal_rcvd); rc = -ENOMEM; From d2bab70977b144a53711f629ff67aeba0c678ca8 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 14 Jan 2016 16:30:58 +0100 Subject: [PATCH 132/320] ALSA: timer: Harden slave timer list handling A slave timer instance might be still accessible in a racy way while operating the master instance as it lacks of locking. Since the master operation is mostly protected with timer->lock, we should cope with it while changing the slave instance, too. Also, some linked lists (active_list and ack_list) of slave instances aren't unlinked immediately at stopping or closing, and this may lead to unexpected accesses. This patch tries to address these issues. It adds spin lock of timer->lock (either from master or slave, which is equivalent) in a few places. For avoiding a deadlock, we ensure that the global slave_active_lock is always locked at first before each timer lock. Also, ack and active_list of slave instances are properly unlinked at snd_timer_stop() and snd_timer_close(). Last but not least, remove the superfluous call of _snd_timer_stop() at removing slave links. This is a noop, and calling it may confuse readers wrt locking. Further cleanup will follow in a later patch. Actually we've got reports of use-after-free by syzkaller fuzzer, and this hopefully fixes these issues. Reported-by: Dmitry Vyukov Cc: Signed-off-by: Takashi Iwai (cherry picked from commit b5a663aa426f4884c71cd8580adae73f33570f0d) Change-Id: I7e7e4e1ab476f93131111d60d8f4e6a1add43193 Signed-off-by: Dennis Cagle --- sound/core/timer.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/sound/core/timer.c b/sound/core/timer.c index 6ddcf06f52f9a..38a137d6b04fd 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -215,11 +215,13 @@ static void snd_timer_check_master(struct snd_timer_instance *master) slave->slave_id == master->slave_id) { list_move_tail(&slave->open_list, &master->slave_list_head); spin_lock_irq(&slave_active_lock); + spin_lock(&master->timer->lock); slave->master = master; slave->timer = master->timer; if (slave->flags & SNDRV_TIMER_IFLG_RUNNING) list_add_tail(&slave->active_list, &master->slave_active_head); + spin_unlock(&master->timer->lock); spin_unlock_irq(&slave_active_lock); } } @@ -345,15 +347,18 @@ int snd_timer_close(struct snd_timer_instance *timeri) timer->hw.close) timer->hw.close(timer); /* remove slave links */ + spin_lock_irq(&slave_active_lock); + spin_lock(&timer->lock); list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head, open_list) { - spin_lock_irq(&slave_active_lock); - _snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION); list_move_tail(&slave->open_list, &snd_timer_slave_list); slave->master = NULL; slave->timer = NULL; - spin_unlock_irq(&slave_active_lock); + list_del_init(&slave->ack_list); + list_del_init(&slave->active_list); } + spin_unlock(&timer->lock); + spin_unlock_irq(&slave_active_lock); mutex_unlock(®ister_mutex); } out: @@ -440,9 +445,12 @@ static int snd_timer_start_slave(struct snd_timer_instance *timeri) spin_lock_irqsave(&slave_active_lock, flags); timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; - if (timeri->master) + if (timeri->master && timeri->timer) { + spin_lock(&timeri->timer->lock); list_add_tail(&timeri->active_list, &timeri->master->slave_active_head); + spin_unlock(&timeri->timer->lock); + } spin_unlock_irqrestore(&slave_active_lock, flags); return 1; /* delayed start */ } @@ -488,6 +496,8 @@ static int _snd_timer_stop(struct snd_timer_instance * timeri, if (!keep_flag) { spin_lock_irqsave(&slave_active_lock, flags); timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; + list_del_init(&timeri->ack_list); + list_del_init(&timeri->active_list); spin_unlock_irqrestore(&slave_active_lock, flags); } goto __end; From 0c0f9f00d635b0898a3ba35aae0d1aa20facf3fd Mon Sep 17 00:00:00 2001 From: Ashish Jain Date: Mon, 18 Jul 2016 16:07:42 +0530 Subject: [PATCH 133/320] ASoC: msm: qdsp6v2: DAP: Update check to validate data length A big negative data length value can bypass the current check, update the condition to ensure that only valid data length is used to copy the params. CRs-Fixed: 1041130 Change-Id: I6e1a58e901e4c042acfb0ab0a6223dec2949aefe Signed-off-by: Ashish Jain --- sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c index 7dafbf9fb35fe..75bb08da21b69 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c @@ -1523,8 +1523,9 @@ static int msm_ds2_dap_get_param(u32 cmd, void *arg) } /* Return if invalid length */ - if (dolby_data->length > - (DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM - DOLBY_PARAM_PAYLOAD_SIZE)) { + if ((dolby_data->length > + (DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM - DOLBY_PARAM_PAYLOAD_SIZE)) || + (dolby_data->length <= 0)) { pr_err("Invalid length %d", dolby_data->length); rc = -EINVAL; goto end; From ab72b41b338277e7a44117b0cde1be60117f4259 Mon Sep 17 00:00:00 2001 From: Lei Yuan Date: Thu, 7 Jul 2016 17:33:58 +0800 Subject: [PATCH 134/320] ARM: dts: msm: camera: Add camera sensor device tree for msm8909 Add camera sensor related device tree for msm8909. Change-Id: I52c55fe387c8f9965af6a8329740bf5bf395fa89 Signed-off-by: Lei Yuan Signed-off-by: Kui Wang Signed-off-by: Depeng Shao --- .../dts/qcom/msm8909-camera-sensor-skuq.dtsi | 174 ++++++++++++++++++ .../dts/qcom/msm8909-pm8916-qrd-skuq.dtsi | 2 +- 2 files changed, 175 insertions(+), 1 deletion(-) create mode 100755 arch/arm/boot/dts/qcom/msm8909-camera-sensor-skuq.dtsi diff --git a/arch/arm/boot/dts/qcom/msm8909-camera-sensor-skuq.dtsi b/arch/arm/boot/dts/qcom/msm8909-camera-sensor-skuq.dtsi new file mode 100755 index 0000000000000..49a3b7b67c751 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8909-camera-sensor-skuq.dtsi @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ +&tlmm_pinmux { + GPIOFLASH_pins { + qcom,pins = <&gp 31>, <&gp 32>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <0>; + label = "GPIOFLASH_pins"; + GPIOFLASH_default: en_default { + drive-strength = <2>; + bias-pull-down; + }; + }; + + cam_mipi_switch { + qcom,pins = <&gp 9>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "cam-mipi-switch"; + /* active state */ + cam_mipi_switch_default: default { + drive-strength = <2>; /* 2 MA */ + bias-disable = <0>; /* No PULL */ + }; + }; + + cam_mipi_switch_sleep { + qcom,pins = <&gp 9>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "cam-mipi-switch"; + /* suspend state */ + cam_mipi_switch_sleep: sleep { + drive-strength = <2>; /* 2 MA */ + bias-pull-down = <0>; /* PULL DOWN */ + }; + }; +}; + +&soc { + flash_GPIOFLASH:flashlight { + compatible = "qcom,leds-gpio-flash"; + status = "okay"; + pinctrl-names = "flash_default"; + pinctrl-0 = <&GPIOFLASH_default>; + qcom,flash-en = <&msm_gpio 31 0>; + qcom,flash-now = <&msm_gpio 32 0>; + qcom,op-seq = "flash_en", "flash_now"; + qcom,torch-seq-val = <0 1>; + qcom,flash-seq-val = <1 0>; + linux,name = "flashlight"; + linux,default-trigger = "flashlight-trigger"; + }; + led_flash0: qcom,camera-led-flash { + cell-index = <0>; + compatible = "qcom,camera-led-flash"; + qcom,flash-type = <3>; + qcom,flash-source = <&flash_GPIOFLASH>; + qcom,torch-source = <&flash_GPIOFLASH>; + }; +}; + +&i2c_3 { + + actuator0: qcom,actuator@0 { + cell-index = <0>; + reg = <0x3>; + compatible = "qcom,actuator"; + qcom,cci-master = <0>; + cam_vaf-supply = <&pm8916_l8>; + qcom,cam-vreg-name = "cam_vaf"; + qcom,cam-vreg-type = <0>; + qcom,cam-vreg-min-voltage = <2850000>; + qcom,cam-vreg-max-voltage = <2900000>; + qcom,cam-vreg-op-mode = <80000>; + }; + + qcom,camera@0 { + cell-index = <0>; + compatible = "qcom,camera"; + reg = <0x2>; + qcom,csiphy-sd-index = <0>; + qcom,csid-sd-index = <0>; + qcom,mount-angle = <90>; + qcom,actuator-src = <&actuator0>; + qcom,led-flash-src = <&led_flash0>; + cam_vdig-supply = <&pm8916_l2>; + cam_vana-supply = <&pm8916_l17>; + cam_vio-supply = <&pm8916_l6>; + cam_vaf-supply = <&pm8916_l8>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", + "cam_vaf"; + qcom,cam-vreg-type = <0 1 0 0>; + qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2850000 2900000>; + qcom,cam-vreg-op-mode = <200000 0 80000 100000>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_default + &cam_sensor_rear_default &cam_mipi_switch_default>; + pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep + &cam_mipi_switch_sleep>; + gpios = <&msm_gpio 26 0>, + <&msm_gpio 35 0>, + <&msm_gpio 34 0>, + <&msm_gpio 9 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-custom1 = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK", + "CAM_RESET1", + "CAM_STANDBY", + "CAM_MIPI_SWITCH"; + qcom,sensor-position = <0>; + qcom,sensor-mode = <0>; + qcom,cci-master = <0>; + status = "ok"; + clocks = <&clock_gcc clk_mclk0_clk_src>, + <&clock_gcc clk_gcc_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; + + qcom,camera@1 { + cell-index = <1>; + compatible = "qcom,camera"; + reg = <0x1>; + qcom,csiphy-sd-index = <0>; + qcom,csid-sd-index = <0>; + qcom,mount-angle = <90>; + cam_vdig-supply = <&pm8916_l2>; + cam_vio-supply = <&pm8916_l6>; + cam_vana-supply = <&pm8916_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + qcom,cam-vreg-type = <0 1 0>; + qcom,cam-vreg-min-voltage = <1200000 0 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2850000>; + qcom,cam-vreg-op-mode = <200000 0 80000>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_default &cam_sensor_front_default + &cam_mipi_switch_default>; + pinctrl-1 = <&cam_sensor_mclk1_sleep &cam_sensor_front_sleep + &cam_mipi_switch_sleep>; + gpios = <&msm_gpio 27 0>, + <&msm_gpio 28 0>, + <&msm_gpio 33 0>, + <&msm_gpio 9 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-custom1 = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK", + "CAM_RESET", + "CAM_STANDBY", + "CAM_MIPI_SWITCH"; + qcom,sensor-position = <1>; + qcom,cci-master = <0>; + status = "ok"; + clocks = <&clock_gcc clk_mclk1_clk_src>, + <&clock_gcc clk_gcc_camss_mclk1_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi index 6d46889487c89..0edb4acf43845 100644 --- a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi +++ b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi @@ -12,7 +12,7 @@ */ #include "msm8909-pm8916-qrd.dtsi" - +#include "msm8909-camera-sensor-skuq.dtsi" / { model = "Qualcomm Technologies, Inc. MSM8909-PM8916 QSIP SKUQ"; compatible = "qcom,msm8909-qrd", "qcom,msm8909", "qcom,qrd"; From a6c88dbb30eaeb2dc64029756b384cadef8f5e7b Mon Sep 17 00:00:00 2001 From: Shalini Krishnamoorthi Date: Thu, 30 Jun 2016 14:00:04 -0700 Subject: [PATCH 135/320] msm: mdss: Correct the format specifiers in sscanf function In many parts of the code the sscanf function was getting an unsigned integer with a wrong format specifier. Changed the format specifiers appropriately. Single variable sscanf were replaced by kstrtouint at reported places. CRs-Fixed: 1024872 Change-Id: I03ce718b0456d437d31d701586965d0aa7443b51 Signed-off-by: Shalini Krishnamoorthi --- drivers/video/msm/mdss/mdss_debug.c | 8 ++++---- drivers/video/msm/mdss/mdss_mdp.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c index a03e194f64975..3513540f0ae4b 100644 --- a/drivers/video/msm/mdss/mdss_debug.c +++ b/drivers/video/msm/mdss/mdss_debug.c @@ -80,7 +80,7 @@ static ssize_t panel_debug_base_offset_write(struct file *file, buf[count] = 0; /* end of string */ - if (sscanf(buf, "%x %x", &off, &cnt) != 2) + if (sscanf(buf, "%x %u", &off, &cnt) != 2) return -EFAULT; if (off > dbg->max_offset) @@ -606,11 +606,11 @@ static ssize_t mdss_debug_factor_write(struct file *file, if (strnchr(buf, count, '/')) { /* Parsing buf as fraction */ - if (sscanf(buf, "%d/%d", &numer, &denom) != 2) + if (sscanf(buf, "%u/%u", &numer, &denom) != 2) return -EFAULT; } else { /* Parsing buf as percentage */ - if (sscanf(buf, "%d", &numer) != 1) + if (kstrtouint(buf, 0, &numer)) return -EFAULT; denom = 100; } @@ -917,7 +917,7 @@ static ssize_t mdss_debug_perf_bw_limit_write(struct file *file, if (strnchr(buf, count, ' ')) { /* Parsing buf */ - if (sscanf(buf, "%d %d", &mode, &val) != 2) + if (sscanf(buf, "%u %u", &mode, &val) != 2) return -EFAULT; } diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c index 7cfe38d1bc455..14514f32ee82a 100644 --- a/drivers/video/msm/mdss/mdss_mdp.c +++ b/drivers/video/msm/mdss/mdss_mdp.c @@ -1429,7 +1429,7 @@ static ssize_t mdss_mdp_store_max_limit_bw(struct device *dev, struct mdss_data_type *mdata = dev_get_drvdata(dev); u32 data = 0; - if (1 != sscanf(buf, "%d", &data)) { + if (kstrtouint(buf, 0, &data)) { pr_info("Not able scan to bw_mode_bitmap\n"); } else { mdata->bw_mode_bitmap = data; From b73841449c85a4737515447c6bf6a51b7a8e8dbc Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 14 Jan 2016 16:30:58 +0100 Subject: [PATCH 136/320] ALSA: timer: Harden slave timer list handling A slave timer instance might be still accessible in a racy way while operating the master instance as it lacks of locking. Since the master operation is mostly protected with timer->lock, we should cope with it while changing the slave instance, too. Also, some linked lists (active_list and ack_list) of slave instances aren't unlinked immediately at stopping or closing, and this may lead to unexpected accesses. This patch tries to address these issues. It adds spin lock of timer->lock (either from master or slave, which is equivalent) in a few places. For avoiding a deadlock, we ensure that the global slave_active_lock is always locked at first before each timer lock. Also, ack and active_list of slave instances are properly unlinked at snd_timer_stop() and snd_timer_close(). Last but not least, remove the superfluous call of _snd_timer_stop() at removing slave links. This is a noop, and calling it may confuse readers wrt locking. Further cleanup will follow in a later patch. Actually we've got reports of use-after-free by syzkaller fuzzer, and this hopefully fixes these issues. Reported-by: Dmitry Vyukov Cc: Signed-off-by: Takashi Iwai (cherry picked from commit b5a663aa426f4884c71cd8580adae73f33570f0d) Change-Id: I7e7e4e1ab476f93131111d60d8f4e6a1add43193 Signed-off-by: Dennis Cagle --- sound/core/timer.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/sound/core/timer.c b/sound/core/timer.c index 6ddcf06f52f9a..38a137d6b04fd 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -215,11 +215,13 @@ static void snd_timer_check_master(struct snd_timer_instance *master) slave->slave_id == master->slave_id) { list_move_tail(&slave->open_list, &master->slave_list_head); spin_lock_irq(&slave_active_lock); + spin_lock(&master->timer->lock); slave->master = master; slave->timer = master->timer; if (slave->flags & SNDRV_TIMER_IFLG_RUNNING) list_add_tail(&slave->active_list, &master->slave_active_head); + spin_unlock(&master->timer->lock); spin_unlock_irq(&slave_active_lock); } } @@ -345,15 +347,18 @@ int snd_timer_close(struct snd_timer_instance *timeri) timer->hw.close) timer->hw.close(timer); /* remove slave links */ + spin_lock_irq(&slave_active_lock); + spin_lock(&timer->lock); list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head, open_list) { - spin_lock_irq(&slave_active_lock); - _snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION); list_move_tail(&slave->open_list, &snd_timer_slave_list); slave->master = NULL; slave->timer = NULL; - spin_unlock_irq(&slave_active_lock); + list_del_init(&slave->ack_list); + list_del_init(&slave->active_list); } + spin_unlock(&timer->lock); + spin_unlock_irq(&slave_active_lock); mutex_unlock(®ister_mutex); } out: @@ -440,9 +445,12 @@ static int snd_timer_start_slave(struct snd_timer_instance *timeri) spin_lock_irqsave(&slave_active_lock, flags); timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; - if (timeri->master) + if (timeri->master && timeri->timer) { + spin_lock(&timeri->timer->lock); list_add_tail(&timeri->active_list, &timeri->master->slave_active_head); + spin_unlock(&timeri->timer->lock); + } spin_unlock_irqrestore(&slave_active_lock, flags); return 1; /* delayed start */ } @@ -488,6 +496,8 @@ static int _snd_timer_stop(struct snd_timer_instance * timeri, if (!keep_flag) { spin_lock_irqsave(&slave_active_lock, flags); timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; + list_del_init(&timeri->ack_list); + list_del_init(&timeri->active_list); spin_unlock_irqrestore(&slave_active_lock, flags); } goto __end; From c8eb74bcb46a7511b5bfb80635c0f6b13f73a617 Mon Sep 17 00:00:00 2001 From: Ashish Jain Date: Mon, 18 Jul 2016 16:07:42 +0530 Subject: [PATCH 137/320] ASoC: msm: qdsp6v2: DAP: Update check to validate data length A big negative data length value can bypass the current check, update the condition to ensure that only valid data length is used to copy the params. CRs-Fixed: 1041130 Change-Id: I6e1a58e901e4c042acfb0ab0a6223dec2949aefe Signed-off-by: Ashish Jain --- sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c index 7dafbf9fb35fe..75bb08da21b69 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c @@ -1523,8 +1523,9 @@ static int msm_ds2_dap_get_param(u32 cmd, void *arg) } /* Return if invalid length */ - if (dolby_data->length > - (DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM - DOLBY_PARAM_PAYLOAD_SIZE)) { + if ((dolby_data->length > + (DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM - DOLBY_PARAM_PAYLOAD_SIZE)) || + (dolby_data->length <= 0)) { pr_err("Invalid length %d", dolby_data->length); rc = -EINVAL; goto end; From e9131484a0b83cf4ae03aed7313f11fcc582b041 Mon Sep 17 00:00:00 2001 From: Ben Romberger Date: Thu, 14 Jul 2016 18:36:56 -0700 Subject: [PATCH 138/320] ASoC : msm: qdsp6v2: Add size check in audio cal ioctl For the audio get calibration ioctl compare the allocated buffer size to the size of the header and cal type header to ensure the buffer is big enough. CRs-Fixed: 1038127 Change-Id: I851b4454e8420706ad3263d67e892720d46e5718 Signed-off-by: Ben Romberger --- sound/soc/msm/qdsp6v2/audio_calibration.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/audio_calibration.c b/sound/soc/msm/qdsp6v2/audio_calibration.c index 3477fd8d942de..c8806481ed03a 100644 --- a/sound/soc/msm/qdsp6v2/audio_calibration.c +++ b/sound/soc/msm/qdsp6v2/audio_calibration.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -494,7 +494,13 @@ static long audio_cal_shared_ioctl(struct file *file, unsigned int cmd, goto unlock; if (data == NULL) goto unlock; - if (copy_to_user((void *)arg, data, + if ((sizeof(data->hdr) + data->hdr.cal_type_size) > size) { + pr_err("%s: header size %zd plus cal type size %d are greater than data buffer size %d\n", + __func__, sizeof(data->hdr), + data->hdr.cal_type_size, size); + ret = -EFAULT; + goto unlock; + } else if (copy_to_user((void *)arg, data, sizeof(data->hdr) + data->hdr.cal_type_size)) { pr_err("%s: Could not copy cal type to user\n", __func__); From de3e3e5930b1edfebec7870390443279ec5b65fe Mon Sep 17 00:00:00 2001 From: Srinivasarao P Date: Fri, 22 Jul 2016 12:48:33 +0530 Subject: [PATCH 139/320] msm : dma_test: Initialize newly allocated memory The MSM_DMA_IOALLOC ioctl command allocates kernel memory and this memory can be read back using the MSM_DMA_IORBUF ioctl command. This memory is not zero-initialized and may contain sensitive data. Change-Id: I8c55d6fe500e7607690b89806715893783eecf9c Signed-off-by: Srinivasarao P --- arch/arm/mach-msm/dma_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-msm/dma_test.c b/arch/arm/mach-msm/dma_test.c index 3d13e4e3cdc7d..1d717c360c8cb 100644 --- a/arch/arm/mach-msm/dma_test.c +++ b/arch/arm/mach-msm/dma_test.c @@ -99,7 +99,7 @@ static int buffer_req(struct msm_dma_alloc_req *req) if (i >= MAX_TEST_BUFFERS) goto error; - buffers[i] = kmalloc(req->size, GFP_KERNEL | __GFP_DMA); + buffers[i] = kzalloc(req->size, GFP_KERNEL | __GFP_DMA); if (buffers[i] == 0) goto error; sizes[i] = req->size; From f2b14daf2f61c54e2121356137a25e95904d4590 Mon Sep 17 00:00:00 2001 From: Shalini Krishnamoorthi Date: Thu, 30 Jun 2016 14:00:04 -0700 Subject: [PATCH 140/320] msm: mdss: Correct the format specifiers in sscanf function In many parts of the code the sscanf function was getting an unsigned integer with a wrong format specifier. Changed the format specifiers appropriately. Single variable sscanf were replaced by kstrtouint at reported places. CRs-Fixed: 1024872 Change-Id: I03ce718b0456d437d31d701586965d0aa7443b51 Signed-off-by: Shalini Krishnamoorthi --- drivers/video/msm/mdss/mdss_debug.c | 8 ++++---- drivers/video/msm/mdss/mdss_mdp.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c index a03e194f64975..3513540f0ae4b 100644 --- a/drivers/video/msm/mdss/mdss_debug.c +++ b/drivers/video/msm/mdss/mdss_debug.c @@ -80,7 +80,7 @@ static ssize_t panel_debug_base_offset_write(struct file *file, buf[count] = 0; /* end of string */ - if (sscanf(buf, "%x %x", &off, &cnt) != 2) + if (sscanf(buf, "%x %u", &off, &cnt) != 2) return -EFAULT; if (off > dbg->max_offset) @@ -606,11 +606,11 @@ static ssize_t mdss_debug_factor_write(struct file *file, if (strnchr(buf, count, '/')) { /* Parsing buf as fraction */ - if (sscanf(buf, "%d/%d", &numer, &denom) != 2) + if (sscanf(buf, "%u/%u", &numer, &denom) != 2) return -EFAULT; } else { /* Parsing buf as percentage */ - if (sscanf(buf, "%d", &numer) != 1) + if (kstrtouint(buf, 0, &numer)) return -EFAULT; denom = 100; } @@ -917,7 +917,7 @@ static ssize_t mdss_debug_perf_bw_limit_write(struct file *file, if (strnchr(buf, count, ' ')) { /* Parsing buf */ - if (sscanf(buf, "%d %d", &mode, &val) != 2) + if (sscanf(buf, "%u %u", &mode, &val) != 2) return -EFAULT; } diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c index 7cfe38d1bc455..14514f32ee82a 100644 --- a/drivers/video/msm/mdss/mdss_mdp.c +++ b/drivers/video/msm/mdss/mdss_mdp.c @@ -1429,7 +1429,7 @@ static ssize_t mdss_mdp_store_max_limit_bw(struct device *dev, struct mdss_data_type *mdata = dev_get_drvdata(dev); u32 data = 0; - if (1 != sscanf(buf, "%d", &data)) { + if (kstrtouint(buf, 0, &data)) { pr_info("Not able scan to bw_mode_bitmap\n"); } else { mdata->bw_mode_bitmap = data; From b86fda11a081a1f041031fce3368e18943ca1e6c Mon Sep 17 00:00:00 2001 From: Ben Romberger Date: Thu, 14 Jul 2016 18:36:56 -0700 Subject: [PATCH 141/320] ASoC : msm: qdsp6v2: Add size check in audio cal ioctl For the audio get calibration ioctl compare the allocated buffer size to the size of the header and cal type header to ensure the buffer is big enough. CRs-Fixed: 1038127 Change-Id: I851b4454e8420706ad3263d67e892720d46e5718 Signed-off-by: Ben Romberger --- sound/soc/msm/qdsp6v2/audio_calibration.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/audio_calibration.c b/sound/soc/msm/qdsp6v2/audio_calibration.c index 3477fd8d942de..c8806481ed03a 100644 --- a/sound/soc/msm/qdsp6v2/audio_calibration.c +++ b/sound/soc/msm/qdsp6v2/audio_calibration.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -494,7 +494,13 @@ static long audio_cal_shared_ioctl(struct file *file, unsigned int cmd, goto unlock; if (data == NULL) goto unlock; - if (copy_to_user((void *)arg, data, + if ((sizeof(data->hdr) + data->hdr.cal_type_size) > size) { + pr_err("%s: header size %zd plus cal type size %d are greater than data buffer size %d\n", + __func__, sizeof(data->hdr), + data->hdr.cal_type_size, size); + ret = -EFAULT; + goto unlock; + } else if (copy_to_user((void *)arg, data, sizeof(data->hdr) + data->hdr.cal_type_size)) { pr_err("%s: Could not copy cal type to user\n", __func__); From 7f888cc17c9a80063abc70395aa15310739c7bbe Mon Sep 17 00:00:00 2001 From: Srinivasarao P Date: Fri, 22 Jul 2016 12:48:33 +0530 Subject: [PATCH 142/320] msm: dma_test: Initialize newly allocated memory The MSM_DMA_IOALLOC ioctl command allocates kernel memory and this memory can be read back using the MSM_DMA_IORBUF ioctl command. This memory is not zero-initialized and may contain sensitive data. Change-Id: I8c55d6fe500e7607690b89806715893783eecf9c Signed-off-by: Srinivasarao P --- arch/arm/mach-msm/dma_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-msm/dma_test.c b/arch/arm/mach-msm/dma_test.c index 3d13e4e3cdc7d..1d717c360c8cb 100644 --- a/arch/arm/mach-msm/dma_test.c +++ b/arch/arm/mach-msm/dma_test.c @@ -99,7 +99,7 @@ static int buffer_req(struct msm_dma_alloc_req *req) if (i >= MAX_TEST_BUFFERS) goto error; - buffers[i] = kmalloc(req->size, GFP_KERNEL | __GFP_DMA); + buffers[i] = kzalloc(req->size, GFP_KERNEL | __GFP_DMA); if (buffers[i] == 0) goto error; sizes[i] = req->size; From b2d5c3387a8963f8f37e07cd94739354ea6117ce Mon Sep 17 00:00:00 2001 From: xiaonian Date: Thu, 28 Jul 2016 15:10:43 +0800 Subject: [PATCH 143/320] ARM: dts: msm: Set SD card property for msm8909 SKUQ according to HW design: 1. set cd-gpio as pull down when suspend and resume to avoid trigger QDSD debugger rescan process. 2. delete property cd-gpios and status_irq as SD card hot swap is not support. 3. set qcom,nonremovable as SD card could not be removed unless plug out battery first. CRs-Fixed: 1041009 Change-Id: Ia40802dfb8a02325ee098e25091271e4fd9649db Signed-off-by: xiaonian --- .../dts/qcom/msm8909-pm8916-qrd-skuq.dtsi | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi index e2e0f2fc9db9e..ffc2a2e5a44c6 100644 --- a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi +++ b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi @@ -124,3 +124,23 @@ qcom,platform-reset-gpio = <&msm_gpio 25 0>; }; + +&sdc2_cd_on { + /delete-property/ bias-pull-up; + bias-pull-down; +}; + +&sdc2_cd_off { + /delete-property/ bias-disable; + bias-pull-down; +}; + +&sdhc_2 { + qcom,nonremovable; + + interrupts = <0 1>; + interrupt-map = <0 &intc 0 125 0 + 1 &intc 0 221 0>; + interrupt-names = "hc_irq", "pwr_irq"; + /delete-property/ cd-gpios; +}; From 6dd76e6228b2e63c01d8c081f153bd4216682ab4 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 13 Feb 2016 02:34:52 +0000 Subject: [PATCH 144/320] pipe: Fix buffer offset after partially failed read Quoting the RHEL advisory: > It was found that the fix for CVE-2015-1805 incorrectly kept buffer > offset and buffer length in sync on a failed atomic read, potentially > resulting in a pipe buffer state corruption. A local, unprivileged user > could use this flaw to crash the system or leak kernel memory to user > space. (CVE-2016-0774, Moderate) The same flawed fix was applied to stable branches from 2.6.32.y to 3.14.y inclusive, and I was able to reproduce the issue on 3.2.y. We need to give pipe_iov_copy_to_user() a separate offset variable and only update the buffer offset if it succeeds. Change-Id: Ibc4d13da6c463d02bd6ef7addc0fc871b6f63760 References: https://rhn.redhat.com/errata/RHSA-2016-0103.html Signed-off-by: Ben Hutchings Git-commit: feae3ca2e5e1a8f44aa6290255d3d9709985d0b2 Git-repo: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git Signed-off-by: Srinivasarao P --- fs/pipe.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/pipe.c b/fs/pipe.c index 3e7ab278bb0c0..50267e6ba6886 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -401,6 +401,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, void *addr; size_t chars = buf->len, remaining; int error, atomic; + int offset; if (chars > total_len) chars = total_len; @@ -414,9 +415,10 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, atomic = !iov_fault_in_pages_write(iov, chars); remaining = chars; + offset = buf->offset; redo: addr = ops->map(pipe, buf, atomic); - error = pipe_iov_copy_to_user(iov, addr, &buf->offset, + error = pipe_iov_copy_to_user(iov, addr, &offset, &remaining, atomic); ops->unmap(pipe, buf, addr); if (unlikely(error)) { @@ -432,6 +434,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, break; } ret += chars; + buf->offset += chars; buf->len -= chars; /* Was it a packet buffer? Clean up and exit */ From df9f6a003edeea0509feb24823052dee9489bcd8 Mon Sep 17 00:00:00 2001 From: Jayant Shekhar Date: Fri, 15 May 2015 00:16:20 +0530 Subject: [PATCH 145/320] msm: mdss: Synchronize pipe allocation and cleanup between framebuffers There is synchronization issue between UNSET called on a pipe on one particular framebuffer and SET for same pipe on another framebuffer. Currently, wait till kickoff is done during set, this lock is released only when cleanup is completed in commit cycle and then only next set/prepare is invoked. This wait is associated with a particular mfd, but if unset and set consecutively happens on seperate mfd's, then pipe allocation failure can happen. To fix this during pipe allocation, check following: -Check for active control paths. -Loop through destroy and cleanup list of pipes -Check for same pipe type. -Wait till cleanup is done and try again for pipe allocation. Change-Id: I32594cbffcd9fcb07bac26a53119c34020537991 Signed-off-by: Jayant Shekhar --- drivers/video/msm/mdss/mdss_mdp.h | 5 + drivers/video/msm/mdss/mdss_mdp_overlay.c | 128 +++++++++++++++++----- drivers/video/msm/mdss/mdss_mdp_pipe.c | 69 +++++++----- 3 files changed, 152 insertions(+), 50 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h index a6242fa3d97d1..cc26cce07ec93 100644 --- a/drivers/video/msm/mdss/mdss_mdp.h +++ b/drivers/video/msm/mdss/mdss_mdp.h @@ -469,6 +469,8 @@ struct mdss_mdp_pipe { u8 chroma_sample_h; u8 chroma_sample_v; u8 csc_coeff_set; + + wait_queue_head_t free_waitq; }; struct mdss_mdp_writeback_arg { @@ -494,6 +496,7 @@ struct mdss_overlay_private { struct list_head overlay_list; struct list_head pipes_used; struct list_head pipes_cleanup; + struct list_head pipes_destroy; struct list_head rot_proc_list; bool mixer_swap; @@ -904,6 +907,8 @@ struct mdss_mdp_pipe *mdss_mdp_pipe_search(struct mdss_data_type *mdata, int mdss_mdp_pipe_map(struct mdss_mdp_pipe *pipe); void mdss_mdp_pipe_unmap(struct mdss_mdp_pipe *pipe); struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_dma(struct mdss_mdp_mixer *mixer); +int mdss_mdp_get_pipe_info(struct mdss_data_type *mdata, u32 type, + struct mdss_mdp_pipe **pipe_pool); u32 mdss_mdp_smp_calc_num_blocks(struct mdss_mdp_pipe *pipe); u32 mdss_mdp_smp_get_size(struct mdss_mdp_pipe *pipe, u32 num_planes); diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c index af5864b156bde..ea8b16115af87 100644 --- a/drivers/video/msm/mdss/mdss_mdp_overlay.c +++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c @@ -44,6 +44,8 @@ #define IS_RIGHT_MIXER_OV(flags, dst_x, left_lm_w) \ ((flags & MDSS_MDP_RIGHT_MIXER) || (dst_x >= left_lm_w)) +#define PIPE_CLEANUP_TIMEOUT_US 100000 + static int mdss_mdp_overlay_free_fb_pipe(struct msm_fb_data_type *mfd); static int mdss_mdp_overlay_fb_parse_dt(struct msm_fb_data_type *mfd); static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd); @@ -570,6 +572,94 @@ static inline void __mdss_mdp_overlay_set_chroma_sample( pipe->chroma_sample_v = 0; } +static int mdss_mdp_wait4pipe_helper(struct mdss_mdp_ctl *ctl, + u32 pipe_type) +{ + struct mdss_mdp_pipe *pipe = NULL; + struct mdss_mdp_mixer *mixer; + struct mdss_overlay_private *mdp5_data; + int pipe_cleanup_map = 0; + + if (!ctl || !ctl->mfd) + return 0; + + mixer = ctl->mixer_left; + mdp5_data = mfd_to_mdp5_data(ctl->mfd); + + if (!mixer->rotator_mode) { + mutex_lock(&mdp5_data->list_lock); + list_for_each_entry(pipe, &mdp5_data->pipes_destroy, list) { + if (pipe_type == pipe->type) { + pipe_cleanup_map |= pipe->ndx; + break; + } + } + if (!pipe_cleanup_map) { + list_for_each_entry(pipe, &mdp5_data->pipes_cleanup, + list) { + if (pipe_type == pipe->type) { + pipe_cleanup_map |= pipe->ndx; + break; + } + } + } + mutex_unlock(&mdp5_data->list_lock); + } else if (mixer->rotator_mode && + (pipe_type == MDSS_MDP_PIPE_TYPE_DMA)) { + if (ctl->mixer_left->num == MDSS_MDP_WB_LAYERMIXER0) + pipe_cleanup_map |= BIT(MDSS_MDP_SSPP_DMA0); + else + pipe_cleanup_map |= BIT(MDSS_MDP_SSPP_DMA1); + } + + return pipe_cleanup_map; +} + +static struct mdss_mdp_pipe *mdss_mdp_wait4pipe(struct msm_fb_data_type *mfd, + struct mdss_mdp_mixer *mixer, u32 pipe_type, + struct mdss_mdp_pipe *left_blend_pipe) +{ + struct mdss_mdp_pipe *pipes = NULL; + u32 i, npipes = 0; + int pipe_cleanup_map = 0; + struct mdss_mdp_pipe *wait_pipe = NULL; + struct mdss_data_type *mdata = mfd_to_mdata(mfd); + struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd); + + for (i = 0; i < mdata->nctl; i++) { + struct mdss_mdp_ctl *ctl = mdata->ctl_off + i; + if ((ctl != mdp5_data->ctl) && mdss_mdp_ctl_is_power_on(ctl)) + pipe_cleanup_map |= mdss_mdp_wait4pipe_helper(ctl, + pipe_type); + } + + npipes = mdss_mdp_get_pipe_info(mdata, pipe_type, &pipes); + + for (i = 0; i < npipes; i++) { + if (pipe_cleanup_map & pipes[i].ndx) { + wait_pipe = &pipes[i]; + break; + } + } + + pr_debug("wait for pipe, pipe_type_used_map = 0x%x, pipe num = %d\n", + pipe_cleanup_map, wait_pipe->num); + + if (wait_pipe) { + int ret; + ret = wait_event_interruptible_timeout(wait_pipe->free_waitq, + !atomic_read(&wait_pipe->kref.refcount), + usecs_to_jiffies(PIPE_CLEANUP_TIMEOUT_US)); + if (IS_ERR_VALUE(ret)) + return NULL; + else + return mdss_mdp_pipe_alloc(mixer, pipe_type, + left_blend_pipe); + } + + return NULL; +} + int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd, struct mdp_overlay *req, struct mdss_mdp_pipe **ppipe, struct mdss_mdp_pipe *left_blend_pipe, bool is_single_layer) @@ -683,6 +773,10 @@ int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd, pipe = mdss_mdp_pipe_alloc(mixer, pipe_type, left_blend_pipe); + if (IS_ERR_OR_NULL(pipe) && (PTR_ERR(pipe) != -EBADSLT)) + pipe = mdss_mdp_wait4pipe(mfd, mixer, pipe_type, + left_blend_pipe); + /* RGB pipes can be used instead of DMA */ if ((req->pipe_type == PIPE_TYPE_AUTO) && !pipe && (pipe_type == MDSS_MDP_PIPE_TYPE_DMA)) { @@ -1091,8 +1185,7 @@ static void __mdss_mdp_overlay_free_list_add(struct msm_fb_data_type *mfd, * Goes through destroy_pipes list and ensures they are ready to be destroyed * and cleaned up. Also cleanup of any pipe buffers after flip. */ -static void mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd, - struct list_head *destroy_pipes) +static void mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd) { struct mdss_mdp_pipe *pipe, *tmp; struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd); @@ -1100,7 +1193,7 @@ static void mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd, bool recovery_mode = false; mutex_lock(&mdp5_data->list_lock); - list_for_each_entry(pipe, destroy_pipes, list) { + list_for_each_entry(pipe, &mdp5_data->pipes_destroy, list) { /* make sure pipe fetch has been halted before freeing buffer */ if (mdss_mdp_pipe_fetch_halt(pipe)) { /* @@ -1135,7 +1228,7 @@ static void mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd, } } - list_for_each_entry_safe(pipe, tmp, destroy_pipes, list) { + list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_destroy, list) { /* * in case of secure UI, the buffer needs to be released as * soon as session is closed. @@ -1158,28 +1251,13 @@ static void mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd, void mdss_mdp_handoff_cleanup_pipes(struct msm_fb_data_type *mfd, u32 type) { - u32 i, npipes; - struct mdss_mdp_pipe *pipes; + u32 i, npipes = 0; + struct mdss_mdp_pipe *pipes = NULL; struct mdss_mdp_pipe *pipe; struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd); struct mdss_data_type *mdata = mfd_to_mdata(mfd); - switch (type) { - case MDSS_MDP_PIPE_TYPE_VIG: - pipes = mdata->vig_pipes; - npipes = mdata->nvig_pipes; - break; - case MDSS_MDP_PIPE_TYPE_RGB: - pipes = mdata->rgb_pipes; - npipes = mdata->nrgb_pipes; - break; - case MDSS_MDP_PIPE_TYPE_DMA: - pipes = mdata->dma_pipes; - npipes = mdata->ndma_pipes; - break; - default: - return; - } + npipes = mdss_mdp_get_pipe_info(mdata, type, &pipes); for (i = 0; i < npipes; i++) { pipe = &pipes[i]; @@ -1446,7 +1524,6 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd, int sd_in_pipe = 0; bool need_cleanup = false; struct mdss_mdp_commit_cb commit_cb; - LIST_HEAD(destroy_pipes); ATRACE_BEGIN(__func__); if (ctl->shared_lock) { @@ -1525,7 +1602,7 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd, mdss_mdp_pipe_queue_data(pipe, NULL); mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_left); mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_right); - list_move(&pipe->list, &destroy_pipes); + list_move(&pipe->list, &mdp5_data->pipes_destroy); need_cleanup = true; } @@ -1588,7 +1665,7 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd, mdss_fb_update_notify_update(mfd); commit_fail: ATRACE_BEGIN("overlay_cleanup"); - mdss_mdp_overlay_cleanup(mfd, &destroy_pipes); + mdss_mdp_overlay_cleanup(mfd); ATRACE_END("overlay_cleanup"); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_FLUSHED); @@ -4141,6 +4218,7 @@ int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd) INIT_LIST_HEAD(&mdp5_data->pipes_used); INIT_LIST_HEAD(&mdp5_data->pipes_cleanup); + INIT_LIST_HEAD(&mdp5_data->pipes_destroy); INIT_LIST_HEAD(&mdp5_data->rot_proc_list); mutex_init(&mdp5_data->list_lock); mutex_init(&mdp5_data->ov_lock); diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c index 77790f297587f..b74767078ae2b 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pipe.c +++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c @@ -805,43 +805,29 @@ static void mdss_mdp_fixed_qos_arbiter_setup(struct mdss_data_type *mdata, mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); } -static struct mdss_mdp_pipe *mdss_mdp_pipe_init(struct mdss_mdp_mixer *mixer, - u32 type, u32 off, struct mdss_mdp_pipe *left_blend_pipe) +int mdss_mdp_get_pipe_info(struct mdss_data_type *mdata, u32 type, + struct mdss_mdp_pipe **pipe_pool) { - struct mdss_mdp_pipe *pipe = NULL; - struct mdss_data_type *mdata; - struct mdss_mdp_pipe *pipe_pool = NULL; - u32 npipes; - bool pipe_share = false; - bool is_realtime; - u32 i, reg_val, force_off_mask; - - if (!mixer || !mixer->ctl || !mixer->ctl->mdata) - return NULL; - - mdata = mixer->ctl->mdata; + int npipes; switch (type) { case MDSS_MDP_PIPE_TYPE_VIG: - pipe_pool = mdata->vig_pipes; + *pipe_pool = mdata->vig_pipes; npipes = mdata->nvig_pipes; break; case MDSS_MDP_PIPE_TYPE_RGB: - pipe_pool = mdata->rgb_pipes; + *pipe_pool = mdata->rgb_pipes; npipes = mdata->nrgb_pipes; break; case MDSS_MDP_PIPE_TYPE_DMA: - pipe_pool = mdata->dma_pipes; + *pipe_pool = mdata->dma_pipes; npipes = mdata->ndma_pipes; - if ((mdata->wfd_mode == MDSS_MDP_WFD_SHARED) && - (mixer->type == MDSS_MDP_MIXER_TYPE_WRITEBACK)) - pipe_share = true; break; case MDSS_MDP_PIPE_TYPE_CURSOR: - pipe_pool = mdata->cursor_pipes; + *pipe_pool = mdata->cursor_pipes; npipes = mdata->ncursor_pipes; break; @@ -849,7 +835,39 @@ static struct mdss_mdp_pipe *mdss_mdp_pipe_init(struct mdss_mdp_mixer *mixer, npipes = 0; pr_err("invalid pipe type %d\n", type); break; - } +} + + return npipes; +} + +static void mdss_mdp_init_pipe_params(struct mdss_mdp_pipe *pipe) +{ + kref_init(&pipe->kref); + init_waitqueue_head(&pipe->free_waitq); +} + +static struct mdss_mdp_pipe *mdss_mdp_pipe_init(struct mdss_mdp_mixer *mixer, + u32 type, u32 off, struct mdss_mdp_pipe *left_blend_pipe) +{ + struct mdss_mdp_pipe *pipe = NULL; + struct mdss_data_type *mdata; + struct mdss_mdp_pipe *pipe_pool = NULL; + u32 npipes = 0; + bool pipe_share = false; + bool is_realtime; + u32 i, reg_val, force_off_mask; + + if (!mixer || !mixer->ctl || !mixer->ctl->mdata) + return NULL; + + mdata = mixer->ctl->mdata; + + npipes = mdss_mdp_get_pipe_info(mdata, type, &pipe_pool); + + if (type == MDSS_MDP_PIPE_TYPE_DMA && + (mdata->wfd_mode == MDSS_MDP_WFD_SHARED) && + (mixer->type == MDSS_MDP_MIXER_TYPE_WRITEBACK)) + pipe_share = true; for (i = off; i < npipes; i++) { pipe = pipe_pool + i; @@ -861,7 +879,7 @@ static struct mdss_mdp_pipe *mdss_mdp_pipe_init(struct mdss_mdp_mixer *mixer, } if (pipe && type == MDSS_MDP_PIPE_TYPE_CURSOR) { - kref_init(&pipe->kref); + mdss_mdp_init_pipe_params(pipe); goto cursor_done; } @@ -900,7 +918,7 @@ static struct mdss_mdp_pipe *mdss_mdp_pipe_init(struct mdss_mdp_mixer *mixer, pr_debug("type=%x pnum=%d\n", pipe->type, pipe->num); mutex_init(&pipe->pp_res.hist.hist_mutex); spin_lock_init(&pipe->pp_res.hist.hist_lock); - kref_init(&pipe->kref); + mdss_mdp_init_pipe_params(pipe); is_realtime = !((mixer->ctl->intf_num == MDSS_MDP_NO_INTF) || mixer->rotator_mode); mdss_mdp_qos_vbif_remapper_setup(mdata, pipe, is_realtime); @@ -1238,6 +1256,7 @@ int mdss_mdp_pipe_destroy(struct mdss_mdp_pipe *pipe) return -EBUSY; } + wake_up_all(&pipe->free_waitq); mutex_unlock(&mdss_mdp_sspp_lock); return 0; @@ -1305,7 +1324,7 @@ int mdss_mdp_pipe_handoff(struct mdss_mdp_pipe *pipe) pipe->is_handed_off = true; pipe->play_cnt = 1; - kref_init(&pipe->kref); + mdss_mdp_init_pipe_params(pipe); error: return rc; From a4423695cafe83fe7994fc6ce65e60199436ad7a Mon Sep 17 00:00:00 2001 From: Anusha Koduru Date: Wed, 8 Jul 2015 17:41:38 +0530 Subject: [PATCH 146/320] msm: mdss: fix NULL pointer dereference in mdss_mdp_wait4pipe Print debug information only if wait_pipe is not NULL. Change-Id: Ie9fb521f841d76010bfa6f1e79ea7e4fab1d000b Signed-off-by: Anusha Koduru --- drivers/video/msm/mdss/mdss_mdp_overlay.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c index ea8b16115af87..a805fab22625a 100644 --- a/drivers/video/msm/mdss/mdss_mdp_overlay.c +++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c @@ -642,11 +642,12 @@ static struct mdss_mdp_pipe *mdss_mdp_wait4pipe(struct msm_fb_data_type *mfd, } } - pr_debug("wait for pipe, pipe_type_used_map = 0x%x, pipe num = %d\n", - pipe_cleanup_map, wait_pipe->num); - if (wait_pipe) { int ret; + + pr_debug("wait for pipe, pipe_type_used_map = 0x%x, pipe num = %d\n", + pipe_cleanup_map, wait_pipe->num); + ret = wait_event_interruptible_timeout(wait_pipe->free_waitq, !atomic_read(&wait_pipe->kref.refcount), usecs_to_jiffies(PIPE_CLEANUP_TIMEOUT_US)); From 1d9e84cd45c79ddf2aa430d977a2d047e9594687 Mon Sep 17 00:00:00 2001 From: raghavendra ambadas Date: Fri, 29 Jul 2016 17:14:14 +0530 Subject: [PATCH 147/320] msm: mdss: Allocating pipe even cleanup map is Null There is synchronisation issue between overlay prepare and cleanup pipe on different frame buffers. When prepare is called on one frame buffer and clean up of same pipe is called from other frame buffer, there are chances where pipe is destroyed between pipe setup and wait4pipe func, because of which cleanup map shows null and returns with out calling mdss_mdp_pipe_alloc. To fix the issue always try to allocate pipe even when cleanup map is NULL. Change-Id: I2abeebaef28c4937f91b7ff40cb8e0a38d1de3d4 Signed-off-by: Raghavendra Ambadas --- drivers/video/msm/mdss/mdss_mdp_overlay.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c index a805fab22625a..3af0c8ad57d31 100644 --- a/drivers/video/msm/mdss/mdss_mdp_overlay.c +++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c @@ -658,7 +658,8 @@ static struct mdss_mdp_pipe *mdss_mdp_wait4pipe(struct msm_fb_data_type *mfd, left_blend_pipe); } - return NULL; + return mdss_mdp_pipe_alloc(mixer, pipe_type, + left_blend_pipe); } int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd, From c50252ece10c165a99aa6c2edf208e5890a53882 Mon Sep 17 00:00:00 2001 From: Charan Teja Reddy Date: Fri, 17 Jun 2016 17:24:41 +0530 Subject: [PATCH 148/320] coresight: fix use-after-free in stm on secure boot devices When the STM driver failed to register, the stmdrvdata variable becomes dangling pointer which may cause APSS to crash. Change-Id: I0e709ac180d8c946f25e026b23edadb08c82a1f3 Signed-off-by: Charan Teja Reddy Signed-off-by: Swetha Chikkaboraiah --- drivers/coresight/coresight-stm.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/coresight/coresight-stm.c b/drivers/coresight/coresight-stm.c index 2cc1f9cd2394f..8833ee0b7c5d5 100644 --- a/drivers/coresight/coresight-stm.c +++ b/drivers/coresight/coresight-stm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -868,8 +868,6 @@ static int stm_probe(struct platform_device *pdev) drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; - /* Store the driver data pointer for use in exported functions */ - stmdrvdata = drvdata; drvdata->dev = &pdev->dev; platform_set_drvdata(pdev, drvdata); @@ -948,6 +946,9 @@ static int stm_probe(struct platform_device *pdev) if (boot_enable) coresight_enable(drvdata->csdev); + /* Store the driver data pointer for use in exported functions */ + stmdrvdata = drvdata; + return 0; err: coresight_unregister(drvdata->csdev); From b8874573428e8ce024f57c6242d662fcca5e5d55 Mon Sep 17 00:00:00 2001 From: VijayaKumar T M Date: Mon, 25 Jul 2016 11:53:19 +0530 Subject: [PATCH 149/320] msm: camera: sensor: Fix use after free condition Add a check to return value before calling csid config which will otherwise lead to use after free scenario. CRs-Fixed: 1040857 Change-Id: I4f4d9e38eeb537875e0d01de0e99913a44dd3f3f Signed-off-by: VijayaKumar T M --- .../platform/msm/camera_v2/sensor/csid/msm_csid.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c index 586409670ef94..7dd2959fbb398 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c +++ b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -518,7 +518,7 @@ static int32_t msm_csid_cmd(struct csid_device *csid_dev, void __user *arg) break; } if (csid_params.lut_params.num_cid < 1 || - csid_params.lut_params.num_cid > 16) { + csid_params.lut_params.num_cid > MAX_CID) { pr_err("%s: %d num_cid outside range\n", __func__, __LINE__); rc = -EINVAL; @@ -547,6 +547,10 @@ static int32_t msm_csid_cmd(struct csid_device *csid_dev, void __user *arg) csid_params.lut_params.vc_cfg[i] = vc_cfg; } csid_dev->csid_sof_debug = 0; + if (rc < 0) { + pr_err("%s:%d failed\n", __func__, __LINE__); + break; + } rc = msm_csid_config(csid_dev, &csid_params); for (i--; i >= 0; i--) kfree(csid_params.lut_params.vc_cfg[i]); @@ -658,7 +662,7 @@ static int32_t msm_csid_cmd32(struct csid_device *csid_dev, void __user *arg) csid_params.lut_params.num_cid = lut_par32.num_cid; if (csid_params.lut_params.num_cid < 1 || - csid_params.lut_params.num_cid > 16) { + csid_params.lut_params.num_cid > MAX_CID) { pr_err("%s: %d num_cid outside range\n", __func__, __LINE__); rc = -EINVAL; From c62951bf8706906e37ba52237a69192c32695820 Mon Sep 17 00:00:00 2001 From: VijayaKumar T M Date: Mon, 25 Jul 2016 11:53:19 +0530 Subject: [PATCH 150/320] msm: camera: sensor: Fix use after free condition Add a check to return value before calling csid config which will otherwise lead to use after free scenario. CRs-Fixed: 1040857 Change-Id: I4f4d9e38eeb537875e0d01de0e99913a44dd3f3f Signed-off-by: VijayaKumar T M --- .../platform/msm/camera_v2/sensor/csid/msm_csid.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c index 586409670ef94..7dd2959fbb398 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c +++ b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -518,7 +518,7 @@ static int32_t msm_csid_cmd(struct csid_device *csid_dev, void __user *arg) break; } if (csid_params.lut_params.num_cid < 1 || - csid_params.lut_params.num_cid > 16) { + csid_params.lut_params.num_cid > MAX_CID) { pr_err("%s: %d num_cid outside range\n", __func__, __LINE__); rc = -EINVAL; @@ -547,6 +547,10 @@ static int32_t msm_csid_cmd(struct csid_device *csid_dev, void __user *arg) csid_params.lut_params.vc_cfg[i] = vc_cfg; } csid_dev->csid_sof_debug = 0; + if (rc < 0) { + pr_err("%s:%d failed\n", __func__, __LINE__); + break; + } rc = msm_csid_config(csid_dev, &csid_params); for (i--; i >= 0; i--) kfree(csid_params.lut_params.vc_cfg[i]); @@ -658,7 +662,7 @@ static int32_t msm_csid_cmd32(struct csid_device *csid_dev, void __user *arg) csid_params.lut_params.num_cid = lut_par32.num_cid; if (csid_params.lut_params.num_cid < 1 || - csid_params.lut_params.num_cid > 16) { + csid_params.lut_params.num_cid > MAX_CID) { pr_err("%s: %d num_cid outside range\n", __func__, __LINE__); rc = -EINVAL; From 499d38029e2feb34d8c05e9a026b2a8a72fc1fdd Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Mon, 18 Jul 2016 13:20:18 -0700 Subject: [PATCH 151/320] qseecom: validate the inputs of __qseecom_send_modfd_resp The resp_len and resp_buf_ptr of qseecom_send_modfd_listener_resp are not checked, then an userspace application that manipulates resp_len can corrupt the kernel memory. Thus make changes to validate these parameters. CRs-fixed: 1036418 Change-Id: Id43ec6b55b332d0dac09a9abb998a410f49b44f7 Signed-off-by: Zhen Kong --- drivers/misc/qseecom.c | 78 +++++++++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index b175965cfe119..116818159dad8 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -3065,41 +3065,80 @@ static int qseecom_send_resp(void) } -static int qseecom_send_modfd_resp(struct qseecom_dev_handle *data, - void __user *argp) +static int __validate_send_modfd_resp_inputs(struct qseecom_dev_handle *data, + struct qseecom_send_modfd_listener_resp *resp, + struct qseecom_registered_listener_list *this_lstnr) { - struct qseecom_send_modfd_listener_resp resp; int i; - struct qseecom_registered_listener_list *this_lstnr = NULL; - if (copy_from_user(&resp, argp, sizeof(resp))) { - pr_err("copy_from_user failed"); + if (!data || !resp || !this_lstnr) { + pr_err("listener handle or resp msg is null\n"); return -EINVAL; } - this_lstnr = __qseecom_find_svc(data->listener.id); - if (this_lstnr == NULL) + + if (resp->resp_buf_ptr == NULL) { + pr_err("resp buffer is null\n"); + return -EINVAL; + } + /* validate resp buf length */ + if ((resp->resp_len == 0) || + (resp->resp_len > this_lstnr->sb_length)) { + pr_err("resp buf length %d not valid\n", resp->resp_len); return -EINVAL; + } - if (resp.resp_buf_ptr == NULL) { - pr_err("Invalid resp_buf_ptr\n"); + if ((uintptr_t)resp->resp_buf_ptr > (ULONG_MAX - resp->resp_len)) { + pr_err("Integer overflow in resp_len & resp_buf\n"); + return -EINVAL; + } + if ((uintptr_t)this_lstnr->user_virt_sb_base > + (ULONG_MAX - this_lstnr->sb_length)) { + pr_err("Integer overflow in user_virt_sb_base & sb_length\n"); return -EINVAL; } + /* validate resp buf */ + if (((uintptr_t)resp->resp_buf_ptr < + (uintptr_t)this_lstnr->user_virt_sb_base) || + ((uintptr_t)resp->resp_buf_ptr >= + ((uintptr_t)this_lstnr->user_virt_sb_base + + this_lstnr->sb_length)) || + (((uintptr_t)resp->resp_buf_ptr + resp->resp_len) > + ((uintptr_t)this_lstnr->user_virt_sb_base + + this_lstnr->sb_length))) { + pr_err("resp buf is out of shared buffer region\n"); + return -EINVAL; + } + /* validate offsets */ for (i = 0; i < MAX_ION_FD; i++) { - if (resp.ifd_data[i].cmd_buf_offset >= resp.resp_len) { + if (resp->ifd_data[i].cmd_buf_offset >= resp->resp_len) { pr_err("Invalid offset %d = 0x%x\n", - i, resp.ifd_data[i].cmd_buf_offset); + i, resp->ifd_data[i].cmd_buf_offset); return -EINVAL; } } - if ((resp.resp_buf_ptr < this_lstnr->user_virt_sb_base) || - ((uintptr_t)resp.resp_buf_ptr >= - ((uintptr_t)this_lstnr->user_virt_sb_base + - this_lstnr->sb_length))) { - pr_err("resp_buf_ptr address not within shared buffer\n"); + return 0; +} + +static int __qseecom_send_modfd_resp(struct qseecom_dev_handle *data, + void __user *argp, bool is_64bit_addr) +{ + struct qseecom_send_modfd_listener_resp resp; + struct qseecom_registered_listener_list *this_lstnr = NULL; + + if (copy_from_user(&resp, argp, sizeof(resp))) { + pr_err("copy_from_user failed"); return -EINVAL; } + + this_lstnr = __qseecom_find_svc(data->listener.id); + if (this_lstnr == NULL) + return -EINVAL; + + if (__validate_send_modfd_resp_inputs(data, &resp, this_lstnr)) + return -EINVAL; + resp.resp_buf_ptr = this_lstnr->sb_virt + (uintptr_t)(resp.resp_buf_ptr - this_lstnr->user_virt_sb_base); __qseecom_update_cmd_buf(&resp, false, data, true); @@ -3108,6 +3147,11 @@ static int qseecom_send_modfd_resp(struct qseecom_dev_handle *data, return 0; } +static int qseecom_send_modfd_resp(struct qseecom_dev_handle *data, + void __user *argp) +{ + return __qseecom_send_modfd_resp(data, argp, false); +} static int qseecom_get_qseos_version(struct qseecom_dev_handle *data, void __user *argp) From e80b88323f9ff0bb0e545f209eec08ec56fca816 Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Mon, 18 Jul 2016 13:20:18 -0700 Subject: [PATCH 152/320] qseecom: validate the inputs of __qseecom_send_modfd_resp The resp_len and resp_buf_ptr of qseecom_send_modfd_listener_resp are not checked, then an userspace application that manipulates resp_len can corrupt the kernel memory. Thus make changes to validate these parameters. CRs-fixed: 1036418 Change-Id: Id43ec6b55b332d0dac09a9abb998a410f49b44f7 Signed-off-by: Zhen Kong --- drivers/misc/qseecom.c | 78 +++++++++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index b175965cfe119..116818159dad8 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -3065,41 +3065,80 @@ static int qseecom_send_resp(void) } -static int qseecom_send_modfd_resp(struct qseecom_dev_handle *data, - void __user *argp) +static int __validate_send_modfd_resp_inputs(struct qseecom_dev_handle *data, + struct qseecom_send_modfd_listener_resp *resp, + struct qseecom_registered_listener_list *this_lstnr) { - struct qseecom_send_modfd_listener_resp resp; int i; - struct qseecom_registered_listener_list *this_lstnr = NULL; - if (copy_from_user(&resp, argp, sizeof(resp))) { - pr_err("copy_from_user failed"); + if (!data || !resp || !this_lstnr) { + pr_err("listener handle or resp msg is null\n"); return -EINVAL; } - this_lstnr = __qseecom_find_svc(data->listener.id); - if (this_lstnr == NULL) + + if (resp->resp_buf_ptr == NULL) { + pr_err("resp buffer is null\n"); + return -EINVAL; + } + /* validate resp buf length */ + if ((resp->resp_len == 0) || + (resp->resp_len > this_lstnr->sb_length)) { + pr_err("resp buf length %d not valid\n", resp->resp_len); return -EINVAL; + } - if (resp.resp_buf_ptr == NULL) { - pr_err("Invalid resp_buf_ptr\n"); + if ((uintptr_t)resp->resp_buf_ptr > (ULONG_MAX - resp->resp_len)) { + pr_err("Integer overflow in resp_len & resp_buf\n"); + return -EINVAL; + } + if ((uintptr_t)this_lstnr->user_virt_sb_base > + (ULONG_MAX - this_lstnr->sb_length)) { + pr_err("Integer overflow in user_virt_sb_base & sb_length\n"); return -EINVAL; } + /* validate resp buf */ + if (((uintptr_t)resp->resp_buf_ptr < + (uintptr_t)this_lstnr->user_virt_sb_base) || + ((uintptr_t)resp->resp_buf_ptr >= + ((uintptr_t)this_lstnr->user_virt_sb_base + + this_lstnr->sb_length)) || + (((uintptr_t)resp->resp_buf_ptr + resp->resp_len) > + ((uintptr_t)this_lstnr->user_virt_sb_base + + this_lstnr->sb_length))) { + pr_err("resp buf is out of shared buffer region\n"); + return -EINVAL; + } + /* validate offsets */ for (i = 0; i < MAX_ION_FD; i++) { - if (resp.ifd_data[i].cmd_buf_offset >= resp.resp_len) { + if (resp->ifd_data[i].cmd_buf_offset >= resp->resp_len) { pr_err("Invalid offset %d = 0x%x\n", - i, resp.ifd_data[i].cmd_buf_offset); + i, resp->ifd_data[i].cmd_buf_offset); return -EINVAL; } } - if ((resp.resp_buf_ptr < this_lstnr->user_virt_sb_base) || - ((uintptr_t)resp.resp_buf_ptr >= - ((uintptr_t)this_lstnr->user_virt_sb_base + - this_lstnr->sb_length))) { - pr_err("resp_buf_ptr address not within shared buffer\n"); + return 0; +} + +static int __qseecom_send_modfd_resp(struct qseecom_dev_handle *data, + void __user *argp, bool is_64bit_addr) +{ + struct qseecom_send_modfd_listener_resp resp; + struct qseecom_registered_listener_list *this_lstnr = NULL; + + if (copy_from_user(&resp, argp, sizeof(resp))) { + pr_err("copy_from_user failed"); return -EINVAL; } + + this_lstnr = __qseecom_find_svc(data->listener.id); + if (this_lstnr == NULL) + return -EINVAL; + + if (__validate_send_modfd_resp_inputs(data, &resp, this_lstnr)) + return -EINVAL; + resp.resp_buf_ptr = this_lstnr->sb_virt + (uintptr_t)(resp.resp_buf_ptr - this_lstnr->user_virt_sb_base); __qseecom_update_cmd_buf(&resp, false, data, true); @@ -3108,6 +3147,11 @@ static int qseecom_send_modfd_resp(struct qseecom_dev_handle *data, return 0; } +static int qseecom_send_modfd_resp(struct qseecom_dev_handle *data, + void __user *argp) +{ + return __qseecom_send_modfd_resp(data, argp, false); +} static int qseecom_get_qseos_version(struct qseecom_dev_handle *data, void __user *argp) From fbcc8a8ecf047eacbd7cc8367599c2da7bbd273f Mon Sep 17 00:00:00 2001 From: Baldev Sahu Date: Mon, 18 Jul 2016 12:51:07 +0530 Subject: [PATCH 153/320] msm: mdss: Use panel supported fps if video is not full screen In Multiwondow usecase, mdp clk is not scaling to max due to low video fps. This is causing overall low fps while scrolling in other window. To accommodate this usecase, use panel supported fps instead when video is not full screen. This improves overall fps. Change-Id: I8a1db7e61171f54c15ad3418845fb25c66e4336d Signed-off-by: Baldev Sahu --- drivers/video/msm/mdss/mdp3_ppp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/video/msm/mdss/mdp3_ppp.c b/drivers/video/msm/mdss/mdp3_ppp.c index 5f556dd2f61e6..0f940d6642a2b 100644 --- a/drivers/video/msm/mdss/mdp3_ppp.c +++ b/drivers/video/msm/mdss/mdp3_ppp.c @@ -584,7 +584,12 @@ int mdp3_calc_ppp_res(struct msm_fb_data_type *mfd, struct blit_req_list *lreq) else fps = panel_info->mipi.frame_rate; } - + if (!(check_if_rgb(req->src.format))) { + /* Set max fps if video is not full screen */ + if((req->dst_rect.w < panel_info->xres) || + ( req->dst_rect.h < panel_info->yres)) + fps = panel_info->mipi.frame_rate; + } mdp3_get_bpp_info(req->src.format, &bpp); if (lreq->req_list[i].flags & MDP_SMART_BLIT) { /* From 35c5378f32f1a0e06c28bbbea3c0c5de99199a00 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 23 Apr 2015 12:46:16 +0100 Subject: [PATCH 154/320] arm64: dma-mapping: always clear allocated buffers [ Upstream commit 6829e274a623187c24f7cfc0e3d35f25d087fcc5 ] Buffers allocated by dma_alloc_coherent() are always zeroed on Alpha, ARM (32bit), MIPS, PowerPC, x86/x86_64 and probably other architectures. It turned out that some drivers rely on this 'feature'. Allocated buffer might be also exposed to userspace with dma_mmap() call, so clearing it is desired from security point of view to avoid exposing random memory to userspace. This patch unifies dma_alloc_coherent() behavior on ARM64 architecture with other implementations by unconditionally zeroing allocated buffer. CRs-Fixed: 1041735 Change-Id: I74bf024e0f603ca8c0b05430dc2ee154d579cfb2 Cc: # v3.14+ Signed-off-by: Marek Szyprowski Signed-off-by: Will Deacon Signed-off-by: Sasha Levin Git-commit: a142e9641dcbead2c8845c949ad518acac96ed28 Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git [lmark@codeaurora.org: resolve merge conflicts] Signed-off-by: Liam Mark --- arch/arm64/mm/dma-mapping.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index d5a107dc275a1..96092f271b528 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -88,6 +88,7 @@ static void *__alloc_from_pool(size_t size, struct page **ret_page) if (pageno < pool->nr_pages) { bitmap_set(pool->bitmap, pageno, count); ptr = pool->vaddr + PAGE_SIZE * pageno; + memset(ptr, 0, size); *ret_page = pool->pages[pageno]; } else { pr_err_once("ERROR: %u KiB atomic DMA coherent pool is too small!\n" @@ -208,6 +209,7 @@ static void *arm64_swiotlb_alloc_coherent(struct device *dev, size_t size, page = pfn_to_page(pfn); addr = page_address(page); + memset(addr, 0, size); if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs) || dma_get_attr(DMA_ATTR_STRONGLY_ORDERED, attrs)) { From 1d57e33f2f3554e36f348b94650faed631699e08 Mon Sep 17 00:00:00 2001 From: Mohamad Ayyash Date: Tue, 24 May 2016 12:57:16 -0700 Subject: [PATCH 155/320] Replace %p with %pK to prevent leaking kernel address BUG: 27532522 Change-Id: Ic0710a9a8cfc682acd88ecf3bbfeece2d798c4a4 Signed-off-by: Mohamad Ayyash --- net/netfilter/xt_qtaguid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c index 82b06f91fb488..c690e0f19b454 100644 --- a/net/netfilter/xt_qtaguid.c +++ b/net/netfilter/xt_qtaguid.c @@ -1923,7 +1923,7 @@ static int qtaguid_ctrl_proc_show(struct seq_file *m, void *v) ); f_count = atomic_long_read( &sock_tag_entry->socket->file->f_count); - seq_printf(m, "sock=%p tag=0x%llx (uid=%u) pid=%u " + seq_printf(m, "sock=%pK tag=0x%llx (uid=%u) pid=%u " "f_count=%lu\n", sock_tag_entry->sk, sock_tag_entry->tag, uid, From 26e8900012e64508e4018ee5a3cc80b8c9e8f6d9 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 23 Apr 2015 12:46:16 +0100 Subject: [PATCH 156/320] arm64: dma-mapping: always clear allocated buffers [ Upstream commit 6829e274a623187c24f7cfc0e3d35f25d087fcc5 ] Buffers allocated by dma_alloc_coherent() are always zeroed on Alpha, ARM (32bit), MIPS, PowerPC, x86/x86_64 and probably other architectures. It turned out that some drivers rely on this 'feature'. Allocated buffer might be also exposed to userspace with dma_mmap() call, so clearing it is desired from security point of view to avoid exposing random memory to userspace. This patch unifies dma_alloc_coherent() behavior on ARM64 architecture with other implementations by unconditionally zeroing allocated buffer. CRs-Fixed: 1041735 Change-Id: I74bf024e0f603ca8c0b05430dc2ee154d579cfb2 Cc: # v3.14+ Signed-off-by: Marek Szyprowski Signed-off-by: Will Deacon Signed-off-by: Sasha Levin Git-commit: a142e9641dcbead2c8845c949ad518acac96ed28 Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git [lmark@codeaurora.org: resolve merge conflicts] Signed-off-by: Liam Mark --- arch/arm64/mm/dma-mapping.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index d5a107dc275a1..96092f271b528 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -88,6 +88,7 @@ static void *__alloc_from_pool(size_t size, struct page **ret_page) if (pageno < pool->nr_pages) { bitmap_set(pool->bitmap, pageno, count); ptr = pool->vaddr + PAGE_SIZE * pageno; + memset(ptr, 0, size); *ret_page = pool->pages[pageno]; } else { pr_err_once("ERROR: %u KiB atomic DMA coherent pool is too small!\n" @@ -208,6 +209,7 @@ static void *arm64_swiotlb_alloc_coherent(struct device *dev, size_t size, page = pfn_to_page(pfn); addr = page_address(page); + memset(addr, 0, size); if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs) || dma_get_attr(DMA_ATTR_STRONGLY_ORDERED, attrs)) { From cf3a8204fc33eefcc826a71956c8e9d9fc8d71a8 Mon Sep 17 00:00:00 2001 From: Shalini Krishnamoorthi Date: Tue, 2 Aug 2016 10:29:00 -0700 Subject: [PATCH 157/320] msm: mdss: Fix to validate data copied from user space The overlay zorder values copied from user space are used as index in left_lm_zo_cnt and right_lm_zo_cnt. This fix will validate the overlay zorder value copied from user space to not go beyond MDSS_MDP_MAX_STAGE, thus preventing any arbitrary increments in kernel memory. CRs-Fixed: 1049232 Change-Id: Ie8e65ce9f58cb357204bfa4c6a6e0fccec82d5ba Signed-off-by: Shalini Krishnamoorthi --- drivers/video/msm/mdss/mdss_mdp_overlay.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c index 3af0c8ad57d31..c61574478a4c3 100644 --- a/drivers/video/msm/mdss/mdss_mdp_overlay.c +++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c @@ -3306,16 +3306,20 @@ static int __mdss_overlay_src_split_sort(struct msm_fb_data_type *mfd, __overlay_swap_func); for (i = 0; i < num_ovs; i++) { + if (ovs[i].z_order >= MDSS_MDP_MAX_STAGE) { + pr_err("invalid stage:%u\n", ovs[i].z_order); + return -EINVAL; + } if (ovs[i].dst_rect.x < left_lm_w) { if (left_lm_zo_cnt[ovs[i].z_order] == 2) { - pr_err("more than 2 ov @ stage%d on left lm\n", + pr_err("more than 2 ov @ stage%u on left lm\n", ovs[i].z_order); return -EINVAL; } left_lm_zo_cnt[ovs[i].z_order]++; } else { if (right_lm_zo_cnt[ovs[i].z_order] == 2) { - pr_err("more than 2 ov @ stage%d on right lm\n", + pr_err("more than 2 ov @ stage%u on right lm\n", ovs[i].z_order); return -EINVAL; } From 848991c9af32763de217935f40112186e2cd5940 Mon Sep 17 00:00:00 2001 From: Shalini Krishnamoorthi Date: Tue, 2 Aug 2016 10:29:00 -0700 Subject: [PATCH 158/320] msm: mdss: Fix to validate data copied from user space The overlay zorder values copied from user space are used as index in left_lm_zo_cnt and right_lm_zo_cnt. This fix will validate the overlay zorder value copied from user space to not go beyond MDSS_MDP_MAX_STAGE, thus preventing any arbitrary increments in kernel memory. CRs-Fixed: 1049232 Change-Id: Ie8e65ce9f58cb357204bfa4c6a6e0fccec82d5ba Signed-off-by: Shalini Krishnamoorthi --- drivers/video/msm/mdss/mdss_mdp_overlay.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c index 5976753e111f3..26df88aee1aa7 100644 --- a/drivers/video/msm/mdss/mdss_mdp_overlay.c +++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c @@ -3223,16 +3223,20 @@ static int __mdss_overlay_src_split_sort(struct msm_fb_data_type *mfd, __overlay_swap_func); for (i = 0; i < num_ovs; i++) { + if (ovs[i].z_order >= MDSS_MDP_MAX_STAGE) { + pr_err("invalid stage:%u\n", ovs[i].z_order); + return -EINVAL; + } if (ovs[i].dst_rect.x < left_lm_w) { if (left_lm_zo_cnt[ovs[i].z_order] == 2) { - pr_err("more than 2 ov @ stage%d on left lm\n", + pr_err("more than 2 ov @ stage%u on left lm\n", ovs[i].z_order); return -EINVAL; } left_lm_zo_cnt[ovs[i].z_order]++; } else { if (right_lm_zo_cnt[ovs[i].z_order] == 2) { - pr_err("more than 2 ov @ stage%d on right lm\n", + pr_err("more than 2 ov @ stage%u on right lm\n", ovs[i].z_order); return -EINVAL; } From 130210d2d16943a16c2493ce32541da3d710c126 Mon Sep 17 00:00:00 2001 From: Abhijeet Dharmapurikar Date: Wed, 15 Jun 2016 09:46:21 -0700 Subject: [PATCH 159/320] spmi: prevent showing the address of spmidev Creating devices with the address of the container spmidev is not indicative of the actual hardware device it represents. Instead use an unique id to indicate the device it represents. CRs-Fixed: 1024197 Change-Id: Id18e2a19f4fa1249901a3f275defa8f589270d69 Signed-off-by: Abhijeet Dharmapurikar --- drivers/spmi/spmi.c | 18 +++++++++++++++--- include/linux/spmi.h | 6 +++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c index bbfb72adc82db..eb614783e608f 100644 --- a/drivers/spmi/spmi.c +++ b/drivers/spmi/spmi.c @@ -32,6 +32,7 @@ struct spmii_boardinfo { static DEFINE_MUTEX(board_lock); static LIST_HEAD(board_list); static DEFINE_IDR(ctrl_idr); +static DEFINE_IDA(spmi_devid_ida); static struct device_type spmi_dev_type; static struct device_type spmi_ctrl_type; @@ -229,22 +230,32 @@ int spmi_add_device(struct spmi_device *spmidev) { int rc; struct device *dev = get_valid_device(spmidev); + int id; if (!dev) { pr_err("invalid SPMI device\n"); return -EINVAL; } + id = ida_simple_get(&spmi_devid_ida, 0, 0, GFP_KERNEL); + if (id < 0) { + pr_err("No id available status = %d\n", id); + return id; + } + /* Set the device name */ - dev_set_name(dev, "%s-%p", spmidev->name, spmidev); + spmidev->id = id; + dev_set_name(dev, "%s-%d", spmidev->name, spmidev->id); /* Device may be bound to an active driver when this returns */ rc = device_add(dev); - if (rc < 0) + if (rc < 0) { + ida_simple_remove(&spmi_devid_ida, spmidev->id); dev_err(dev, "Can't add %s, status %d\n", dev_name(dev), rc); - else + } else { dev_dbg(dev, "device %s registered\n", dev_name(dev)); + } return rc; } @@ -292,6 +303,7 @@ EXPORT_SYMBOL_GPL(spmi_new_device); void spmi_remove_device(struct spmi_device *spmi_dev) { device_unregister(&spmi_dev->dev); + ida_simple_remove(&spmi_devid_ida, spmi_dev->id); } EXPORT_SYMBOL_GPL(spmi_remove_device); diff --git a/include/linux/spmi.h b/include/linux/spmi.h index b581de80bbacf..5a8525d7694d5 100644 --- a/include/linux/spmi.h +++ b/include/linux/spmi.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -120,6 +120,9 @@ struct spmi_resource { * @dev_node: array of SPMI resources when used with spmi-dev-container. * @num_dev_node: number of device_node structures. * @sid: Slave Identifier. + * @id: Unique identifier to differentiate from other spmi devices with + * possibly same name. + * */ struct spmi_device { struct device dev; @@ -129,6 +132,7 @@ struct spmi_device { struct spmi_resource *dev_node; u32 num_dev_node; u8 sid; + int id; }; #define to_spmi_device(d) container_of(d, struct spmi_device, dev) From 495a24d893a683d05245351f1b84e1c7a7e6ffbc Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 19 Feb 2016 17:36:21 -0800 Subject: [PATCH 160/320] AIO: properly check iovec sizes In Linus's tree, the iovec code has been reworked massively, but in older kernels the AIO layer should be checking this before passing the request on to other layers. Many thanks to Ben Hawkes of Google Project Zero for pointing out the issue. Change-Id: I625e1b4376bb2342d6c5f88eb3f202e99a0c5b07 Reported-by: Ben Hawkes Acked-by: Benjamin LaHaise Tested-by: Willy Tarreau [backported to 3.10 - willy] Signed-off-by: Greg Kroah-Hartman Git-commit: 8a5e5e02fc83aaf67053ab53b359af08c6c49aaf Git-repo: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git Signed-off-by: Ravi Kumar Siddojigari --- fs/aio.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/aio.c b/fs/aio.c index ded94c4fa30d3..9798d4edfd8f2 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -977,12 +977,17 @@ static ssize_t aio_setup_vectored_rw(int rw, struct kiocb *kiocb, bool compat) static ssize_t aio_setup_single_vector(int rw, struct kiocb *kiocb) { - if (unlikely(!access_ok(!rw, kiocb->ki_buf, kiocb->ki_nbytes))) - return -EFAULT; + size_t len = kiocb->ki_nbytes; + + if (len > MAX_RW_COUNT) + len = MAX_RW_COUNT; + + if (unlikely(!access_ok(!rw, kiocb->ki_buf, len))) + return -EFAULT; kiocb->ki_iovec = &kiocb->ki_inline_vec; kiocb->ki_iovec->iov_base = kiocb->ki_buf; - kiocb->ki_iovec->iov_len = kiocb->ki_nbytes; + kiocb->ki_iovec->iov_len = len; kiocb->ki_nr_segs = 1; return 0; } From 077199fc58b3553c5641a8ac240ec2b5801bf19a Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 10 Jan 2016 22:40:55 -0800 Subject: [PATCH 161/320] tty: Fix unsafe ldisc reference via ioctl(TIOCGETD) ioctl(TIOCGETD) retrieves the line discipline id directly from the ldisc because the line discipline id (c_line) in termios is untrustworthy; userspace may have set termios via ioctl(TCSETS*) without actually changing the line discipline via ioctl(TIOCSETD). However, directly accessing the current ldisc via tty->ldisc is unsafe; the ldisc ptr dereferenced may be stale if the line discipline is changing via ioctl(TIOCSETD) or hangup. Wait for the line discipline reference (just like read() or write()) to retrieve the "current" line discipline id. Change-Id: I7b2e474af7e1885a1ca7e277ee7478a3c0ec01a7 Cc: Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman Git-Commit:5c17c861a357e9458001f021a7afa7aab9937439 Git-Repo: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git Signed-off-by: Ravi Kumar Siddojigari --- drivers/tty/tty_io.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 8db44198af1f3..494bf9b9764f0 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2569,6 +2569,28 @@ static int tiocsetd(struct tty_struct *tty, int __user *p) return ret; } +/** + * tiocgetd - get line discipline + * @tty: tty device + * @p: pointer to user data + * + * Retrieves the line discipline id directly from the ldisc. + * + * Locking: waits for ldisc reference (in case the line discipline + * is changing or the tty is being hungup) + */ + +static int tiocgetd(struct tty_struct *tty, int __user *p) +{ + struct tty_ldisc *ld; + int ret; + + ld = tty_ldisc_ref_wait(tty); + ret = put_user(ld->ops->num, p); + tty_ldisc_deref(ld); + return ret; +} + /** * send_break - performed time break * @tty: device to break on @@ -2786,7 +2808,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case TIOCGSID: return tiocgsid(tty, real_tty, p); case TIOCGETD: - return put_user(tty->ldisc->ops->num, (int __user *)p); + return tiocgetd(tty, p); case TIOCSETD: return tiocsetd(tty, p); case TIOCVHANGUP: From 6f183a67d5dce6baedef94a8d4763a409fce707a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 19 Feb 2016 17:36:21 -0800 Subject: [PATCH 162/320] AIO: properly check iovec sizes In Linus's tree, the iovec code has been reworked massively, but in older kernels the AIO layer should be checking this before passing the request on to other layers. Many thanks to Ben Hawkes of Google Project Zero for pointing out the issue. Change-Id: I625e1b4376bb2342d6c5f88eb3f202e99a0c5b07 Reported-by: Ben Hawkes Acked-by: Benjamin LaHaise Tested-by: Willy Tarreau [backported to 3.10 - willy] Signed-off-by: Greg Kroah-Hartman Git-commit: 8a5e5e02fc83aaf67053ab53b359af08c6c49aaf Git-repo: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git Signed-off-by: Ravi Kumar Siddojigari --- fs/aio.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/aio.c b/fs/aio.c index ded94c4fa30d3..9798d4edfd8f2 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -977,12 +977,17 @@ static ssize_t aio_setup_vectored_rw(int rw, struct kiocb *kiocb, bool compat) static ssize_t aio_setup_single_vector(int rw, struct kiocb *kiocb) { - if (unlikely(!access_ok(!rw, kiocb->ki_buf, kiocb->ki_nbytes))) - return -EFAULT; + size_t len = kiocb->ki_nbytes; + + if (len > MAX_RW_COUNT) + len = MAX_RW_COUNT; + + if (unlikely(!access_ok(!rw, kiocb->ki_buf, len))) + return -EFAULT; kiocb->ki_iovec = &kiocb->ki_inline_vec; kiocb->ki_iovec->iov_base = kiocb->ki_buf; - kiocb->ki_iovec->iov_len = kiocb->ki_nbytes; + kiocb->ki_iovec->iov_len = len; kiocb->ki_nr_segs = 1; return 0; } From 649611bb4b8fdd0282d790f5a56bd0e25dc9fece Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 10 Jan 2016 22:40:55 -0800 Subject: [PATCH 163/320] tty: Fix unsafe ldisc reference via ioctl(TIOCGETD) ioctl(TIOCGETD) retrieves the line discipline id directly from the ldisc because the line discipline id (c_line) in termios is untrustworthy; userspace may have set termios via ioctl(TCSETS*) without actually changing the line discipline via ioctl(TIOCSETD). However, directly accessing the current ldisc via tty->ldisc is unsafe; the ldisc ptr dereferenced may be stale if the line discipline is changing via ioctl(TIOCSETD) or hangup. Wait for the line discipline reference (just like read() or write()) to retrieve the "current" line discipline id. Change-Id: I7b2e474af7e1885a1ca7e277ee7478a3c0ec01a7 Cc: Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman Git-Commit:5c17c861a357e9458001f021a7afa7aab9937439 Git-Repo: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git Signed-off-by: Ravi Kumar Siddojigari --- drivers/tty/tty_io.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 8db44198af1f3..494bf9b9764f0 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2569,6 +2569,28 @@ static int tiocsetd(struct tty_struct *tty, int __user *p) return ret; } +/** + * tiocgetd - get line discipline + * @tty: tty device + * @p: pointer to user data + * + * Retrieves the line discipline id directly from the ldisc. + * + * Locking: waits for ldisc reference (in case the line discipline + * is changing or the tty is being hungup) + */ + +static int tiocgetd(struct tty_struct *tty, int __user *p) +{ + struct tty_ldisc *ld; + int ret; + + ld = tty_ldisc_ref_wait(tty); + ret = put_user(ld->ops->num, p); + tty_ldisc_deref(ld); + return ret; +} + /** * send_break - performed time break * @tty: device to break on @@ -2786,7 +2808,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case TIOCGSID: return tiocgsid(tty, real_tty, p); case TIOCGETD: - return put_user(tty->ldisc->ops->num, (int __user *)p); + return tiocgetd(tty, p); case TIOCSETD: return tiocsetd(tty, p); case TIOCVHANGUP: From bc664cd0134de05691079e345ddffa137ec22ef2 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 13 Feb 2016 02:34:52 +0000 Subject: [PATCH 164/320] pipe: Fix buffer offset after partially failed read Quoting the RHEL advisory: > It was found that the fix for CVE-2015-1805 incorrectly kept buffer > offset and buffer length in sync on a failed atomic read, potentially > resulting in a pipe buffer state corruption. A local, unprivileged user > could use this flaw to crash the system or leak kernel memory to user > space. (CVE-2016-0774, Moderate) The same flawed fix was applied to stable branches from 2.6.32.y to 3.14.y inclusive, and I was able to reproduce the issue on 3.2.y. We need to give pipe_iov_copy_to_user() a separate offset variable and only update the buffer offset if it succeeds. References: https://rhn.redhat.com/errata/RHSA-2016-0103.html cherry picked from commit feae3ca2e5e1a8f44aa6290255d3d9709985d0b2) Git-commit: feae3ca2e5e1a8f44aa6290255d3d9709985d0b2 Git-repo : https://android.googlesource.com/kernel/common change-Id: I988802f38acf40c7671fa0978880928b02d29b56 Signed-off-by: Srinivasa Rao Kuppala --- fs/pipe.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/pipe.c b/fs/pipe.c index 3e7ab278bb0c0..50267e6ba6886 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -401,6 +401,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, void *addr; size_t chars = buf->len, remaining; int error, atomic; + int offset; if (chars > total_len) chars = total_len; @@ -414,9 +415,10 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, atomic = !iov_fault_in_pages_write(iov, chars); remaining = chars; + offset = buf->offset; redo: addr = ops->map(pipe, buf, atomic); - error = pipe_iov_copy_to_user(iov, addr, &buf->offset, + error = pipe_iov_copy_to_user(iov, addr, &offset, &remaining, atomic); ops->unmap(pipe, buf, addr); if (unlikely(error)) { @@ -432,6 +434,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, break; } ret += chars; + buf->offset += chars; buf->len -= chars; /* Was it a packet buffer? Clean up and exit */ From 7a47bea52d1ede65471d58a611df206b0f8ececa Mon Sep 17 00:00:00 2001 From: Dennis Cagle Date: Mon, 1 Aug 2016 11:48:04 -0700 Subject: [PATCH 165/320] adf: Zero out the mapping data The adf_device_post_nocopy function eventually calls the dma_buf_attach and dma_buf_map_attachment functions. If the dma_buf_attach function succeeds but the dma_buf_map_attachment function fails, both the adf_buffer_map function and the adf_device_post_nocopy function will call the dma_buf_detach function to tear down the same dma-buf attachment. b/28447556 Change-Id: I8eb40486496fe2a2ae5dfa1be4b76a4af0d6b827 Signed-off-by: Dennis Cagle --- drivers/video/adf/adf_client.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/video/adf/adf_client.c b/drivers/video/adf/adf_client.c index 8061d8e6b9fbd..75b2f0b18522e 100644 --- a/drivers/video/adf/adf_client.c +++ b/drivers/video/adf/adf_client.c @@ -305,8 +305,10 @@ static int adf_buffer_map(struct adf_device *dev, struct adf_buffer *buf, } done: - if (ret < 0) + if (ret < 0) { adf_buffer_mapping_cleanup(mapping, buf); + memset(mapping, 0, sizeof(*mapping)); + } return ret; } From 5a99ecbb4546ddb28019c604cb5e4a755be0671e Mon Sep 17 00:00:00 2001 From: Krishna Srinivas Date: Fri, 17 Jun 2016 10:33:45 -0700 Subject: [PATCH 166/320] msm: mdss: Fix memleak in framebuffer register and remove In FB registration, free allocated memory if an error condition is hit. Also free allocated memory in FB remove. Change-Id: I533e2d6a760ebd52047c521c1a1e85bfc754fce1 Signed-off-by: Krishna Srinivas --- drivers/video/msm/mdss/mdss_fb.c | 2 ++ drivers/video/msm/mdss/mdss_panel.c | 11 ++++++++--- drivers/video/msm/mdss/mdss_panel.h | 1 + 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c index 96fdc93f95015..c06abd3d95167 100644 --- a/drivers/video/msm/mdss/mdss_fb.c +++ b/drivers/video/msm/mdss/mdss_fb.c @@ -922,6 +922,8 @@ static int mdss_fb_remove(struct platform_device *pdev) if (mfd->key != MFD_KEY) return -EINVAL; + mdss_panel_debugfs_cleanup(mfd->panel_info); + if (mdss_fb_suspend_sub(mfd)) pr_err("msm_fb_remove: can't stop the device %d\n", mfd->index); diff --git a/drivers/video/msm/mdss/mdss_panel.c b/drivers/video/msm/mdss/mdss_panel.c index 4095eee43046a..a240429d35c79 100644 --- a/drivers/video/msm/mdss/mdss_panel.c +++ b/drivers/video/msm/mdss/mdss_panel.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -33,6 +33,7 @@ int mdss_panel_debugfs_setup(struct mdss_panel_info *panel_info, struct dentry } debugfs_info->root = debugfs_create_dir(dsi_str, parent); + debugfs_info->parent = parent; if (IS_ERR_OR_NULL(debugfs_info->root)) { pr_err("Debugfs create dir failed with error: %ld\n", PTR_ERR(debugfs_info->root)); @@ -100,6 +101,7 @@ int mdss_panel_debugfs_init(struct mdss_panel_info *panel_info) dsi_str); if (rc) { pr_err("error in initilizing panel debugfs\n"); + mdss_panel_debugfs_cleanup(&pdata->panel_info); return rc; } pdata = pdata->next; @@ -113,13 +115,16 @@ void mdss_panel_debugfs_cleanup(struct mdss_panel_info *panel_info) { struct mdss_panel_data *pdata; struct mdss_panel_debugfs_info *debugfs_info; + struct dentry *parent = NULL; pdata = container_of(panel_info, struct mdss_panel_data, panel_info); do { debugfs_info = pdata->panel_info.debugfs_info; - if (debugfs_info && debugfs_info->root) - debugfs_remove_recursive(debugfs_info->root); + if (debugfs_info && !parent) + parent = debugfs_info->parent; + kfree(debugfs_info); pdata = pdata->next; } while (pdata); + debugfs_remove_recursive(parent); pr_debug("Cleaned up mdss_panel_debugfs_info\n"); } diff --git a/drivers/video/msm/mdss/mdss_panel.h b/drivers/video/msm/mdss/mdss_panel.h index 1e3673add268c..61452f66dc2f8 100644 --- a/drivers/video/msm/mdss/mdss_panel.h +++ b/drivers/video/msm/mdss/mdss_panel.h @@ -466,6 +466,7 @@ struct mdss_panel_debugfs_info { u32 xres; u32 yres; struct lcd_panel_info lcdc; + struct dentry *parent; u32 override_flag; char frame_rate; struct mdss_panel_debugfs_info *next; From 2d34ce0ce203f06128583dc23dfef4cc6c1e8df8 Mon Sep 17 00:00:00 2001 From: Sanjay Singh Date: Tue, 9 Aug 2016 17:39:35 +0530 Subject: [PATCH 167/320] msm: vidc: use %pK instead of %p which respects kptr_restrict sysctl Hide kernel pointers from unprivileged ussers by using %pK format- specifier instead of %p. This respects the kptr_restrict sysctl setting which is by default on. So by default %pK will print zeroes as address. echo 1 to kptr_restrict to print proper kernel addresses. CRs-Fixed: 987018 Change-Id: I4772257a557c6730ecc0624cbc8e5614e893e9fd Signed-off-by: Sanjay Singh --- .../platform/msm/vidc/hfi_packetization.c | 8 +- .../platform/msm/vidc/hfi_response_handler.c | 44 +++--- drivers/media/platform/msm/vidc/msm_smem.c | 20 +-- .../media/platform/msm/vidc/msm_v4l2_vidc.c | 6 +- drivers/media/platform/msm/vidc/msm_vdec.c | 36 ++--- drivers/media/platform/msm/vidc/msm_venc.c | 30 ++-- drivers/media/platform/msm/vidc/msm_vidc.c | 36 ++--- .../media/platform/msm/vidc/msm_vidc_common.c | 146 +++++++++--------- .../media/platform/msm/vidc/msm_vidc_debug.c | 18 +-- drivers/media/platform/msm/vidc/q6_hfi.c | 22 +-- drivers/media/platform/msm/vidc/venus_hfi.c | 84 +++++----- drivers/media/platform/msm/vidc/vidc_hfi.c | 4 +- 12 files changed, 227 insertions(+), 227 deletions(-) diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c index f74ae08880567..d49acc41a775c 100644 --- a/drivers/media/platform/msm/vidc/hfi_packetization.c +++ b/drivers/media/platform/msm/vidc/hfi_packetization.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1300,7 +1300,7 @@ int create_pkt_cmd_session_set_property( break; default: dprintk(VIDC_ERR, - "Invalid Rate control setting: 0x%p\n", + "Invalid Rate control setting: 0x%pK\n", pdata); break; } @@ -1956,7 +1956,7 @@ int create_pkt_ssr_cmd(enum hal_ssr_trigger_type type, struct hfi_cmd_sys_test_ssr_packet *pkt) { if (!pkt) { - dprintk(VIDC_ERR, "Invalid params, device: %p\n", pkt); + dprintk(VIDC_ERR, "Invalid params, device: %pK\n", pkt); return -EINVAL; } pkt->size = sizeof(struct hfi_cmd_sys_test_ssr_packet); @@ -1969,7 +1969,7 @@ int create_pkt_cmd_sys_image_version( struct hfi_cmd_sys_get_property_packet *pkt) { if (!pkt) { - dprintk(VIDC_ERR, "%s invalid param :%p\n", __func__, pkt); + dprintk(VIDC_ERR, "%s invalid param :%pK\n", __func__, pkt); return -EINVAL; } pkt->size = sizeof(struct hfi_cmd_sys_get_property_packet); diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c index f4ffecbd0f58a..416fc9a60ed2d 100644 --- a/drivers/media/platform/msm/vidc/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -258,7 +258,7 @@ static void hfi_process_event_notify(msm_vidc_callback callback, u32 device_id, hfi_process_sys_error(callback, device_id); break; case HFI_EVENT_SESSION_PROPERTY_CHANGED: - dprintk(VIDC_INFO, "HFI_EVENT_SESSION_PROPERTY_CHANGED[%p]\n", + dprintk(VIDC_INFO, "HFI_EVENT_SESSION_PROPERTY_CHANGED[%pK]\n", session); break; } @@ -270,24 +270,24 @@ static void hfi_process_event_notify(msm_vidc_callback callback, u32 device_id, switch (pkt->event_id) { case HFI_EVENT_SESSION_ERROR: - dprintk(VIDC_INFO, "HFI_EVENT_SESSION_ERROR[%p]\n", session); + dprintk(VIDC_INFO, "HFI_EVENT_SESSION_ERROR[%pK]\n", session); hfi_process_session_error(callback, device_id, session, pkt); break; case HFI_EVENT_SESSION_SEQUENCE_CHANGED: - dprintk(VIDC_INFO, "HFI_EVENT_SESSION_SEQUENCE_CHANGED[%p]\n", + dprintk(VIDC_INFO, "HFI_EVENT_SESSION_SEQUENCE_CHANGED[%pK]\n", session); hfi_process_sess_evt_seq_changed(callback, device_id, session, pkt); break; case HFI_EVENT_RELEASE_BUFFER_REFERENCE: - dprintk(VIDC_INFO, "HFI_EVENT_RELEASE_BUFFER_REFERENCE[%p]\n", + dprintk(VIDC_INFO, "HFI_EVENT_RELEASE_BUFFER_REFERENCE[%pK]\n", session); hfi_process_evt_release_buffer_ref(callback, device_id, session, pkt); break; default: dprintk(VIDC_WARN, - "hal_process_event_notify: unknown_event_id[%p]\n", + "hal_process_event_notify: unknown_event_id[%pK]\n", session); break; } @@ -691,7 +691,7 @@ static void hfi_process_sess_get_prop_profile_level( dprintk(VIDC_DBG, "Entered %s\n", __func__); if (!prop) { dprintk(VIDC_ERR, - "hal_process_sess_get_profile_level: bad_prop: %p\n", + "hal_process_sess_get_profile_level: bad_prop: %pK\n", prop); return; } @@ -722,7 +722,7 @@ static void hfi_process_sess_get_prop_buf_req( if (!prop) { dprintk(VIDC_ERR, - "hal_process_sess_get_prop_buf_req: bad_prop: %p\n", + "hal_process_sess_get_prop_buf_req: bad_prop: %pK\n", prop); return; } @@ -841,7 +841,7 @@ static void hfi_process_session_prop_info(msm_vidc_callback callback, struct buffer_requirements buff_req; memset(&buff_req, 0, sizeof(struct buffer_requirements)); - dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO[%p]\n", session); + dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO[%pK]\n", session); if (pkt->size < sizeof(struct hfi_msg_session_property_info_packet)) { dprintk(VIDC_ERR, @@ -897,7 +897,7 @@ static void hfi_process_session_init_done( memset(&session_init_done, 0, sizeof(struct vidc_hal_session_init_done)); - dprintk(VIDC_DBG, "RECEIVED: SESSION_INIT_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_INIT_DONE[%pK]\n", session); if (sizeof(struct hfi_msg_sys_session_init_done_packet) > pkt->size) { @@ -915,7 +915,7 @@ static void hfi_process_session_init_done( pkt, &session_init_done); } else { dprintk(VIDC_WARN, - "Sess init failed: 0x%p, 0x%p\n", + "Sess init failed: 0x%pK, 0x%pK\n", session->session_id, session); } cmd_done.size = sizeof(struct vidc_hal_session_init_done); @@ -927,7 +927,7 @@ static void hfi_process_session_load_res_done(msm_vidc_callback callback, struct hfi_msg_session_load_resources_done_packet *pkt) { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_LOAD_RESOURCES_DONE[%p]\n", + dprintk(VIDC_DBG, "RECEIVED: SESSION_LOAD_RESOURCES_DONE[%pK]\n", session); if (sizeof(struct hfi_msg_session_load_resources_done_packet) != @@ -952,7 +952,7 @@ static void hfi_process_session_flush_done(msm_vidc_callback callback, { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_FLUSH_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_FLUSH_DONE[%pK]\n", session); if (sizeof(struct hfi_msg_session_flush_done_packet) != pkt->size) { dprintk(VIDC_ERR, @@ -975,7 +975,7 @@ static void hfi_process_session_etb_done(msm_vidc_callback callback, { struct msm_vidc_cb_data_done data_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%pK]\n", session); if (!pkt || pkt->size < sizeof(struct hfi_msg_session_empty_buffer_done_packet)) { @@ -1016,7 +1016,7 @@ static void hfi_process_session_ftb_done(msm_vidc_callback callback, return; } - dprintk(VIDC_DBG, "RECEIVED: SESSION_FTB_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_FTB_DONE[%pK]\n", session); if (is_decoder == 0) { struct hfi_msg_session_fill_buffer_done_compressed_packet *pkt = @@ -1116,7 +1116,7 @@ static void hfi_process_session_start_done(msm_vidc_callback callback, { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_START_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_START_DONE[%pK]\n", session); if (!pkt || pkt->size != sizeof(struct hfi_msg_session_start_done_packet)) { @@ -1139,7 +1139,7 @@ static void hfi_process_session_stop_done(msm_vidc_callback callback, { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_STOP_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_STOP_DONE[%pK]\n", session); if (!pkt || pkt->size != sizeof(struct hfi_msg_session_stop_done_packet)) { @@ -1162,7 +1162,7 @@ static void hfi_process_session_rel_res_done(msm_vidc_callback callback, { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_RELEASE_RESOURCES_DONE[%p]\n", + dprintk(VIDC_DBG, "RECEIVED: SESSION_RELEASE_RESOURCES_DONE[%pK]\n", session); if (!pkt || pkt->size != @@ -1193,7 +1193,7 @@ static void hfi_process_session_rel_buf_done(msm_vidc_callback callback, pkt ? pkt->size : 0); return; } - dprintk(VIDC_DBG, "RECEIVED:SESSION_RELEASE_BUFFER_DONE[%p]\n", + dprintk(VIDC_DBG, "RECEIVED:SESSION_RELEASE_BUFFER_DONE[%pK]\n", session); cmd_done.device_id = device_id; @@ -1215,7 +1215,7 @@ static void hfi_process_session_end_done(msm_vidc_callback callback, { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_END_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_END_DONE[%pK]\n", session); if (!pkt || pkt->size != sizeof(struct hfi_msg_sys_session_end_done_packet)) { @@ -1237,7 +1237,7 @@ static void hfi_process_session_abort_done(msm_vidc_callback callback, { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_ABORT_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_ABORT_DONE[%pK]\n", session); if (!pkt || pkt->size != sizeof(struct hfi_msg_sys_session_abort_done_packet)) { @@ -1274,7 +1274,7 @@ static void hfi_process_session_get_seq_hdr_done(msm_vidc_callback callback, __func__); return; } - dprintk(VIDC_DBG, "RECEIVED:SESSION_GET_SEQ_HDR_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED:SESSION_GET_SEQ_HDR_DONE[%pK]\n", session); data_done.device_id = device_id; data_done.size = sizeof(struct msm_vidc_cb_data_done); diff --git a/drivers/media/platform/msm/vidc/msm_smem.c b/drivers/media/platform/msm/vidc/msm_smem.c index 50e375df67e86..f0455cc9e9854 100644 --- a/drivers/media/platform/msm/vidc/msm_smem.c +++ b/drivers/media/platform/msm/vidc/msm_smem.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -34,7 +34,7 @@ static int get_device_address(struct smem_client *smem_client, struct ion_client *clnt = NULL; if (!iova || !buffer_size || !hndl || !smem_client) { - dprintk(VIDC_ERR, "Invalid params: %p, %p, %p, %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK, %pK, %pK, %pK\n", smem_client, hndl, iova, buffer_size); return -EINVAL; } @@ -86,7 +86,7 @@ static void put_device_address(struct smem_client *smem_client, struct ion_client *clnt = NULL; if (!hndl || !smem_client) { - dprintk(VIDC_WARN, "Invalid params: %p, %p\n", + dprintk(VIDC_WARN, "Invalid params: %pK, %pK\n", smem_client, hndl); return; } @@ -120,7 +120,7 @@ static int ion_user_to_kernel(struct smem_client *client, int fd, u32 offset, hndl = ion_import_dma_buf(client->clnt, fd); if (IS_ERR_OR_NULL(hndl)) { - dprintk(VIDC_ERR, "Failed to get handle: %p, %d, %d, %p\n", + dprintk(VIDC_ERR, "Failed to get handle: %pK, %d, %d, %pK\n", client, fd, offset, hndl); rc = -ENOMEM; goto fail_import_fd; @@ -153,7 +153,7 @@ static int ion_user_to_kernel(struct smem_client *client, int fd, u32 offset, goto fail_device_address; } dprintk(VIDC_DBG, - "%s: ion_handle = 0x%p, fd = %d, device_addr = 0x%pa, size = %zx, kvaddr = 0x%p, buffer_type = %d, flags = 0x%lx\n", + "%s: ion_handle = 0x%pK, fd = %d, device_addr = 0x%pa, size = %zx, kvaddr = 0x%pK, buffer_type = %d, flags = 0x%lx\n", __func__, mem->smem_priv, fd, &mem->device_addr, mem->size, mem->kvaddr, mem->buffer_type, mem->flags); return rc; @@ -198,7 +198,7 @@ static int alloc_ion_mem(struct smem_client *client, size_t size, u32 align, hndl = ion_alloc(client->clnt, size, align, heap_mask, flags); if (IS_ERR_OR_NULL(hndl)) { dprintk(VIDC_ERR, - "Failed to allocate shared memory = %p, %zx, %d, 0x%x\n", + "Failed to allocate shared memory = %pK, %zx, %d, 0x%x\n", client, size, align, flags); rc = -ENOMEM; goto fail_shared_mem_alloc; @@ -236,7 +236,7 @@ static int alloc_ion_mem(struct smem_client *client, size_t size, u32 align, } mem->size = size; dprintk(VIDC_DBG, - "%s: ion_handle = 0x%p, device_addr = 0x%pa, size = 0x%zx, kvaddr = 0x%p, buffer_type = 0x%x, flags = 0x%lx\n", + "%s: ion_handle = 0x%pK, device_addr = 0x%pa, size = 0x%zx, kvaddr = 0x%pK, buffer_type = 0x%x, flags = 0x%lx\n", __func__, mem->smem_priv, &mem->device_addr, mem->size, mem->kvaddr, mem->buffer_type, mem->flags); @@ -254,7 +254,7 @@ static void free_ion_mem(struct smem_client *client, struct msm_smem *mem) int domain, partition, rc; dprintk(VIDC_DBG, - "%s: ion_handle = 0x%p, device_addr = 0x%pa, size = 0x%zx, kvaddr = 0x%p, buffer_type = 0x%x\n", + "%s: ion_handle = 0x%pK, device_addr = 0x%pa, size = 0x%zx, kvaddr = 0x%pK, buffer_type = 0x%x\n", __func__, mem->smem_priv, &mem->device_addr, mem->size, mem->kvaddr, mem->buffer_type); rc = msm_smem_get_domain_partition((void *)client, mem->flags, @@ -332,7 +332,7 @@ static int ion_cache_operations(struct smem_client *client, int rc = 0; int msm_cache_ops = 0; if (!mem || !client) { - dprintk(VIDC_ERR, "Invalid params: %p, %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK, %pK\n", mem, client); return -EINVAL; } @@ -379,7 +379,7 @@ int msm_smem_cache_operations(void *clt, struct msm_smem *mem, struct smem_client *client = clt; int rc = 0; if (!client) { - dprintk(VIDC_ERR, "Invalid params: %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK\n", client); return -EINVAL; } diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c index b57104354a50f..a46eda705ab18 100644 --- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -296,7 +296,7 @@ static int read_platform_resources(struct msm_vidc_core *core, struct platform_device *pdev) { if (!core || !pdev) { - dprintk(VIDC_ERR, "%s: Invalid params %p %p\n", + dprintk(VIDC_ERR, "%s: Invalid params %pK %pK\n", __func__, core, pdev); return -EINVAL; } @@ -641,7 +641,7 @@ static int msm_vidc_remove(struct platform_device *pdev) struct msm_vidc_core *core; if (!pdev) { - dprintk(VIDC_ERR, "%s invalid input %p", __func__, pdev); + dprintk(VIDC_ERR, "%s invalid input %pK", __func__, pdev); return -EINVAL; } core = pdev->dev.platform_data; diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c index 342a8bf2db33e..8c2b8731c2439 100644 --- a/drivers/media/platform/msm/vidc/msm_vdec.c +++ b/drivers/media/platform/msm/vidc/msm_vdec.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -791,7 +791,7 @@ int msm_vdec_prepare_buf(struct msm_vidc_inst *inst, if (inst->state == MSM_VIDC_CORE_INVALID || inst->core->state == VIDC_CORE_INVALID) { dprintk(VIDC_ERR, - "Core %p in bad state, ignoring prepare buf\n", + "Core %pK in bad state, ignoring prepare buf\n", inst->core); goto exit; } @@ -870,7 +870,7 @@ int msm_vdec_release_buf(struct msm_vidc_inst *inst, if (inst->state == MSM_VIDC_CORE_INVALID || core->state == VIDC_CORE_INVALID) { dprintk(VIDC_ERR, - "Core %p in bad state, ignoring release output buf\n", + "Core %pK in bad state, ignoring release output buf\n", core); goto exit; } @@ -963,7 +963,7 @@ int msm_vdec_reqbufs(struct msm_vidc_inst *inst, struct v4l2_requestbuffers *b) int rc = 0; if (!inst || !b) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, buffer = %p\n", inst, b); + "Invalid input, inst = %pK, buffer = %pK\n", inst, b); return -EINVAL; } q = msm_comm_get_vb2q(inst, b->type); @@ -994,7 +994,7 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) if (!inst || !f || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, format = %p\n", inst, f); + "Invalid input, inst = %pK, format = %pK\n", inst, f); return -EINVAL; } @@ -1157,7 +1157,7 @@ int msm_vdec_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a) fps = fps - 1; if (inst->prop.fps != fps) { - dprintk(VIDC_PROF, "reported fps changed for %p: %d->%d\n", + dprintk(VIDC_PROF, "reported fps changed for %pK: %d->%d\n", inst, inst->prop.fps, fps); inst->prop.fps = fps; msm_comm_init_dcvs_load(inst); @@ -1502,7 +1502,7 @@ int msm_vdec_querycap(struct msm_vidc_inst *inst, struct v4l2_capability *cap) { if (!inst || !cap) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, cap = %p\n", inst, cap); + "Invalid input, inst = %pK, cap = %pK\n", inst, cap); return -EINVAL; } strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver)); @@ -1522,7 +1522,7 @@ int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) int rc = 0; if (!inst || !f) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, f = %p\n", inst, f); + "Invalid input, inst = %pK, f = %pK\n", inst, f); return -EINVAL; } if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { @@ -1564,7 +1564,7 @@ static int msm_vdec_queue_setup(struct vb2_queue *q, if (!q || !num_buffers || !num_planes || !sizes || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %p, %p, %p\n", + dprintk(VIDC_ERR, "Invalid input, q = %pK, %pK, %pK\n", q, num_buffers, num_planes); return -EINVAL; } @@ -1725,7 +1725,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst) rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto fail_start; } msm_comm_init_dcvs_load(inst); @@ -1762,7 +1762,7 @@ static inline int stop_streaming(struct msm_vidc_inst *inst) rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); if (rc) dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); return rc; } @@ -1772,7 +1772,7 @@ static int msm_vdec_start_streaming(struct vb2_queue *q, unsigned int count) int rc = 0; struct hfi_device *hdev; if (!q || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %p\n", q); + dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); return -EINVAL; } inst = q->drv_priv; @@ -1805,7 +1805,7 @@ static int msm_vdec_stop_streaming(struct vb2_queue *q) struct msm_vidc_inst *inst; int rc = 0; if (!q || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %p\n", q); + dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); return -EINVAL; } inst = q->drv_priv; @@ -1830,7 +1830,7 @@ static int msm_vdec_stop_streaming(struct vb2_queue *q) if (rc) dprintk(VIDC_ERR, - "Failed to move inst: %p, cap = %d to state: %d\n", + "Failed to move inst: %pK, cap = %d to state: %d\n", inst, q->type, MSM_VIDC_RELEASE_RESOURCES_DONE); return rc; } @@ -1888,7 +1888,7 @@ int msm_vdec_cmd(struct msm_vidc_inst *inst, struct v4l2_decoder_cmd *dec) if (inst->state == MSM_VIDC_CORE_INVALID || core->state == VIDC_CORE_INVALID) { dprintk(VIDC_ERR, - "Core %p in bad state, Sending CLOSE event\n", + "Core %pK in bad state, Sending CLOSE event\n", core); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_CLOSE_DONE); @@ -1930,7 +1930,7 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) { int rc = 0; if (!inst) { - dprintk(VIDC_ERR, "Invalid input = %p\n", inst); + dprintk(VIDC_ERR, "Invalid input = %pK\n", inst); return -EINVAL; } inst->fmts[OUTPUT_PORT] = &vdec_formats[1]; @@ -2455,7 +2455,7 @@ static int msm_vdec_op_s_ctrl(struct v4l2_ctrl *ctrl) rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto failed_open_done; } @@ -2487,7 +2487,7 @@ static int msm_vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl) rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto failed_open_done; } for (c = 0; c < master->ncontrols; ++c) { diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c index c374dca86ebb7..f36a152656a6e 100644 --- a/drivers/media/platform/msm/vidc/msm_venc.c +++ b/drivers/media/platform/msm/vidc/msm_venc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1424,7 +1424,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst) rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto fail_start; } mutex_lock(&inst->pendingq.lock); @@ -1450,7 +1450,7 @@ static int msm_venc_start_streaming(struct vb2_queue *q, unsigned int count) struct msm_vidc_inst *inst; int rc = 0; if (!q || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %p\n", q); + dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); return -EINVAL; } inst = q->drv_priv; @@ -1477,7 +1477,7 @@ static int msm_venc_stop_streaming(struct vb2_queue *q) struct msm_vidc_inst *inst; int rc = 0; if (!q || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %p\n", q); + dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); return -EINVAL; } inst = q->drv_priv; @@ -1498,7 +1498,7 @@ static int msm_venc_stop_streaming(struct vb2_queue *q) if (rc) dprintk(VIDC_ERR, - "Failed to move inst: %p, cap = %d to state: %d\n", + "Failed to move inst: %pK, cap = %d to state: %d\n", inst, q->type, MSM_VIDC_CLOSE_DONE); return rc; } @@ -2854,7 +2854,7 @@ static int msm_venc_op_s_ctrl(struct v4l2_ctrl *ctrl) if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto failed_open_done; } @@ -2898,7 +2898,7 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) { int rc = 0; if (!inst) { - dprintk(VIDC_ERR, "Invalid input = %p\n", inst); + dprintk(VIDC_ERR, "Invalid input = %pK\n", inst); return -EINVAL; } inst->fmts[CAPTURE_PORT] = &venc_formats[1]; @@ -2980,7 +2980,7 @@ int msm_venc_querycap(struct msm_vidc_inst *inst, struct v4l2_capability *cap) { if (!inst || !cap) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, cap = %p\n", inst, cap); + "Invalid input, inst = %pK, cap = %pK\n", inst, cap); return -EINVAL; } strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver)); @@ -3000,7 +3000,7 @@ int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) int rc = 0; if (!inst || !f) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, f = %p\n", inst, f); + "Invalid input, inst = %pK, f = %pK\n", inst, f); return -EINVAL; } if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { @@ -3074,7 +3074,7 @@ int msm_venc_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a) fps = fps - 1; if (inst->prop.fps != fps) { - dprintk(VIDC_PROF, "reported fps changed for %p: %d->%d\n", + dprintk(VIDC_PROF, "reported fps changed for %pK: %d->%d\n", inst, inst->prop.fps, fps); inst->prop.fps = fps; frame_rate.frame_rate = inst->prop.fps * (0x1<<16); @@ -3127,7 +3127,7 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) struct hfi_device *hdev; if (!inst || !f) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, format = %p\n", inst, f); + "Invalid input, inst = %pK, format = %pK\n", inst, f); return -EINVAL; } @@ -3294,7 +3294,7 @@ int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) if (!inst || !f) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, format = %p\n", inst, f); + "Invalid input, inst = %pK, format = %pK\n", inst, f); return -EINVAL; } @@ -3359,7 +3359,7 @@ int msm_venc_reqbufs(struct msm_vidc_inst *inst, struct v4l2_requestbuffers *b) int rc = 0; if (!inst || !b) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, buffer = %p\n", inst, b); + "Invalid input, inst = %pK, buffer = %pK\n", inst, b); return -EINVAL; } q = msm_comm_get_vb2q(inst, b->type); @@ -3396,7 +3396,7 @@ int msm_venc_prepare_buf(struct msm_vidc_inst *inst, if (inst->state == MSM_VIDC_CORE_INVALID || inst->core->state == VIDC_CORE_INVALID) { dprintk(VIDC_ERR, - "Core %p in bad state, ignoring prepare buf\n", + "Core %pK in bad state, ignoring prepare buf\n", inst->core); goto exit; } @@ -3467,7 +3467,7 @@ int msm_venc_release_buf(struct msm_vidc_inst *inst, rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to release res done state\n", + "Failed to move inst: %pK to release res done state\n", inst); goto exit; } diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c index 9a3baade344b9..dcdd1d2dc9bbb 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_vidc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -330,7 +330,7 @@ struct buffer_info *device_to_uvaddr(struct msm_vidc_list *buf_list, if (!buf_list || !device_addr) { dprintk(VIDC_ERR, - "Invalid input- device_addr: 0x%pa buf_list: %p\n", + "Invalid input- device_addr: 0x%pa buf_list: %pK\n", &device_addr, buf_list); goto err_invalid_input; } @@ -486,7 +486,7 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) goto exit; } - dprintk(VIDC_DBG, "[MAP] Create binfo = %p fd = %d type = %d\n", + dprintk(VIDC_DBG, "[MAP] Create binfo = %pK fd = %d type = %d\n", binfo, b->m.planes[0].reserved[0], b->type); for (i = 0; i < b->length; ++i) { @@ -569,7 +569,7 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) goto exit; } dprintk(VIDC_DBG, - "%s: [MAP] binfo = %p, handle[%d] = %p, device_addr = 0x%pa, fd = %d, offset = %d, mapped = %d\n", + "%s: [MAP] binfo = %pK, handle[%d] = %pK, device_addr = 0x%pa, fd = %d, offset = %d, mapped = %d\n", __func__, binfo, i, binfo->handle[i], &binfo->device_addr[i], binfo->fd[i], binfo->buff_off[i], binfo->mapped[i]); @@ -592,7 +592,7 @@ int unmap_and_deregister_buf(struct msm_vidc_inst *inst, bool found = false, keep_node = false; if (!inst || !binfo) { - dprintk(VIDC_ERR, "%s invalid param: %p %p\n", + dprintk(VIDC_ERR, "%s invalid param: %pK %pK\n", __func__, inst, binfo); return -EINVAL; } @@ -622,7 +622,7 @@ int unmap_and_deregister_buf(struct msm_vidc_inst *inst, for (i = 0; i < temp->num_planes; i++) { dprintk(VIDC_DBG, - "%s: [UNMAP] binfo = %p, handle[%d] = %p, device_addr = 0x%pa, fd = %d, offset = %d, mapped = %d\n", + "%s: [UNMAP] binfo = %pK, handle[%d] = %pK, device_addr = 0x%pa, fd = %d, offset = %d, mapped = %d\n", __func__, temp, i, temp->handle[i], &temp->device_addr[i], temp->fd[i], temp->buff_off[i], temp->mapped[i]); @@ -651,12 +651,12 @@ int unmap_and_deregister_buf(struct msm_vidc_inst *inst, } } if (!keep_node) { - dprintk(VIDC_DBG, "[UNMAP] AND-FREED binfo: %p\n", temp); + dprintk(VIDC_DBG, "[UNMAP] AND-FREED binfo: %pK\n", temp); list_del(&temp->list); kfree(temp); } else { temp->inactive = true; - dprintk(VIDC_DBG, "[UNMAP] NOT-FREED binfo: %p\n", temp); + dprintk(VIDC_DBG, "[UNMAP] NOT-FREED binfo: %pK\n", temp); } exit: return 0; @@ -670,7 +670,7 @@ int qbuf_dynamic_buf(struct msm_vidc_inst *inst, struct v4l2_plane plane[VIDEO_MAX_PLANES] = { {0} }; if (!binfo) { - dprintk(VIDC_ERR, "%s invalid param: %p\n", __func__, binfo); + dprintk(VIDC_ERR, "%s invalid param: %pK\n", __func__, binfo); return -EINVAL; } dprintk(VIDC_DBG, "%s fd[0] = %d\n", __func__, binfo->fd[0]); @@ -693,7 +693,7 @@ int output_buffer_cache_invalidate(struct msm_vidc_inst *inst, int rc = 0; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid inst: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst); return -EINVAL; } @@ -701,7 +701,7 @@ int output_buffer_cache_invalidate(struct msm_vidc_inst *inst, return 0; if (!binfo) { - dprintk(VIDC_ERR, "%s: invalid buffer info: %p\n", + dprintk(VIDC_ERR, "%s: invalid buffer info: %pK\n", __func__, inst); return -EINVAL; } @@ -779,7 +779,7 @@ int msm_vidc_release_buffers(void *instance, int buffer_type) rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to release res done\n", + "Failed to move inst: %pK to release res done\n", inst); } } @@ -842,7 +842,7 @@ int msm_vidc_release_buffers(void *instance, int buffer_type) for (i = 0; i < bi->num_planes; i++) { if (bi->handle[i] && bi->mapped[i]) { dprintk(VIDC_DBG, - "%s: [UNMAP] binfo = 0x%p, handle[%d] = %p, device_addr = 0x%pa, fd = %d, offset = %d, mapped = %d\n", + "%s: [UNMAP] binfo = 0x%pK, handle[%d] = %pK, device_addr = 0x%pa, fd = %d, offset = %d, mapped = %d\n", __func__, bi, i, bi->handle[i], &bi->device_addr[i], bi->fd[i], bi->buff_off[i], bi->mapped[i]); @@ -1069,7 +1069,7 @@ int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize) struct msm_vidc_core_capability *capability = NULL; if (!inst || !fsize) { - dprintk(VIDC_ERR, "%s: invalid parameter: %p %p\n", + dprintk(VIDC_ERR, "%s: invalid parameter: %pK %pK\n", __func__, inst, fsize); return -EINVAL; } @@ -1136,7 +1136,7 @@ void *msm_vidc_smem_get_client(void *instance) struct msm_vidc_inst *inst = instance; if (!inst || !inst->mem_client) { - dprintk(VIDC_ERR, "%s: invalid instance or client = %p\n", + dprintk(VIDC_ERR, "%s: invalid instance or client = %pK\n", __func__, inst); return NULL; } @@ -1194,7 +1194,7 @@ static int setup_event_queue(void *inst, struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst; if (!inst || !pvdev) { - dprintk(VIDC_ERR, "%s Invalid params inst %p pvdev %p\n", + dprintk(VIDC_ERR, "%s Invalid params inst %pK pvdev %pK\n", __func__, inst, pvdev); return -EINVAL; } @@ -1270,7 +1270,7 @@ void *msm_vidc_open(int core_id, int session_type) goto err_invalid_core; } - pr_info(VIDC_DBG_TAG "Opening video instance: %p, %d\n", + pr_info(VIDC_DBG_TAG "Opening video instance: %pK, %d\n", VIDC_MSG_PRIO2STRING(VIDC_INFO), inst, session_type); mutex_init(&inst->sync_lock); mutex_init(&inst->bufq[CAPTURE_PORT].lock); @@ -1469,7 +1469,7 @@ int msm_vidc_close(void *instance) msm_smem_delete_client(inst->mem_client); - pr_info(VIDC_DBG_TAG "Closed video instance: %p\n", + pr_info(VIDC_DBG_TAG "Closed video instance: %pK\n", VIDC_MSG_PRIO2STRING(VIDC_INFO), inst); kfree(inst); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c index 08a450cb64725..dc76227a1749d 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -130,7 +130,7 @@ static inline int msm_comm_count_active_instances(struct msm_vidc_core *core) int active_instances = 0; struct msm_vidc_inst *inst = NULL; if (!core) { - dprintk(VIDC_ERR, "%s: Invalid args: %p\n", __func__, core); + dprintk(VIDC_ERR, "%s: Invalid args: %pK\n", __func__, core); return -EINVAL; } @@ -175,7 +175,7 @@ static int msm_comm_get_inst_load(struct msm_vidc_inst *inst, if (is_non_realtime_session(inst) && (quirks & LOAD_CALC_IGNORE_NON_REALTIME_LOAD)) { if (!inst->prop.fps) { - dprintk(VIDC_INFO, "%s: instance:%p prop->fps is set 0\n", __func__, inst); + dprintk(VIDC_INFO, "%s: instance:%pK prop->fps is set 0\n", __func__, inst); load = 0; } else load = msm_comm_get_mbs_per_sec(inst) / inst->prop.fps; @@ -190,7 +190,7 @@ static int msm_comm_get_load(struct msm_vidc_core *core, int num_mbs_per_sec = 0; if (!core) { - dprintk(VIDC_ERR, "Invalid args: %p\n", core); + dprintk(VIDC_ERR, "Invalid args: %pK\n", core); return -EINVAL; } @@ -285,13 +285,13 @@ static int msm_comm_vote_bus(struct msm_vidc_core *core) struct vidc_bus_vote_data *vote_data = NULL; if (!core) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, core); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "%s Invalid device handle: %p\n", + dprintk(VIDC_ERR, "%s Invalid device handle: %pK\n", __func__, hdev); return -EINVAL; } @@ -380,7 +380,7 @@ const struct msm_vidc_format *msm_comm_get_pixel_fmt_index( { int i, k = 0; if (!fmt || index < 0) { - dprintk(VIDC_ERR, "Invalid inputs, fmt = %p, index = %d\n", + dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK, index = %d\n", fmt, index); return NULL; } @@ -402,7 +402,7 @@ struct msm_vidc_format *msm_comm_get_pixel_fmt_fourcc( { int i; if (!fmt) { - dprintk(VIDC_ERR, "Invalid inputs, fmt = %p\n", fmt); + dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK\n", fmt); return NULL; } for (i = 0; i < size; i++) { @@ -462,7 +462,7 @@ static void handle_sys_init_done(enum command_response cmd, void *data) HAL_VIDEO_CODEC_MVC; dprintk(VIDC_DBG, "supported_codecs: enc = 0x%x, dec = 0x%x\n", core->enc_codec_supported, core->dec_codec_supported); - dprintk(VIDC_DBG, "ptr[%d] = %p\n", index, &(core->completions[index])); + dprintk(VIDC_DBG, "ptr[%d] = %pK\n", index, &(core->completions[index])); complete(&(core->completions[index])); } @@ -546,11 +546,11 @@ static void change_inst_state(struct msm_vidc_inst *inst, mutex_lock(&inst->lock); if (inst->state == MSM_VIDC_CORE_INVALID) { dprintk(VIDC_DBG, - "Inst: %p is in bad state can't change state to %d\n", + "Inst: %pK is in bad state can't change state to %d\n", inst, state); goto exit; } - dprintk(VIDC_DBG, "Moved inst: %p from state: %d to state: %d\n", + dprintk(VIDC_DBG, "Moved inst: %pK from state: %d to state: %d\n", inst, inst->state, state); inst->state = state; exit: @@ -561,7 +561,7 @@ static int signal_session_msg_receipt(enum command_response cmd, struct msm_vidc_inst *inst) { if (!inst) { - dprintk(VIDC_ERR, "Invalid(%p) instance id\n", inst); + dprintk(VIDC_ERR, "Invalid(%pK) instance id\n", inst); return -EINVAL; } if (IS_SESSION_CMD_VALID(cmd)) { @@ -602,7 +602,7 @@ static int wait_for_state(struct msm_vidc_inst *inst, { int rc = 0; if (IS_ALREADY_IN_STATE(flipped_state, desired_state)) { - dprintk(VIDC_INFO, "inst: %p is already in state: %d\n", + dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n", inst, inst->state); goto err_same_state; } @@ -648,7 +648,7 @@ static void handle_session_init_done(enum command_response cmd, void *data) response->data; inst = (struct msm_vidc_inst *)response->session_id; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s: invalid parameters (0x%p)\n", + dprintk(VIDC_ERR, "%s: invalid parameters (0x%pK)\n", __func__, inst); return; } @@ -723,7 +723,7 @@ static void handle_event_change(enum command_response cmd, void *data) u32 *ptr = NULL; dprintk(VIDC_DBG, - "%s - inst: %p buffer: 0x%pa extra: 0x%pa\n", + "%s - inst: %pK buffer: 0x%pa extra: 0x%pa\n", __func__, inst, &event_notify->packet_buffer, &event_notify->extra_data_buffer); @@ -1054,7 +1054,7 @@ static void handle_sys_idle(enum command_response cmd, void *data) goto exit; } - dprintk(VIDC_DBG, "SYS_IDLE received for core %p\n", core); + dprintk(VIDC_DBG, "SYS_IDLE received for core %pK\n", core); if (core->resources.dynamic_bw_update) { mutex_lock(&core->lock); core->idle_stats.start_time = ktime_get(); @@ -1086,24 +1086,24 @@ static void handle_session_error(enum command_response cmd, void *data) if (!inst || !inst->session || !inst->core->device) { dprintk(VIDC_ERR, - "Session (%p) not in a stable enough state to handle session error\n", + "Session (%pK) not in a stable enough state to handle session error\n", inst); return; } hdev = inst->core->device; - dprintk(VIDC_WARN, "Session error received for session %p\n", inst); + dprintk(VIDC_WARN, "Session error received for session %pK\n", inst); change_inst_state(inst, MSM_VIDC_CORE_INVALID); if (response->status == VIDC_ERR_MAX_CLIENTS) { dprintk(VIDC_WARN, - "send max clients reached error to client: %p\n", + "send max clients reached error to client: %pK\n", inst); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_MAX_CLIENTS); } else { dprintk(VIDC_ERR, - "send session error to client: %p\n", + "send session error to client: %pK\n", inst); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); @@ -1118,7 +1118,7 @@ static void msm_comm_clean_notify_client(struct msm_vidc_core *core) return; } - dprintk(VIDC_WARN, "%s: Core %p\n", __func__, core); + dprintk(VIDC_WARN, "%s: Core %pK\n", __func__, core); mutex_lock(&core->lock); core->state = VIDC_CORE_INVALID; @@ -1127,7 +1127,7 @@ static void msm_comm_clean_notify_client(struct msm_vidc_core *core) inst->state = MSM_VIDC_CORE_INVALID; mutex_unlock(&inst->lock); dprintk(VIDC_WARN, - "%s Send sys error for inst %p\n", __func__, inst); + "%s Send sys error for inst %pK\n", __func__, inst); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); } @@ -1202,7 +1202,7 @@ static void handle_sys_error(enum command_response cmd, void *data) return; } - dprintk(VIDC_WARN, "SYS_ERROR %d received for core %p\n", cmd, core); + dprintk(VIDC_WARN, "SYS_ERROR %d received for core %pK\n", cmd, core); msm_comm_clean_notify_client(core); handler = kzalloc(sizeof(*handler), GFP_KERNEL); @@ -1237,12 +1237,12 @@ void msm_comm_session_clean(struct msm_vidc_inst *inst) hdev = inst->core->device; mutex_lock(&inst->lock); if (hdev && inst->session) { - dprintk(VIDC_DBG, "cleaning up instance: 0x%p\n", inst); + dprintk(VIDC_DBG, "cleaning up instance: 0x%pK\n", inst); rc = call_hfi_op(hdev, session_clean, (void *) inst->session); if (rc) { dprintk(VIDC_ERR, - "Session clean failed :%p\n", inst); + "Session clean failed :%pK\n", inst); } inst->session = NULL; } @@ -1644,7 +1644,7 @@ static void handle_fbd(enum command_response cmd, void *data) if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { dprintk(VIDC_DBG, - "extradata: userptr = %p;" + "extradata: userptr = %pK;" " bytesused = %d; length = %d\n", (u8 *)vb->v4l2_planes[extra_idx].m.userptr, vb->v4l2_planes[extra_idx].bytesused, @@ -1810,7 +1810,7 @@ void msm_comm_init_dcvs_load(struct msm_vidc_inst *inst) dprintk(VIDC_DBG, "Init DCVS Load\n"); if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst); return; } @@ -1854,7 +1854,7 @@ void msm_comm_init_dcvs(struct msm_vidc_inst *inst) dprintk(VIDC_DBG, "Init DCVS Struct\n"); if (!inst) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst); return; } @@ -1871,7 +1871,7 @@ static void msm_comm_dcvs_monitor_buffer(struct msm_vidc_inst *inst) struct hal_buffer_requirements *output_buf_req; if (!inst) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst); return; } @@ -1881,7 +1881,7 @@ static void msm_comm_dcvs_monitor_buffer(struct msm_vidc_inst *inst) msm_comm_get_hal_output_buffer(inst)); if (!output_buf_req) { - dprintk(VIDC_ERR, "%s : Get output buffer req failed %p\n", + dprintk(VIDC_ERR, "%s : Get output buffer req failed %pK\n", __func__, inst); mutex_unlock(&inst->lock); return; @@ -2039,13 +2039,13 @@ static int msm_comm_scale_clocks(struct msm_vidc_core *core) struct msm_vidc_inst *inst = NULL; if (!core) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, core); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "%s Invalid device handle: %p\n", + dprintk(VIDC_ERR, "%s Invalid device handle: %pK\n", __func__, hdev); return -EINVAL; } @@ -2192,7 +2192,7 @@ static int msm_comm_session_abort(struct msm_vidc_inst *inst) msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { dprintk(VIDC_ERR, - "%s: Wait interrupted or timed out [%p]: %d\n", + "%s: Wait interrupted or timed out [%pK]: %d\n", __func__, inst, abort_completion); rc = -EBUSY; } else { @@ -2219,7 +2219,7 @@ static void handle_thermal_event(struct msm_vidc_core *core) mutex_unlock(&core->lock); if (inst->state >= MSM_VIDC_OPEN_DONE && inst->state < MSM_VIDC_CLOSE_DONE) { - dprintk(VIDC_WARN, "%s: abort inst %p\n", + dprintk(VIDC_WARN, "%s: abort inst %pK\n", __func__, inst); change_inst_state(inst, MSM_VIDC_CORE_INVALID); @@ -2231,7 +2231,7 @@ static void handle_thermal_event(struct msm_vidc_core *core) goto err_sess_abort; } dprintk(VIDC_WARN, - "%s Send sys error for inst %p\n", + "%s Send sys error for inst %pK\n", __func__, inst); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); @@ -2469,7 +2469,7 @@ static int msm_comm_session_init(int flipped_state, hdev = inst->core->device; if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_OPEN)) { - dprintk(VIDC_INFO, "inst: %p is already in state: %d\n", + dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2490,7 +2490,7 @@ static int msm_comm_session_init(int flipped_state, if (!inst->session) { dprintk(VIDC_ERR, - "Failed to call session init for: %p, %p, %d, %d\n", + "Failed to call session init for: %pK, %pK, %d, %d\n", inst->core->device, inst, inst->session_type, fourcc); rc = -EINVAL; @@ -2582,7 +2582,7 @@ static int msm_vidc_load_resources(int flipped_state, hdev = core->device; if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_LOAD_RESOURCES)) { - dprintk(VIDC_INFO, "inst: %p is already in state: %d\n", + dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2618,7 +2618,7 @@ static int msm_vidc_start(int flipped_state, struct msm_vidc_inst *inst) if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_START)) { dprintk(VIDC_INFO, - "inst: %p is already in state: %d\n", + "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2648,7 +2648,7 @@ static int msm_vidc_stop(int flipped_state, struct msm_vidc_inst *inst) if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_STOP)) { dprintk(VIDC_INFO, - "inst: %p is already in state: %d\n", + "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2678,7 +2678,7 @@ static int msm_vidc_release_res(int flipped_state, struct msm_vidc_inst *inst) if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_RELEASE_RESOURCES)) { dprintk(VIDC_INFO, - "inst: %p is already in state: %d\n", + "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2710,7 +2710,7 @@ static int msm_comm_session_close(int flipped_state, hdev = inst->core->device; if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_CLOSE)) { dprintk(VIDC_INFO, - "inst: %p is already in state: %d\n", + "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -3106,16 +3106,16 @@ int msm_comm_try_state(struct msm_vidc_inst *inst, int state) struct msm_vidc_core *core; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } dprintk(VIDC_DBG, - "Trying to move inst: %p from: 0x%x to 0x%x\n", + "Trying to move inst: %pK from: 0x%x to 0x%x\n", inst, inst->state, state); core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", inst); + "Invalid core pointer = %pK\n", inst); return -EINVAL; } mutex_lock(&inst->sync_lock); @@ -3285,7 +3285,7 @@ int msm_comm_qbuf(struct vb2_buffer *vb) int extra_idx = 0; if (!vb || !vb->vb2_queue) { - dprintk(VIDC_ERR, "%s: Invalid input: %p\n", + dprintk(VIDC_ERR, "%s: Invalid input: %pK\n", __func__, vb); return -EINVAL; } @@ -3293,7 +3293,7 @@ int msm_comm_qbuf(struct vb2_buffer *vb) q = vb->vb2_queue; inst = q->drv_priv; if (!inst) { - dprintk(VIDC_ERR, "%s: Invalid input: %p\n", + dprintk(VIDC_ERR, "%s: Invalid input: %pK\n", __func__, vb); return -EINVAL; } @@ -3301,12 +3301,12 @@ int msm_comm_qbuf(struct vb2_buffer *vb) core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid input: %p, %p, %p\n", inst, core, vb); + "Invalid input: %pK, %pK, %pK\n", inst, core, vb); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "%s: Invalid input: %p\n", + dprintk(VIDC_ERR, "%s: Invalid input: %pK\n", __func__, hdev); return -EINVAL; } @@ -3458,7 +3458,7 @@ int msm_comm_qbuf(struct vb2_buffer *vb) (void *) inst->session, &seq_hdr); if (!rc) { inst->vb2_seq_hdr = vb; - dprintk(VIDC_DBG, "Seq_hdr: %p\n", + dprintk(VIDC_DBG, "Seq_hdr: %pK\n", inst->vb2_seq_hdr); } atomic_dec(&inst->seq_hdr_reqs); @@ -3591,7 +3591,7 @@ int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype, msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { dprintk(VIDC_ERR, - "%s: Wait interrupted or timed out [%p]: %d\n", + "%s: Wait interrupted or timed out [%pK]: %d\n", __func__, inst, SESSION_MSG_INDEX(SESSION_PROPERTY_INFO)); inst->state = MSM_VIDC_CORE_INVALID; @@ -3628,18 +3628,18 @@ int msm_comm_release_output_buffers(struct msm_vidc_inst *inst) struct hfi_device *hdev; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", core); + "Invalid core pointer = %pK\n", core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "Invalid device pointer = %p\n", hdev); + dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); return -EINVAL; } mutex_lock(&inst->outputbufs.lock); @@ -3733,18 +3733,18 @@ int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst, enum hal_buffer sufficiency = HAL_BUFFER_NONE; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", core); + "Invalid core pointer = %pK\n", core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "Invalid device pointer = %p\n", hdev); + dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); return -EINVAL; } @@ -3821,18 +3821,18 @@ int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst) struct hfi_device *hdev; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", core); + "Invalid core pointer = %pK\n", core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "Invalid device pointer = %p\n", hdev); + dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); return -EINVAL; } @@ -3881,7 +3881,7 @@ int msm_comm_try_set_prop(struct msm_vidc_inst *inst, int rc = 0; struct hfi_device *hdev; if (!inst) { - dprintk(VIDC_ERR, "Invalid input: %p\n", inst); + dprintk(VIDC_ERR, "Invalid input: %pK\n", inst); return -EINVAL; } @@ -4104,7 +4104,7 @@ void msm_comm_flush_pending_dynamic_buffers(struct msm_vidc_inst *inst) list_for_each_entry(binfo, &inst->registeredbufs.list, list) { if (binfo->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { dprintk(VIDC_DBG, - "%s: binfo = %p device_addr = 0x%pa\n", + "%s: binfo = %pK device_addr = 0x%pa\n", __func__, binfo, &binfo->device_addr[0]); buf_ref_put(inst, binfo); } @@ -4124,18 +4124,18 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) struct hfi_device *hdev; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", core); + "Invalid core pointer = %pK\n", core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "Invalid device pointer = %p\n", hdev); + dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); return -EINVAL; } @@ -4152,7 +4152,7 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) if (inst->state == MSM_VIDC_CORE_INVALID || core->state == VIDC_CORE_INVALID) { dprintk(VIDC_ERR, - "Core %p and inst %p are in bad state\n", + "Core %pK and inst %pK are in bad state\n", core, inst); msm_comm_flush_in_invalid_state(inst); return 0; @@ -4349,7 +4349,7 @@ int msm_vidc_trigger_ssr(struct msm_vidc_core *core, int rc = 0; struct hfi_device *hdev; if (!core || !core->device) { - dprintk(VIDC_WARN, "Invalid parameters: %p\n", core); + dprintk(VIDC_WARN, "Invalid parameters: %pK\n", core); return -EINVAL; } hdev = core->device; @@ -4656,7 +4656,7 @@ int msm_comm_kill_session(struct msm_vidc_inst *inst) change_inst_state(inst, MSM_VIDC_CLOSE_DONE); } else { dprintk(VIDC_WARN, - "Inactive session %p, triggering an internal session error\n", + "Inactive session %pK, triggering an internal session error\n", inst); msm_comm_generate_session_error(inst); @@ -4688,7 +4688,7 @@ struct msm_smem *msm_comm_smem_alloc(struct msm_vidc_inst *inst, struct msm_smem *m = NULL; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid inst: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst); return NULL; } mutex_lock(&inst->core->lock); @@ -4706,7 +4706,7 @@ void msm_comm_smem_free(struct msm_vidc_inst *inst, struct msm_smem *mem) { if (!inst || !inst->core || !mem) { dprintk(VIDC_ERR, - "%s: invalid params: %p %p\n", __func__, inst, mem); + "%s: invalid params: %pK %pK\n", __func__, inst, mem); return; } mutex_lock(&inst->core->lock); @@ -4723,7 +4723,7 @@ int msm_comm_smem_cache_operations(struct msm_vidc_inst *inst, { if (!inst || !mem) { dprintk(VIDC_ERR, - "%s: invalid params: %p %p\n", __func__, inst, mem); + "%s: invalid params: %pK %pK\n", __func__, inst, mem); return -EINVAL; } return msm_smem_cache_operations(inst->mem_client, mem, cache_ops); @@ -4735,7 +4735,7 @@ struct msm_smem *msm_comm_smem_user_to_kernel(struct msm_vidc_inst *inst, struct msm_smem *m = NULL; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid inst: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst); return NULL; } mutex_lock(&inst->core->lock); @@ -4754,7 +4754,7 @@ int msm_comm_smem_get_domain_partition(struct msm_vidc_inst *inst, int *domain_num, int *partition_num) { if (!inst || !domain_num || !partition_num) { - dprintk(VIDC_ERR, "%s: invalid params: %p %p %p\n", + dprintk(VIDC_ERR, "%s: invalid params: %pK %pK %pK\n", __func__, inst, domain_num, partition_num); return -EINVAL; } diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c index a83fa114c4cab..b0bda5de403fa 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -72,13 +72,13 @@ static ssize_t core_info_read(struct file *file, char __user *buf, int i = 0, rc = 0; if (!core || !core->device) { - dprintk(VIDC_ERR, "Invalid params, core: %p\n", core); + dprintk(VIDC_ERR, "Invalid params, core: %pK\n", core); return 0; } hdev = core->device; INIT_DBG_BUF(dbg_buf); write_str(&dbg_buf, "===============================\n"); - write_str(&dbg_buf, "CORE %d: 0x%p\n", core->id, core); + write_str(&dbg_buf, "CORE %d: 0x%pK\n", core->id, core); write_str(&dbg_buf, "===============================\n"); write_str(&dbg_buf, "Core state: %d\n", core->state); rc = call_hfi_op(hdev, get_fw_info, hdev->hfi_device_data, &fw_info); @@ -215,7 +215,7 @@ struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core, struct dentry *dir = NULL; char debugfs_name[MAX_DEBUGFS_NAME]; if (!core) { - dprintk(VIDC_ERR, "Invalid params, core: %p\n", core); + dprintk(VIDC_ERR, "Invalid params, core: %pK\n", core); goto failed_create_dir; } @@ -279,15 +279,15 @@ static ssize_t inst_info_read(struct file *file, char __user *buf, struct msm_vidc_inst *inst = file->private_data; int i, j; if (!inst) { - dprintk(VIDC_ERR, "Invalid params, core: %p\n", inst); + dprintk(VIDC_ERR, "Invalid params, core: %pK\n", inst); return 0; } INIT_DBG_BUF(dbg_buf); write_str(&dbg_buf, "===============================\n"); - write_str(&dbg_buf, "INSTANCE: 0x%p (%s)\n", inst, + write_str(&dbg_buf, "INSTANCE: 0x%pK (%s)\n", inst, inst->session_type == MSM_VIDC_ENCODER ? "Encoder" : "Decoder"); write_str(&dbg_buf, "===============================\n"); - write_str(&dbg_buf, "core: 0x%p\n", inst->core); + write_str(&dbg_buf, "core: 0x%pK\n", inst->core); write_str(&dbg_buf, "height: %d\n", inst->prop.height[CAPTURE_PORT]); write_str(&dbg_buf, "width: %d\n", inst->prop.width[CAPTURE_PORT]); write_str(&dbg_buf, "fps: %d\n", inst->prop.fps); @@ -354,10 +354,10 @@ struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst, struct dentry *dir = NULL; char debugfs_name[MAX_DEBUGFS_NAME]; if (!inst) { - dprintk(VIDC_ERR, "Invalid params, inst: %p\n", inst); + dprintk(VIDC_ERR, "Invalid params, inst: %pK\n", inst); goto failed_create_dir; } - snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%p", inst); + snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%pK", inst); dir = debugfs_create_dir(debugfs_name, parent); if (!dir) { dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n"); diff --git a/drivers/media/platform/msm/vidc/q6_hfi.c b/drivers/media/platform/msm/vidc/q6_hfi.c index 10f4baaccd45f..31f6263535759 100644 --- a/drivers/media/platform/msm/vidc/q6_hfi.c +++ b/drivers/media/platform/msm/vidc/q6_hfi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -202,7 +202,7 @@ static int q6_hfi_register_iommu_domains(struct q6_hfi_device *device) struct iommu_info *iommu_map; if (!device || !device->res) { - dprintk(VIDC_ERR, "Invalid parameter: %p\n", device); + dprintk(VIDC_ERR, "Invalid parameter: %pK\n", device); return -EINVAL; } @@ -220,7 +220,7 @@ static int q6_hfi_register_iommu_domains(struct q6_hfi_device *device) domain = iommu_group_get_iommudata(iommu_map->group); if (IS_ERR_OR_NULL(domain)) { dprintk(VIDC_ERR, - "Failed to get domain data for group %p\n", + "Failed to get domain data for group %pK\n", iommu_map->group); rc = -EINVAL; goto fail_group; @@ -228,7 +228,7 @@ static int q6_hfi_register_iommu_domains(struct q6_hfi_device *device) iommu_map->domain = msm_find_domain_no(domain); if (iommu_map->domain < 0) { dprintk(VIDC_ERR, - "Failed to get domain index for domain %p\n", + "Failed to get domain index for domain %pK\n", domain); rc = -EINVAL; goto fail_group; @@ -254,7 +254,7 @@ static void q6_hfi_deregister_iommu_domains(struct q6_hfi_device *device) int i = 0; if (!device || !device->res) { - dprintk(VIDC_ERR, "Invalid parameter: %p\n", device); + dprintk(VIDC_ERR, "Invalid parameter: %pK\n", device); return; } @@ -347,7 +347,7 @@ static void *q6_hfi_get_device(u32 device_id, int rc = 0; if (!callback) { - dprintk(VIDC_ERR, "%s Invalid params: %p\n", + dprintk(VIDC_ERR, "%s Invalid params: %pK\n", __func__, callback); return NULL; } @@ -663,7 +663,7 @@ static int q6_hfi_session_clean(void *session) return -EINVAL; } sess_close = session; - dprintk(VIDC_DBG, "deleted the session: 0x%p\n", + dprintk(VIDC_DBG, "deleted the session: 0x%pK\n", sess_close->session_id); mutex_lock(&((struct q6_hfi_device *) sess_close->device)->session_lock); @@ -1207,7 +1207,7 @@ static int q6_hfi_iommu_attach(struct q6_hfi_device *device) struct iommu_info *iommu_map; if (!device || !device->res) { - dprintk(VIDC_ERR, "Invalid parameter: %p\n", device); + dprintk(VIDC_ERR, "Invalid parameter: %pK\n", device); return -EINVAL; } @@ -1222,7 +1222,7 @@ static int q6_hfi_iommu_attach(struct q6_hfi_device *device) rc = PTR_ERR(domain) ?: -EINVAL; break; } - dprintk(VIDC_DBG, "Attaching domain(id:%d) %p to group %p\n", + dprintk(VIDC_DBG, "Attaching domain(id:%d) %pK to group %pK\n", iommu_map->domain, domain, group); rc = iommu_attach_group(domain, group); if (rc) { @@ -1253,7 +1253,7 @@ static void q6_hfi_iommu_detach(struct q6_hfi_device *device) int i; if (!device || !device->res) { - dprintk(VIDC_ERR, "Invalid parameter: %p\n", device); + dprintk(VIDC_ERR, "Invalid parameter: %pK\n", device); return; } @@ -1382,7 +1382,7 @@ int q6_hfi_initialize(struct hfi_device *hdev, u32 device_id, int rc = 0; if (!hdev || !res || !callback) { - dprintk(VIDC_ERR, "Invalid params: %p %p %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK %pK %pK\n", hdev, res, callback); rc = -EINVAL; goto err_hfi_init; diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c index 86e00d339aafc..c6f88da49fba6 100644 --- a/drivers/media/platform/msm/vidc/venus_hfi.c +++ b/drivers/media/platform/msm/vidc/venus_hfi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -367,7 +367,7 @@ static int venus_hfi_write_queue(void *info, u8 *packet, u32 *rx_req_is_set) } if (msm_vidc_debug & VIDC_PKT) { - dprintk(VIDC_PKT, "%s: %p\n", __func__, qinfo); + dprintk(VIDC_PKT, "%s: %pK\n", __func__, qinfo); venus_hfi_dump_packet(packet); } @@ -576,7 +576,7 @@ static int venus_hfi_read_queue(void *info, u8 *packet, u32 *pb_tx_req_is_set) *pb_tx_req_is_set = (1 == queue->qhdr_tx_req) ? 1 : 0; if (msm_vidc_debug & VIDC_PKT) { - dprintk(VIDC_PKT, "%s: %p\n", __func__, qinfo); + dprintk(VIDC_PKT, "%s: %pK\n", __func__, qinfo); venus_hfi_dump_packet(packet); } @@ -607,7 +607,7 @@ static int venus_hfi_alloc(struct venus_hfi_device *dev, void *mem, rc = -ENOMEM; goto fail_smem_alloc; } - dprintk(VIDC_DBG, "venus_hfi_alloc: ptr = %p, size = %d\n", + dprintk(VIDC_DBG, "venus_hfi_alloc: ptr = %pK, size = %d\n", alloc->kvaddr, size); rc = msm_smem_cache_operations(dev->hal_client, alloc, SMEM_CACHE_CLEAN); @@ -627,7 +627,7 @@ static int venus_hfi_alloc(struct venus_hfi_device *dev, void *mem, static void venus_hfi_free(struct venus_hfi_device *dev, struct msm_smem *mem) { if (!dev || !mem) { - dprintk(VIDC_ERR, "invalid param %p %p\n", dev, mem); + dprintk(VIDC_ERR, "invalid param %pK %pK\n", dev, mem); return; } @@ -643,7 +643,7 @@ static void venus_hfi_write_register( u32 hwiosymaddr = reg; u8 *base_addr; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return; } if (device->clk_state != ENABLED_PREPARED) { @@ -653,7 +653,7 @@ static void venus_hfi_write_register( } base_addr = device->hal_data->register_base; - dprintk(VIDC_DBG, "Base addr: 0x%p, written to: 0x%x, Value: 0x%x...\n", + dprintk(VIDC_DBG, "Base addr: 0x%pK, written to: 0x%x, Value: 0x%x...\n", base_addr, hwiosymaddr, value); base_addr += hwiosymaddr; writel_relaxed(value, base_addr); @@ -665,7 +665,7 @@ static int venus_hfi_read_register(struct venus_hfi_device *device, u32 reg) int rc = 0; u8 *base_addr; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } if (device->clk_state != ENABLED_PREPARED) { @@ -677,7 +677,7 @@ static int venus_hfi_read_register(struct venus_hfi_device *device, u32 reg) rc = readl_relaxed(base_addr + reg); rmb(); - dprintk(VIDC_DBG, "Base addr: 0x%p, read from: 0x%x, value: 0x%x...\n", + dprintk(VIDC_DBG, "Base addr: 0x%pK, read from: 0x%x, value: 0x%x...\n", base_addr, reg, rc); return rc; @@ -779,7 +779,7 @@ static void venus_hfi_iommu_detach(struct venus_hfi_device *device) int i; if (!device || !device->res) { - dprintk(VIDC_ERR, "Invalid paramter: %p\n", device); + dprintk(VIDC_ERR, "Invalid paramter: %pK\n", device); return; } @@ -1160,7 +1160,7 @@ static int __alloc_ocmem(struct venus_hfi_device *device) unsigned long size; if (!device || !device->res) { - dprintk(VIDC_ERR, "%s Invalid param, device: 0x%p\n", + dprintk(VIDC_ERR, "%s Invalid param, device: 0x%pK\n", __func__, device); return -EINVAL; } @@ -1195,7 +1195,7 @@ static int __free_ocmem(struct venus_hfi_device *device) int rc = 0; if (!device || !device->res) { - dprintk(VIDC_ERR, "%s Invalid param, device: 0x%p\n", + dprintk(VIDC_ERR, "%s Invalid param, device: 0x%pK\n", __func__, device); return -EINVAL; } @@ -1219,14 +1219,14 @@ static int __set_ocmem(struct venus_hfi_device *device, bool locked) struct on_chip_mem *ocmem; if (!device) { - dprintk(VIDC_ERR, "%s Invalid param, device: 0x%p\n", + dprintk(VIDC_ERR, "%s Invalid param, device: 0x%pK\n", __func__, device); return -EINVAL; } ocmem = &device->resources.ocmem; if (!ocmem->buf) { - dprintk(VIDC_ERR, "Invalid params, ocmem_buffer: 0x%p\n", + dprintk(VIDC_ERR, "Invalid params, ocmem_buffer: 0x%pK\n", ocmem->buf); return -EINVAL; } @@ -1255,7 +1255,7 @@ static int __unset_ocmem(struct venus_hfi_device *device) int rc = 0; if (!device) { - dprintk(VIDC_ERR, "%s Invalid param, device: 0x%p\n", + dprintk(VIDC_ERR, "%s Invalid param, device: 0x%pK\n", __func__, device); rc = -EINVAL; goto ocmem_unset_failed; @@ -1286,7 +1286,7 @@ static int __alloc_set_ocmem(struct venus_hfi_device *device, bool locked) int rc = 0; if (!device || !device->res) { - dprintk(VIDC_ERR, "%s Invalid param, device: 0x%p\n", + dprintk(VIDC_ERR, "%s Invalid param, device: 0x%pK\n", __func__, device); return -EINVAL; } @@ -1326,7 +1326,7 @@ static int __unset_free_ocmem(struct venus_hfi_device *device) int rc = 0; if (!device || !device->res) { - dprintk(VIDC_ERR, "%s Invalid param, device: 0x%p\n", + dprintk(VIDC_ERR, "%s Invalid param, device: 0x%pK\n", __func__, device); return -EINVAL; } @@ -1464,7 +1464,7 @@ static unsigned long venus_hfi_get_core_clock_rate(void *dev) struct clock_info *vc; if (!device) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, device); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, device); return -EINVAL; } @@ -1536,7 +1536,7 @@ static int venus_hfi_halt_axi(struct venus_hfi_device *device) u32 reg; int rc = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid input: %p\n", device); + dprintk(VIDC_ERR, "Invalid input: %pK\n", device); return -EINVAL; } /* @@ -1571,7 +1571,7 @@ static inline int venus_hfi_power_off(struct venus_hfi_device *device) int rc = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } if (!device->power_enabled) { @@ -1642,7 +1642,7 @@ static inline int venus_hfi_power_on(struct venus_hfi_device *device) int rc = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } if (device->power_enabled) @@ -1770,7 +1770,7 @@ static int venus_hfi_power_enable(void *dev) int rc = 0; struct venus_hfi_device *device = dev; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } mutex_lock(&device->write_lock); @@ -1789,7 +1789,7 @@ static int venus_hfi_scale_clocks(void *dev, int load, int codecs_enabled) struct clock_info *cl; if (!device) { - dprintk(VIDC_ERR, "Invalid args: %p\n", device); + dprintk(VIDC_ERR, "Invalid args: %pK\n", device); return -EINVAL; } device->clk_load = load; @@ -2385,7 +2385,7 @@ static int venus_hfi_core_init(void *device) goto err_core_init; } - dprintk(VIDC_DBG, "Dev_Virt: 0x%pa, Reg_Virt: 0x%p\n", + dprintk(VIDC_DBG, "Dev_Virt: 0x%pa, Reg_Virt: 0x%pK\n", &dev->hal_data->firmware_base, dev->hal_data->register_base); @@ -2531,12 +2531,12 @@ static void venus_hfi_core_clear_interrupt(struct venus_hfi_device *device) device->intr_status |= intr_status; device->reg_count++; dprintk(VIDC_DBG, - "INTERRUPT for device: 0x%p: times: %d interrupt_status: %d\n", + "INTERRUPT for device: 0x%pK: times: %d interrupt_status: %d\n", device, device->reg_count, intr_status); } else { device->spur_count++; dprintk(VIDC_INFO, - "SPURIOUS_INTR for device: 0x%p: times: %d interrupt_status: %d\n", + "SPURIOUS_INTR for device: 0x%pK: times: %d interrupt_status: %d\n", device, device->spur_count, intr_status); } @@ -2683,7 +2683,7 @@ static int venus_hfi_session_clean(void *session) sess_close = session; device = sess_close->device; venus_hfi_flush_debug_queue(sess_close->device, NULL); - dprintk(VIDC_DBG, "deleted the session: 0x%p\n", + dprintk(VIDC_DBG, "deleted the session: 0x%pK\n", sess_close); mutex_lock(&device->session_lock); list_del(&sess_close->list); @@ -3404,7 +3404,7 @@ static void venus_hfi_core_work_handler(struct work_struct *work) dprintk(VIDC_INFO, "GOT INTERRUPT\n"); if (!device->callback) { - dprintk(VIDC_ERR, "No interrupt callback function: %p\n", + dprintk(VIDC_ERR, "No interrupt callback function: %pK\n", device); return; } @@ -3502,7 +3502,7 @@ static inline int venus_hfi_init_clocks(struct msm_vidc_platform_resources *res, struct clock_info *cl = NULL; if (!res || !device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } @@ -3571,7 +3571,7 @@ static inline void venus_hfi_disable_unprepare_clks( struct clock_info *cl; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return; } @@ -3604,7 +3604,7 @@ static inline int venus_hfi_prepare_enable_clks(struct venus_hfi_device *device) struct clock_info *cl = NULL, *cl_fail = NULL; int rc = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } @@ -3667,7 +3667,7 @@ static int venus_hfi_register_iommu_domains(struct venus_hfi_device *device, domain = iommu_group_get_iommudata(iommu_map->group); if (!domain) { dprintk(VIDC_ERR, - "Failed to get domain data for group %p\n", + "Failed to get domain data for group %pK\n", iommu_map->group); rc = -EINVAL; goto fail_group; @@ -3675,7 +3675,7 @@ static int venus_hfi_register_iommu_domains(struct venus_hfi_device *device, iommu_map->domain = msm_find_domain_no(domain); if (iommu_map->domain < 0) { dprintk(VIDC_ERR, - "Failed to get domain index for domain %p\n", + "Failed to get domain index for domain %pK\n", domain); rc = -EINVAL; goto fail_group; @@ -3821,7 +3821,7 @@ static int venus_hfi_init_resources(struct venus_hfi_device *device, device->res = res; if (!res) { - dprintk(VIDC_ERR, "Invalid params: %p\n", res); + dprintk(VIDC_ERR, "Invalid params: %pK\n", res); return -ENODEV; } @@ -3878,7 +3878,7 @@ static int venus_hfi_iommu_get_domain_partition(void *dev, u32 flags, struct venus_hfi_device *device = dev; if (!device) { - dprintk(VIDC_ERR, "%s: Invalid param device: %p\n", + dprintk(VIDC_ERR, "%s: Invalid param device: %pK\n", __func__, device); return -EINVAL; } @@ -3903,7 +3903,7 @@ static int protect_cp_mem(struct venus_hfi_device *device) iommu_group_set = &device->res->iommu_group_set; if (!iommu_group_set) { - dprintk(VIDC_ERR, "invalid params: %p\n", iommu_group_set); + dprintk(VIDC_ERR, "invalid params: %pK\n", iommu_group_set); return -EINVAL; } @@ -4057,7 +4057,7 @@ static int venus_hfi_load_fw(void *dev) struct venus_hfi_device *device = dev; if (!device) { - dprintk(VIDC_ERR, "%s Invalid paramter: %p\n", + dprintk(VIDC_ERR, "%s Invalid paramter: %pK\n", __func__, device); return -EINVAL; } @@ -4145,7 +4145,7 @@ static void venus_hfi_unload_fw(void *dev) { struct venus_hfi_device *device = dev; if (!device) { - dprintk(VIDC_ERR, "%s Invalid paramter: %p\n", + dprintk(VIDC_ERR, "%s Invalid paramter: %pK\n", __func__, device); return; } @@ -4176,7 +4176,7 @@ static int venus_hfi_resurrect_fw(void *dev) int rc = 0; if (!device) { - dprintk(VIDC_ERR, "%s Invalid paramter: %p\n", + dprintk(VIDC_ERR, "%s Invalid paramter: %pK\n", __func__, device); return -EINVAL; } @@ -4222,7 +4222,7 @@ static int venus_hfi_get_fw_info(void *dev, struct hal_fw_info *fw_info) if (!device || !fw_info) { dprintk(VIDC_ERR, - "%s Invalid paramter: device = %p fw_info = %p\n", + "%s Invalid paramter: device = %pK fw_info = %pK\n", __func__, device, fw_info); return -EINVAL; } @@ -4409,7 +4409,7 @@ static void *venus_hfi_get_device(u32 device_id, int rc = 0; if (!res || !callback) { - dprintk(VIDC_ERR, "Invalid params: %p %p\n", res, callback); + dprintk(VIDC_ERR, "Invalid params: %pK %pK\n", res, callback); return NULL; } @@ -4510,7 +4510,7 @@ int venus_hfi_initialize(struct hfi_device *hdev, u32 device_id, int rc = 0; if (!hdev || !res || !callback) { - dprintk(VIDC_ERR, "Invalid params: %p %p %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK %pK %pK\n", hdev, res, callback); rc = -EINVAL; goto err_venus_hfi_init; diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.c b/drivers/media/platform/msm/vidc/vidc_hfi.c index ef0de370eb09a..193b42f69aae9 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi.c +++ b/drivers/media/platform/msm/vidc/vidc_hfi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -61,7 +61,7 @@ void vidc_hfi_deinitialize(enum msm_vidc_hfi_type hfi_type, struct hfi_device *hdev) { if (!hdev) { - dprintk(VIDC_ERR, "%s invalid device %p", __func__, hdev); + dprintk(VIDC_ERR, "%s invalid device %pK", __func__, hdev); return; } From 3b65b999cc3314efd74805f106fe68b1bd06e1dc Mon Sep 17 00:00:00 2001 From: Sanjay Singh Date: Tue, 9 Aug 2016 17:39:35 +0530 Subject: [PATCH 168/320] msm: vidc: use %pK instead of %p which respects kptr_restrict sysctl Hide kernel pointers from unprivileged ussers by using %pK format- specifier instead of %p. This respects the kptr_restrict sysctl setting which is by default on. So by default %pK will print zeroes as address. echo 1 to kptr_restrict to print proper kernel addresses. CRs-Fixed: 987018 Change-Id: I4772257a557c6730ecc0624cbc8e5614e893e9fd Signed-off-by: Sanjay Singh --- .../platform/msm/vidc/hfi_packetization.c | 8 +- .../platform/msm/vidc/hfi_response_handler.c | 44 +++--- drivers/media/platform/msm/vidc/msm_smem.c | 20 +-- .../media/platform/msm/vidc/msm_v4l2_vidc.c | 6 +- drivers/media/platform/msm/vidc/msm_vdec.c | 36 ++--- drivers/media/platform/msm/vidc/msm_venc.c | 30 ++-- drivers/media/platform/msm/vidc/msm_vidc.c | 36 ++--- .../media/platform/msm/vidc/msm_vidc_common.c | 146 +++++++++--------- .../media/platform/msm/vidc/msm_vidc_debug.c | 18 +-- drivers/media/platform/msm/vidc/q6_hfi.c | 22 +-- drivers/media/platform/msm/vidc/venus_hfi.c | 84 +++++----- drivers/media/platform/msm/vidc/vidc_hfi.c | 4 +- 12 files changed, 227 insertions(+), 227 deletions(-) diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c index f74ae08880567..d49acc41a775c 100644 --- a/drivers/media/platform/msm/vidc/hfi_packetization.c +++ b/drivers/media/platform/msm/vidc/hfi_packetization.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1300,7 +1300,7 @@ int create_pkt_cmd_session_set_property( break; default: dprintk(VIDC_ERR, - "Invalid Rate control setting: 0x%p\n", + "Invalid Rate control setting: 0x%pK\n", pdata); break; } @@ -1956,7 +1956,7 @@ int create_pkt_ssr_cmd(enum hal_ssr_trigger_type type, struct hfi_cmd_sys_test_ssr_packet *pkt) { if (!pkt) { - dprintk(VIDC_ERR, "Invalid params, device: %p\n", pkt); + dprintk(VIDC_ERR, "Invalid params, device: %pK\n", pkt); return -EINVAL; } pkt->size = sizeof(struct hfi_cmd_sys_test_ssr_packet); @@ -1969,7 +1969,7 @@ int create_pkt_cmd_sys_image_version( struct hfi_cmd_sys_get_property_packet *pkt) { if (!pkt) { - dprintk(VIDC_ERR, "%s invalid param :%p\n", __func__, pkt); + dprintk(VIDC_ERR, "%s invalid param :%pK\n", __func__, pkt); return -EINVAL; } pkt->size = sizeof(struct hfi_cmd_sys_get_property_packet); diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c index f4ffecbd0f58a..416fc9a60ed2d 100644 --- a/drivers/media/platform/msm/vidc/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -258,7 +258,7 @@ static void hfi_process_event_notify(msm_vidc_callback callback, u32 device_id, hfi_process_sys_error(callback, device_id); break; case HFI_EVENT_SESSION_PROPERTY_CHANGED: - dprintk(VIDC_INFO, "HFI_EVENT_SESSION_PROPERTY_CHANGED[%p]\n", + dprintk(VIDC_INFO, "HFI_EVENT_SESSION_PROPERTY_CHANGED[%pK]\n", session); break; } @@ -270,24 +270,24 @@ static void hfi_process_event_notify(msm_vidc_callback callback, u32 device_id, switch (pkt->event_id) { case HFI_EVENT_SESSION_ERROR: - dprintk(VIDC_INFO, "HFI_EVENT_SESSION_ERROR[%p]\n", session); + dprintk(VIDC_INFO, "HFI_EVENT_SESSION_ERROR[%pK]\n", session); hfi_process_session_error(callback, device_id, session, pkt); break; case HFI_EVENT_SESSION_SEQUENCE_CHANGED: - dprintk(VIDC_INFO, "HFI_EVENT_SESSION_SEQUENCE_CHANGED[%p]\n", + dprintk(VIDC_INFO, "HFI_EVENT_SESSION_SEQUENCE_CHANGED[%pK]\n", session); hfi_process_sess_evt_seq_changed(callback, device_id, session, pkt); break; case HFI_EVENT_RELEASE_BUFFER_REFERENCE: - dprintk(VIDC_INFO, "HFI_EVENT_RELEASE_BUFFER_REFERENCE[%p]\n", + dprintk(VIDC_INFO, "HFI_EVENT_RELEASE_BUFFER_REFERENCE[%pK]\n", session); hfi_process_evt_release_buffer_ref(callback, device_id, session, pkt); break; default: dprintk(VIDC_WARN, - "hal_process_event_notify: unknown_event_id[%p]\n", + "hal_process_event_notify: unknown_event_id[%pK]\n", session); break; } @@ -691,7 +691,7 @@ static void hfi_process_sess_get_prop_profile_level( dprintk(VIDC_DBG, "Entered %s\n", __func__); if (!prop) { dprintk(VIDC_ERR, - "hal_process_sess_get_profile_level: bad_prop: %p\n", + "hal_process_sess_get_profile_level: bad_prop: %pK\n", prop); return; } @@ -722,7 +722,7 @@ static void hfi_process_sess_get_prop_buf_req( if (!prop) { dprintk(VIDC_ERR, - "hal_process_sess_get_prop_buf_req: bad_prop: %p\n", + "hal_process_sess_get_prop_buf_req: bad_prop: %pK\n", prop); return; } @@ -841,7 +841,7 @@ static void hfi_process_session_prop_info(msm_vidc_callback callback, struct buffer_requirements buff_req; memset(&buff_req, 0, sizeof(struct buffer_requirements)); - dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO[%p]\n", session); + dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO[%pK]\n", session); if (pkt->size < sizeof(struct hfi_msg_session_property_info_packet)) { dprintk(VIDC_ERR, @@ -897,7 +897,7 @@ static void hfi_process_session_init_done( memset(&session_init_done, 0, sizeof(struct vidc_hal_session_init_done)); - dprintk(VIDC_DBG, "RECEIVED: SESSION_INIT_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_INIT_DONE[%pK]\n", session); if (sizeof(struct hfi_msg_sys_session_init_done_packet) > pkt->size) { @@ -915,7 +915,7 @@ static void hfi_process_session_init_done( pkt, &session_init_done); } else { dprintk(VIDC_WARN, - "Sess init failed: 0x%p, 0x%p\n", + "Sess init failed: 0x%pK, 0x%pK\n", session->session_id, session); } cmd_done.size = sizeof(struct vidc_hal_session_init_done); @@ -927,7 +927,7 @@ static void hfi_process_session_load_res_done(msm_vidc_callback callback, struct hfi_msg_session_load_resources_done_packet *pkt) { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_LOAD_RESOURCES_DONE[%p]\n", + dprintk(VIDC_DBG, "RECEIVED: SESSION_LOAD_RESOURCES_DONE[%pK]\n", session); if (sizeof(struct hfi_msg_session_load_resources_done_packet) != @@ -952,7 +952,7 @@ static void hfi_process_session_flush_done(msm_vidc_callback callback, { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_FLUSH_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_FLUSH_DONE[%pK]\n", session); if (sizeof(struct hfi_msg_session_flush_done_packet) != pkt->size) { dprintk(VIDC_ERR, @@ -975,7 +975,7 @@ static void hfi_process_session_etb_done(msm_vidc_callback callback, { struct msm_vidc_cb_data_done data_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%pK]\n", session); if (!pkt || pkt->size < sizeof(struct hfi_msg_session_empty_buffer_done_packet)) { @@ -1016,7 +1016,7 @@ static void hfi_process_session_ftb_done(msm_vidc_callback callback, return; } - dprintk(VIDC_DBG, "RECEIVED: SESSION_FTB_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_FTB_DONE[%pK]\n", session); if (is_decoder == 0) { struct hfi_msg_session_fill_buffer_done_compressed_packet *pkt = @@ -1116,7 +1116,7 @@ static void hfi_process_session_start_done(msm_vidc_callback callback, { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_START_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_START_DONE[%pK]\n", session); if (!pkt || pkt->size != sizeof(struct hfi_msg_session_start_done_packet)) { @@ -1139,7 +1139,7 @@ static void hfi_process_session_stop_done(msm_vidc_callback callback, { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_STOP_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_STOP_DONE[%pK]\n", session); if (!pkt || pkt->size != sizeof(struct hfi_msg_session_stop_done_packet)) { @@ -1162,7 +1162,7 @@ static void hfi_process_session_rel_res_done(msm_vidc_callback callback, { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_RELEASE_RESOURCES_DONE[%p]\n", + dprintk(VIDC_DBG, "RECEIVED: SESSION_RELEASE_RESOURCES_DONE[%pK]\n", session); if (!pkt || pkt->size != @@ -1193,7 +1193,7 @@ static void hfi_process_session_rel_buf_done(msm_vidc_callback callback, pkt ? pkt->size : 0); return; } - dprintk(VIDC_DBG, "RECEIVED:SESSION_RELEASE_BUFFER_DONE[%p]\n", + dprintk(VIDC_DBG, "RECEIVED:SESSION_RELEASE_BUFFER_DONE[%pK]\n", session); cmd_done.device_id = device_id; @@ -1215,7 +1215,7 @@ static void hfi_process_session_end_done(msm_vidc_callback callback, { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_END_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_END_DONE[%pK]\n", session); if (!pkt || pkt->size != sizeof(struct hfi_msg_sys_session_end_done_packet)) { @@ -1237,7 +1237,7 @@ static void hfi_process_session_abort_done(msm_vidc_callback callback, { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_ABORT_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_ABORT_DONE[%pK]\n", session); if (!pkt || pkt->size != sizeof(struct hfi_msg_sys_session_abort_done_packet)) { @@ -1274,7 +1274,7 @@ static void hfi_process_session_get_seq_hdr_done(msm_vidc_callback callback, __func__); return; } - dprintk(VIDC_DBG, "RECEIVED:SESSION_GET_SEQ_HDR_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED:SESSION_GET_SEQ_HDR_DONE[%pK]\n", session); data_done.device_id = device_id; data_done.size = sizeof(struct msm_vidc_cb_data_done); diff --git a/drivers/media/platform/msm/vidc/msm_smem.c b/drivers/media/platform/msm/vidc/msm_smem.c index 50e375df67e86..f0455cc9e9854 100644 --- a/drivers/media/platform/msm/vidc/msm_smem.c +++ b/drivers/media/platform/msm/vidc/msm_smem.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -34,7 +34,7 @@ static int get_device_address(struct smem_client *smem_client, struct ion_client *clnt = NULL; if (!iova || !buffer_size || !hndl || !smem_client) { - dprintk(VIDC_ERR, "Invalid params: %p, %p, %p, %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK, %pK, %pK, %pK\n", smem_client, hndl, iova, buffer_size); return -EINVAL; } @@ -86,7 +86,7 @@ static void put_device_address(struct smem_client *smem_client, struct ion_client *clnt = NULL; if (!hndl || !smem_client) { - dprintk(VIDC_WARN, "Invalid params: %p, %p\n", + dprintk(VIDC_WARN, "Invalid params: %pK, %pK\n", smem_client, hndl); return; } @@ -120,7 +120,7 @@ static int ion_user_to_kernel(struct smem_client *client, int fd, u32 offset, hndl = ion_import_dma_buf(client->clnt, fd); if (IS_ERR_OR_NULL(hndl)) { - dprintk(VIDC_ERR, "Failed to get handle: %p, %d, %d, %p\n", + dprintk(VIDC_ERR, "Failed to get handle: %pK, %d, %d, %pK\n", client, fd, offset, hndl); rc = -ENOMEM; goto fail_import_fd; @@ -153,7 +153,7 @@ static int ion_user_to_kernel(struct smem_client *client, int fd, u32 offset, goto fail_device_address; } dprintk(VIDC_DBG, - "%s: ion_handle = 0x%p, fd = %d, device_addr = 0x%pa, size = %zx, kvaddr = 0x%p, buffer_type = %d, flags = 0x%lx\n", + "%s: ion_handle = 0x%pK, fd = %d, device_addr = 0x%pa, size = %zx, kvaddr = 0x%pK, buffer_type = %d, flags = 0x%lx\n", __func__, mem->smem_priv, fd, &mem->device_addr, mem->size, mem->kvaddr, mem->buffer_type, mem->flags); return rc; @@ -198,7 +198,7 @@ static int alloc_ion_mem(struct smem_client *client, size_t size, u32 align, hndl = ion_alloc(client->clnt, size, align, heap_mask, flags); if (IS_ERR_OR_NULL(hndl)) { dprintk(VIDC_ERR, - "Failed to allocate shared memory = %p, %zx, %d, 0x%x\n", + "Failed to allocate shared memory = %pK, %zx, %d, 0x%x\n", client, size, align, flags); rc = -ENOMEM; goto fail_shared_mem_alloc; @@ -236,7 +236,7 @@ static int alloc_ion_mem(struct smem_client *client, size_t size, u32 align, } mem->size = size; dprintk(VIDC_DBG, - "%s: ion_handle = 0x%p, device_addr = 0x%pa, size = 0x%zx, kvaddr = 0x%p, buffer_type = 0x%x, flags = 0x%lx\n", + "%s: ion_handle = 0x%pK, device_addr = 0x%pa, size = 0x%zx, kvaddr = 0x%pK, buffer_type = 0x%x, flags = 0x%lx\n", __func__, mem->smem_priv, &mem->device_addr, mem->size, mem->kvaddr, mem->buffer_type, mem->flags); @@ -254,7 +254,7 @@ static void free_ion_mem(struct smem_client *client, struct msm_smem *mem) int domain, partition, rc; dprintk(VIDC_DBG, - "%s: ion_handle = 0x%p, device_addr = 0x%pa, size = 0x%zx, kvaddr = 0x%p, buffer_type = 0x%x\n", + "%s: ion_handle = 0x%pK, device_addr = 0x%pa, size = 0x%zx, kvaddr = 0x%pK, buffer_type = 0x%x\n", __func__, mem->smem_priv, &mem->device_addr, mem->size, mem->kvaddr, mem->buffer_type); rc = msm_smem_get_domain_partition((void *)client, mem->flags, @@ -332,7 +332,7 @@ static int ion_cache_operations(struct smem_client *client, int rc = 0; int msm_cache_ops = 0; if (!mem || !client) { - dprintk(VIDC_ERR, "Invalid params: %p, %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK, %pK\n", mem, client); return -EINVAL; } @@ -379,7 +379,7 @@ int msm_smem_cache_operations(void *clt, struct msm_smem *mem, struct smem_client *client = clt; int rc = 0; if (!client) { - dprintk(VIDC_ERR, "Invalid params: %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK\n", client); return -EINVAL; } diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c index b57104354a50f..a46eda705ab18 100644 --- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -296,7 +296,7 @@ static int read_platform_resources(struct msm_vidc_core *core, struct platform_device *pdev) { if (!core || !pdev) { - dprintk(VIDC_ERR, "%s: Invalid params %p %p\n", + dprintk(VIDC_ERR, "%s: Invalid params %pK %pK\n", __func__, core, pdev); return -EINVAL; } @@ -641,7 +641,7 @@ static int msm_vidc_remove(struct platform_device *pdev) struct msm_vidc_core *core; if (!pdev) { - dprintk(VIDC_ERR, "%s invalid input %p", __func__, pdev); + dprintk(VIDC_ERR, "%s invalid input %pK", __func__, pdev); return -EINVAL; } core = pdev->dev.platform_data; diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c index 342a8bf2db33e..8c2b8731c2439 100644 --- a/drivers/media/platform/msm/vidc/msm_vdec.c +++ b/drivers/media/platform/msm/vidc/msm_vdec.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -791,7 +791,7 @@ int msm_vdec_prepare_buf(struct msm_vidc_inst *inst, if (inst->state == MSM_VIDC_CORE_INVALID || inst->core->state == VIDC_CORE_INVALID) { dprintk(VIDC_ERR, - "Core %p in bad state, ignoring prepare buf\n", + "Core %pK in bad state, ignoring prepare buf\n", inst->core); goto exit; } @@ -870,7 +870,7 @@ int msm_vdec_release_buf(struct msm_vidc_inst *inst, if (inst->state == MSM_VIDC_CORE_INVALID || core->state == VIDC_CORE_INVALID) { dprintk(VIDC_ERR, - "Core %p in bad state, ignoring release output buf\n", + "Core %pK in bad state, ignoring release output buf\n", core); goto exit; } @@ -963,7 +963,7 @@ int msm_vdec_reqbufs(struct msm_vidc_inst *inst, struct v4l2_requestbuffers *b) int rc = 0; if (!inst || !b) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, buffer = %p\n", inst, b); + "Invalid input, inst = %pK, buffer = %pK\n", inst, b); return -EINVAL; } q = msm_comm_get_vb2q(inst, b->type); @@ -994,7 +994,7 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) if (!inst || !f || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, format = %p\n", inst, f); + "Invalid input, inst = %pK, format = %pK\n", inst, f); return -EINVAL; } @@ -1157,7 +1157,7 @@ int msm_vdec_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a) fps = fps - 1; if (inst->prop.fps != fps) { - dprintk(VIDC_PROF, "reported fps changed for %p: %d->%d\n", + dprintk(VIDC_PROF, "reported fps changed for %pK: %d->%d\n", inst, inst->prop.fps, fps); inst->prop.fps = fps; msm_comm_init_dcvs_load(inst); @@ -1502,7 +1502,7 @@ int msm_vdec_querycap(struct msm_vidc_inst *inst, struct v4l2_capability *cap) { if (!inst || !cap) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, cap = %p\n", inst, cap); + "Invalid input, inst = %pK, cap = %pK\n", inst, cap); return -EINVAL; } strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver)); @@ -1522,7 +1522,7 @@ int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) int rc = 0; if (!inst || !f) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, f = %p\n", inst, f); + "Invalid input, inst = %pK, f = %pK\n", inst, f); return -EINVAL; } if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { @@ -1564,7 +1564,7 @@ static int msm_vdec_queue_setup(struct vb2_queue *q, if (!q || !num_buffers || !num_planes || !sizes || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %p, %p, %p\n", + dprintk(VIDC_ERR, "Invalid input, q = %pK, %pK, %pK\n", q, num_buffers, num_planes); return -EINVAL; } @@ -1725,7 +1725,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst) rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto fail_start; } msm_comm_init_dcvs_load(inst); @@ -1762,7 +1762,7 @@ static inline int stop_streaming(struct msm_vidc_inst *inst) rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); if (rc) dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); return rc; } @@ -1772,7 +1772,7 @@ static int msm_vdec_start_streaming(struct vb2_queue *q, unsigned int count) int rc = 0; struct hfi_device *hdev; if (!q || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %p\n", q); + dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); return -EINVAL; } inst = q->drv_priv; @@ -1805,7 +1805,7 @@ static int msm_vdec_stop_streaming(struct vb2_queue *q) struct msm_vidc_inst *inst; int rc = 0; if (!q || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %p\n", q); + dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); return -EINVAL; } inst = q->drv_priv; @@ -1830,7 +1830,7 @@ static int msm_vdec_stop_streaming(struct vb2_queue *q) if (rc) dprintk(VIDC_ERR, - "Failed to move inst: %p, cap = %d to state: %d\n", + "Failed to move inst: %pK, cap = %d to state: %d\n", inst, q->type, MSM_VIDC_RELEASE_RESOURCES_DONE); return rc; } @@ -1888,7 +1888,7 @@ int msm_vdec_cmd(struct msm_vidc_inst *inst, struct v4l2_decoder_cmd *dec) if (inst->state == MSM_VIDC_CORE_INVALID || core->state == VIDC_CORE_INVALID) { dprintk(VIDC_ERR, - "Core %p in bad state, Sending CLOSE event\n", + "Core %pK in bad state, Sending CLOSE event\n", core); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_CLOSE_DONE); @@ -1930,7 +1930,7 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) { int rc = 0; if (!inst) { - dprintk(VIDC_ERR, "Invalid input = %p\n", inst); + dprintk(VIDC_ERR, "Invalid input = %pK\n", inst); return -EINVAL; } inst->fmts[OUTPUT_PORT] = &vdec_formats[1]; @@ -2455,7 +2455,7 @@ static int msm_vdec_op_s_ctrl(struct v4l2_ctrl *ctrl) rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto failed_open_done; } @@ -2487,7 +2487,7 @@ static int msm_vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl) rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto failed_open_done; } for (c = 0; c < master->ncontrols; ++c) { diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c index c374dca86ebb7..f36a152656a6e 100644 --- a/drivers/media/platform/msm/vidc/msm_venc.c +++ b/drivers/media/platform/msm/vidc/msm_venc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1424,7 +1424,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst) rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto fail_start; } mutex_lock(&inst->pendingq.lock); @@ -1450,7 +1450,7 @@ static int msm_venc_start_streaming(struct vb2_queue *q, unsigned int count) struct msm_vidc_inst *inst; int rc = 0; if (!q || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %p\n", q); + dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); return -EINVAL; } inst = q->drv_priv; @@ -1477,7 +1477,7 @@ static int msm_venc_stop_streaming(struct vb2_queue *q) struct msm_vidc_inst *inst; int rc = 0; if (!q || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %p\n", q); + dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); return -EINVAL; } inst = q->drv_priv; @@ -1498,7 +1498,7 @@ static int msm_venc_stop_streaming(struct vb2_queue *q) if (rc) dprintk(VIDC_ERR, - "Failed to move inst: %p, cap = %d to state: %d\n", + "Failed to move inst: %pK, cap = %d to state: %d\n", inst, q->type, MSM_VIDC_CLOSE_DONE); return rc; } @@ -2854,7 +2854,7 @@ static int msm_venc_op_s_ctrl(struct v4l2_ctrl *ctrl) if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto failed_open_done; } @@ -2898,7 +2898,7 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) { int rc = 0; if (!inst) { - dprintk(VIDC_ERR, "Invalid input = %p\n", inst); + dprintk(VIDC_ERR, "Invalid input = %pK\n", inst); return -EINVAL; } inst->fmts[CAPTURE_PORT] = &venc_formats[1]; @@ -2980,7 +2980,7 @@ int msm_venc_querycap(struct msm_vidc_inst *inst, struct v4l2_capability *cap) { if (!inst || !cap) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, cap = %p\n", inst, cap); + "Invalid input, inst = %pK, cap = %pK\n", inst, cap); return -EINVAL; } strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver)); @@ -3000,7 +3000,7 @@ int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) int rc = 0; if (!inst || !f) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, f = %p\n", inst, f); + "Invalid input, inst = %pK, f = %pK\n", inst, f); return -EINVAL; } if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { @@ -3074,7 +3074,7 @@ int msm_venc_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a) fps = fps - 1; if (inst->prop.fps != fps) { - dprintk(VIDC_PROF, "reported fps changed for %p: %d->%d\n", + dprintk(VIDC_PROF, "reported fps changed for %pK: %d->%d\n", inst, inst->prop.fps, fps); inst->prop.fps = fps; frame_rate.frame_rate = inst->prop.fps * (0x1<<16); @@ -3127,7 +3127,7 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) struct hfi_device *hdev; if (!inst || !f) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, format = %p\n", inst, f); + "Invalid input, inst = %pK, format = %pK\n", inst, f); return -EINVAL; } @@ -3294,7 +3294,7 @@ int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) if (!inst || !f) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, format = %p\n", inst, f); + "Invalid input, inst = %pK, format = %pK\n", inst, f); return -EINVAL; } @@ -3359,7 +3359,7 @@ int msm_venc_reqbufs(struct msm_vidc_inst *inst, struct v4l2_requestbuffers *b) int rc = 0; if (!inst || !b) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, buffer = %p\n", inst, b); + "Invalid input, inst = %pK, buffer = %pK\n", inst, b); return -EINVAL; } q = msm_comm_get_vb2q(inst, b->type); @@ -3396,7 +3396,7 @@ int msm_venc_prepare_buf(struct msm_vidc_inst *inst, if (inst->state == MSM_VIDC_CORE_INVALID || inst->core->state == VIDC_CORE_INVALID) { dprintk(VIDC_ERR, - "Core %p in bad state, ignoring prepare buf\n", + "Core %pK in bad state, ignoring prepare buf\n", inst->core); goto exit; } @@ -3467,7 +3467,7 @@ int msm_venc_release_buf(struct msm_vidc_inst *inst, rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to release res done state\n", + "Failed to move inst: %pK to release res done state\n", inst); goto exit; } diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c index 9a3baade344b9..dcdd1d2dc9bbb 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_vidc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -330,7 +330,7 @@ struct buffer_info *device_to_uvaddr(struct msm_vidc_list *buf_list, if (!buf_list || !device_addr) { dprintk(VIDC_ERR, - "Invalid input- device_addr: 0x%pa buf_list: %p\n", + "Invalid input- device_addr: 0x%pa buf_list: %pK\n", &device_addr, buf_list); goto err_invalid_input; } @@ -486,7 +486,7 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) goto exit; } - dprintk(VIDC_DBG, "[MAP] Create binfo = %p fd = %d type = %d\n", + dprintk(VIDC_DBG, "[MAP] Create binfo = %pK fd = %d type = %d\n", binfo, b->m.planes[0].reserved[0], b->type); for (i = 0; i < b->length; ++i) { @@ -569,7 +569,7 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) goto exit; } dprintk(VIDC_DBG, - "%s: [MAP] binfo = %p, handle[%d] = %p, device_addr = 0x%pa, fd = %d, offset = %d, mapped = %d\n", + "%s: [MAP] binfo = %pK, handle[%d] = %pK, device_addr = 0x%pa, fd = %d, offset = %d, mapped = %d\n", __func__, binfo, i, binfo->handle[i], &binfo->device_addr[i], binfo->fd[i], binfo->buff_off[i], binfo->mapped[i]); @@ -592,7 +592,7 @@ int unmap_and_deregister_buf(struct msm_vidc_inst *inst, bool found = false, keep_node = false; if (!inst || !binfo) { - dprintk(VIDC_ERR, "%s invalid param: %p %p\n", + dprintk(VIDC_ERR, "%s invalid param: %pK %pK\n", __func__, inst, binfo); return -EINVAL; } @@ -622,7 +622,7 @@ int unmap_and_deregister_buf(struct msm_vidc_inst *inst, for (i = 0; i < temp->num_planes; i++) { dprintk(VIDC_DBG, - "%s: [UNMAP] binfo = %p, handle[%d] = %p, device_addr = 0x%pa, fd = %d, offset = %d, mapped = %d\n", + "%s: [UNMAP] binfo = %pK, handle[%d] = %pK, device_addr = 0x%pa, fd = %d, offset = %d, mapped = %d\n", __func__, temp, i, temp->handle[i], &temp->device_addr[i], temp->fd[i], temp->buff_off[i], temp->mapped[i]); @@ -651,12 +651,12 @@ int unmap_and_deregister_buf(struct msm_vidc_inst *inst, } } if (!keep_node) { - dprintk(VIDC_DBG, "[UNMAP] AND-FREED binfo: %p\n", temp); + dprintk(VIDC_DBG, "[UNMAP] AND-FREED binfo: %pK\n", temp); list_del(&temp->list); kfree(temp); } else { temp->inactive = true; - dprintk(VIDC_DBG, "[UNMAP] NOT-FREED binfo: %p\n", temp); + dprintk(VIDC_DBG, "[UNMAP] NOT-FREED binfo: %pK\n", temp); } exit: return 0; @@ -670,7 +670,7 @@ int qbuf_dynamic_buf(struct msm_vidc_inst *inst, struct v4l2_plane plane[VIDEO_MAX_PLANES] = { {0} }; if (!binfo) { - dprintk(VIDC_ERR, "%s invalid param: %p\n", __func__, binfo); + dprintk(VIDC_ERR, "%s invalid param: %pK\n", __func__, binfo); return -EINVAL; } dprintk(VIDC_DBG, "%s fd[0] = %d\n", __func__, binfo->fd[0]); @@ -693,7 +693,7 @@ int output_buffer_cache_invalidate(struct msm_vidc_inst *inst, int rc = 0; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid inst: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst); return -EINVAL; } @@ -701,7 +701,7 @@ int output_buffer_cache_invalidate(struct msm_vidc_inst *inst, return 0; if (!binfo) { - dprintk(VIDC_ERR, "%s: invalid buffer info: %p\n", + dprintk(VIDC_ERR, "%s: invalid buffer info: %pK\n", __func__, inst); return -EINVAL; } @@ -779,7 +779,7 @@ int msm_vidc_release_buffers(void *instance, int buffer_type) rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to release res done\n", + "Failed to move inst: %pK to release res done\n", inst); } } @@ -842,7 +842,7 @@ int msm_vidc_release_buffers(void *instance, int buffer_type) for (i = 0; i < bi->num_planes; i++) { if (bi->handle[i] && bi->mapped[i]) { dprintk(VIDC_DBG, - "%s: [UNMAP] binfo = 0x%p, handle[%d] = %p, device_addr = 0x%pa, fd = %d, offset = %d, mapped = %d\n", + "%s: [UNMAP] binfo = 0x%pK, handle[%d] = %pK, device_addr = 0x%pa, fd = %d, offset = %d, mapped = %d\n", __func__, bi, i, bi->handle[i], &bi->device_addr[i], bi->fd[i], bi->buff_off[i], bi->mapped[i]); @@ -1069,7 +1069,7 @@ int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize) struct msm_vidc_core_capability *capability = NULL; if (!inst || !fsize) { - dprintk(VIDC_ERR, "%s: invalid parameter: %p %p\n", + dprintk(VIDC_ERR, "%s: invalid parameter: %pK %pK\n", __func__, inst, fsize); return -EINVAL; } @@ -1136,7 +1136,7 @@ void *msm_vidc_smem_get_client(void *instance) struct msm_vidc_inst *inst = instance; if (!inst || !inst->mem_client) { - dprintk(VIDC_ERR, "%s: invalid instance or client = %p\n", + dprintk(VIDC_ERR, "%s: invalid instance or client = %pK\n", __func__, inst); return NULL; } @@ -1194,7 +1194,7 @@ static int setup_event_queue(void *inst, struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst; if (!inst || !pvdev) { - dprintk(VIDC_ERR, "%s Invalid params inst %p pvdev %p\n", + dprintk(VIDC_ERR, "%s Invalid params inst %pK pvdev %pK\n", __func__, inst, pvdev); return -EINVAL; } @@ -1270,7 +1270,7 @@ void *msm_vidc_open(int core_id, int session_type) goto err_invalid_core; } - pr_info(VIDC_DBG_TAG "Opening video instance: %p, %d\n", + pr_info(VIDC_DBG_TAG "Opening video instance: %pK, %d\n", VIDC_MSG_PRIO2STRING(VIDC_INFO), inst, session_type); mutex_init(&inst->sync_lock); mutex_init(&inst->bufq[CAPTURE_PORT].lock); @@ -1469,7 +1469,7 @@ int msm_vidc_close(void *instance) msm_smem_delete_client(inst->mem_client); - pr_info(VIDC_DBG_TAG "Closed video instance: %p\n", + pr_info(VIDC_DBG_TAG "Closed video instance: %pK\n", VIDC_MSG_PRIO2STRING(VIDC_INFO), inst); kfree(inst); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c index 08a450cb64725..dc76227a1749d 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -130,7 +130,7 @@ static inline int msm_comm_count_active_instances(struct msm_vidc_core *core) int active_instances = 0; struct msm_vidc_inst *inst = NULL; if (!core) { - dprintk(VIDC_ERR, "%s: Invalid args: %p\n", __func__, core); + dprintk(VIDC_ERR, "%s: Invalid args: %pK\n", __func__, core); return -EINVAL; } @@ -175,7 +175,7 @@ static int msm_comm_get_inst_load(struct msm_vidc_inst *inst, if (is_non_realtime_session(inst) && (quirks & LOAD_CALC_IGNORE_NON_REALTIME_LOAD)) { if (!inst->prop.fps) { - dprintk(VIDC_INFO, "%s: instance:%p prop->fps is set 0\n", __func__, inst); + dprintk(VIDC_INFO, "%s: instance:%pK prop->fps is set 0\n", __func__, inst); load = 0; } else load = msm_comm_get_mbs_per_sec(inst) / inst->prop.fps; @@ -190,7 +190,7 @@ static int msm_comm_get_load(struct msm_vidc_core *core, int num_mbs_per_sec = 0; if (!core) { - dprintk(VIDC_ERR, "Invalid args: %p\n", core); + dprintk(VIDC_ERR, "Invalid args: %pK\n", core); return -EINVAL; } @@ -285,13 +285,13 @@ static int msm_comm_vote_bus(struct msm_vidc_core *core) struct vidc_bus_vote_data *vote_data = NULL; if (!core) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, core); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "%s Invalid device handle: %p\n", + dprintk(VIDC_ERR, "%s Invalid device handle: %pK\n", __func__, hdev); return -EINVAL; } @@ -380,7 +380,7 @@ const struct msm_vidc_format *msm_comm_get_pixel_fmt_index( { int i, k = 0; if (!fmt || index < 0) { - dprintk(VIDC_ERR, "Invalid inputs, fmt = %p, index = %d\n", + dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK, index = %d\n", fmt, index); return NULL; } @@ -402,7 +402,7 @@ struct msm_vidc_format *msm_comm_get_pixel_fmt_fourcc( { int i; if (!fmt) { - dprintk(VIDC_ERR, "Invalid inputs, fmt = %p\n", fmt); + dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK\n", fmt); return NULL; } for (i = 0; i < size; i++) { @@ -462,7 +462,7 @@ static void handle_sys_init_done(enum command_response cmd, void *data) HAL_VIDEO_CODEC_MVC; dprintk(VIDC_DBG, "supported_codecs: enc = 0x%x, dec = 0x%x\n", core->enc_codec_supported, core->dec_codec_supported); - dprintk(VIDC_DBG, "ptr[%d] = %p\n", index, &(core->completions[index])); + dprintk(VIDC_DBG, "ptr[%d] = %pK\n", index, &(core->completions[index])); complete(&(core->completions[index])); } @@ -546,11 +546,11 @@ static void change_inst_state(struct msm_vidc_inst *inst, mutex_lock(&inst->lock); if (inst->state == MSM_VIDC_CORE_INVALID) { dprintk(VIDC_DBG, - "Inst: %p is in bad state can't change state to %d\n", + "Inst: %pK is in bad state can't change state to %d\n", inst, state); goto exit; } - dprintk(VIDC_DBG, "Moved inst: %p from state: %d to state: %d\n", + dprintk(VIDC_DBG, "Moved inst: %pK from state: %d to state: %d\n", inst, inst->state, state); inst->state = state; exit: @@ -561,7 +561,7 @@ static int signal_session_msg_receipt(enum command_response cmd, struct msm_vidc_inst *inst) { if (!inst) { - dprintk(VIDC_ERR, "Invalid(%p) instance id\n", inst); + dprintk(VIDC_ERR, "Invalid(%pK) instance id\n", inst); return -EINVAL; } if (IS_SESSION_CMD_VALID(cmd)) { @@ -602,7 +602,7 @@ static int wait_for_state(struct msm_vidc_inst *inst, { int rc = 0; if (IS_ALREADY_IN_STATE(flipped_state, desired_state)) { - dprintk(VIDC_INFO, "inst: %p is already in state: %d\n", + dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n", inst, inst->state); goto err_same_state; } @@ -648,7 +648,7 @@ static void handle_session_init_done(enum command_response cmd, void *data) response->data; inst = (struct msm_vidc_inst *)response->session_id; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s: invalid parameters (0x%p)\n", + dprintk(VIDC_ERR, "%s: invalid parameters (0x%pK)\n", __func__, inst); return; } @@ -723,7 +723,7 @@ static void handle_event_change(enum command_response cmd, void *data) u32 *ptr = NULL; dprintk(VIDC_DBG, - "%s - inst: %p buffer: 0x%pa extra: 0x%pa\n", + "%s - inst: %pK buffer: 0x%pa extra: 0x%pa\n", __func__, inst, &event_notify->packet_buffer, &event_notify->extra_data_buffer); @@ -1054,7 +1054,7 @@ static void handle_sys_idle(enum command_response cmd, void *data) goto exit; } - dprintk(VIDC_DBG, "SYS_IDLE received for core %p\n", core); + dprintk(VIDC_DBG, "SYS_IDLE received for core %pK\n", core); if (core->resources.dynamic_bw_update) { mutex_lock(&core->lock); core->idle_stats.start_time = ktime_get(); @@ -1086,24 +1086,24 @@ static void handle_session_error(enum command_response cmd, void *data) if (!inst || !inst->session || !inst->core->device) { dprintk(VIDC_ERR, - "Session (%p) not in a stable enough state to handle session error\n", + "Session (%pK) not in a stable enough state to handle session error\n", inst); return; } hdev = inst->core->device; - dprintk(VIDC_WARN, "Session error received for session %p\n", inst); + dprintk(VIDC_WARN, "Session error received for session %pK\n", inst); change_inst_state(inst, MSM_VIDC_CORE_INVALID); if (response->status == VIDC_ERR_MAX_CLIENTS) { dprintk(VIDC_WARN, - "send max clients reached error to client: %p\n", + "send max clients reached error to client: %pK\n", inst); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_MAX_CLIENTS); } else { dprintk(VIDC_ERR, - "send session error to client: %p\n", + "send session error to client: %pK\n", inst); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); @@ -1118,7 +1118,7 @@ static void msm_comm_clean_notify_client(struct msm_vidc_core *core) return; } - dprintk(VIDC_WARN, "%s: Core %p\n", __func__, core); + dprintk(VIDC_WARN, "%s: Core %pK\n", __func__, core); mutex_lock(&core->lock); core->state = VIDC_CORE_INVALID; @@ -1127,7 +1127,7 @@ static void msm_comm_clean_notify_client(struct msm_vidc_core *core) inst->state = MSM_VIDC_CORE_INVALID; mutex_unlock(&inst->lock); dprintk(VIDC_WARN, - "%s Send sys error for inst %p\n", __func__, inst); + "%s Send sys error for inst %pK\n", __func__, inst); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); } @@ -1202,7 +1202,7 @@ static void handle_sys_error(enum command_response cmd, void *data) return; } - dprintk(VIDC_WARN, "SYS_ERROR %d received for core %p\n", cmd, core); + dprintk(VIDC_WARN, "SYS_ERROR %d received for core %pK\n", cmd, core); msm_comm_clean_notify_client(core); handler = kzalloc(sizeof(*handler), GFP_KERNEL); @@ -1237,12 +1237,12 @@ void msm_comm_session_clean(struct msm_vidc_inst *inst) hdev = inst->core->device; mutex_lock(&inst->lock); if (hdev && inst->session) { - dprintk(VIDC_DBG, "cleaning up instance: 0x%p\n", inst); + dprintk(VIDC_DBG, "cleaning up instance: 0x%pK\n", inst); rc = call_hfi_op(hdev, session_clean, (void *) inst->session); if (rc) { dprintk(VIDC_ERR, - "Session clean failed :%p\n", inst); + "Session clean failed :%pK\n", inst); } inst->session = NULL; } @@ -1644,7 +1644,7 @@ static void handle_fbd(enum command_response cmd, void *data) if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { dprintk(VIDC_DBG, - "extradata: userptr = %p;" + "extradata: userptr = %pK;" " bytesused = %d; length = %d\n", (u8 *)vb->v4l2_planes[extra_idx].m.userptr, vb->v4l2_planes[extra_idx].bytesused, @@ -1810,7 +1810,7 @@ void msm_comm_init_dcvs_load(struct msm_vidc_inst *inst) dprintk(VIDC_DBG, "Init DCVS Load\n"); if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst); return; } @@ -1854,7 +1854,7 @@ void msm_comm_init_dcvs(struct msm_vidc_inst *inst) dprintk(VIDC_DBG, "Init DCVS Struct\n"); if (!inst) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst); return; } @@ -1871,7 +1871,7 @@ static void msm_comm_dcvs_monitor_buffer(struct msm_vidc_inst *inst) struct hal_buffer_requirements *output_buf_req; if (!inst) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst); return; } @@ -1881,7 +1881,7 @@ static void msm_comm_dcvs_monitor_buffer(struct msm_vidc_inst *inst) msm_comm_get_hal_output_buffer(inst)); if (!output_buf_req) { - dprintk(VIDC_ERR, "%s : Get output buffer req failed %p\n", + dprintk(VIDC_ERR, "%s : Get output buffer req failed %pK\n", __func__, inst); mutex_unlock(&inst->lock); return; @@ -2039,13 +2039,13 @@ static int msm_comm_scale_clocks(struct msm_vidc_core *core) struct msm_vidc_inst *inst = NULL; if (!core) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, core); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "%s Invalid device handle: %p\n", + dprintk(VIDC_ERR, "%s Invalid device handle: %pK\n", __func__, hdev); return -EINVAL; } @@ -2192,7 +2192,7 @@ static int msm_comm_session_abort(struct msm_vidc_inst *inst) msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { dprintk(VIDC_ERR, - "%s: Wait interrupted or timed out [%p]: %d\n", + "%s: Wait interrupted or timed out [%pK]: %d\n", __func__, inst, abort_completion); rc = -EBUSY; } else { @@ -2219,7 +2219,7 @@ static void handle_thermal_event(struct msm_vidc_core *core) mutex_unlock(&core->lock); if (inst->state >= MSM_VIDC_OPEN_DONE && inst->state < MSM_VIDC_CLOSE_DONE) { - dprintk(VIDC_WARN, "%s: abort inst %p\n", + dprintk(VIDC_WARN, "%s: abort inst %pK\n", __func__, inst); change_inst_state(inst, MSM_VIDC_CORE_INVALID); @@ -2231,7 +2231,7 @@ static void handle_thermal_event(struct msm_vidc_core *core) goto err_sess_abort; } dprintk(VIDC_WARN, - "%s Send sys error for inst %p\n", + "%s Send sys error for inst %pK\n", __func__, inst); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); @@ -2469,7 +2469,7 @@ static int msm_comm_session_init(int flipped_state, hdev = inst->core->device; if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_OPEN)) { - dprintk(VIDC_INFO, "inst: %p is already in state: %d\n", + dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2490,7 +2490,7 @@ static int msm_comm_session_init(int flipped_state, if (!inst->session) { dprintk(VIDC_ERR, - "Failed to call session init for: %p, %p, %d, %d\n", + "Failed to call session init for: %pK, %pK, %d, %d\n", inst->core->device, inst, inst->session_type, fourcc); rc = -EINVAL; @@ -2582,7 +2582,7 @@ static int msm_vidc_load_resources(int flipped_state, hdev = core->device; if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_LOAD_RESOURCES)) { - dprintk(VIDC_INFO, "inst: %p is already in state: %d\n", + dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2618,7 +2618,7 @@ static int msm_vidc_start(int flipped_state, struct msm_vidc_inst *inst) if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_START)) { dprintk(VIDC_INFO, - "inst: %p is already in state: %d\n", + "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2648,7 +2648,7 @@ static int msm_vidc_stop(int flipped_state, struct msm_vidc_inst *inst) if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_STOP)) { dprintk(VIDC_INFO, - "inst: %p is already in state: %d\n", + "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2678,7 +2678,7 @@ static int msm_vidc_release_res(int flipped_state, struct msm_vidc_inst *inst) if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_RELEASE_RESOURCES)) { dprintk(VIDC_INFO, - "inst: %p is already in state: %d\n", + "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2710,7 +2710,7 @@ static int msm_comm_session_close(int flipped_state, hdev = inst->core->device; if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_CLOSE)) { dprintk(VIDC_INFO, - "inst: %p is already in state: %d\n", + "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -3106,16 +3106,16 @@ int msm_comm_try_state(struct msm_vidc_inst *inst, int state) struct msm_vidc_core *core; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } dprintk(VIDC_DBG, - "Trying to move inst: %p from: 0x%x to 0x%x\n", + "Trying to move inst: %pK from: 0x%x to 0x%x\n", inst, inst->state, state); core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", inst); + "Invalid core pointer = %pK\n", inst); return -EINVAL; } mutex_lock(&inst->sync_lock); @@ -3285,7 +3285,7 @@ int msm_comm_qbuf(struct vb2_buffer *vb) int extra_idx = 0; if (!vb || !vb->vb2_queue) { - dprintk(VIDC_ERR, "%s: Invalid input: %p\n", + dprintk(VIDC_ERR, "%s: Invalid input: %pK\n", __func__, vb); return -EINVAL; } @@ -3293,7 +3293,7 @@ int msm_comm_qbuf(struct vb2_buffer *vb) q = vb->vb2_queue; inst = q->drv_priv; if (!inst) { - dprintk(VIDC_ERR, "%s: Invalid input: %p\n", + dprintk(VIDC_ERR, "%s: Invalid input: %pK\n", __func__, vb); return -EINVAL; } @@ -3301,12 +3301,12 @@ int msm_comm_qbuf(struct vb2_buffer *vb) core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid input: %p, %p, %p\n", inst, core, vb); + "Invalid input: %pK, %pK, %pK\n", inst, core, vb); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "%s: Invalid input: %p\n", + dprintk(VIDC_ERR, "%s: Invalid input: %pK\n", __func__, hdev); return -EINVAL; } @@ -3458,7 +3458,7 @@ int msm_comm_qbuf(struct vb2_buffer *vb) (void *) inst->session, &seq_hdr); if (!rc) { inst->vb2_seq_hdr = vb; - dprintk(VIDC_DBG, "Seq_hdr: %p\n", + dprintk(VIDC_DBG, "Seq_hdr: %pK\n", inst->vb2_seq_hdr); } atomic_dec(&inst->seq_hdr_reqs); @@ -3591,7 +3591,7 @@ int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype, msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { dprintk(VIDC_ERR, - "%s: Wait interrupted or timed out [%p]: %d\n", + "%s: Wait interrupted or timed out [%pK]: %d\n", __func__, inst, SESSION_MSG_INDEX(SESSION_PROPERTY_INFO)); inst->state = MSM_VIDC_CORE_INVALID; @@ -3628,18 +3628,18 @@ int msm_comm_release_output_buffers(struct msm_vidc_inst *inst) struct hfi_device *hdev; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", core); + "Invalid core pointer = %pK\n", core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "Invalid device pointer = %p\n", hdev); + dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); return -EINVAL; } mutex_lock(&inst->outputbufs.lock); @@ -3733,18 +3733,18 @@ int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst, enum hal_buffer sufficiency = HAL_BUFFER_NONE; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", core); + "Invalid core pointer = %pK\n", core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "Invalid device pointer = %p\n", hdev); + dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); return -EINVAL; } @@ -3821,18 +3821,18 @@ int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst) struct hfi_device *hdev; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", core); + "Invalid core pointer = %pK\n", core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "Invalid device pointer = %p\n", hdev); + dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); return -EINVAL; } @@ -3881,7 +3881,7 @@ int msm_comm_try_set_prop(struct msm_vidc_inst *inst, int rc = 0; struct hfi_device *hdev; if (!inst) { - dprintk(VIDC_ERR, "Invalid input: %p\n", inst); + dprintk(VIDC_ERR, "Invalid input: %pK\n", inst); return -EINVAL; } @@ -4104,7 +4104,7 @@ void msm_comm_flush_pending_dynamic_buffers(struct msm_vidc_inst *inst) list_for_each_entry(binfo, &inst->registeredbufs.list, list) { if (binfo->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { dprintk(VIDC_DBG, - "%s: binfo = %p device_addr = 0x%pa\n", + "%s: binfo = %pK device_addr = 0x%pa\n", __func__, binfo, &binfo->device_addr[0]); buf_ref_put(inst, binfo); } @@ -4124,18 +4124,18 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) struct hfi_device *hdev; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", core); + "Invalid core pointer = %pK\n", core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "Invalid device pointer = %p\n", hdev); + dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); return -EINVAL; } @@ -4152,7 +4152,7 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) if (inst->state == MSM_VIDC_CORE_INVALID || core->state == VIDC_CORE_INVALID) { dprintk(VIDC_ERR, - "Core %p and inst %p are in bad state\n", + "Core %pK and inst %pK are in bad state\n", core, inst); msm_comm_flush_in_invalid_state(inst); return 0; @@ -4349,7 +4349,7 @@ int msm_vidc_trigger_ssr(struct msm_vidc_core *core, int rc = 0; struct hfi_device *hdev; if (!core || !core->device) { - dprintk(VIDC_WARN, "Invalid parameters: %p\n", core); + dprintk(VIDC_WARN, "Invalid parameters: %pK\n", core); return -EINVAL; } hdev = core->device; @@ -4656,7 +4656,7 @@ int msm_comm_kill_session(struct msm_vidc_inst *inst) change_inst_state(inst, MSM_VIDC_CLOSE_DONE); } else { dprintk(VIDC_WARN, - "Inactive session %p, triggering an internal session error\n", + "Inactive session %pK, triggering an internal session error\n", inst); msm_comm_generate_session_error(inst); @@ -4688,7 +4688,7 @@ struct msm_smem *msm_comm_smem_alloc(struct msm_vidc_inst *inst, struct msm_smem *m = NULL; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid inst: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst); return NULL; } mutex_lock(&inst->core->lock); @@ -4706,7 +4706,7 @@ void msm_comm_smem_free(struct msm_vidc_inst *inst, struct msm_smem *mem) { if (!inst || !inst->core || !mem) { dprintk(VIDC_ERR, - "%s: invalid params: %p %p\n", __func__, inst, mem); + "%s: invalid params: %pK %pK\n", __func__, inst, mem); return; } mutex_lock(&inst->core->lock); @@ -4723,7 +4723,7 @@ int msm_comm_smem_cache_operations(struct msm_vidc_inst *inst, { if (!inst || !mem) { dprintk(VIDC_ERR, - "%s: invalid params: %p %p\n", __func__, inst, mem); + "%s: invalid params: %pK %pK\n", __func__, inst, mem); return -EINVAL; } return msm_smem_cache_operations(inst->mem_client, mem, cache_ops); @@ -4735,7 +4735,7 @@ struct msm_smem *msm_comm_smem_user_to_kernel(struct msm_vidc_inst *inst, struct msm_smem *m = NULL; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid inst: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst); return NULL; } mutex_lock(&inst->core->lock); @@ -4754,7 +4754,7 @@ int msm_comm_smem_get_domain_partition(struct msm_vidc_inst *inst, int *domain_num, int *partition_num) { if (!inst || !domain_num || !partition_num) { - dprintk(VIDC_ERR, "%s: invalid params: %p %p %p\n", + dprintk(VIDC_ERR, "%s: invalid params: %pK %pK %pK\n", __func__, inst, domain_num, partition_num); return -EINVAL; } diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c index a83fa114c4cab..b0bda5de403fa 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -72,13 +72,13 @@ static ssize_t core_info_read(struct file *file, char __user *buf, int i = 0, rc = 0; if (!core || !core->device) { - dprintk(VIDC_ERR, "Invalid params, core: %p\n", core); + dprintk(VIDC_ERR, "Invalid params, core: %pK\n", core); return 0; } hdev = core->device; INIT_DBG_BUF(dbg_buf); write_str(&dbg_buf, "===============================\n"); - write_str(&dbg_buf, "CORE %d: 0x%p\n", core->id, core); + write_str(&dbg_buf, "CORE %d: 0x%pK\n", core->id, core); write_str(&dbg_buf, "===============================\n"); write_str(&dbg_buf, "Core state: %d\n", core->state); rc = call_hfi_op(hdev, get_fw_info, hdev->hfi_device_data, &fw_info); @@ -215,7 +215,7 @@ struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core, struct dentry *dir = NULL; char debugfs_name[MAX_DEBUGFS_NAME]; if (!core) { - dprintk(VIDC_ERR, "Invalid params, core: %p\n", core); + dprintk(VIDC_ERR, "Invalid params, core: %pK\n", core); goto failed_create_dir; } @@ -279,15 +279,15 @@ static ssize_t inst_info_read(struct file *file, char __user *buf, struct msm_vidc_inst *inst = file->private_data; int i, j; if (!inst) { - dprintk(VIDC_ERR, "Invalid params, core: %p\n", inst); + dprintk(VIDC_ERR, "Invalid params, core: %pK\n", inst); return 0; } INIT_DBG_BUF(dbg_buf); write_str(&dbg_buf, "===============================\n"); - write_str(&dbg_buf, "INSTANCE: 0x%p (%s)\n", inst, + write_str(&dbg_buf, "INSTANCE: 0x%pK (%s)\n", inst, inst->session_type == MSM_VIDC_ENCODER ? "Encoder" : "Decoder"); write_str(&dbg_buf, "===============================\n"); - write_str(&dbg_buf, "core: 0x%p\n", inst->core); + write_str(&dbg_buf, "core: 0x%pK\n", inst->core); write_str(&dbg_buf, "height: %d\n", inst->prop.height[CAPTURE_PORT]); write_str(&dbg_buf, "width: %d\n", inst->prop.width[CAPTURE_PORT]); write_str(&dbg_buf, "fps: %d\n", inst->prop.fps); @@ -354,10 +354,10 @@ struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst, struct dentry *dir = NULL; char debugfs_name[MAX_DEBUGFS_NAME]; if (!inst) { - dprintk(VIDC_ERR, "Invalid params, inst: %p\n", inst); + dprintk(VIDC_ERR, "Invalid params, inst: %pK\n", inst); goto failed_create_dir; } - snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%p", inst); + snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%pK", inst); dir = debugfs_create_dir(debugfs_name, parent); if (!dir) { dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n"); diff --git a/drivers/media/platform/msm/vidc/q6_hfi.c b/drivers/media/platform/msm/vidc/q6_hfi.c index 10f4baaccd45f..31f6263535759 100644 --- a/drivers/media/platform/msm/vidc/q6_hfi.c +++ b/drivers/media/platform/msm/vidc/q6_hfi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -202,7 +202,7 @@ static int q6_hfi_register_iommu_domains(struct q6_hfi_device *device) struct iommu_info *iommu_map; if (!device || !device->res) { - dprintk(VIDC_ERR, "Invalid parameter: %p\n", device); + dprintk(VIDC_ERR, "Invalid parameter: %pK\n", device); return -EINVAL; } @@ -220,7 +220,7 @@ static int q6_hfi_register_iommu_domains(struct q6_hfi_device *device) domain = iommu_group_get_iommudata(iommu_map->group); if (IS_ERR_OR_NULL(domain)) { dprintk(VIDC_ERR, - "Failed to get domain data for group %p\n", + "Failed to get domain data for group %pK\n", iommu_map->group); rc = -EINVAL; goto fail_group; @@ -228,7 +228,7 @@ static int q6_hfi_register_iommu_domains(struct q6_hfi_device *device) iommu_map->domain = msm_find_domain_no(domain); if (iommu_map->domain < 0) { dprintk(VIDC_ERR, - "Failed to get domain index for domain %p\n", + "Failed to get domain index for domain %pK\n", domain); rc = -EINVAL; goto fail_group; @@ -254,7 +254,7 @@ static void q6_hfi_deregister_iommu_domains(struct q6_hfi_device *device) int i = 0; if (!device || !device->res) { - dprintk(VIDC_ERR, "Invalid parameter: %p\n", device); + dprintk(VIDC_ERR, "Invalid parameter: %pK\n", device); return; } @@ -347,7 +347,7 @@ static void *q6_hfi_get_device(u32 device_id, int rc = 0; if (!callback) { - dprintk(VIDC_ERR, "%s Invalid params: %p\n", + dprintk(VIDC_ERR, "%s Invalid params: %pK\n", __func__, callback); return NULL; } @@ -663,7 +663,7 @@ static int q6_hfi_session_clean(void *session) return -EINVAL; } sess_close = session; - dprintk(VIDC_DBG, "deleted the session: 0x%p\n", + dprintk(VIDC_DBG, "deleted the session: 0x%pK\n", sess_close->session_id); mutex_lock(&((struct q6_hfi_device *) sess_close->device)->session_lock); @@ -1207,7 +1207,7 @@ static int q6_hfi_iommu_attach(struct q6_hfi_device *device) struct iommu_info *iommu_map; if (!device || !device->res) { - dprintk(VIDC_ERR, "Invalid parameter: %p\n", device); + dprintk(VIDC_ERR, "Invalid parameter: %pK\n", device); return -EINVAL; } @@ -1222,7 +1222,7 @@ static int q6_hfi_iommu_attach(struct q6_hfi_device *device) rc = PTR_ERR(domain) ?: -EINVAL; break; } - dprintk(VIDC_DBG, "Attaching domain(id:%d) %p to group %p\n", + dprintk(VIDC_DBG, "Attaching domain(id:%d) %pK to group %pK\n", iommu_map->domain, domain, group); rc = iommu_attach_group(domain, group); if (rc) { @@ -1253,7 +1253,7 @@ static void q6_hfi_iommu_detach(struct q6_hfi_device *device) int i; if (!device || !device->res) { - dprintk(VIDC_ERR, "Invalid parameter: %p\n", device); + dprintk(VIDC_ERR, "Invalid parameter: %pK\n", device); return; } @@ -1382,7 +1382,7 @@ int q6_hfi_initialize(struct hfi_device *hdev, u32 device_id, int rc = 0; if (!hdev || !res || !callback) { - dprintk(VIDC_ERR, "Invalid params: %p %p %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK %pK %pK\n", hdev, res, callback); rc = -EINVAL; goto err_hfi_init; diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c index 86e00d339aafc..c6f88da49fba6 100644 --- a/drivers/media/platform/msm/vidc/venus_hfi.c +++ b/drivers/media/platform/msm/vidc/venus_hfi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -367,7 +367,7 @@ static int venus_hfi_write_queue(void *info, u8 *packet, u32 *rx_req_is_set) } if (msm_vidc_debug & VIDC_PKT) { - dprintk(VIDC_PKT, "%s: %p\n", __func__, qinfo); + dprintk(VIDC_PKT, "%s: %pK\n", __func__, qinfo); venus_hfi_dump_packet(packet); } @@ -576,7 +576,7 @@ static int venus_hfi_read_queue(void *info, u8 *packet, u32 *pb_tx_req_is_set) *pb_tx_req_is_set = (1 == queue->qhdr_tx_req) ? 1 : 0; if (msm_vidc_debug & VIDC_PKT) { - dprintk(VIDC_PKT, "%s: %p\n", __func__, qinfo); + dprintk(VIDC_PKT, "%s: %pK\n", __func__, qinfo); venus_hfi_dump_packet(packet); } @@ -607,7 +607,7 @@ static int venus_hfi_alloc(struct venus_hfi_device *dev, void *mem, rc = -ENOMEM; goto fail_smem_alloc; } - dprintk(VIDC_DBG, "venus_hfi_alloc: ptr = %p, size = %d\n", + dprintk(VIDC_DBG, "venus_hfi_alloc: ptr = %pK, size = %d\n", alloc->kvaddr, size); rc = msm_smem_cache_operations(dev->hal_client, alloc, SMEM_CACHE_CLEAN); @@ -627,7 +627,7 @@ static int venus_hfi_alloc(struct venus_hfi_device *dev, void *mem, static void venus_hfi_free(struct venus_hfi_device *dev, struct msm_smem *mem) { if (!dev || !mem) { - dprintk(VIDC_ERR, "invalid param %p %p\n", dev, mem); + dprintk(VIDC_ERR, "invalid param %pK %pK\n", dev, mem); return; } @@ -643,7 +643,7 @@ static void venus_hfi_write_register( u32 hwiosymaddr = reg; u8 *base_addr; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return; } if (device->clk_state != ENABLED_PREPARED) { @@ -653,7 +653,7 @@ static void venus_hfi_write_register( } base_addr = device->hal_data->register_base; - dprintk(VIDC_DBG, "Base addr: 0x%p, written to: 0x%x, Value: 0x%x...\n", + dprintk(VIDC_DBG, "Base addr: 0x%pK, written to: 0x%x, Value: 0x%x...\n", base_addr, hwiosymaddr, value); base_addr += hwiosymaddr; writel_relaxed(value, base_addr); @@ -665,7 +665,7 @@ static int venus_hfi_read_register(struct venus_hfi_device *device, u32 reg) int rc = 0; u8 *base_addr; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } if (device->clk_state != ENABLED_PREPARED) { @@ -677,7 +677,7 @@ static int venus_hfi_read_register(struct venus_hfi_device *device, u32 reg) rc = readl_relaxed(base_addr + reg); rmb(); - dprintk(VIDC_DBG, "Base addr: 0x%p, read from: 0x%x, value: 0x%x...\n", + dprintk(VIDC_DBG, "Base addr: 0x%pK, read from: 0x%x, value: 0x%x...\n", base_addr, reg, rc); return rc; @@ -779,7 +779,7 @@ static void venus_hfi_iommu_detach(struct venus_hfi_device *device) int i; if (!device || !device->res) { - dprintk(VIDC_ERR, "Invalid paramter: %p\n", device); + dprintk(VIDC_ERR, "Invalid paramter: %pK\n", device); return; } @@ -1160,7 +1160,7 @@ static int __alloc_ocmem(struct venus_hfi_device *device) unsigned long size; if (!device || !device->res) { - dprintk(VIDC_ERR, "%s Invalid param, device: 0x%p\n", + dprintk(VIDC_ERR, "%s Invalid param, device: 0x%pK\n", __func__, device); return -EINVAL; } @@ -1195,7 +1195,7 @@ static int __free_ocmem(struct venus_hfi_device *device) int rc = 0; if (!device || !device->res) { - dprintk(VIDC_ERR, "%s Invalid param, device: 0x%p\n", + dprintk(VIDC_ERR, "%s Invalid param, device: 0x%pK\n", __func__, device); return -EINVAL; } @@ -1219,14 +1219,14 @@ static int __set_ocmem(struct venus_hfi_device *device, bool locked) struct on_chip_mem *ocmem; if (!device) { - dprintk(VIDC_ERR, "%s Invalid param, device: 0x%p\n", + dprintk(VIDC_ERR, "%s Invalid param, device: 0x%pK\n", __func__, device); return -EINVAL; } ocmem = &device->resources.ocmem; if (!ocmem->buf) { - dprintk(VIDC_ERR, "Invalid params, ocmem_buffer: 0x%p\n", + dprintk(VIDC_ERR, "Invalid params, ocmem_buffer: 0x%pK\n", ocmem->buf); return -EINVAL; } @@ -1255,7 +1255,7 @@ static int __unset_ocmem(struct venus_hfi_device *device) int rc = 0; if (!device) { - dprintk(VIDC_ERR, "%s Invalid param, device: 0x%p\n", + dprintk(VIDC_ERR, "%s Invalid param, device: 0x%pK\n", __func__, device); rc = -EINVAL; goto ocmem_unset_failed; @@ -1286,7 +1286,7 @@ static int __alloc_set_ocmem(struct venus_hfi_device *device, bool locked) int rc = 0; if (!device || !device->res) { - dprintk(VIDC_ERR, "%s Invalid param, device: 0x%p\n", + dprintk(VIDC_ERR, "%s Invalid param, device: 0x%pK\n", __func__, device); return -EINVAL; } @@ -1326,7 +1326,7 @@ static int __unset_free_ocmem(struct venus_hfi_device *device) int rc = 0; if (!device || !device->res) { - dprintk(VIDC_ERR, "%s Invalid param, device: 0x%p\n", + dprintk(VIDC_ERR, "%s Invalid param, device: 0x%pK\n", __func__, device); return -EINVAL; } @@ -1464,7 +1464,7 @@ static unsigned long venus_hfi_get_core_clock_rate(void *dev) struct clock_info *vc; if (!device) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, device); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, device); return -EINVAL; } @@ -1536,7 +1536,7 @@ static int venus_hfi_halt_axi(struct venus_hfi_device *device) u32 reg; int rc = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid input: %p\n", device); + dprintk(VIDC_ERR, "Invalid input: %pK\n", device); return -EINVAL; } /* @@ -1571,7 +1571,7 @@ static inline int venus_hfi_power_off(struct venus_hfi_device *device) int rc = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } if (!device->power_enabled) { @@ -1642,7 +1642,7 @@ static inline int venus_hfi_power_on(struct venus_hfi_device *device) int rc = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } if (device->power_enabled) @@ -1770,7 +1770,7 @@ static int venus_hfi_power_enable(void *dev) int rc = 0; struct venus_hfi_device *device = dev; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } mutex_lock(&device->write_lock); @@ -1789,7 +1789,7 @@ static int venus_hfi_scale_clocks(void *dev, int load, int codecs_enabled) struct clock_info *cl; if (!device) { - dprintk(VIDC_ERR, "Invalid args: %p\n", device); + dprintk(VIDC_ERR, "Invalid args: %pK\n", device); return -EINVAL; } device->clk_load = load; @@ -2385,7 +2385,7 @@ static int venus_hfi_core_init(void *device) goto err_core_init; } - dprintk(VIDC_DBG, "Dev_Virt: 0x%pa, Reg_Virt: 0x%p\n", + dprintk(VIDC_DBG, "Dev_Virt: 0x%pa, Reg_Virt: 0x%pK\n", &dev->hal_data->firmware_base, dev->hal_data->register_base); @@ -2531,12 +2531,12 @@ static void venus_hfi_core_clear_interrupt(struct venus_hfi_device *device) device->intr_status |= intr_status; device->reg_count++; dprintk(VIDC_DBG, - "INTERRUPT for device: 0x%p: times: %d interrupt_status: %d\n", + "INTERRUPT for device: 0x%pK: times: %d interrupt_status: %d\n", device, device->reg_count, intr_status); } else { device->spur_count++; dprintk(VIDC_INFO, - "SPURIOUS_INTR for device: 0x%p: times: %d interrupt_status: %d\n", + "SPURIOUS_INTR for device: 0x%pK: times: %d interrupt_status: %d\n", device, device->spur_count, intr_status); } @@ -2683,7 +2683,7 @@ static int venus_hfi_session_clean(void *session) sess_close = session; device = sess_close->device; venus_hfi_flush_debug_queue(sess_close->device, NULL); - dprintk(VIDC_DBG, "deleted the session: 0x%p\n", + dprintk(VIDC_DBG, "deleted the session: 0x%pK\n", sess_close); mutex_lock(&device->session_lock); list_del(&sess_close->list); @@ -3404,7 +3404,7 @@ static void venus_hfi_core_work_handler(struct work_struct *work) dprintk(VIDC_INFO, "GOT INTERRUPT\n"); if (!device->callback) { - dprintk(VIDC_ERR, "No interrupt callback function: %p\n", + dprintk(VIDC_ERR, "No interrupt callback function: %pK\n", device); return; } @@ -3502,7 +3502,7 @@ static inline int venus_hfi_init_clocks(struct msm_vidc_platform_resources *res, struct clock_info *cl = NULL; if (!res || !device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } @@ -3571,7 +3571,7 @@ static inline void venus_hfi_disable_unprepare_clks( struct clock_info *cl; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return; } @@ -3604,7 +3604,7 @@ static inline int venus_hfi_prepare_enable_clks(struct venus_hfi_device *device) struct clock_info *cl = NULL, *cl_fail = NULL; int rc = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } @@ -3667,7 +3667,7 @@ static int venus_hfi_register_iommu_domains(struct venus_hfi_device *device, domain = iommu_group_get_iommudata(iommu_map->group); if (!domain) { dprintk(VIDC_ERR, - "Failed to get domain data for group %p\n", + "Failed to get domain data for group %pK\n", iommu_map->group); rc = -EINVAL; goto fail_group; @@ -3675,7 +3675,7 @@ static int venus_hfi_register_iommu_domains(struct venus_hfi_device *device, iommu_map->domain = msm_find_domain_no(domain); if (iommu_map->domain < 0) { dprintk(VIDC_ERR, - "Failed to get domain index for domain %p\n", + "Failed to get domain index for domain %pK\n", domain); rc = -EINVAL; goto fail_group; @@ -3821,7 +3821,7 @@ static int venus_hfi_init_resources(struct venus_hfi_device *device, device->res = res; if (!res) { - dprintk(VIDC_ERR, "Invalid params: %p\n", res); + dprintk(VIDC_ERR, "Invalid params: %pK\n", res); return -ENODEV; } @@ -3878,7 +3878,7 @@ static int venus_hfi_iommu_get_domain_partition(void *dev, u32 flags, struct venus_hfi_device *device = dev; if (!device) { - dprintk(VIDC_ERR, "%s: Invalid param device: %p\n", + dprintk(VIDC_ERR, "%s: Invalid param device: %pK\n", __func__, device); return -EINVAL; } @@ -3903,7 +3903,7 @@ static int protect_cp_mem(struct venus_hfi_device *device) iommu_group_set = &device->res->iommu_group_set; if (!iommu_group_set) { - dprintk(VIDC_ERR, "invalid params: %p\n", iommu_group_set); + dprintk(VIDC_ERR, "invalid params: %pK\n", iommu_group_set); return -EINVAL; } @@ -4057,7 +4057,7 @@ static int venus_hfi_load_fw(void *dev) struct venus_hfi_device *device = dev; if (!device) { - dprintk(VIDC_ERR, "%s Invalid paramter: %p\n", + dprintk(VIDC_ERR, "%s Invalid paramter: %pK\n", __func__, device); return -EINVAL; } @@ -4145,7 +4145,7 @@ static void venus_hfi_unload_fw(void *dev) { struct venus_hfi_device *device = dev; if (!device) { - dprintk(VIDC_ERR, "%s Invalid paramter: %p\n", + dprintk(VIDC_ERR, "%s Invalid paramter: %pK\n", __func__, device); return; } @@ -4176,7 +4176,7 @@ static int venus_hfi_resurrect_fw(void *dev) int rc = 0; if (!device) { - dprintk(VIDC_ERR, "%s Invalid paramter: %p\n", + dprintk(VIDC_ERR, "%s Invalid paramter: %pK\n", __func__, device); return -EINVAL; } @@ -4222,7 +4222,7 @@ static int venus_hfi_get_fw_info(void *dev, struct hal_fw_info *fw_info) if (!device || !fw_info) { dprintk(VIDC_ERR, - "%s Invalid paramter: device = %p fw_info = %p\n", + "%s Invalid paramter: device = %pK fw_info = %pK\n", __func__, device, fw_info); return -EINVAL; } @@ -4409,7 +4409,7 @@ static void *venus_hfi_get_device(u32 device_id, int rc = 0; if (!res || !callback) { - dprintk(VIDC_ERR, "Invalid params: %p %p\n", res, callback); + dprintk(VIDC_ERR, "Invalid params: %pK %pK\n", res, callback); return NULL; } @@ -4510,7 +4510,7 @@ int venus_hfi_initialize(struct hfi_device *hdev, u32 device_id, int rc = 0; if (!hdev || !res || !callback) { - dprintk(VIDC_ERR, "Invalid params: %p %p %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK %pK %pK\n", hdev, res, callback); rc = -EINVAL; goto err_venus_hfi_init; diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.c b/drivers/media/platform/msm/vidc/vidc_hfi.c index ef0de370eb09a..193b42f69aae9 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi.c +++ b/drivers/media/platform/msm/vidc/vidc_hfi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -61,7 +61,7 @@ void vidc_hfi_deinitialize(enum msm_vidc_hfi_type hfi_type, struct hfi_device *hdev) { if (!hdev) { - dprintk(VIDC_ERR, "%s invalid device %p", __func__, hdev); + dprintk(VIDC_ERR, "%s invalid device %pK", __func__, hdev); return; } From 220020c1c7b24fd3aae74d796065d4a96f093681 Mon Sep 17 00:00:00 2001 From: Suman Mukherjee Date: Wed, 15 Jun 2016 11:31:04 +0530 Subject: [PATCH 169/320] msm: vidc: add ion_handle checking before mapping buffers. Compare ion handles in driver instead of matching fds to check if a buffer is already mapped or not . Bug: 28747768 Change-Id: Ifd18d8689351c4a6a22c988d359fb413be19e142 Signed-off-by: Ashray Kulkarni Signed-off-by: Praveen Chavan Signed-off-by: Deva Ramasubramanian Signed-off-by: Arun Menon Signed-off-by: Suman Mukherjee Signed-off-by: Paras Nagda Signed-off-by: Vasantha Balla --- drivers/media/platform/msm/vidc/msm_smem.c | 11 +++++++++++ drivers/media/platform/msm/vidc/msm_vidc.c | 12 +++++++++--- drivers/media/platform/msm/vidc/msm_vidc_internal.h | 1 + 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/vidc/msm_smem.c b/drivers/media/platform/msm/vidc/msm_smem.c index 50e375df67e86..cba998489ebad 100644 --- a/drivers/media/platform/msm/vidc/msm_smem.c +++ b/drivers/media/platform/msm/vidc/msm_smem.c @@ -325,6 +325,17 @@ struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset, return mem; } +bool msm_smem_compare_buffers(void *clt, int fd, void *priv) { + struct smem_client *client = clt; + struct ion_handle *handle = NULL; + bool ret = false; + handle = ion_import_dma_buf(client->clnt, fd); + ret = handle == priv; + handle ? ion_free(client->clnt, handle) : 0; + return ret; +} + + static int ion_cache_operations(struct smem_client *client, struct msm_smem *mem, enum smem_cache_ops cache_op) { diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c index 9a3baade344b9..c1a38b572d147 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_vidc.c @@ -259,9 +259,11 @@ struct buffer_info *get_registered_buf(struct msm_vidc_inst *inst, list_for_each_entry(temp, &inst->registeredbufs.list, list) { for (i = 0; (i < temp->num_planes) && (i < VIDEO_MAX_PLANES); i++) { + bool ion_hndl_matches = + msm_smem_compare_buffers(inst->mem_client, fd, + temp->handle[i]->smem_priv); if (temp && - ((fd == temp->fd[i]) || - (device_addr == temp->device_addr[i])) && + (device_addr == temp->device_addr[i] || ion_hndl_matches) && (CONTAINS(temp->buff_off[i], temp->size[i], buff_off) || CONTAINS(buff_off, @@ -467,6 +469,9 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) int plane = 0; int i = 0, rc = 0; struct msm_smem *same_fd_handle = NULL; + bool check_same_fd_handle = !is_dynamic_output_buffer_mode(b, inst) && + !( inst->session_type == MSM_VIDC_ENCODER && + b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); if (!b || !inst) { dprintk(VIDC_ERR, "%s: invalid input\n", __func__); @@ -530,7 +535,8 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) if (rc < 0) goto exit; - if (!is_dynamic_output_buffer_mode(b, inst)) + //if (!is_dynamic_output_buffer_mode(b, inst)) + if (check_same_fd_handle) same_fd_handle = get_same_fd_buffer( &inst->registeredbufs, b->m.planes[i].reserved[0]); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h index ed696710215f6..4340308966176 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h +++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h @@ -390,6 +390,7 @@ int msm_smem_cache_operations(void *clt, struct msm_smem *mem, enum smem_cache_ops); struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset, enum hal_buffer buffer_type); +bool msm_smem_compare_buffers(void *clt, int fd, void *priv); int msm_smem_get_domain_partition(void *clt, u32 flags, enum hal_buffer buffer_type, int *domain_num, int *partition_num); void msm_vidc_fw_unload_handler(struct work_struct *work); From 87b50b7b07137da05c959363c2e6867dbf1966a9 Mon Sep 17 00:00:00 2001 From: Sathish Ambley Date: Wed, 10 Jun 2015 00:39:41 -0700 Subject: [PATCH 170/320] msm: ADSPRPC: Do not access user memory directly The buffers being passed in the invocation are copied from user memory into the context using copy_from_user. Lookup the buffer pointers from the context where it was copied rather than directly accessing it from the user memory. Change-Id: Ief5a840f17f6287ebd48b4ae52facaccb271fab8 Signed-off-by: Sathish Ambley --- drivers/char/adsprpc_compat.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/char/adsprpc_compat.c b/drivers/char/adsprpc_compat.c index 31c2897546eb6..ee324dcf91f0e 100644 --- a/drivers/char/adsprpc_compat.c +++ b/drivers/char/adsprpc_compat.c @@ -98,8 +98,9 @@ static int compat_get_fastrpc_ioctl_invoke( if (err) return -EFAULT; - inv->inv.pra = (union remote_arg *)(inv + 1); - err = put_user(sc, &inv->inv.sc); + pra = (union remote_arg *)(inv + 1); + err = put_user(pra, &inv->inv.pra); + err |= put_user(sc, &inv->inv.sc); err |= get_user(u, &inv32->inv.handle); err |= put_user(u, &inv->inv.handle); err |= get_user(p, &inv32->inv.pra); @@ -107,12 +108,11 @@ static int compat_get_fastrpc_ioctl_invoke( return err; pra32 = compat_ptr(p); - pra = inv->inv.pra; + pra = (union remote_arg *)(inv + 1); num = REMOTE_SCALARS_INBUFS(sc) + REMOTE_SCALARS_OUTBUFS(sc); for (j = 0; j < num; j++) { err |= get_user(p, &pra32[j].buf.pv); - pra[j].buf.pv = NULL; - err |= put_user(p, (compat_uptr_t *)&pra[j].buf.pv); + err |= put_user(p, (uintptr_t *)&pra[j].buf.pv); err |= get_user(s, &pra32[j].buf.len); err |= put_user(s, &pra[j].buf.len); } @@ -121,7 +121,7 @@ static int compat_get_fastrpc_ioctl_invoke( err |= put_user(u, &pra[num + j].h); } - inv->fds = NULL; + err |= put_user(NULL, &inv->fds); if (cmd == COMPAT_FASTRPC_IOCTL_INVOKE_FD) { err |= get_user(p, &inv32->fds); err |= put_user(p, (compat_uptr_t *)&inv->fds); @@ -173,8 +173,7 @@ static int compat_get_fastrpc_ioctl_mmap( err |= get_user(u, &map32->flags); err |= put_user(u, &map->flags); err |= get_user(p, &map32->vaddrin); - map->vaddrin = NULL; - err |= put_user(p, (compat_uptr_t *)&map->vaddrin); + err |= put_user(p, (uintptr_t *)&map->vaddrin); err |= get_user(s, &map32->size); err |= put_user(s, &map->size); From 643914ec7db364f927106e0b5d95af7cb69b49ec Mon Sep 17 00:00:00 2001 From: Padmanabhan Komanduru Date: Fri, 31 Oct 2014 15:02:55 +0530 Subject: [PATCH 171/320] msm: mdss: add support for DMA TPG for sending panel commands Currently,the DSI controller fetches DMA commands through the MDP VBIF interface. The DMA data is fetched from memory only when software triggers command DMA. The latency might be long between fetches. A FIFO is present in the DSI controller to bypass the VBIF interface from DSI rev 1.3.0. The user can pre-fill the DMA data in the FIFO via the AHB bus before triggering the command DMA operation. Add support for this. Change-Id: Ieff7575fa4483c87e3b3665149f313828d9b09a7 Signed-off-by: Padmanabhan Komanduru --- drivers/video/msm/mdss/mdss_dsi.h | 4 +- drivers/video/msm/mdss/mdss_dsi_cmd.h | 1 + drivers/video/msm/mdss/mdss_dsi_host.c | 186 ++++++++++++++++++++----- 3 files changed, 155 insertions(+), 36 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h index 23c72f87089a0..047aa154754a2 100644 --- a/drivers/video/msm/mdss/mdss_dsi.h +++ b/drivers/video/msm/mdss/mdss_dsi.h @@ -432,10 +432,10 @@ int dsi_panel_device_register(struct device_node *pan_node, struct mdss_dsi_ctrl_pdata *ctrl_pdata); int mdss_dsi_cmds_tx(struct mdss_dsi_ctrl_pdata *ctrl, - struct dsi_cmd_desc *cmds, int cnt); + struct dsi_cmd_desc *cmds, int cnt, int use_dma_tpg); int mdss_dsi_cmds_rx(struct mdss_dsi_ctrl_pdata *ctrl, - struct dsi_cmd_desc *cmds, int rlen); + struct dsi_cmd_desc *cmds, int rlen, int use_dma_tpg); void mdss_dsi_host_init(struct mdss_panel_data *pdata); void mdss_dsi_op_mode_config(int mode, diff --git a/drivers/video/msm/mdss/mdss_dsi_cmd.h b/drivers/video/msm/mdss/mdss_dsi_cmd.h index 119ce349100ec..a015426241e57 100644 --- a/drivers/video/msm/mdss/mdss_dsi_cmd.h +++ b/drivers/video/msm/mdss/mdss_dsi_cmd.h @@ -99,6 +99,7 @@ struct dsi_cmd_desc { #define CMD_REQ_COMMIT 0x0002 #define CMD_CLK_CTRL 0x0004 #define CMD_REQ_UNICAST 0x0008 +#define CMD_REQ_DMA_TPG 0x0040 #define CMD_REQ_NO_MAX_PKT_SIZE 0x0008 #define CMD_REQ_LP_MODE 0x0010 #define CMD_REQ_HS_MODE 0x0020 diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c index 24c3e63b13717..e894d08a9a69b 100644 --- a/drivers/video/msm/mdss/mdss_dsi_host.c +++ b/drivers/video/msm/mdss/mdss_dsi_host.c @@ -29,6 +29,8 @@ #include "mdss_debug.h" #define VSYNC_PERIOD 17 +#define DMA_TX_TIMEOUT 200 +#define DMA_TPG_FIFO_LEN 64 struct mdss_dsi_ctrl_pdata *ctrl_list[DSI_CTRL_MAX]; @@ -1211,8 +1213,107 @@ static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl, static int mdss_dsi_cmd_dma_rx(struct mdss_dsi_ctrl_pdata *ctrl, struct dsi_buf *rp, int rlen); +static int mdss_dsi_cmd_dma_tpg_tx(struct mdss_dsi_ctrl_pdata *ctrl, + struct dsi_buf *tp) +{ + int len, i, ret = 0, data = 0; + u32 *bp, ctrl_rev; + struct mdss_dsi_ctrl_pdata *mctrl = NULL; + + if (tp->len > DMA_TPG_FIFO_LEN) { + pr_debug("command length more than FIFO length\n"); + return -EINVAL; + } + + ctrl_rev = MIPI_INP(ctrl->ctrl_base); + + if (ctrl_rev < MDSS_DSI_HW_REV_103) { + pr_err("CMD DMA TPG not supported for this DSI version\n"); + return -EINVAL; + } + + bp = (u32 *)tp->data; + len = ALIGN(tp->len, 4); + + INIT_COMPLETION(ctrl->dma_comp); + + if (mdss_dsi_sync_wait_trigger(ctrl)) + mctrl = mdss_dsi_get_other_ctrl(ctrl); + + data = BIT(16) | BIT(17); /* select CMD_DMA_PATTERN_SEL to 3 */ + data |= BIT(2); /* select CMD_DMA_FIFO_MODE to 1 */ + data |= BIT(1); /* enable CMD_DMA_TPG */ + + MIPI_OUTP(ctrl->ctrl_base + 0x15c, data); + if (mctrl) + MIPI_OUTP(mctrl->ctrl_base + 0x15c, data); + + /* + * The DMA command parameters need to be programmed to the DMA_INIT_VAL + * register in the proper order. The 'len' value will be a multiple + * of 4, the padding bytes to make sure of this will be taken care of in + * mdss_dsi_cmd_dma_add API. + */ + for (i = 0; i < len; i += 4) { + MIPI_OUTP(ctrl->ctrl_base + 0x17c, *bp); + if (mctrl) + MIPI_OUTP(mctrl->ctrl_base + 0x17c, *bp); + wmb(); /* make sure write happens before writing next command */ + bp++; + } + + /* + * The number of writes to the DMA_INIT_VAL register should be an even + * number of dwords (32 bits). In case 'len' is not a multiple of 8, + * we need to do make an extra write to the register with 0x00 to + * satisfy this condition. + */ + if ((len % 8) != 0) { + MIPI_OUTP(ctrl->ctrl_base + 0x17c, 0x00); + if (mctrl) + MIPI_OUTP(mctrl->ctrl_base + 0x17c, 0x00); + } + + if (mctrl) { + MIPI_OUTP(mctrl->ctrl_base + 0x04c, len); + MIPI_OUTP(mctrl->ctrl_base + 0x090, 0x01); /* trigger */ + } + MIPI_OUTP(ctrl->ctrl_base + 0x04c, len); + wmb(); /* make sure DMA length is programmed */ + + MIPI_OUTP(ctrl->ctrl_base + 0x090, 0x01); /* trigger */ + wmb(); /* make sure DMA trigger happens */ + + ret = wait_for_completion_timeout(&ctrl->dma_comp, + msecs_to_jiffies(DMA_TX_TIMEOUT)); + if (ret == 0) + ret = -ETIMEDOUT; + else + ret = tp->len; + + /* Reset the DMA TPG FIFO */ + MIPI_OUTP(ctrl->ctrl_base + 0x1ec, 0x1); + wmb(); /* make sure FIFO reset happens */ + MIPI_OUTP(ctrl->ctrl_base + 0x1ec, 0x0); + wmb(); /* make sure FIFO reset happens */ + /* Disable CMD_DMA_TPG */ + MIPI_OUTP(ctrl->ctrl_base + 0x15c, 0x0); + + if (mctrl) { + /* Reset the DMA TPG FIFO */ + MIPI_OUTP(mctrl->ctrl_base + 0x1ec, 0x1); + wmb(); /* make sure FIFO reset happens */ + MIPI_OUTP(mctrl->ctrl_base + 0x1ec, 0x0); + wmb(); /* make sure FIFO reset happens */ + /* Disable CMD_DMA_TPG */ + MIPI_OUTP(mctrl->ctrl_base + 0x15c, 0x0); + } + + return ret; +} + static int mdss_dsi_cmds2buf_tx(struct mdss_dsi_ctrl_pdata *ctrl, - struct dsi_cmd_desc *cmds, int cnt) + struct dsi_cmd_desc *cmds, int cnt, int use_dma_tpg) { struct dsi_buf *tp; struct dsi_cmd_desc *cm; @@ -1239,7 +1340,10 @@ static int mdss_dsi_cmds2buf_tx(struct mdss_dsi_ctrl_pdata *ctrl, wait = mdss_dsi_wait4video_eng_busy(ctrl); mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM); - len = mdss_dsi_cmd_dma_tx(ctrl, tp); + if (use_dma_tpg) + len = mdss_dsi_cmd_dma_tpg_tx(ctrl, tp); + else + len = mdss_dsi_cmd_dma_tx(ctrl, tp); if (IS_ERR_VALUE(len)) { mdss_dsi_disable_irq(ctrl, DSI_CMD_TERM); pr_err("%s: failed to call cmd_dma_tx for cmd = 0x%x\n", @@ -1297,7 +1401,7 @@ static inline bool __mdss_dsi_cmd_mode_config( * thread context only */ int mdss_dsi_cmds_tx(struct mdss_dsi_ctrl_pdata *ctrl, - struct dsi_cmd_desc *cmds, int cnt) + struct dsi_cmd_desc *cmds, int cnt, int use_dma_tpg) { int len = 0; struct mdss_dsi_ctrl_pdata *mctrl = NULL; @@ -1332,7 +1436,7 @@ int mdss_dsi_cmds_tx(struct mdss_dsi_ctrl_pdata *ctrl, do_send: ctrl->cmd_cfg_restore = __mdss_dsi_cmd_mode_config(ctrl, 1); - len = mdss_dsi_cmds2buf_tx(ctrl, cmds, cnt); + len = mdss_dsi_cmds2buf_tx(ctrl, cmds, cnt, use_dma_tpg); if (!len) pr_err("%s: failed to call\n", __func__); @@ -1373,7 +1477,7 @@ static struct dsi_cmd_desc pkt_size_cmd = { * */ int mdss_dsi_cmds_rx(struct mdss_dsi_ctrl_pdata *ctrl, - struct dsi_cmd_desc *cmds, int rlen) + struct dsi_cmd_desc *cmds, int rlen, int use_dma_tpg) { int data_byte, rx_byte, dlen, end; int short_response, diff, pkt_size, ret = 0; @@ -1455,7 +1559,10 @@ int mdss_dsi_cmds_rx(struct mdss_dsi_ctrl_pdata *ctrl, mdss_dsi_wait4video_eng_busy(ctrl); mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM); - ret = mdss_dsi_cmd_dma_tx(ctrl, tp); + if (use_dma_tpg) + ret = mdss_dsi_cmd_dma_tpg_tx(ctrl, tp); + else + ret = mdss_dsi_cmd_dma_tx(ctrl, tp); if (IS_ERR_VALUE(ret)) { mdss_dsi_disable_irq(ctrl, DSI_CMD_TERM); pr_err("%s: failed to tx max_pkt_size\n", @@ -1488,7 +1595,10 @@ int mdss_dsi_cmds_rx(struct mdss_dsi_ctrl_pdata *ctrl, mdss_dsi_wait4video_eng_busy(ctrl); /* video mode only */ mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM); /* transmit read comamnd to client */ - ret = mdss_dsi_cmd_dma_tx(ctrl, tp); + if (use_dma_tpg) + ret = mdss_dsi_cmd_dma_tpg_tx(ctrl, tp); + else + ret = mdss_dsi_cmd_dma_tx(ctrl, tp); if (IS_ERR_VALUE(ret)) { mdss_dsi_disable_irq(ctrl, DSI_CMD_TERM); pr_err("%s: failed to tx cmd = 0x%x\n", @@ -1589,8 +1699,6 @@ int mdss_dsi_cmds_rx(struct mdss_dsi_ctrl_pdata *ctrl, return rp->read_cnt; } -#define DMA_TX_TIMEOUT 200 - static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl, struct dsi_buf *tp) { @@ -1984,7 +2092,8 @@ int mdss_dsi_cmdlist_tx(struct mdss_dsi_ctrl_pdata *ctrl, ctrl->do_unicast = true; } - len = mdss_dsi_cmds_tx(ctrl, req->cmds, req->cmds_cnt); + len = mdss_dsi_cmds_tx(ctrl, req->cmds, req->cmds_cnt, + (req->flags & CMD_REQ_DMA_TPG)); if (req->cb) req->cb(len); @@ -2000,7 +2109,8 @@ int mdss_dsi_cmdlist_rx(struct mdss_dsi_ctrl_pdata *ctrl, if (req->rbuf) { rp = &ctrl->rx_buf; - len = mdss_dsi_cmds_rx(ctrl, req->cmds, req->rlen); + len = mdss_dsi_cmds_rx(ctrl, req->cmds, req->rlen, + (req->flags & CMD_REQ_DMA_TPG)); memcpy(req->rbuf, rp->data, rp->len); ctrl->rx_len = len; } else { @@ -2020,6 +2130,7 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp) struct mdss_rect *roi = NULL; int ret = -EINVAL; int rc = 0; + u32 ctrl_rev; if (mdss_get_sd_client_cnt()) return -EPERM; @@ -2047,6 +2158,12 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp) return rc; } + ctrl_rev = MIPI_INP(ctrl->ctrl_base); + + /* For DSI versions less than 1.3.0, CMD DMA TPG is not supported */ + if (ctrl_rev < MDSS_DSI_HW_REV_103) + req->flags &= ~CMD_REQ_DMA_TPG; + pr_debug("%s: ctrl=%d from_mdp=%d pid=%d\n", __func__, ctrl->ndx, from_mdp, current->pid); @@ -2071,27 +2188,25 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp) MDSS_XLOG(ctrl->ndx, req->flags, req->cmds_cnt, from_mdp, current->pid); - /* - * mdss interrupt is generated in mdp core clock domain - * mdp clock need to be enabled to receive dsi interrupt - * also, axi bus bandwidth need since dsi controller will - * fetch dcs commands from axi bus - */ - if (ctrl->mdss_util->bus_bandwidth_ctrl) - ctrl->mdss_util->bus_bandwidth_ctrl(1); - - if (ctrl->mdss_util->bus_scale_set_quota) - ctrl->mdss_util->bus_scale_set_quota(MDSS_DSI_RT, SZ_1M, SZ_1M); pr_debug("%s: from_mdp=%d pid=%d\n", __func__, from_mdp, current->pid); mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 1); - if (ctrl->mdss_util->iommu_ctrl) { - rc = ctrl->mdss_util->iommu_ctrl(1); - if (IS_ERR_VALUE(rc)) { - pr_err("IOMMU attach failed\n"); - mutex_unlock(&ctrl->cmd_mutex); - return rc; + if (!(req->flags & CMD_REQ_DMA_TPG)) { + if (ctrl->mdss_util->bus_bandwidth_ctrl) + ctrl->mdss_util->bus_bandwidth_ctrl(1); + + if (ctrl->mdss_util->bus_scale_set_quota) + ctrl->mdss_util->bus_scale_set_quota(MDSS_DSI_RT, + SZ_1M, SZ_1M); + + if (ctrl->mdss_util->iommu_ctrl) { + rc = ctrl->mdss_util->iommu_ctrl(1); + if (IS_ERR_VALUE(rc)) { + pr_err("IOMMU attach failed\n"); + mutex_unlock(&ctrl->cmd_mutex); + return rc; + } } } @@ -2106,14 +2221,17 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp) if (req->flags & CMD_REQ_HS_MODE) mdss_dsi_set_tx_power_mode(1, &ctrl->panel_data); - if (ctrl->mdss_util->iommu_ctrl) - ctrl->mdss_util->iommu_ctrl(0); + if (!(req->flags & CMD_REQ_DMA_TPG)) { + if (ctrl->mdss_util->iommu_ctrl) + ctrl->mdss_util->iommu_ctrl(0); + + if (ctrl->mdss_util->bus_scale_set_quota) + ctrl->mdss_util->bus_scale_set_quota(MDSS_DSI_RT, 0, 0); + if (ctrl->mdss_util->bus_bandwidth_ctrl) + ctrl->mdss_util->bus_bandwidth_ctrl(0); + } mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 0); - if (ctrl->mdss_util->bus_scale_set_quota) - ctrl->mdss_util->bus_scale_set_quota(MDSS_DSI_RT, 0, 0); - if (ctrl->mdss_util->bus_bandwidth_ctrl) - ctrl->mdss_util->bus_bandwidth_ctrl(0); need_lock: MDSS_XLOG(ctrl->ndx, from_mdp, ctrl->mdp_busy, current->pid, From a308f66db5118b593951da3f72caa8af0c5775a7 Mon Sep 17 00:00:00 2001 From: Naveen Ramaraj Date: Wed, 10 Aug 2016 16:45:23 +0530 Subject: [PATCH 172/320] msm: mdss: Use clock safe wrapper for reading DSI hw version Attempting to read without proper clock votes will result in a unclocked access leading to a watchdog. Enable only the DSI BUS clocks instead of all the DSI clocks while reading the DSI revision register. Change-Id: Ia83fda764d145e96d2df813379c57cf6529b1c0c Signed-off-by: Naveen Ramaraj Signed-off-by: Chandan Uddaraju --- drivers/video/msm/mdss/mdss_dsi_host.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c index e894d08a9a69b..ace2895d48f94 100644 --- a/drivers/video/msm/mdss/mdss_dsi_host.c +++ b/drivers/video/msm/mdss/mdss_dsi_host.c @@ -264,9 +264,12 @@ void mdss_dsi_cmd_test_pattern(struct mdss_dsi_ctrl_pdata *ctrl) void mdss_dsi_get_hw_revision(struct mdss_dsi_ctrl_pdata *ctrl) { - mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 1); + if (ctrl->hw_rev) + return; + + mdss_dsi_clk_ctrl(ctrl, DSI_BUS_CLKS, 1); ctrl->hw_rev = MIPI_INP(ctrl->ctrl_base); - mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 0); + mdss_dsi_clk_ctrl(ctrl, DSI_BUS_CLKS, 0); pr_debug("%s: ndx=%d hw_rev=%x\n", __func__, ctrl->ndx, ctrl->hw_rev); @@ -1217,7 +1220,7 @@ static int mdss_dsi_cmd_dma_tpg_tx(struct mdss_dsi_ctrl_pdata *ctrl, struct dsi_buf *tp) { int len, i, ret = 0, data = 0; - u32 *bp, ctrl_rev; + u32 *bp; struct mdss_dsi_ctrl_pdata *mctrl = NULL; if (tp->len > DMA_TPG_FIFO_LEN) { @@ -1225,9 +1228,9 @@ static int mdss_dsi_cmd_dma_tpg_tx(struct mdss_dsi_ctrl_pdata *ctrl, return -EINVAL; } - ctrl_rev = MIPI_INP(ctrl->ctrl_base); + mdss_dsi_get_hw_revision(ctrl); - if (ctrl_rev < MDSS_DSI_HW_REV_103) { + if (ctrl->hw_rev < MDSS_DSI_HW_REV_103) { pr_err("CMD DMA TPG not supported for this DSI version\n"); return -EINVAL; } @@ -2130,7 +2133,6 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp) struct mdss_rect *roi = NULL; int ret = -EINVAL; int rc = 0; - u32 ctrl_rev; if (mdss_get_sd_client_cnt()) return -EPERM; @@ -2158,10 +2160,9 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp) return rc; } - ctrl_rev = MIPI_INP(ctrl->ctrl_base); - + mdss_dsi_get_hw_revision(ctrl); /* For DSI versions less than 1.3.0, CMD DMA TPG is not supported */ - if (ctrl_rev < MDSS_DSI_HW_REV_103) + if (ctrl->hw_rev < MDSS_DSI_HW_REV_103) req->flags &= ~CMD_REQ_DMA_TPG; pr_debug("%s: ctrl=%d from_mdp=%d pid=%d\n", __func__, From 5f452268e432474fa652ecb24513b5be5be346e0 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 16 Dec 2015 13:32:38 -0500 Subject: [PATCH 173/320] USB: fix invalid memory access in hub_activate() Commit 8520f38099cc ("USB: change hub initialization sleeps to delayed_work") changed the hub_activate() routine to make part of it run in a workqueue. However, the commit failed to take a reference to the usb_hub structure or to lock the hub interface while doing so. As a result, if a hub is plugged in and quickly unplugged before the work routine can run, the routine will try to access memory that has been deallocated. Or, if the hub is unplugged while the routine is running, the memory may be deallocated while it is in active use. This patch fixes the problem by taking a reference to the usb_hub at the start of hub_activate() and releasing it at the end (when the work is finished), and by locking the hub interface while the work routine is running. It also adds a check at the start of the routine to see if the hub has already been disconnected, in which nothing should be done. Change-Id: I1e5a67d22a5b61898e5a2aab8ea87b0c08e1130c Signed-off-by: Alan Stern Reported-by: Alexandru Cornea Tested-by: Alexandru Cornea Fixes: 8520f38099cc ("USB: change hub initialization sleeps to delayed_work") CC: Signed-off-by: Greg Kroah-Hartman Git-commit: e50293ef9775c5f1cf3fcc093037dd6a8c5684ea Git-repo: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git Signed-off-by: Ravi Kumar Siddojigari --- drivers/usb/core/hub.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 9ef2d2c15ecc9..a9fafabf4db4b 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -113,6 +113,7 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem); #define HUB_DEBOUNCE_STEP 25 #define HUB_DEBOUNCE_STABLE 100 +static void hub_release(struct kref *kref); static int usb_reset_and_verify_device(struct usb_device *udev); static inline char *portspeed(struct usb_hub *hub, int portstatus) @@ -1001,10 +1002,20 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) unsigned delay; /* Continue a partial initialization */ - if (type == HUB_INIT2) - goto init2; - if (type == HUB_INIT3) + if (type == HUB_INIT2 || type == HUB_INIT3) { + device_lock(hub->intfdev); + + /* Was the hub disconnected while we were waiting? */ + if (hub->disconnected) { + device_unlock(hub->intfdev); + kref_put(&hub->kref, hub_release); + return; + } + if (type == HUB_INIT2) + goto init2; goto init3; + } + kref_get(&hub->kref); /* The superspeed hub except for root hub has to use Hub Depth * value as an offset into the route string to locate the bits @@ -1209,6 +1220,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func3); schedule_delayed_work(&hub->init_work, msecs_to_jiffies(delay)); + device_unlock(hub->intfdev); return; /* Continues at init3: below */ } else { msleep(delay); @@ -1229,6 +1241,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) /* Allow autosuspend if it was suppressed */ if (type <= HUB_INIT3) usb_autopm_put_interface_async(to_usb_interface(hub->intfdev)); + + if (type == HUB_INIT2 || type == HUB_INIT3) + device_unlock(hub->intfdev); + + kref_put(&hub->kref, hub_release); } /* Implement the continuations for the delays above */ From 282d67b3504be987ae1becda177c0c2b6d6e2f28 Mon Sep 17 00:00:00 2001 From: Dennis Cagle Date: Mon, 1 Aug 2016 11:48:04 -0700 Subject: [PATCH 174/320] adf: Zero out the mapping data The adf_device_post_nocopy function eventually calls the dma_buf_attach and dma_buf_map_attachment functions. If the dma_buf_attach function succeeds but the dma_buf_map_attachment function fails, both the adf_buffer_map function and the adf_device_post_nocopy function will call the dma_buf_detach function to tear down the same dma-buf attachment. b/28447556 Change-Id: I8eb40486496fe2a2ae5dfa1be4b76a4af0d6b827 Signed-off-by: Dennis Cagle --- drivers/video/adf/adf_client.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/video/adf/adf_client.c b/drivers/video/adf/adf_client.c index 8061d8e6b9fbd..75b2f0b18522e 100644 --- a/drivers/video/adf/adf_client.c +++ b/drivers/video/adf/adf_client.c @@ -305,8 +305,10 @@ static int adf_buffer_map(struct adf_device *dev, struct adf_buffer *buf, } done: - if (ret < 0) + if (ret < 0) { adf_buffer_mapping_cleanup(mapping, buf); + memset(mapping, 0, sizeof(*mapping)); + } return ret; } From 5eb64ee6b9b3d1275a9a455c02c4be40a1fd8c9a Mon Sep 17 00:00:00 2001 From: Ravi Kumar Siddojigari Date: Fri, 12 Aug 2016 14:03:00 +0530 Subject: [PATCH 175/320] Revert "arm64: Introduce execute-only page access permissions" This reverts commit f72129c2203e0e7f4381411a9060c6d46f71ce1b. While the aim is increased security for --x memory maps, it does not protect against kernel level reads. Until SECCOMP is implemented for arm64, revert this patch to avoid giving a false idea of execute-only mappings. Change-Id: Ifb2fb182450bc656189738842f344f63daa5e317 Signed-off-by: Catalin Marinas Git-commit:5a0fdfada3a2aa50d7b947a2e958bf00cbe0d830 Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Signed-off-by: Ravi Kumar Siddojigari --- arch/arm64/include/asm/pgtable.h | 9 +++------ arch/arm64/mm/fault.c | 5 +++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index dfb28ff502da6..6594eefc41377 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -90,7 +90,6 @@ extern pgprot_t pgprot_default; #define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) #define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) #define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) -#define __PAGE_EXECONLY __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN) #endif /* __ASSEMBLY__ */ @@ -98,7 +97,7 @@ extern pgprot_t pgprot_default; #define __P001 __PAGE_READONLY #define __P010 __PAGE_COPY #define __P011 __PAGE_COPY -#define __P100 __PAGE_EXECONLY +#define __P100 __PAGE_READONLY_EXEC #define __P101 __PAGE_READONLY_EXEC #define __P110 __PAGE_COPY_EXEC #define __P111 __PAGE_COPY_EXEC @@ -107,7 +106,7 @@ extern pgprot_t pgprot_default; #define __S001 __PAGE_READONLY #define __S010 __PAGE_SHARED #define __S011 __PAGE_SHARED -#define __S100 __PAGE_EXECONLY +#define __S100 __PAGE_READONLY_EXEC #define __S101 __PAGE_READONLY_EXEC #define __S110 __PAGE_SHARED_EXEC #define __S111 __PAGE_SHARED_EXEC @@ -144,8 +143,6 @@ extern struct page *empty_zero_page; #define pte_write(pte) (!!(pte_val(pte) & PTE_WRITE)) #define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) -#define pte_valid_ng(pte) \ - ((pte_val(pte) & (PTE_VALID | PTE_NG)) == (PTE_VALID | PTE_NG)) #define pte_valid_user(pte) \ ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER)) #define pte_valid_not_user(pte) \ @@ -224,7 +221,7 @@ extern void __sync_icache_dcache(pte_t pteval, unsigned long addr); static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) { - if (pte_valid_ng(pte)) { + if (pte_valid_user(pte)) { if (!pte_special(pte) && pte_exec(pte)) __sync_icache_dcache(pte, addr); if (pte_dirty(pte) && pte_write(pte)) diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 877b0ed14dad1..45fc1beb37720 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -177,7 +177,8 @@ static int __do_page_fault(struct mm_struct *mm, unsigned long addr, good_area: /* * Check that the permissions on the VMA allow for the fault which - * occurred. + * occurred. If we encountered a write or exec fault, we must have + * appropriate permissions, otherwise we allow any permission. */ if (!(vma->vm_flags & vm_flags)) { fault = VM_FAULT_BADACCESS; @@ -199,7 +200,7 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, struct task_struct *tsk; struct mm_struct *mm; int fault, sig, code; - unsigned long vm_flags = VM_READ | VM_WRITE; + unsigned long vm_flags = VM_READ | VM_WRITE | VM_EXEC; unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; tsk = current; From b43706bfc68bf0659cd4a6ec55aea90cf2bcb515 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 16 Dec 2015 13:32:38 -0500 Subject: [PATCH 176/320] USB: fix invalid memory access in hub_activate() Commit 8520f38099cc ("USB: change hub initialization sleeps to delayed_work") changed the hub_activate() routine to make part of it run in a workqueue. However, the commit failed to take a reference to the usb_hub structure or to lock the hub interface while doing so. As a result, if a hub is plugged in and quickly unplugged before the work routine can run, the routine will try to access memory that has been deallocated. Or, if the hub is unplugged while the routine is running, the memory may be deallocated while it is in active use. This patch fixes the problem by taking a reference to the usb_hub at the start of hub_activate() and releasing it at the end (when the work is finished), and by locking the hub interface while the work routine is running. It also adds a check at the start of the routine to see if the hub has already been disconnected, in which nothing should be done. Change-Id: I1e5a67d22a5b61898e5a2aab8ea87b0c08e1130c Signed-off-by: Alan Stern Reported-by: Alexandru Cornea Tested-by: Alexandru Cornea Fixes: 8520f38099cc ("USB: change hub initialization sleeps to delayed_work") CC: Signed-off-by: Greg Kroah-Hartman Git-commit: e50293ef9775c5f1cf3fcc093037dd6a8c5684ea Git-repo: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git Signed-off-by: Ravi Kumar Siddojigari --- drivers/usb/core/hub.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 9ef2d2c15ecc9..a9fafabf4db4b 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -113,6 +113,7 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem); #define HUB_DEBOUNCE_STEP 25 #define HUB_DEBOUNCE_STABLE 100 +static void hub_release(struct kref *kref); static int usb_reset_and_verify_device(struct usb_device *udev); static inline char *portspeed(struct usb_hub *hub, int portstatus) @@ -1001,10 +1002,20 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) unsigned delay; /* Continue a partial initialization */ - if (type == HUB_INIT2) - goto init2; - if (type == HUB_INIT3) + if (type == HUB_INIT2 || type == HUB_INIT3) { + device_lock(hub->intfdev); + + /* Was the hub disconnected while we were waiting? */ + if (hub->disconnected) { + device_unlock(hub->intfdev); + kref_put(&hub->kref, hub_release); + return; + } + if (type == HUB_INIT2) + goto init2; goto init3; + } + kref_get(&hub->kref); /* The superspeed hub except for root hub has to use Hub Depth * value as an offset into the route string to locate the bits @@ -1209,6 +1220,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func3); schedule_delayed_work(&hub->init_work, msecs_to_jiffies(delay)); + device_unlock(hub->intfdev); return; /* Continues at init3: below */ } else { msleep(delay); @@ -1229,6 +1241,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) /* Allow autosuspend if it was suppressed */ if (type <= HUB_INIT3) usb_autopm_put_interface_async(to_usb_interface(hub->intfdev)); + + if (type == HUB_INIT2 || type == HUB_INIT3) + device_unlock(hub->intfdev); + + kref_put(&hub->kref, hub_release); } /* Implement the continuations for the delays above */ From df2b32ef11c64fcbf94a24c643fa8651e4254c64 Mon Sep 17 00:00:00 2001 From: Ravi Kumar Siddojigari Date: Fri, 12 Aug 2016 14:03:00 +0530 Subject: [PATCH 177/320] Revert "arm64: Introduce execute-only page access permissions" This reverts commit f72129c2203e0e7f4381411a9060c6d46f71ce1b. While the aim is increased security for --x memory maps, it does not protect against kernel level reads. Until SECCOMP is implemented for arm64, revert this patch to avoid giving a false idea of execute-only mappings. Change-Id: Ifb2fb182450bc656189738842f344f63daa5e317 Signed-off-by: Catalin Marinas Git-commit:5a0fdfada3a2aa50d7b947a2e958bf00cbe0d830 Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Signed-off-by: Ravi Kumar Siddojigari --- arch/arm64/include/asm/pgtable.h | 9 +++------ arch/arm64/mm/fault.c | 5 +++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index dfb28ff502da6..6594eefc41377 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -90,7 +90,6 @@ extern pgprot_t pgprot_default; #define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) #define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) #define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) -#define __PAGE_EXECONLY __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN) #endif /* __ASSEMBLY__ */ @@ -98,7 +97,7 @@ extern pgprot_t pgprot_default; #define __P001 __PAGE_READONLY #define __P010 __PAGE_COPY #define __P011 __PAGE_COPY -#define __P100 __PAGE_EXECONLY +#define __P100 __PAGE_READONLY_EXEC #define __P101 __PAGE_READONLY_EXEC #define __P110 __PAGE_COPY_EXEC #define __P111 __PAGE_COPY_EXEC @@ -107,7 +106,7 @@ extern pgprot_t pgprot_default; #define __S001 __PAGE_READONLY #define __S010 __PAGE_SHARED #define __S011 __PAGE_SHARED -#define __S100 __PAGE_EXECONLY +#define __S100 __PAGE_READONLY_EXEC #define __S101 __PAGE_READONLY_EXEC #define __S110 __PAGE_SHARED_EXEC #define __S111 __PAGE_SHARED_EXEC @@ -144,8 +143,6 @@ extern struct page *empty_zero_page; #define pte_write(pte) (!!(pte_val(pte) & PTE_WRITE)) #define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) -#define pte_valid_ng(pte) \ - ((pte_val(pte) & (PTE_VALID | PTE_NG)) == (PTE_VALID | PTE_NG)) #define pte_valid_user(pte) \ ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER)) #define pte_valid_not_user(pte) \ @@ -224,7 +221,7 @@ extern void __sync_icache_dcache(pte_t pteval, unsigned long addr); static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) { - if (pte_valid_ng(pte)) { + if (pte_valid_user(pte)) { if (!pte_special(pte) && pte_exec(pte)) __sync_icache_dcache(pte, addr); if (pte_dirty(pte) && pte_write(pte)) diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 877b0ed14dad1..45fc1beb37720 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -177,7 +177,8 @@ static int __do_page_fault(struct mm_struct *mm, unsigned long addr, good_area: /* * Check that the permissions on the VMA allow for the fault which - * occurred. + * occurred. If we encountered a write or exec fault, we must have + * appropriate permissions, otherwise we allow any permission. */ if (!(vma->vm_flags & vm_flags)) { fault = VM_FAULT_BADACCESS; @@ -199,7 +200,7 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, struct task_struct *tsk; struct mm_struct *mm; int fault, sig, code; - unsigned long vm_flags = VM_READ | VM_WRITE; + unsigned long vm_flags = VM_READ | VM_WRITE | VM_EXEC; unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; tsk = current; From 4e12d5b2b52653b7ce9b0c506387ffd263ac6004 Mon Sep 17 00:00:00 2001 From: Skylar Chang Date: Fri, 22 Jul 2016 15:03:16 -0700 Subject: [PATCH 178/320] msm: ipa: handle information leak on ADD_FLT_RULE_INDEX ioctl IPA might have Information leak and device crash due to kernel heap overread in IPA driver when processing WAN_IOC_ADD_FLT_RULE_INDEX ioctl. The fix is to add check on max number of filter rules send to modem. Change-Id: I454e04d05cfcb7af8fc4bd2b4a1bade55c4684d0 Signed-off-by: Skylar Chang --- drivers/platform/msm/ipa/ipa_qmi_service.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_qmi_service.c index a02eb5f6d1918..6259060f470e8 100644 --- a/drivers/platform/msm/ipa/ipa_qmi_service.c +++ b/drivers/platform/msm/ipa/ipa_qmi_service.c @@ -432,7 +432,7 @@ int qmi_filter_request_send(struct ipa_install_fltr_rule_req_msg_v01 *req) if (req->filter_spec_list_len == 0) { IPAWANDBG("IPACM pass zero rules to Q6\n"); } else { - IPAWANDBG("IPACM pass %d rules to Q6\n", + IPAWANDBG("IPACM pass %u rules to Q6\n", req->filter_spec_list_len); } @@ -469,6 +469,11 @@ int qmi_filter_notify_send(struct ipa_fltr_installed_notif_req_msg_v01 *req) IPAWANERR(" delete UL filter rule for pipe %d\n", req->source_pipe_index); return -EINVAL; + } else if (req->filter_index_list_len > QMI_IPA_MAX_FILTERS_V01) { + IPAWANERR(" UL filter rule for pipe %d exceed max (%u)\n", + req->source_pipe_index, + req->filter_index_list_len); + return -EINVAL; } else if (req->filter_index_list[0].filter_index == 0 && req->source_pipe_index != ipa_get_ep_mapping(IPA_CLIENT_APPS_LAN_WAN_PROD)) { From 8e29d611fa5ed53d49cf3cded83abaad3fb79f7e Mon Sep 17 00:00:00 2001 From: Sathish Ambley Date: Wed, 10 Jun 2015 00:39:41 -0700 Subject: [PATCH 179/320] msm: ADSPRPC: Do not access user memory directly The buffers being passed in the invocation are copied from user memory into the context using copy_from_user. Lookup the buffer pointers from the context where it was copied rather than directly accessing it from the user memory. Change-Id: Ief5a840f17f6287ebd48b4ae52facaccb271fab8 Signed-off-by: Sathish Ambley --- drivers/char/adsprpc_compat.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/char/adsprpc_compat.c b/drivers/char/adsprpc_compat.c index 31c2897546eb6..ee324dcf91f0e 100644 --- a/drivers/char/adsprpc_compat.c +++ b/drivers/char/adsprpc_compat.c @@ -98,8 +98,9 @@ static int compat_get_fastrpc_ioctl_invoke( if (err) return -EFAULT; - inv->inv.pra = (union remote_arg *)(inv + 1); - err = put_user(sc, &inv->inv.sc); + pra = (union remote_arg *)(inv + 1); + err = put_user(pra, &inv->inv.pra); + err |= put_user(sc, &inv->inv.sc); err |= get_user(u, &inv32->inv.handle); err |= put_user(u, &inv->inv.handle); err |= get_user(p, &inv32->inv.pra); @@ -107,12 +108,11 @@ static int compat_get_fastrpc_ioctl_invoke( return err; pra32 = compat_ptr(p); - pra = inv->inv.pra; + pra = (union remote_arg *)(inv + 1); num = REMOTE_SCALARS_INBUFS(sc) + REMOTE_SCALARS_OUTBUFS(sc); for (j = 0; j < num; j++) { err |= get_user(p, &pra32[j].buf.pv); - pra[j].buf.pv = NULL; - err |= put_user(p, (compat_uptr_t *)&pra[j].buf.pv); + err |= put_user(p, (uintptr_t *)&pra[j].buf.pv); err |= get_user(s, &pra32[j].buf.len); err |= put_user(s, &pra[j].buf.len); } @@ -121,7 +121,7 @@ static int compat_get_fastrpc_ioctl_invoke( err |= put_user(u, &pra[num + j].h); } - inv->fds = NULL; + err |= put_user(NULL, &inv->fds); if (cmd == COMPAT_FASTRPC_IOCTL_INVOKE_FD) { err |= get_user(p, &inv32->fds); err |= put_user(p, (compat_uptr_t *)&inv->fds); @@ -173,8 +173,7 @@ static int compat_get_fastrpc_ioctl_mmap( err |= get_user(u, &map32->flags); err |= put_user(u, &map->flags); err |= get_user(p, &map32->vaddrin); - map->vaddrin = NULL; - err |= put_user(p, (compat_uptr_t *)&map->vaddrin); + err |= put_user(p, (uintptr_t *)&map->vaddrin); err |= get_user(s, &map32->size); err |= put_user(s, &map->size); From 18231016dc414a6a7d4b1ffaaf461f74707d5b7c Mon Sep 17 00:00:00 2001 From: Skylar Chang Date: Fri, 22 Jul 2016 15:03:16 -0700 Subject: [PATCH 180/320] msm: ipa: handle information leak on ADD_FLT_RULE_INDEX ioctl IPA might have Information leak and device crash due to kernel heap overread in IPA driver when processing WAN_IOC_ADD_FLT_RULE_INDEX ioctl. The fix is to add check on max number of filter rules send to modem. Change-Id: I454e04d05cfcb7af8fc4bd2b4a1bade55c4684d0 Signed-off-by: Skylar Chang --- drivers/platform/msm/ipa/ipa_qmi_service.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_qmi_service.c index a02eb5f6d1918..6259060f470e8 100644 --- a/drivers/platform/msm/ipa/ipa_qmi_service.c +++ b/drivers/platform/msm/ipa/ipa_qmi_service.c @@ -432,7 +432,7 @@ int qmi_filter_request_send(struct ipa_install_fltr_rule_req_msg_v01 *req) if (req->filter_spec_list_len == 0) { IPAWANDBG("IPACM pass zero rules to Q6\n"); } else { - IPAWANDBG("IPACM pass %d rules to Q6\n", + IPAWANDBG("IPACM pass %u rules to Q6\n", req->filter_spec_list_len); } @@ -469,6 +469,11 @@ int qmi_filter_notify_send(struct ipa_fltr_installed_notif_req_msg_v01 *req) IPAWANERR(" delete UL filter rule for pipe %d\n", req->source_pipe_index); return -EINVAL; + } else if (req->filter_index_list_len > QMI_IPA_MAX_FILTERS_V01) { + IPAWANERR(" UL filter rule for pipe %d exceed max (%u)\n", + req->source_pipe_index, + req->filter_index_list_len); + return -EINVAL; } else if (req->filter_index_list[0].filter_index == 0 && req->source_pipe_index != ipa_get_ep_mapping(IPA_CLIENT_APPS_LAN_WAN_PROD)) { From 80878dafd58578cddbc545db60bf19eaa9838b43 Mon Sep 17 00:00:00 2001 From: Skylar Chang Date: Fri, 8 Jul 2016 16:20:33 -0700 Subject: [PATCH 181/320] msm: ipa: fix potential race condition ioctls There are numerous potential race condition ioctls in the IPA driver. The fix is to add check wherever it copies arguments from user-space memory and process. Change-Id: I5a440f89153518507acdf5dad42625503732e59a Signed-off-by: Skylar Chang --- drivers/platform/msm/ipa/ipa.c | 236 +++++++++++++++++++++++++++------ 1 file changed, 196 insertions(+), 40 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa.c b/drivers/platform/msm/ipa/ipa.c index 41a024746e1ee..ddb716caf2e0c 100644 --- a/drivers/platform/msm/ipa/ipa.c +++ b/drivers/platform/msm/ipa/ipa.c @@ -277,6 +277,7 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) struct ipa_ioc_v4_nat_del nat_del; struct ipa_ioc_rm_dependency rm_depend; size_t sz; + int pre_entry; IPADBG("cmd=%x nr=%d\n", cmd, _IOC_NR(cmd)); @@ -325,11 +326,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - + pre_entry = + ((struct ipa_ioc_nat_dma_cmd *)header)->entries; pyld_sz = sizeof(struct ipa_ioc_nat_dma_cmd) + - ((struct ipa_ioc_nat_dma_cmd *)header)->entries * - sizeof(struct ipa_ioc_nat_dma_one); + pre_entry * sizeof(struct ipa_ioc_nat_dma_one); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -340,7 +341,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_nat_dma_cmd *)param)->entries + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_nat_dma_cmd *)param)->entries, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_nat_dma_cmd((struct ipa_ioc_nat_dma_cmd *)param)) { retval = -EFAULT; break; @@ -365,10 +374,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_add_hdr *)header)->num_hdrs; pyld_sz = sizeof(struct ipa_ioc_add_hdr) + - ((struct ipa_ioc_add_hdr *)header)->num_hdrs * - sizeof(struct ipa_hdr_add); + pre_entry * sizeof(struct ipa_hdr_add); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -378,6 +388,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_hdr *)param)->num_hdrs + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_add_hdr *)param)->num_hdrs, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_add_hdr((struct ipa_ioc_add_hdr *)param)) { retval = -EFAULT; break; @@ -394,10 +413,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_del_hdr *)header)->num_hdls; pyld_sz = sizeof(struct ipa_ioc_del_hdr) + - ((struct ipa_ioc_del_hdr *)header)->num_hdls * - sizeof(struct ipa_hdr_del); + pre_entry * sizeof(struct ipa_hdr_del); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -407,6 +427,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_del_hdr *)param)->num_hdls + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_del_hdr *)param)->num_hdls, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_del_hdr((struct ipa_ioc_del_hdr *)param)) { retval = -EFAULT; break; @@ -423,10 +452,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_add_rt_rule *)header)->num_rules; pyld_sz = sizeof(struct ipa_ioc_add_rt_rule) + - ((struct ipa_ioc_add_rt_rule *)header)->num_rules * - sizeof(struct ipa_rt_rule_add); + pre_entry * sizeof(struct ipa_rt_rule_add); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -436,6 +466,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_rt_rule *)param)->num_rules + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_add_rt_rule *)param)-> + num_rules, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_add_rt_rule((struct ipa_ioc_add_rt_rule *)param)) { retval = -EFAULT; break; @@ -452,10 +492,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_mdfy_rt_rule *)header)->num_rules; pyld_sz = sizeof(struct ipa_ioc_mdfy_rt_rule) + - ((struct ipa_ioc_mdfy_rt_rule *)header)->num_rules * - sizeof(struct ipa_rt_rule_mdfy); + pre_entry * sizeof(struct ipa_rt_rule_mdfy); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -465,6 +506,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_mdfy_rt_rule *)param)->num_rules + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_mdfy_rt_rule *)param)-> + num_rules, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_mdfy_rt_rule((struct ipa_ioc_mdfy_rt_rule *)param)) { retval = -EFAULT; break; @@ -481,10 +532,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_del_rt_rule *)header)->num_hdls; pyld_sz = sizeof(struct ipa_ioc_del_rt_rule) + - ((struct ipa_ioc_del_rt_rule *)header)->num_hdls * - sizeof(struct ipa_rt_rule_del); + pre_entry * sizeof(struct ipa_rt_rule_del); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -494,6 +546,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_del_rt_rule *)param)->num_hdls + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_del_rt_rule *)param)->num_hdls, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_del_rt_rule((struct ipa_ioc_del_rt_rule *)param)) { retval = -EFAULT; break; @@ -510,10 +571,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_add_flt_rule *)header)->num_rules; pyld_sz = sizeof(struct ipa_ioc_add_flt_rule) + - ((struct ipa_ioc_add_flt_rule *)header)->num_rules * - sizeof(struct ipa_flt_rule_add); + pre_entry * sizeof(struct ipa_flt_rule_add); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -523,6 +585,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_flt_rule *)param)->num_rules + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_add_flt_rule *)param)-> + num_rules, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_add_flt_rule((struct ipa_ioc_add_flt_rule *)param)) { retval = -EFAULT; break; @@ -539,10 +611,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_del_flt_rule *)header)->num_hdls; pyld_sz = sizeof(struct ipa_ioc_del_flt_rule) + - ((struct ipa_ioc_del_flt_rule *)header)->num_hdls * - sizeof(struct ipa_flt_rule_del); + pre_entry * sizeof(struct ipa_flt_rule_del); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -552,6 +625,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_del_flt_rule *)param)->num_hdls + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_del_flt_rule *)param)-> + num_hdls, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_del_flt_rule((struct ipa_ioc_del_flt_rule *)param)) { retval = -EFAULT; break; @@ -568,10 +651,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_mdfy_flt_rule *)header)->num_rules; pyld_sz = sizeof(struct ipa_ioc_mdfy_flt_rule) + - ((struct ipa_ioc_mdfy_flt_rule *)header)->num_rules * - sizeof(struct ipa_flt_rule_mdfy); + pre_entry * sizeof(struct ipa_flt_rule_mdfy); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -581,6 +665,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_mdfy_flt_rule *)param)->num_rules + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_mdfy_flt_rule *)param)-> + num_rules, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_mdfy_flt_rule((struct ipa_ioc_mdfy_flt_rule *)param)) { retval = -EFAULT; break; @@ -688,15 +782,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - - if (((struct ipa_ioc_query_intf_tx_props *)header)->num_tx_props - > IPA_NUM_PROPS_MAX) { + if (((struct ipa_ioc_query_intf_tx_props *) + header)->num_tx_props > IPA_NUM_PROPS_MAX) { retval = -EFAULT; break; } - - pyld_sz = sz + ((struct ipa_ioc_query_intf_tx_props *) - header)->num_tx_props * + pre_entry = + ((struct ipa_ioc_query_intf_tx_props *) + header)->num_tx_props; + pyld_sz = sz + pre_entry * sizeof(struct ipa_ioc_tx_intf_prop); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { @@ -707,6 +801,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_query_intf_tx_props *) + param)->num_tx_props + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_query_intf_tx_props *) + param)->num_tx_props, pre_entry); + retval = -EFAULT; + break; + } if (ipa_query_intf_tx_props( (struct ipa_ioc_query_intf_tx_props *)param)) { retval = -1; @@ -723,15 +827,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - - if (((struct ipa_ioc_query_intf_rx_props *)header)->num_rx_props - > IPA_NUM_PROPS_MAX) { + if (((struct ipa_ioc_query_intf_rx_props *) + header)->num_rx_props > IPA_NUM_PROPS_MAX) { retval = -EFAULT; break; } - - pyld_sz = sz + ((struct ipa_ioc_query_intf_rx_props *) - header)->num_rx_props * + pre_entry = + ((struct ipa_ioc_query_intf_rx_props *) + header)->num_rx_props; + pyld_sz = sz + pre_entry * sizeof(struct ipa_ioc_rx_intf_prop); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { @@ -742,6 +846,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_query_intf_rx_props *) + param)->num_rx_props != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_query_intf_rx_props *) + param)->num_rx_props, pre_entry); + retval = -EFAULT; + break; + } if (ipa_query_intf_rx_props( (struct ipa_ioc_query_intf_rx_props *)param)) { retval = -1; @@ -764,9 +877,10 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - - pyld_sz = sz + ((struct ipa_ioc_query_intf_ext_props *) - header)->num_ext_props * + pre_entry = + ((struct ipa_ioc_query_intf_ext_props *) + header)->num_ext_props; + pyld_sz = sz + pre_entry * sizeof(struct ipa_ioc_ext_intf_prop); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { @@ -777,6 +891,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_query_intf_ext_props *) + param)->num_ext_props != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_query_intf_ext_props *) + param)->num_ext_props, pre_entry); + retval = -EFAULT; + break; + } if (ipa_query_intf_ext_props( (struct ipa_ioc_query_intf_ext_props *)param)) { retval = -1; @@ -793,8 +916,10 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_msg_meta *)header)->msg_len; pyld_sz = sizeof(struct ipa_msg_meta) + - ((struct ipa_msg_meta *)header)->msg_len; + pre_entry; param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -804,6 +929,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_msg_meta *)param)->msg_len + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_msg_meta *)param)->msg_len, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_pull_msg((struct ipa_msg_meta *)param, (char *)param + sizeof(struct ipa_msg_meta), ((struct ipa_msg_meta *)param)->msg_len) != @@ -919,10 +1053,12 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_add_hdr_proc_ctx *) + header)->num_proc_ctxs; pyld_sz = sizeof(struct ipa_ioc_add_hdr_proc_ctx) + - ((struct ipa_ioc_add_hdr_proc_ctx *)header)->num_proc_ctxs * - sizeof(struct ipa_hdr_proc_ctx_add); + pre_entry * sizeof(struct ipa_hdr_proc_ctx_add); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -932,6 +1068,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_hdr_proc_ctx *) + param)->num_proc_ctxs != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_add_hdr_proc_ctx *) + param)->num_proc_ctxs, pre_entry); + retval = -EFAULT; + break; + } if (ipa_add_hdr_proc_ctx( (struct ipa_ioc_add_hdr_proc_ctx *)param)) { retval = -EFAULT; @@ -948,10 +1093,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_del_hdr_proc_ctx *)header)->num_hdls; pyld_sz = sizeof(struct ipa_ioc_del_hdr_proc_ctx) + - ((struct ipa_ioc_del_hdr_proc_ctx *)header)->num_hdls * - sizeof(struct ipa_hdr_proc_ctx_del); + pre_entry * sizeof(struct ipa_hdr_proc_ctx_del); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -961,6 +1107,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_del_hdr_proc_ctx *) + param)->num_hdls != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_del_hdr_proc_ctx *)param)-> + num_hdls, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_del_hdr_proc_ctx( (struct ipa_ioc_del_hdr_proc_ctx *)param)) { retval = -EFAULT; From 59239adbfbe42d0616e6b50d8288311e5863a269 Mon Sep 17 00:00:00 2001 From: Archana Sathyakumar Date: Wed, 29 Jun 2016 11:47:47 -0600 Subject: [PATCH 182/320] msm-core: debug: Fix the number of arguments for sysfs nodes Ptable and enable node parses the input arguments incorrectly. Parse the input message into exact number of arguments that are required for the respective nodes. CRs-fixed: 1032875 Change-Id: I881f18217b703a497efa4799288dee39a28ea8ab Signed-off-by: Archana Sathyakumar --- drivers/power/qcom/debug_core.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/power/qcom/debug_core.c b/drivers/power/qcom/debug_core.c index 51feae8849ebb..e1375ff95ee53 100644 --- a/drivers/power/qcom/debug_core.c +++ b/drivers/power/qcom/debug_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -21,6 +21,8 @@ #include #define MAX_PSTATES 20 +#define NUM_OF_PENTRY 3 /* number of variables for ptable node */ +#define NUM_OF_EENTRY 2 /* number of variables for enable node */ enum arg_offset { CPU_OFFSET, @@ -130,13 +132,15 @@ static void add_to_ptable(uint64_t *arg) node->ptr->len = node->len; } -static int split_ptable_args(char *line, uint64_t *arg) +static int split_ptable_args(char *line, uint64_t *arg, uint32_t n) { char *args; int i; int ret = 0; - for (i = 0; line; i++) { + for (i = 0; i < n; i++) { + if (!line) + break; args = strsep(&line, " "); ret = kstrtoull(args, 10, &arg[i]); } @@ -162,7 +166,7 @@ static ssize_t msm_core_ptable_write(struct file *file, goto done; } kbuf[len] = '\0'; - ret = split_ptable_args(kbuf, arg); + ret = split_ptable_args(kbuf, arg, NUM_OF_PENTRY); if (!ret) { add_to_ptable(arg); ret = len; @@ -226,7 +230,7 @@ static ssize_t msm_core_enable_write(struct file *file, goto done; } kbuf[len] = '\0'; - ret = split_ptable_args(kbuf, arg); + ret = split_ptable_args(kbuf, arg, NUM_OF_EENTRY); if (ret) goto done; cpu = arg[CPU_OFFSET]; From 45796d2380c39c15f0289c3f1317d9b0b42de462 Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Fri, 29 Jul 2016 15:32:31 -0700 Subject: [PATCH 183/320] msm: crypto: Fix integer over flow check in qcedev driver Integer overflow check always fails when ULONG_MAX is used, as ULONG_MAX is 2^64-1, while req->data[i].len and total are uint32_t. Make change to use U32_MAX instead of ULONG_MAX. CRs-fixed: 1046507 Change-Id: Iccf9c32400ecc7ffc0afae16f58c38e5d78a5b64 Signed-off-by: Zhen Kong --- drivers/crypto/msm/qcedev.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c index 3975418c48949..2313d927c53ad 100644 --- a/drivers/crypto/msm/qcedev.c +++ b/drivers/crypto/msm/qcedev.c @@ -1,6 +1,6 @@ /* Qualcomm CE device driver. * - * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -43,6 +43,10 @@ #define CACHE_LINE_SIZE 32 #define CE_SHA_BLOCK_SIZE SHA256_BLOCK_SIZE +#ifndef U32_MAX +#define U32_MAX ((u32)(~0U)) +#endif + /* are FIPS integrity tests done ?? */ bool is_fips_qcedev_integritytest_done; @@ -1559,7 +1563,7 @@ static int qcedev_check_cipher_params(struct qcedev_cipher_op_req *req, } /* Check for sum of all dst length is equal to data_len */ for (i = 0; i < req->entries; i++) { - if (req->vbuf.dst[i].len >= ULONG_MAX - total) { + if (req->vbuf.dst[i].len >= U32_MAX - total) { pr_err("%s: Integer overflow on total req dst vbuf length\n", __func__); goto error; @@ -1573,7 +1577,7 @@ static int qcedev_check_cipher_params(struct qcedev_cipher_op_req *req, } /* Check for sum of all src length is equal to data_len */ for (i = 0, total = 0; i < req->entries; i++) { - if (req->vbuf.src[i].len > ULONG_MAX - total) { + if (req->vbuf.src[i].len > U32_MAX - total) { pr_err("%s: Integer overflow on total req src vbuf length\n", __func__); goto error; @@ -1636,7 +1640,7 @@ static int qcedev_check_sha_params(struct qcedev_sha_op_req *req, /* Check for sum of all src length is equal to data_len */ for (i = 0, total = 0; i < req->entries; i++) { - if (req->data[i].len > ULONG_MAX - total) { + if (req->data[i].len > U32_MAX - total) { pr_err("%s: Integer overflow on total req buf length\n", __func__); goto sha_error; From 4e8ddd406d497968ac03adbe35fb695d1c78390b Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Fri, 29 Jul 2016 15:32:31 -0700 Subject: [PATCH 184/320] msm: crypto: Fix integer over flow check in qcedev driver Integer overflow check always fails when ULONG_MAX is used, as ULONG_MAX is 2^64-1, while req->data[i].len and total are uint32_t. Make change to use U32_MAX instead of ULONG_MAX CRs-fixed: 1046507 Change-Id: Iccf9c32400ecc7ffc0afae16f58c38e5d78a5b64 Signed-off-by: Zhen Kong --- drivers/crypto/msm/qcedev.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c index 3975418c48949..2313d927c53ad 100644 --- a/drivers/crypto/msm/qcedev.c +++ b/drivers/crypto/msm/qcedev.c @@ -1,6 +1,6 @@ /* Qualcomm CE device driver. * - * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -43,6 +43,10 @@ #define CACHE_LINE_SIZE 32 #define CE_SHA_BLOCK_SIZE SHA256_BLOCK_SIZE +#ifndef U32_MAX +#define U32_MAX ((u32)(~0U)) +#endif + /* are FIPS integrity tests done ?? */ bool is_fips_qcedev_integritytest_done; @@ -1559,7 +1563,7 @@ static int qcedev_check_cipher_params(struct qcedev_cipher_op_req *req, } /* Check for sum of all dst length is equal to data_len */ for (i = 0; i < req->entries; i++) { - if (req->vbuf.dst[i].len >= ULONG_MAX - total) { + if (req->vbuf.dst[i].len >= U32_MAX - total) { pr_err("%s: Integer overflow on total req dst vbuf length\n", __func__); goto error; @@ -1573,7 +1577,7 @@ static int qcedev_check_cipher_params(struct qcedev_cipher_op_req *req, } /* Check for sum of all src length is equal to data_len */ for (i = 0, total = 0; i < req->entries; i++) { - if (req->vbuf.src[i].len > ULONG_MAX - total) { + if (req->vbuf.src[i].len > U32_MAX - total) { pr_err("%s: Integer overflow on total req src vbuf length\n", __func__); goto error; @@ -1636,7 +1640,7 @@ static int qcedev_check_sha_params(struct qcedev_sha_op_req *req, /* Check for sum of all src length is equal to data_len */ for (i = 0, total = 0; i < req->entries; i++) { - if (req->data[i].len > ULONG_MAX - total) { + if (req->data[i].len > U32_MAX - total) { pr_err("%s: Integer overflow on total req buf length\n", __func__); goto sha_error; From 35535869ef6513dab209fa5d025de6accdbf3fbc Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Tue, 22 Dec 2015 12:24:37 -0800 Subject: [PATCH 185/320] diag: Change to update the range correctly on a range mismatch Setting message masks with tools outside of the initial range causes a reallocation of the structure with the wrong size. This change updates the sizes to the correct values. CRs-Fixed: 965686 Change-Id: I8bb0d0b77cd4d2417b10345b6e4b09ff29ba5f8c Signed-off-by: Christopher Lew Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_masks.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c index c007cb568fd48..a4589d19b3354 100644 --- a/drivers/char/diag/diag_masks.c +++ b/drivers/char/diag/diag_masks.c @@ -546,7 +546,8 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, mask = (struct diag_msg_mask_t *)msg_mask.ptr; for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { if ((req->ssid_first < mask->ssid_first) || - (req->ssid_first > mask->ssid_last_tools)) { + (req->ssid_first > (mask->ssid_first + + MAX_SSID_PER_RANGE))) { continue; } found = 1; @@ -564,8 +565,10 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, pr_debug("diag: Msg SSID range mismatch\n"); if (mask_size != MAX_SSID_PER_RANGE) mask->ssid_last_tools = req->ssid_last; + mask->range_tools = + mask->ssid_last_tools - mask->ssid_first + 1; temp = krealloc(mask->ptr, - mask_size * sizeof(uint32_t), + mask->range_tools * sizeof(uint32_t), GFP_KERNEL); if (!temp) { pr_err_ratelimited("diag: In %s, unable to allocate memory for msg mask ptr, mask_size: %d\n", @@ -573,7 +576,6 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, return -ENOMEM; } mask->ptr = temp; - mask->range_tools = mask_size; } offset = req->ssid_first - mask->ssid_first; From c223b83c1123e82dbf6481e332d0fc596707d9a6 Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Mon, 13 Jun 2016 18:27:47 +0530 Subject: [PATCH 186/320] diag: Fix possible mask pointer corruption This patch updates the stale pointer corrupted at specific ssid ranges. CRs-Fixed: 980487 Change-Id: I2b8afcef25dceb76118b803c67f4c5656feae82b Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_masks.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c index a4589d19b3354..ff75a950514b2 100644 --- a/drivers/char/diag/diag_masks.c +++ b/drivers/char/diag/diag_masks.c @@ -532,6 +532,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, struct diag_msg_mask_t *mask = NULL; struct diag_msg_build_mask_t *req = NULL; struct diag_msg_build_mask_t rsp; + struct diag_msg_mask_t *mask_next = NULL; uint32_t *temp = NULL; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { @@ -545,11 +546,18 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, mutex_lock(&msg_mask.lock); mask = (struct diag_msg_mask_t *)msg_mask.ptr; for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { + if (i < (driver->msg_mask_tbl_count - 1)) { + mask_next = mask; + mask_next++; + } else + mask_next = NULL; + if ((req->ssid_first < mask->ssid_first) || - (req->ssid_first > (mask->ssid_first + - MAX_SSID_PER_RANGE))) { + (req->ssid_first > mask->ssid_first + MAX_SSID_PER_RANGE) || + (mask_next && (req->ssid_first >= mask_next->ssid_first))) { continue; } + mask_next = NULL; found = 1; mask_size = req->ssid_last - req->ssid_first + 1; if (mask_size > MAX_SSID_PER_RANGE) { From 2d0999d733a99cd0038cce6ec8f981255f4ad3a6 Mon Sep 17 00:00:00 2001 From: Charan Teja Reddy Date: Fri, 17 Jun 2016 17:24:41 +0530 Subject: [PATCH 187/320] coresight: fix use-after-free in stm on secure boot devices When the STM driver failed to register, the stmdrvdata variable becomes dangling pointer which may cause APSS to crash. Change-Id: I0e709ac180d8c946f25e026b23edadb08c82a1f3 Signed-off-by: Charan Teja Reddy Signed-off-by: Swetha Chikkaboraiah --- drivers/coresight/coresight-stm.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/coresight/coresight-stm.c b/drivers/coresight/coresight-stm.c index 2cc1f9cd2394f..8833ee0b7c5d5 100644 --- a/drivers/coresight/coresight-stm.c +++ b/drivers/coresight/coresight-stm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -868,8 +868,6 @@ static int stm_probe(struct platform_device *pdev) drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; - /* Store the driver data pointer for use in exported functions */ - stmdrvdata = drvdata; drvdata->dev = &pdev->dev; platform_set_drvdata(pdev, drvdata); @@ -948,6 +946,9 @@ static int stm_probe(struct platform_device *pdev) if (boot_enable) coresight_enable(drvdata->csdev); + /* Store the driver data pointer for use in exported functions */ + stmdrvdata = drvdata; + return 0; err: coresight_unregister(drvdata->csdev); From eca0a38997b9d6819c18e83dcca194f050486742 Mon Sep 17 00:00:00 2001 From: Krishna Srinivas Date: Fri, 17 Jun 2016 10:33:45 -0700 Subject: [PATCH 188/320] msm: mdss: Fix memleak in framebuffer register and remove In FB registration, free allocated memory if an error condition is hit. Also free allocated memory in FB remove. Change-Id: I533e2d6a760ebd52047c521c1a1e85bfc754fce1 Signed-off-by: Krishna Srinivas --- drivers/video/msm/mdss/mdss_fb.c | 2 ++ drivers/video/msm/mdss/mdss_panel.c | 11 ++++++++--- drivers/video/msm/mdss/mdss_panel.h | 1 + 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c index 96fdc93f95015..c06abd3d95167 100644 --- a/drivers/video/msm/mdss/mdss_fb.c +++ b/drivers/video/msm/mdss/mdss_fb.c @@ -922,6 +922,8 @@ static int mdss_fb_remove(struct platform_device *pdev) if (mfd->key != MFD_KEY) return -EINVAL; + mdss_panel_debugfs_cleanup(mfd->panel_info); + if (mdss_fb_suspend_sub(mfd)) pr_err("msm_fb_remove: can't stop the device %d\n", mfd->index); diff --git a/drivers/video/msm/mdss/mdss_panel.c b/drivers/video/msm/mdss/mdss_panel.c index 4095eee43046a..a240429d35c79 100644 --- a/drivers/video/msm/mdss/mdss_panel.c +++ b/drivers/video/msm/mdss/mdss_panel.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -33,6 +33,7 @@ int mdss_panel_debugfs_setup(struct mdss_panel_info *panel_info, struct dentry } debugfs_info->root = debugfs_create_dir(dsi_str, parent); + debugfs_info->parent = parent; if (IS_ERR_OR_NULL(debugfs_info->root)) { pr_err("Debugfs create dir failed with error: %ld\n", PTR_ERR(debugfs_info->root)); @@ -100,6 +101,7 @@ int mdss_panel_debugfs_init(struct mdss_panel_info *panel_info) dsi_str); if (rc) { pr_err("error in initilizing panel debugfs\n"); + mdss_panel_debugfs_cleanup(&pdata->panel_info); return rc; } pdata = pdata->next; @@ -113,13 +115,16 @@ void mdss_panel_debugfs_cleanup(struct mdss_panel_info *panel_info) { struct mdss_panel_data *pdata; struct mdss_panel_debugfs_info *debugfs_info; + struct dentry *parent = NULL; pdata = container_of(panel_info, struct mdss_panel_data, panel_info); do { debugfs_info = pdata->panel_info.debugfs_info; - if (debugfs_info && debugfs_info->root) - debugfs_remove_recursive(debugfs_info->root); + if (debugfs_info && !parent) + parent = debugfs_info->parent; + kfree(debugfs_info); pdata = pdata->next; } while (pdata); + debugfs_remove_recursive(parent); pr_debug("Cleaned up mdss_panel_debugfs_info\n"); } diff --git a/drivers/video/msm/mdss/mdss_panel.h b/drivers/video/msm/mdss/mdss_panel.h index 1e3673add268c..61452f66dc2f8 100644 --- a/drivers/video/msm/mdss/mdss_panel.h +++ b/drivers/video/msm/mdss/mdss_panel.h @@ -466,6 +466,7 @@ struct mdss_panel_debugfs_info { u32 xres; u32 yres; struct lcd_panel_info lcdc; + struct dentry *parent; u32 override_flag; char frame_rate; struct mdss_panel_debugfs_info *next; From beec5e405b633d8a65157d6e76f01db33ad707dd Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Tue, 19 Jul 2016 13:39:29 +0530 Subject: [PATCH 189/320] USB: usbfs: fix potential infoleak in devio The stack object "ci" has a total size of 8 bytes. Its last 3 bytes are padding bytes which are not initialized and leaked to userland via "copy_to_user". Change-Id: Iedd743ab04eb30b6133fc45bb549fcbae60c12fa Signed-off-by: Kangjie Lu Signed-off-by: Greg Kroah-Hartman Git-commit: 681fef8380eb818c0b845fca5d2ab1dcbab114ee Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Signed-off-by: Ravi Kumar Siddojigari --- drivers/usb/core/devio.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index ce773cca2bf52..87734840292b6 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1105,10 +1105,11 @@ static int proc_getdriver(struct dev_state *ps, void __user *arg) static int proc_connectinfo(struct dev_state *ps, void __user *arg) { - struct usbdevfs_connectinfo ci = { - .devnum = ps->dev->devnum, - .slow = ps->dev->speed == USB_SPEED_LOW - }; + struct usbdevfs_connectinfo ci; + + memset(&ci, 0, sizeof(ci)); + ci.devnum = ps->dev->devnum; + ci.slow = ps->dev->speed == USB_SPEED_LOW; if (copy_to_user(arg, &ci, sizeof(ci))) return -EFAULT; From df37fb38db4d6106ed1f6df468f36329be237f58 Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Tue, 19 Jul 2016 13:39:29 +0530 Subject: [PATCH 190/320] USB: usbfs: fix potential infoleak in devio The stack object "ci" has a total size of 8 bytes. Its last 3 bytes are padding bytes which are not initialized and leaked to userland via "copy_to_user". Change-Id: Iedd743ab04eb30b6133fc45bb549fcbae60c12fa Signed-off-by: Kangjie Lu Signed-off-by: Greg Kroah-Hartman Git-commit: 681fef8380eb818c0b845fca5d2ab1dcbab114ee Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Signed-off-by: Ravi Kumar Siddojigari --- drivers/usb/core/devio.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index ce773cca2bf52..87734840292b6 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1105,10 +1105,11 @@ static int proc_getdriver(struct dev_state *ps, void __user *arg) static int proc_connectinfo(struct dev_state *ps, void __user *arg) { - struct usbdevfs_connectinfo ci = { - .devnum = ps->dev->devnum, - .slow = ps->dev->speed == USB_SPEED_LOW - }; + struct usbdevfs_connectinfo ci; + + memset(&ci, 0, sizeof(ci)); + ci.devnum = ps->dev->devnum; + ci.slow = ps->dev->speed == USB_SPEED_LOW; if (copy_to_user(arg, &ci, sizeof(ci))) return -EFAULT; From b413d0e9fd82a99d2aead7e741adbf1e90ee843d Mon Sep 17 00:00:00 2001 From: Ben Romberger Date: Thu, 11 Dec 2014 18:03:43 -0800 Subject: [PATCH 191/320] msm: soc: Prevent overwrite of APR service data Change the apr_register function so when an APR port is registered the private data pointer for the APR service callback does not get overwritten with the private data of the APR port callback. Change-Id: Id025eab3da2147344a775a1e45478b557fc469c8 Signed-off-by: Ben Romberger --- drivers/soc/qcom/qdsp6v2/apr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/qcom/qdsp6v2/apr.c b/drivers/soc/qcom/qdsp6v2/apr.c index d723432aa1ca7..3a904d3eee59d 100644 --- a/drivers/soc/qcom/qdsp6v2/apr.c +++ b/drivers/soc/qcom/qdsp6v2/apr.c @@ -398,7 +398,6 @@ struct apr_svc *apr_register(char *dest, char *svc_name, apr_fn svc_fn, pr_err("APR: Service needs reset\n"); goto done; } - svc->priv = priv; svc->id = svc_id; svc->dest_id = dest_id; svc->client_id = client_id; @@ -423,6 +422,7 @@ struct apr_svc *apr_register(char *dest, char *svc_name, apr_fn svc_fn, svc->fn = svc_fn; if (svc->port_cnt) svc->svc_cnt++; + svc->priv = priv; } } From a6eed7e3365b8539cdf7842fbb6820010fc1adef Mon Sep 17 00:00:00 2001 From: Haynes Mathew George Date: Wed, 3 Aug 2016 11:55:07 -0700 Subject: [PATCH 192/320] misc: qcom: qdsp6v2: Add missing initialization Use vars in driver context after proper initialization Change-Id: I3e59e27534b8e1088d74b42c72e0075d2fe910e6 Signed-off-by: Haynes Mathew George --- drivers/misc/qcom/qdsp6v2/audio_utils.c | 3 ++- drivers/misc/qcom/qdsp6v2/audio_utils_aio.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils.c b/drivers/misc/qcom/qdsp6v2/audio_utils.c index 30f207810e3aa..9dd52b6391816 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -588,6 +588,7 @@ long audio_in_compat_ioctl(struct file *file, } case AUDIO_GET_CONFIG_32: { struct msm_audio_config32 cfg_32; + memset(&cfg_32, 0, sizeof(cfg_32)); cfg_32.buffer_size = audio->pcm_cfg.buffer_size; cfg_32.buffer_count = audio->pcm_cfg.buffer_count; cfg_32.channel_count = audio->pcm_cfg.channel_count; diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c index 6db7519dcbf43..a1d5e461a7c42 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c @@ -1875,6 +1875,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, case AUDIO_GET_CONFIG_32: { struct msm_audio_config32 cfg_32; mutex_lock(&audio->lock); + memset(&cfg_32, 0, sizeof(cfg_32)); cfg_32.buffer_size = audio->pcm_cfg.buffer_size; cfg_32.buffer_count = audio->pcm_cfg.buffer_count; cfg_32.channel_count = audio->pcm_cfg.channel_count; From ed9797abdba5439a587b2cdf02e77a1e85ffd931 Mon Sep 17 00:00:00 2001 From: Abhijeet Dharmapurikar Date: Wed, 15 Jun 2016 09:46:21 -0700 Subject: [PATCH 193/320] spmi: prevent showing the address of spmidev Creating devices with the address of the container spmidev is not indicative of the actual hardware device it represents. Instead use an unique id to indicate the device it represents. CRs-Fixed: 1024197 Change-Id: Id18e2a19f4fa1249901a3f275defa8f589270d69 Signed-off-by: Abhijeet Dharmapurikar --- drivers/spmi/spmi.c | 18 +++++++++++++++--- include/linux/spmi.h | 6 +++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c index bbfb72adc82db..eb614783e608f 100644 --- a/drivers/spmi/spmi.c +++ b/drivers/spmi/spmi.c @@ -32,6 +32,7 @@ struct spmii_boardinfo { static DEFINE_MUTEX(board_lock); static LIST_HEAD(board_list); static DEFINE_IDR(ctrl_idr); +static DEFINE_IDA(spmi_devid_ida); static struct device_type spmi_dev_type; static struct device_type spmi_ctrl_type; @@ -229,22 +230,32 @@ int spmi_add_device(struct spmi_device *spmidev) { int rc; struct device *dev = get_valid_device(spmidev); + int id; if (!dev) { pr_err("invalid SPMI device\n"); return -EINVAL; } + id = ida_simple_get(&spmi_devid_ida, 0, 0, GFP_KERNEL); + if (id < 0) { + pr_err("No id available status = %d\n", id); + return id; + } + /* Set the device name */ - dev_set_name(dev, "%s-%p", spmidev->name, spmidev); + spmidev->id = id; + dev_set_name(dev, "%s-%d", spmidev->name, spmidev->id); /* Device may be bound to an active driver when this returns */ rc = device_add(dev); - if (rc < 0) + if (rc < 0) { + ida_simple_remove(&spmi_devid_ida, spmidev->id); dev_err(dev, "Can't add %s, status %d\n", dev_name(dev), rc); - else + } else { dev_dbg(dev, "device %s registered\n", dev_name(dev)); + } return rc; } @@ -292,6 +303,7 @@ EXPORT_SYMBOL_GPL(spmi_new_device); void spmi_remove_device(struct spmi_device *spmi_dev) { device_unregister(&spmi_dev->dev); + ida_simple_remove(&spmi_devid_ida, spmi_dev->id); } EXPORT_SYMBOL_GPL(spmi_remove_device); diff --git a/include/linux/spmi.h b/include/linux/spmi.h index b581de80bbacf..5a8525d7694d5 100644 --- a/include/linux/spmi.h +++ b/include/linux/spmi.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -120,6 +120,9 @@ struct spmi_resource { * @dev_node: array of SPMI resources when used with spmi-dev-container. * @num_dev_node: number of device_node structures. * @sid: Slave Identifier. + * @id: Unique identifier to differentiate from other spmi devices with + * possibly same name. + * */ struct spmi_device { struct device dev; @@ -129,6 +132,7 @@ struct spmi_device { struct spmi_resource *dev_node; u32 num_dev_node; u8 sid; + int id; }; #define to_spmi_device(d) container_of(d, struct spmi_device, dev) From fd762df76f06748935e81ac471619391cff79968 Mon Sep 17 00:00:00 2001 From: Skylar Chang Date: Fri, 8 Jul 2016 16:20:33 -0700 Subject: [PATCH 194/320] msm: ipa: fix potential race condition ioctls There are numerous potential race condition ioctls in the IPA driver. The fix is to add check wherever it copies arguments from user-space memory and process. Change-Id: I5a440f89153518507acdf5dad42625503732e59a Signed-off-by: Skylar Chang --- drivers/platform/msm/ipa/ipa.c | 236 +++++++++++++++++++++++++++------ 1 file changed, 196 insertions(+), 40 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa.c b/drivers/platform/msm/ipa/ipa.c index 41a024746e1ee..ddb716caf2e0c 100644 --- a/drivers/platform/msm/ipa/ipa.c +++ b/drivers/platform/msm/ipa/ipa.c @@ -277,6 +277,7 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) struct ipa_ioc_v4_nat_del nat_del; struct ipa_ioc_rm_dependency rm_depend; size_t sz; + int pre_entry; IPADBG("cmd=%x nr=%d\n", cmd, _IOC_NR(cmd)); @@ -325,11 +326,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - + pre_entry = + ((struct ipa_ioc_nat_dma_cmd *)header)->entries; pyld_sz = sizeof(struct ipa_ioc_nat_dma_cmd) + - ((struct ipa_ioc_nat_dma_cmd *)header)->entries * - sizeof(struct ipa_ioc_nat_dma_one); + pre_entry * sizeof(struct ipa_ioc_nat_dma_one); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -340,7 +341,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_nat_dma_cmd *)param)->entries + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_nat_dma_cmd *)param)->entries, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_nat_dma_cmd((struct ipa_ioc_nat_dma_cmd *)param)) { retval = -EFAULT; break; @@ -365,10 +374,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_add_hdr *)header)->num_hdrs; pyld_sz = sizeof(struct ipa_ioc_add_hdr) + - ((struct ipa_ioc_add_hdr *)header)->num_hdrs * - sizeof(struct ipa_hdr_add); + pre_entry * sizeof(struct ipa_hdr_add); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -378,6 +388,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_hdr *)param)->num_hdrs + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_add_hdr *)param)->num_hdrs, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_add_hdr((struct ipa_ioc_add_hdr *)param)) { retval = -EFAULT; break; @@ -394,10 +413,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_del_hdr *)header)->num_hdls; pyld_sz = sizeof(struct ipa_ioc_del_hdr) + - ((struct ipa_ioc_del_hdr *)header)->num_hdls * - sizeof(struct ipa_hdr_del); + pre_entry * sizeof(struct ipa_hdr_del); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -407,6 +427,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_del_hdr *)param)->num_hdls + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_del_hdr *)param)->num_hdls, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_del_hdr((struct ipa_ioc_del_hdr *)param)) { retval = -EFAULT; break; @@ -423,10 +452,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_add_rt_rule *)header)->num_rules; pyld_sz = sizeof(struct ipa_ioc_add_rt_rule) + - ((struct ipa_ioc_add_rt_rule *)header)->num_rules * - sizeof(struct ipa_rt_rule_add); + pre_entry * sizeof(struct ipa_rt_rule_add); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -436,6 +466,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_rt_rule *)param)->num_rules + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_add_rt_rule *)param)-> + num_rules, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_add_rt_rule((struct ipa_ioc_add_rt_rule *)param)) { retval = -EFAULT; break; @@ -452,10 +492,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_mdfy_rt_rule *)header)->num_rules; pyld_sz = sizeof(struct ipa_ioc_mdfy_rt_rule) + - ((struct ipa_ioc_mdfy_rt_rule *)header)->num_rules * - sizeof(struct ipa_rt_rule_mdfy); + pre_entry * sizeof(struct ipa_rt_rule_mdfy); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -465,6 +506,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_mdfy_rt_rule *)param)->num_rules + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_mdfy_rt_rule *)param)-> + num_rules, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_mdfy_rt_rule((struct ipa_ioc_mdfy_rt_rule *)param)) { retval = -EFAULT; break; @@ -481,10 +532,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_del_rt_rule *)header)->num_hdls; pyld_sz = sizeof(struct ipa_ioc_del_rt_rule) + - ((struct ipa_ioc_del_rt_rule *)header)->num_hdls * - sizeof(struct ipa_rt_rule_del); + pre_entry * sizeof(struct ipa_rt_rule_del); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -494,6 +546,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_del_rt_rule *)param)->num_hdls + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_del_rt_rule *)param)->num_hdls, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_del_rt_rule((struct ipa_ioc_del_rt_rule *)param)) { retval = -EFAULT; break; @@ -510,10 +571,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_add_flt_rule *)header)->num_rules; pyld_sz = sizeof(struct ipa_ioc_add_flt_rule) + - ((struct ipa_ioc_add_flt_rule *)header)->num_rules * - sizeof(struct ipa_flt_rule_add); + pre_entry * sizeof(struct ipa_flt_rule_add); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -523,6 +585,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_flt_rule *)param)->num_rules + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_add_flt_rule *)param)-> + num_rules, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_add_flt_rule((struct ipa_ioc_add_flt_rule *)param)) { retval = -EFAULT; break; @@ -539,10 +611,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_del_flt_rule *)header)->num_hdls; pyld_sz = sizeof(struct ipa_ioc_del_flt_rule) + - ((struct ipa_ioc_del_flt_rule *)header)->num_hdls * - sizeof(struct ipa_flt_rule_del); + pre_entry * sizeof(struct ipa_flt_rule_del); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -552,6 +625,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_del_flt_rule *)param)->num_hdls + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_del_flt_rule *)param)-> + num_hdls, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_del_flt_rule((struct ipa_ioc_del_flt_rule *)param)) { retval = -EFAULT; break; @@ -568,10 +651,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_mdfy_flt_rule *)header)->num_rules; pyld_sz = sizeof(struct ipa_ioc_mdfy_flt_rule) + - ((struct ipa_ioc_mdfy_flt_rule *)header)->num_rules * - sizeof(struct ipa_flt_rule_mdfy); + pre_entry * sizeof(struct ipa_flt_rule_mdfy); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -581,6 +665,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_mdfy_flt_rule *)param)->num_rules + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_mdfy_flt_rule *)param)-> + num_rules, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_mdfy_flt_rule((struct ipa_ioc_mdfy_flt_rule *)param)) { retval = -EFAULT; break; @@ -688,15 +782,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - - if (((struct ipa_ioc_query_intf_tx_props *)header)->num_tx_props - > IPA_NUM_PROPS_MAX) { + if (((struct ipa_ioc_query_intf_tx_props *) + header)->num_tx_props > IPA_NUM_PROPS_MAX) { retval = -EFAULT; break; } - - pyld_sz = sz + ((struct ipa_ioc_query_intf_tx_props *) - header)->num_tx_props * + pre_entry = + ((struct ipa_ioc_query_intf_tx_props *) + header)->num_tx_props; + pyld_sz = sz + pre_entry * sizeof(struct ipa_ioc_tx_intf_prop); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { @@ -707,6 +801,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_query_intf_tx_props *) + param)->num_tx_props + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_query_intf_tx_props *) + param)->num_tx_props, pre_entry); + retval = -EFAULT; + break; + } if (ipa_query_intf_tx_props( (struct ipa_ioc_query_intf_tx_props *)param)) { retval = -1; @@ -723,15 +827,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - - if (((struct ipa_ioc_query_intf_rx_props *)header)->num_rx_props - > IPA_NUM_PROPS_MAX) { + if (((struct ipa_ioc_query_intf_rx_props *) + header)->num_rx_props > IPA_NUM_PROPS_MAX) { retval = -EFAULT; break; } - - pyld_sz = sz + ((struct ipa_ioc_query_intf_rx_props *) - header)->num_rx_props * + pre_entry = + ((struct ipa_ioc_query_intf_rx_props *) + header)->num_rx_props; + pyld_sz = sz + pre_entry * sizeof(struct ipa_ioc_rx_intf_prop); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { @@ -742,6 +846,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_query_intf_rx_props *) + param)->num_rx_props != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_query_intf_rx_props *) + param)->num_rx_props, pre_entry); + retval = -EFAULT; + break; + } if (ipa_query_intf_rx_props( (struct ipa_ioc_query_intf_rx_props *)param)) { retval = -1; @@ -764,9 +877,10 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - - pyld_sz = sz + ((struct ipa_ioc_query_intf_ext_props *) - header)->num_ext_props * + pre_entry = + ((struct ipa_ioc_query_intf_ext_props *) + header)->num_ext_props; + pyld_sz = sz + pre_entry * sizeof(struct ipa_ioc_ext_intf_prop); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { @@ -777,6 +891,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_query_intf_ext_props *) + param)->num_ext_props != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_query_intf_ext_props *) + param)->num_ext_props, pre_entry); + retval = -EFAULT; + break; + } if (ipa_query_intf_ext_props( (struct ipa_ioc_query_intf_ext_props *)param)) { retval = -1; @@ -793,8 +916,10 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_msg_meta *)header)->msg_len; pyld_sz = sizeof(struct ipa_msg_meta) + - ((struct ipa_msg_meta *)header)->msg_len; + pre_entry; param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -804,6 +929,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_msg_meta *)param)->msg_len + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_msg_meta *)param)->msg_len, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_pull_msg((struct ipa_msg_meta *)param, (char *)param + sizeof(struct ipa_msg_meta), ((struct ipa_msg_meta *)param)->msg_len) != @@ -919,10 +1053,12 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_add_hdr_proc_ctx *) + header)->num_proc_ctxs; pyld_sz = sizeof(struct ipa_ioc_add_hdr_proc_ctx) + - ((struct ipa_ioc_add_hdr_proc_ctx *)header)->num_proc_ctxs * - sizeof(struct ipa_hdr_proc_ctx_add); + pre_entry * sizeof(struct ipa_hdr_proc_ctx_add); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -932,6 +1068,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_hdr_proc_ctx *) + param)->num_proc_ctxs != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_add_hdr_proc_ctx *) + param)->num_proc_ctxs, pre_entry); + retval = -EFAULT; + break; + } if (ipa_add_hdr_proc_ctx( (struct ipa_ioc_add_hdr_proc_ctx *)param)) { retval = -EFAULT; @@ -948,10 +1093,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_del_hdr_proc_ctx *)header)->num_hdls; pyld_sz = sizeof(struct ipa_ioc_del_hdr_proc_ctx) + - ((struct ipa_ioc_del_hdr_proc_ctx *)header)->num_hdls * - sizeof(struct ipa_hdr_proc_ctx_del); + pre_entry * sizeof(struct ipa_hdr_proc_ctx_del); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -961,6 +1107,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_del_hdr_proc_ctx *) + param)->num_hdls != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_del_hdr_proc_ctx *)param)-> + num_hdls, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_del_hdr_proc_ctx( (struct ipa_ioc_del_hdr_proc_ctx *)param)) { retval = -EFAULT; From afef112d3507ddebe12c0cb427ee133757042a17 Mon Sep 17 00:00:00 2001 From: Depeng Shao Date: Wed, 10 Aug 2016 17:18:06 +0800 Subject: [PATCH 195/320] ARM: dts: msm: camera: update camera device tree for msm8909 1. Add camera eeprom device tree for msm8909 back camera; 2. Modify the flash sequence to enable the flash; 3. Delete mipi switch gpio pinctrl from camera0 as the same gpio pinctrl has set up in camera1. Change-Id: Id7cab8e1bbfccf25c9c52f13b6d5cfb82181ccd9 Signed-off-by: Depeng Shao --- .../dts/qcom/msm8909-camera-sensor-skuq.dtsi | 93 +++++++++++++++++-- 1 file changed, 87 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/qcom/msm8909-camera-sensor-skuq.dtsi b/arch/arm/boot/dts/qcom/msm8909-camera-sensor-skuq.dtsi index 49a3b7b67c751..b8e6af402a38a 100755 --- a/arch/arm/boot/dts/qcom/msm8909-camera-sensor-skuq.dtsi +++ b/arch/arm/boot/dts/qcom/msm8909-camera-sensor-skuq.dtsi @@ -56,8 +56,8 @@ qcom,flash-en = <&msm_gpio 31 0>; qcom,flash-now = <&msm_gpio 32 0>; qcom,op-seq = "flash_en", "flash_now"; - qcom,torch-seq-val = <0 1>; - qcom,flash-seq-val = <1 0>; + qcom,torch-seq-val = <1 0>; + qcom,flash-seq-val = <1 1>; linux,name = "flashlight"; linux,default-trigger = "flashlight-trigger"; }; @@ -85,6 +85,88 @@ qcom,cam-vreg-op-mode = <80000>; }; + eeprom0: qcom,eeprom@20{ + cell-index = <0>; + reg = <0x20>; + qcom,eeprom-name = "truly_ov8856"; + compatible = "qcom,eeprom"; + qcom,slave-addr = <0x20>; + qcom,cci-master = <0>; + + qcom,num-blocks = <10>; + qcom,page0 = <1 0x0100 2 0x01 1 1>; + qcom,poll0 = <0 0x0 2 0 1 1>; + qcom,mem0 = <0 0x0 2 0 1 0>; + qcom,page1 = <1 0x5002 2 0xa8 1 1>; + qcom,poll1 = <0 0x0 2 0 1 1>; + qcom,mem1 = <0 0x0 2 0 1 0>; + qcom,page2 = <1 0x3d84 2 0xc0 1 1>; + qcom,poll2 = <0 0x0 2 0 1 1>; + qcom,mem2 = <0 0x0 2 0 1 0>; + qcom,page3 = <1 0x3d88 2 0x7010 2 1>; + qcom,poll3 = <0 0x0 2 0 1 1>; + qcom,mem3 = <0 0x3d00 2 0 1 0>; + qcom,page4 = <1 0x3d8a 2 0x720a 2 1>; + qcom,poll4 = <0 0x0 2 0 1 1>; + qcom,mem4 = <0 0x3d00 2 0 1 0>; + qcom,page5 = <1 0x3d81 2 0x01 1 10>; + qcom,poll5 = <0 0x0 2 0 1 1>; + qcom,mem5 = <0 0x3d00 2 0 1 0>; + qcom,page6 = <0 0x0 2 0x0 1 1>; + qcom,poll6 = <0 0x0 2 0 1 1>; + qcom,mem6 = <507 0x7010 2 0 1 0>; + qcom,page7 = <0 0x0 2 0x0 1 1>; + qcom,poll7 = <0 0x0 2 0 1 1>; + qcom,mem7 = <1 0x5000 2 0 1 1>; + qcom,page8 = <1 0x5002 2 0xaa 1 1>; + qcom,poll8 = <0 0x0 2 0 1 1>; + qcom,mem8 = <0 0x0 2 0 1 0>; + qcom,page9 = <1 0x5002 2 0x00 1 1>; + qcom,poll9 = <0 0x0 2 0 1 1>; + qcom,mem9 = <0 0x0 2 0 1 0>; + + cam_vdig-supply = <&pm8916_l2>; + cam_vana-supply = <&pm8916_l17>; + cam_vio-supply = <&pm8916_l6>; + cam_vaf-supply = <&pm8916_l8>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", + "cam_vaf"; + qcom,cam-vreg-type = <0 1 0 0>; + qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2850000 2900000>; + qcom,cam-vreg-op-mode = <200000 0 80000 100000>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_default + &cam_sensor_rear_default>; + pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep>; + gpios = <&msm_gpio 26 0>, + <&msm_gpio 35 0>, + <&msm_gpio 34 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK", + "CAM_RESET1", + "CAM_STANDBY"; + + qcom,cam-power-seq-type = "sensor_vreg", + "sensor_vreg", "sensor_vreg", + "sensor_gpio", "sensor_gpio", + "sensor_clk"; + qcom,cam-power-seq-val = "cam_vio", + "cam_vana", "cam_vdig", + "sensor_gpio_reset", + "sensor_gpio_standby", + "sensor_cam_mclk"; + qcom,cam-power-seq-cfg-val = <1 1 1 1 1 24000000>; + qcom,cam-power-seq-delay = <10 10 10 10 10 5>; + + clocks = <&clock_gcc clk_mclk0_clk_src>, + <&clock_gcc clk_gcc_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; + qcom,camera@0 { cell-index = <0>; compatible = "qcom,camera"; @@ -94,6 +176,7 @@ qcom,mount-angle = <90>; qcom,actuator-src = <&actuator0>; qcom,led-flash-src = <&led_flash0>; + qcom,eeprom-src = <&eeprom0>; cam_vdig-supply = <&pm8916_l2>; cam_vana-supply = <&pm8916_l17>; cam_vio-supply = <&pm8916_l6>; @@ -105,10 +188,8 @@ qcom,cam-vreg-max-voltage = <1200000 0 2850000 2900000>; qcom,cam-vreg-op-mode = <200000 0 80000 100000>; pinctrl-names = "cam_default", "cam_suspend"; - pinctrl-0 = <&cam_sensor_mclk0_default - &cam_sensor_rear_default &cam_mipi_switch_default>; - pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep - &cam_mipi_switch_sleep>; + pinctrl-0 = <&cam_sensor_mclk0_default &cam_sensor_rear_default>; + pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep>; gpios = <&msm_gpio 26 0>, <&msm_gpio 35 0>, <&msm_gpio 34 0>, From 2847ac41fa265c7b863f4bf8557db123168aeb13 Mon Sep 17 00:00:00 2001 From: Mayank Rana Date: Wed, 29 Apr 2015 18:17:04 -0700 Subject: [PATCH 196/320] usb: gadget: f_mtp: Add support to capture time taken with vfs_write/read This change captures time taken by each vfs_read() and vfs_write() call made from USB MTP gadget driver where data size is equal to USB request buffer size. It provides debugfs entry to get this information for 100 such call and resetting the same. How-To use: To get stats: cat /sys/kernel/debug/usb_mtp/status To reset stats: echo 0 > /sys/kernel/debug/usb_mtp/status Change-Id: I252e830568704e9e557660c1ae0f7597823e4b17 Signed-off-by: Mayank Rana --- drivers/usb/gadget/f_mtp.c | 142 ++++++++++++++++++++++++++++++++++++- 1 file changed, 141 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c index 5a06296aaded6..40ec454502394 100644 --- a/drivers/usb/gadget/f_mtp.c +++ b/drivers/usb/gadget/f_mtp.c @@ -26,6 +26,8 @@ #include #include +#include +#include #include #include #include @@ -67,6 +69,8 @@ #define MTP_RESPONSE_OK 0x2001 #define MTP_RESPONSE_DEVICE_BUSY 0x2019 +#define MAX_ITERATION 100 + unsigned int mtp_rx_req_len = MTP_BULK_BUFFER_SIZE; module_param(mtp_rx_req_len, uint, S_IRUGO | S_IWUSR); @@ -116,6 +120,14 @@ struct mtp_dev { uint16_t xfer_command; uint32_t xfer_transaction_id; int xfer_result; + struct { + unsigned long vfs_rbytes; + unsigned long vfs_wbytes; + unsigned vfs_rtime; + unsigned vfs_wtime; + } perf[MAX_ITERATION]; + unsigned dbg_read_index; + unsigned dbg_write_index; }; static struct usb_interface_descriptor mtp_interface_desc = { @@ -760,6 +772,7 @@ static void send_file_work(struct work_struct *data) int xfer, ret, hdr_size; int r = 0; int sendZLP = 0; + ktime_t start_time; /* read our parameters */ smp_rmb(); @@ -815,14 +828,19 @@ static void send_file_work(struct work_struct *data) header->transaction_id = __cpu_to_le32(dev->xfer_transaction_id); } - + start_time = ktime_get(); ret = vfs_read(filp, req->buf + hdr_size, xfer - hdr_size, &offset); if (ret < 0) { r = ret; break; } + xfer = ret + hdr_size; + dev->perf[dev->dbg_read_index].vfs_rtime = + ktime_to_us(ktime_sub(ktime_get(), start_time)); + dev->perf[dev->dbg_read_index].vfs_rbytes = xfer; + dev->dbg_read_index = (dev->dbg_read_index + 1) % MAX_ITERATION; hdr_size = 0; req->length = xfer; @@ -862,6 +880,7 @@ static void receive_file_work(struct work_struct *data) int64_t count; int ret, cur_buf = 0; int r = 0; + ktime_t start_time; /* read our parameters */ smp_rmb(); @@ -895,6 +914,7 @@ static void receive_file_work(struct work_struct *data) if (write_req) { DBG(cdev, "rx %p %d\n", write_req, write_req->actual); + start_time = ktime_get(); ret = vfs_write(filp, write_req->buf, write_req->actual, &offset); DBG(cdev, "vfs_write %d\n", ret); @@ -904,6 +924,11 @@ static void receive_file_work(struct work_struct *data) dev->state = STATE_ERROR; break; } + dev->perf[dev->dbg_write_index].vfs_wtime = + ktime_to_us(ktime_sub(ktime_get(), start_time)); + dev->perf[dev->dbg_write_index].vfs_wbytes = ret; + dev->dbg_write_index = + (dev->dbg_write_index + 1) % MAX_ITERATION; write_req = NULL; } @@ -1465,6 +1490,119 @@ static int mtp_bind_config(struct usb_configuration *c, bool ptp_config) return usb_add_function(c, &dev->function); } +static int debug_mtp_read_stats(struct seq_file *s, void *unused) +{ + struct mtp_dev *dev = _mtp_dev; + int i; + unsigned long flags; + unsigned min, max = 0, sum = 0, iteration = 0; + + seq_puts(s, "\n=======================\n"); + seq_puts(s, "MTP Write Stats:\n"); + seq_puts(s, "\n=======================\n"); + spin_lock_irqsave(&dev->lock, flags); + min = dev->perf[0].vfs_wtime; + for (i = 0; i < MAX_ITERATION; i++) { + seq_printf(s, "vfs write: bytes:%ld\t\t time:%d\n", + dev->perf[i].vfs_wbytes, + dev->perf[i].vfs_wtime); + if (dev->perf[i].vfs_wbytes == mtp_rx_req_len) { + sum += dev->perf[i].vfs_wtime; + if (min > dev->perf[i].vfs_wtime) + min = dev->perf[i].vfs_wtime; + if (max < dev->perf[i].vfs_wtime) + max = dev->perf[i].vfs_wtime; + iteration++; + } + } + + seq_printf(s, "vfs_write(time in usec) min:%d\t max:%d\t avg:%d\n", + min, max, sum / iteration); + min = max = sum = iteration = 0; + seq_puts(s, "\n=======================\n"); + seq_puts(s, "MTP Read Stats:\n"); + seq_puts(s, "\n=======================\n"); + + min = dev->perf[0].vfs_rtime; + for (i = 0; i < MAX_ITERATION; i++) { + seq_printf(s, "vfs read: bytes:%ld\t\t time:%d\n", + dev->perf[i].vfs_rbytes, + dev->perf[i].vfs_rtime); + if (dev->perf[i].vfs_rbytes == mtp_tx_req_len) { + sum += dev->perf[i].vfs_rtime; + if (min > dev->perf[i].vfs_rtime) + min = dev->perf[i].vfs_rtime; + if (max < dev->perf[i].vfs_rtime) + max = dev->perf[i].vfs_rtime; + iteration++; + } + } + + seq_printf(s, "vfs_read(time in usec) min:%d\t max:%d\t avg:%d\n", + min, max, sum / iteration); + spin_unlock_irqrestore(&dev->lock, flags); + return 0; +} + +static ssize_t debug_mtp_reset_stats(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + int clear_stats; + unsigned long flags; + struct mtp_dev *dev = _mtp_dev; + + if (buf == NULL) { + pr_err("[%s] EINVAL\n", __func__); + goto done; + } + + if (sscanf(buf, "%u", &clear_stats) != 1 || clear_stats != 0) { + pr_err("Wrong value. To clear stats, enter value as 0.\n"); + goto done; + } + + spin_lock_irqsave(&dev->lock, flags); + memset(&dev->perf[0], 0, MAX_ITERATION * sizeof(dev->perf[0])); + dev->dbg_read_index = 0; + dev->dbg_write_index = 0; + spin_unlock_irqrestore(&dev->lock, flags); +done: + return count; +} + +static int debug_mtp_open(struct inode *inode, struct file *file) +{ + return single_open(file, debug_mtp_read_stats, inode->i_private); +} + +static const struct file_operations debug_mtp_ops = { + .open = debug_mtp_open, + .read = seq_read, + .write = debug_mtp_reset_stats, +}; + +struct dentry *dent_mtp; +static void mtp_debugfs_init(void) +{ + struct dentry *dent_mtp_status; + dent_mtp = debugfs_create_dir("usb_mtp", 0); + if (!dent_mtp || IS_ERR(dent_mtp)) + return; + + dent_mtp_status = debugfs_create_file("status", S_IRUGO | S_IWUSR, + dent_mtp, 0, &debug_mtp_ops); + if (!dent_mtp_status || IS_ERR(dent_mtp_status)) { + debugfs_remove(dent_mtp); + dent_mtp = NULL; + return; + } +} + +static void mtp_debugfs_remove(void) +{ + debugfs_remove_recursive(dent_mtp); +} + static int mtp_setup(void) { struct mtp_dev *dev; @@ -1497,6 +1635,7 @@ static int mtp_setup(void) if (ret) goto err2; + mtp_debugfs_init(); return 0; err2: @@ -1515,6 +1654,7 @@ static void mtp_cleanup(void) if (!dev) return; + mtp_debugfs_remove(); misc_deregister(&mtp_device); destroy_workqueue(dev->wq); _mtp_dev = NULL; From b0cb576c82177f1508b2da122820054d303ca628 Mon Sep 17 00:00:00 2001 From: Azhar Shaikh Date: Wed, 29 Jul 2015 20:34:46 -0700 Subject: [PATCH 197/320] usb: gadget: f_mtp: Change the icon to camera for PTP composition The existing code shows the phone icon in 'My Computer' of windows host, for PTP composition. Create a new Extended Configuration Descriptor for PTP composition and update the compatibleID to display a camera icon for PTP composition. Change-Id: If286c5b80874a95be0b5ecc533d0e5c7a14f39d3 Signed-off-by: Azhar Shaikh --- drivers/usb/gadget/f_mtp.c | 41 +++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c index 40ec454502394..98b67ae8bbc02 100644 --- a/drivers/usb/gadget/f_mtp.c +++ b/drivers/usb/gadget/f_mtp.c @@ -128,6 +128,7 @@ struct mtp_dev { } perf[MAX_ITERATION]; unsigned dbg_read_index; unsigned dbg_write_index; + bool is_ptp; }; static struct usb_interface_descriptor mtp_interface_desc = { @@ -334,10 +335,12 @@ struct mtp_ext_config_desc_function { }; /* MTP Extended Configuration Descriptor */ -struct { +struct ext_mtp_desc { struct mtp_ext_config_desc_header header; struct mtp_ext_config_desc_function function; -} mtp_ext_config_desc = { +}; + +struct ext_mtp_desc mtp_ext_config_desc = { .header = { .dwLength = __constant_cpu_to_le32(sizeof(mtp_ext_config_desc)), .bcdVersion = __constant_cpu_to_le16(0x0100), @@ -351,6 +354,20 @@ struct { }, }; +struct ext_mtp_desc ptp_ext_config_desc = { + .header = { + .dwLength = cpu_to_le32(sizeof(mtp_ext_config_desc)), + .bcdVersion = cpu_to_le16(0x0100), + .wIndex = cpu_to_le16(4), + .bCount = cpu_to_le16(1), + }, + .function = { + .bFirstInterfaceNumber = 0, + .bInterfaceCount = 1, + .compatibleID = { 'P', 'T', 'P' }, + }, +}; + struct mtp_device_status { __le16 wLength; __le16 wCode; @@ -1263,9 +1280,21 @@ static int mtp_ctrlrequest(struct usb_composite_dev *cdev, if (ctrl->bRequest == 1 && (ctrl->bRequestType & USB_DIR_IN) && (w_index == 4 || w_index == 5)) { - value = (w_length < sizeof(mtp_ext_config_desc) ? - w_length : sizeof(mtp_ext_config_desc)); - memcpy(cdev->req->buf, &mtp_ext_config_desc, value); + if (!dev->is_ptp) { + value = (w_length < + sizeof(mtp_ext_config_desc) ? + w_length : + sizeof(mtp_ext_config_desc)); + memcpy(cdev->req->buf, &mtp_ext_config_desc, + value); + } else { + value = (w_length < + sizeof(ptp_ext_config_desc) ? + w_length : + sizeof(ptp_ext_config_desc)); + memcpy(cdev->req->buf, &ptp_ext_config_desc, + value); + } } } else if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) { DBG(cdev, "class request: %d index: %d value: %d length: %d\n", @@ -1381,6 +1410,7 @@ mtp_function_unbind(struct usb_configuration *c, struct usb_function *f) while ((req = mtp_req_get(dev, &dev->intr_idle))) mtp_request_free(req, dev->ep_intr); dev->state = STATE_OFFLINE; + dev->is_ptp = false; } static int mtp_function_set_alt(struct usb_function *f, @@ -1487,6 +1517,7 @@ static int mtp_bind_config(struct usb_configuration *c, bool ptp_config) dev->function.set_alt = mtp_function_set_alt; dev->function.disable = mtp_function_disable; + dev->is_ptp = ptp_config; return usb_add_function(c, &dev->function); } From c8578f5b7566c41a9e1b104f595a0a6dc5e07352 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 20 Mar 2015 17:41:43 +0000 Subject: [PATCH 198/320] net: validate the range we feed to iov_iter_init() in sys_sendto/sys_recvfrom b/28759139 Cc: stable@vger.kernel.org # v3.19 Signed-off-by: Al Viro Signed-off-by: David S. Miller Signed-off-by: Dennis Cagle Git-commit: 4de930efc23b92ddf88ce91c405ee645fe6e27ea Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git (cherry picked from commit 4de930efc23b92ddf88ce91c405ee645fe6e27ea) Change-Id: I81577c193559f93826c5e85aa2cb06271340a2e8 --- net/socket.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/socket.c b/net/socket.c index ed2dde71036ea..10981131a81c8 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1797,6 +1797,8 @@ SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len, if (len > INT_MAX) len = INT_MAX; + if (unlikely(!access_ok(VERIFY_READ, buff, len))) + return -EFAULT; sock = sockfd_lookup_light(fd, &err, &fput_needed); if (!sock) goto out; @@ -1858,6 +1860,8 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, if (size > INT_MAX) size = INT_MAX; + if (unlikely(!access_ok(VERIFY_WRITE, ubuf, size))) + return -EFAULT; sock = sockfd_lookup_light(fd, &err, &fput_needed); if (!sock) goto out; From 8bf76c7a1ed0844e57052fd0ee73f380f09e100b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 12 Jan 2016 15:36:27 +0100 Subject: [PATCH 199/320] ALSA: seq: Fix race at timer setup and close ALSA sequencer code has an open race between the timer setup ioctl and the close of the client. This was triggered by syzkaller fuzzer, and a use-after-free was caught there as a result. This patch papers over it by adding a proper queue->timer_mutex lock around the timer-related calls in the relevant code path. b/28695438 Reported-by: Dmitry Vyukov Tested-by: Dmitry Vyukov Cc: Git-commit: 3567eb6af614dac436c4b16a8d426f9faed639b3 Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Signed-off-by: Takashi Iwai Signed-off-by: Dennis Cagle (cherry picked from commit 3567eb6af614dac436c4b16a8d426f9faed639b3) Change-Id: I398dd27dcdd1241917fd6d127b2debffc2afd413 --- sound/core/seq/seq_queue.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c index f9077361c119d..4c9aa462de9b1 100644 --- a/sound/core/seq/seq_queue.c +++ b/sound/core/seq/seq_queue.c @@ -144,8 +144,10 @@ static struct snd_seq_queue *queue_new(int owner, int locked) static void queue_delete(struct snd_seq_queue *q) { /* stop and release the timer */ + mutex_lock(&q->timer_mutex); snd_seq_timer_stop(q->timer); snd_seq_timer_close(q); + mutex_unlock(&q->timer_mutex); /* wait until access free */ snd_use_lock_sync(&q->use_lock); /* release resources... */ From b02bb06a3f7c3d8485bf14e42713d05c9f91d5de Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 13 Jan 2016 17:48:01 +0100 Subject: [PATCH 200/320] ALSA: timer: Fix race among timer ioctls ALSA timer ioctls have an open race and this may lead to a use-after-free of timer instance object. A simplistic fix is to make each ioctl exclusive. We have already tread_sem for controlling the tread, and extend this as a global mutex to be applied to each ioctl. The downside is, of course, the worse concurrency. But these ioctls aren't to be parallel accessible, in anyway, so it should be fine to serialize there. b/28694392 Reported-by: Dmitry Vyukov Tested-by: Dmitry Vyukov Cc: Git-commit: af368027a49a751d6ff4ee9e3f9961f35bb4fede Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Signed-off-by: Takashi Iwai Signed-off-by: Dennis Cagle (cherry picked from commit af368027a49a751d6ff4ee9e3f9961f35bb4fede) Change-Id: I9d45e3d142b42d5dee6ae54c25e78504c871eef8 --- sound/core/timer.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/sound/core/timer.c b/sound/core/timer.c index 38a137d6b04fd..1d5461719e31f 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -73,7 +73,7 @@ struct snd_timer_user { struct timespec tstamp; /* trigger tstamp */ wait_queue_head_t qchange_sleep; struct fasync_struct *fasync; - struct mutex tread_sem; + struct mutex ioctl_lock; }; /* list of timers */ @@ -1266,7 +1266,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file) return -ENOMEM; spin_lock_init(&tu->qlock); init_waitqueue_head(&tu->qchange_sleep); - mutex_init(&tu->tread_sem); + mutex_init(&tu->ioctl_lock); tu->ticks = 1; tu->queue_size = 128; tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read), @@ -1286,8 +1286,10 @@ static int snd_timer_user_release(struct inode *inode, struct file *file) if (file->private_data) { tu = file->private_data; file->private_data = NULL; + mutex_lock(&tu->ioctl_lock); if (tu->timeri) snd_timer_close(tu->timeri); + mutex_unlock(&tu->ioctl_lock); kfree(tu->queue); kfree(tu->tqueue); kfree(tu); @@ -1525,7 +1527,6 @@ static int snd_timer_user_tselect(struct file *file, int err = 0; tu = file->private_data; - mutex_lock(&tu->tread_sem); if (tu->timeri) { snd_timer_close(tu->timeri); tu->timeri = NULL; @@ -1569,7 +1570,6 @@ static int snd_timer_user_tselect(struct file *file, } __err: - mutex_unlock(&tu->tread_sem); return err; } @@ -1782,7 +1782,7 @@ enum { SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23), }; -static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, +static long __snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct snd_timer_user *tu; @@ -1799,17 +1799,11 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, { int xarg; - mutex_lock(&tu->tread_sem); - if (tu->timeri) { /* too late */ - mutex_unlock(&tu->tread_sem); + if (tu->timeri) /* too late */ return -EBUSY; - } - if (get_user(xarg, p)) { - mutex_unlock(&tu->tread_sem); + if (get_user(xarg, p)) return -EFAULT; - } tu->tread = xarg ? 1 : 0; - mutex_unlock(&tu->tread_sem); return 0; } case SNDRV_TIMER_IOCTL_GINFO: @@ -1842,6 +1836,18 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, return -ENOTTY; } +static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct snd_timer_user *tu = file->private_data; + long ret; + + mutex_lock(&tu->ioctl_lock); + ret = __snd_timer_user_ioctl(file, cmd, arg); + mutex_unlock(&tu->ioctl_lock); + return ret; +} + static int snd_timer_user_fasync(int fd, struct file * file, int on) { struct snd_timer_user *tu; From a38c99dd155e4e943d07b068611cbec93cfa8a96 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 19 Jan 2016 21:35:15 +0000 Subject: [PATCH 201/320] BACKPORT: perf tools: Document the perf sysctls perf_event_paranoid was only documented in source code and a perf error message. Copy the documentation from the error message to Documentation/sysctl/kernel.txt. Conflicts: Documentation/sysctl/kernel.txt tools/perf/util/evsel.c Signed-off-by: Ben Hutchings Cc: Peter Zijlstra Cc: linux-doc@vger.kernel.org Link: http://lkml.kernel.org/r/20160119213515.GG2637@decadent.org.uk [ Remove reference to external Documentation file, provide info inline, as before ] Signed-off-by: Arnaldo Carvalho de Melo Bug: 29054680 Bug: 29119870 Signed-off-by: Dennis Cagle Change-Id: I13e73cfb2ad761c94762d0c8196df7725abdf5c5 (cherry picked from commit 746938f9d97d74f6c2833a0ede49506bdfcd89e4) --- Documentation/sysctl/kernel.txt | 41 +++++++++++++++++++++------------ tools/perf/util/evsel.c | 15 +++++++----- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 550ece773ff1d..942d769b78b26 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -51,8 +51,9 @@ show up in /proc/sys/kernel: - overflowuid - panic - panic_on_oops -- panic_on_unrecovered_nmi - panic_on_stackoverflow +- panic_on_unrecovered_nmi +- perf_event_paranoid - pid_max - powersave-nap [ PPC only ] - printk @@ -427,19 +428,6 @@ the recommended setting is 60. ============================================================== -panic_on_unrecovered_nmi: - -The default Linux behaviour on an NMI of either memory or unknown is -to continue operation. For many environments such as scientific -computing it is preferable that the box is taken out and the error -dealt with than an uncorrected parity/ECC error get propagated. - -A small number of systems do generate NMI's for bizarre random reasons -such as power management so the default is off. That sysctl works like -the existing panic controls already in that directory. - -============================================================== - panic_on_oops: Controls the kernel's behaviour when an oops or BUG is encountered. @@ -459,7 +447,6 @@ This file shows up if CONFIG_DEBUG_STACKOVERFLOW is enabled. 0: try to continue operation. -1: panic immediately. ============================================================== @@ -489,6 +476,30 @@ allowed to execute. ============================================================== +panic_on_unrecovered_nmi: + +The default Linux behaviour on an NMI of either memory or unknown is +to continue operation. For many environments such as scientific +computing it is preferable that the box is taken out and the error +dealt with than an uncorrected parity/ECC error get propagated. + +A small number of systems do generate NMI's for bizarre random reasons +such as power management so the default is off. That sysctl works like +the existing panic controls already in that directory. + +============================================================== + +perf_event_paranoid: + +Controls use of the performance events system by unprivileged +users (without CAP_SYS_ADMIN). The default value is 1. + + -1: Allow use of (almost) all events by all users +>=0: Disallow raw tracepoint access by users without CAP_IOC_LOCK +>=1: Disallow CPU event access by users without CAP_SYS_ADMIN +>=2: Disallow kernel profiling by users without CAP_SYS_ADMIN + +============================================================== pid_max: diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 63b6f8c8edf28..54494df33dd27 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1515,12 +1515,15 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, case EPERM: case EACCES: return scnprintf(msg, size, - "You may not have permission to collect %sstats.\n" - "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n" - " -1 - Not paranoid at all\n" - " 0 - Disallow raw tracepoint access for unpriv\n" - " 1 - Disallow cpu events for unpriv\n" - " 2 - Disallow kernel profiling for unpriv", + "You may not have permission to collect %sstats.\n\n" + "Consider tweaking /proc/sys/kernel/perf_event_paranoid,\n" + "which controls use of the performance events system by\n" + "unprivileged users (without CAP_SYS_ADMIN).\n\n" + "The default value is 1:\n\n" + " -1: Allow use of (almost) all events by all users\n" + ">= 0: Disallow raw tracepoint access by users without CAP_IOC_LOCK\n" + ">= 1: Disallow CPU event access by users without CAP_SYS_ADMIN\n" + ">= 2: Disallow kernel profiling by users without CAP_SYS_ADMIN", target->system_wide ? "system-wide " : ""); case ENOENT: return scnprintf(msg, size, "The %s event is not supported.", From 88ec9674db3bfe82228cea4b8acf79c75e85c278 Mon Sep 17 00:00:00 2001 From: Jeff Vander Stoep Date: Sun, 29 May 2016 14:22:32 -0700 Subject: [PATCH 202/320] FROMLIST: security,perf: Allow further restriction of perf_event_open When kernel.perf_event_open is set to 3 (or greater), disallow all access to performance events by users without CAP_SYS_ADMIN. Add a Kconfig symbol CONFIG_SECURITY_PERF_EVENTS_RESTRICT that makes this value the default. This is based on a similar feature in grsecurity (CONFIG_GRKERNSEC_PERF_HARDEN). This version doesn't include making the variable read-only. It also allows enabling further restriction at run-time regardless of whether the default is changed. https://lkml.org/lkml/2016/1/11/587 Conflicts: kernel/events/core.c Signed-off-by: Ben Hutchings Signed-off-by: Dennis Cagle Bug: 29054680 Bug: 29119870 Change-Id: Iff5bff4fc1042e85866df9faa01bce8d04335ab8 (cherry picked from commit f16929ac8586f37949c638c738a6f0de969ed1ea) --- Documentation/sysctl/kernel.txt | 4 +++- include/linux/perf_event.h | 5 +++++ kernel/events/core.c | 6 ++++++ security/Kconfig | 9 +++++++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 942d769b78b26..d438fd2c21a6a 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -492,12 +492,14 @@ the existing panic controls already in that directory. perf_event_paranoid: Controls use of the performance events system by unprivileged -users (without CAP_SYS_ADMIN). The default value is 1. +users (without CAP_SYS_ADMIN). The default value is 3 if +CONFIG_SECURITY_PERF_EVENTS_RESTRICT is set, or 1 otherwise. -1: Allow use of (almost) all events by all users >=0: Disallow raw tracepoint access by users without CAP_IOC_LOCK >=1: Disallow CPU event access by users without CAP_SYS_ADMIN >=2: Disallow kernel profiling by users without CAP_SYS_ADMIN +>=3: Disallow all event access by users without CAP_SYS_ADMIN ============================================================== diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 012d67f465c54..d3ac528a935bd 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -710,6 +710,11 @@ extern int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write, loff_t *ppos); +static inline bool perf_paranoid_any(void) +{ + return sysctl_perf_event_paranoid > 2; +} + static inline bool perf_paranoid_tracepoint_raw(void) { return sysctl_perf_event_paranoid > -1; diff --git a/kernel/events/core.c b/kernel/events/core.c index 3bdbe1ad5c846..5bd52c9c8c252 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -156,9 +156,12 @@ static struct srcu_struct pmus_srcu; * 0 - disallow raw tracepoint access for unpriv * 1 - disallow cpu events for unpriv * 2 - disallow kernel profiling for unpriv + * 3 - disallow all unpriv perf event use */ #ifdef CONFIG_PERF_EVENTS_USERMODE int sysctl_perf_event_paranoid __read_mostly = -1; +#elif defined CONFIG_SECURITY_PERF_EVENTS_RESTRICT +int sysctl_perf_event_paranoid __read_mostly = 3; #else int sysctl_perf_event_paranoid __read_mostly = 1; #endif @@ -6687,6 +6690,9 @@ SYSCALL_DEFINE5(perf_event_open, if (flags & ~PERF_FLAG_ALL) return -EINVAL; + if (perf_paranoid_any() && !capable(CAP_SYS_ADMIN)) + return -EACCES; + err = perf_copy_attr(attr_uptr, &attr); if (err) return err; diff --git a/security/Kconfig b/security/Kconfig index 01145437611ea..66a5f8082971a 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -18,6 +18,15 @@ config SECURITY_DMESG_RESTRICT If you are unsure how to answer this question, answer N. +config SECURITY_PERF_EVENTS_RESTRICT + bool "Restrict unprivileged use of performance events" + depends on PERF_EVENTS + help + If you say Y here, the kernel.perf_event_paranoid sysctl + will be set to 3 by default, and no unprivileged use of the + perf_event_open syscall will be permitted unless it is + changed. + config SECURITY bool "Enable different security models" depends on SYSFS From b45671e4239f6dd70c095847847aac6c4994f8a4 Mon Sep 17 00:00:00 2001 From: Dennis Cagle Date: Mon, 15 Aug 2016 14:35:18 -0700 Subject: [PATCH 203/320] msm_defconfig: Enable config for b/29119870 Restriction of kernel performance events requires a change to the defconfig. Bug: 29119870 Change-Id: Ib7e565a52446e2dcae1aa8c561d4770f2762a4d7 Signed-off-by: Dennis Cagle --- arch/arm64/configs/msm_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig index cc666ceb2bb15..4b783083369d0 100644 --- a/arch/arm64/configs/msm_defconfig +++ b/arch/arm64/configs/msm_defconfig @@ -558,6 +558,7 @@ CONFIG_DYNAMIC_DEBUG=y CONFIG_PANIC_ON_DATA_CORRUPTION=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_LSM_MMAP_MIN_ADDR=4096 CONFIG_SECURITY_SELINUX=y CONFIG_CRYPTO_NULL=y From e2a073b6cd612b29d994ac5f75fb444529ca0800 Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Tue, 3 May 2016 16:46:24 -0400 Subject: [PATCH 204/320] net: fix infoleak in rtnetlink MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The stack object “map” has a total size of 32 bytes. Its last 4 bytes are padding generated by compiler. These padding bytes are not initialized and sent out via “nla_put”. Conflicts: net/core/rtnetlink.c b/28620102 Signed-off-by: Kangjie Lu Signed-off-by: David S. Miller Signed-off-by: Dennis Cagle Git-commit: 5f8e44741f9f216e33736ea4ec65ca9ac03036e6 Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git (cherry picked from commit 5f8e44741f9f216e33736ea4ec65ca9ac03036e6) Change-Id: I41f4745f24720c7af5ab08dc4274224d7fe4dcfe --- net/core/rtnetlink.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index ae43dd807bb2b..8d2327d2cd885 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -907,6 +907,14 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, .dma = dev->dma, .port = dev->if_port, }; + memset(&map, 0, sizeof(map)); + map.mem_start = dev->mem_start; + map.mem_end = dev->mem_end; + map.base_addr = dev->base_addr; + map.irq = dev->irq; + map.dma = dev->dma; + map.port = dev->if_port; + if (nla_put(skb, IFLA_MAP, sizeof(map), &map)) goto nla_put_failure; } From 9dfaacecbcbf2647bb3cab24fc5a3645dc1994b3 Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Tue, 3 May 2016 16:44:07 -0400 Subject: [PATCH 205/320] ALSA: timer: Fix leak in SNDRV_TIMER_IOCTL_PARAMS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The stack object “tread” has a total size of 32 bytes. Its field “event” and “val” both contain 4 bytes padding. These 8 bytes padding bytes are sent to user without being initialized. b/28980557 Git-commit: cec8f96e49d9be372fdb0c3836dcf31ec71e457e Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Signed-off-by: Kangjie Lu Signed-off-by: Takashi Iwai Signed-off-by: Dennis Cagle (cherry picked from commit cec8f96e49d9be372fdb0c3836dcf31ec71e457e) Change-Id: I3b42ee147fd0883696f9783f0a38d5bef888a10a --- sound/core/timer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/core/timer.c b/sound/core/timer.c index 38a137d6b04fd..fa7824b2b5ab3 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -1683,6 +1683,7 @@ static int snd_timer_user_params(struct file *file, if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) { if (tu->tread) { struct snd_timer_tread tread; + memset(&tread, 0, sizeof(tread)); tread.event = SNDRV_TIMER_EVENT_EARLY; tread.tstamp.tv_sec = 0; tread.tstamp.tv_nsec = 0; From 39ecf6c814f4fe62409fe65aff0dc850d7f74eaa Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Tue, 3 May 2016 16:44:32 -0400 Subject: [PATCH 206/320] ALSA: timer: Fix leak in events via snd_timer_user_tinterrupt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The stack object “r1” has a total size of 32 bytes. Its field “event” and “val” both contain 4 bytes padding. These 8 bytes padding bytes are sent to user without being initialized. b/28980217 Git-commit: e4ec8cc8039a7063e24204299b462bd1383184a5 Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Signed-off-by: Kangjie Lu Signed-off-by: Takashi Iwai Signed-off-by: Dennis Cagle (cherry picked from commit e4ec8cc8039a7063e24204299b462bd1383184a5) Change-Id: I53aa15632e941199010aae670cefb65c8fd56833 --- sound/core/timer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/core/timer.c b/sound/core/timer.c index 38a137d6b04fd..411113ac2f178 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -1218,6 +1218,7 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri, } if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && tu->last_resolution != resolution) { + memset(&r1, 0, sizeof(r1)); r1.event = SNDRV_TIMER_EVENT_RESOLUTION; r1.tstamp = tstamp; r1.val = resolution; From 809b3b8f60bd117a31b662e52ccb55fb1e652919 Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Tue, 3 May 2016 16:44:20 -0400 Subject: [PATCH 207/320] ALSA: timer: Fix leak in events via snd_timer_user_ccallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The stack object “r1” has a total size of 32 bytes. Its field “event” and “val” both contain 4 bytes padding. These 8 bytes padding bytes are sent to user without being initialized. b/28980217 Git-commit: 9a47e9cff994f37f7f0dbd9ae23740d0f64f9fe6 Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Signed-off-by: Kangjie Lu Signed-off-by: Takashi Iwai Signed-off-by: Dennis Cagle (cherry picked from commit 9a47e9cff994f37f7f0dbd9ae23740d0f64f9fe6) Change-Id: I12949efac2aba669d302908704005fb94ba7efd7 --- sound/core/timer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/core/timer.c b/sound/core/timer.c index 411113ac2f178..ce2867b7f97f6 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -1184,6 +1184,7 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri, tu->tstamp = *tstamp; if ((tu->filter & (1 << event)) == 0 || !tu->tread) return; + memset(&r1, 0, sizeof(r1)); r1.event = event; r1.tstamp = *tstamp; r1.val = resolution; From 47ae528fdc240c72d52ba39adc366ef61d7c1d6e Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Tue, 16 Aug 2016 12:46:12 -0700 Subject: [PATCH 208/320] msm: crypto: Fix integer over flow check in qcrypto driver Integer overflow check is invalid when ULONG_MAX is used, as ULONG_MAX has typeof 'unsigned long', while req->assoclen, req->crytlen, and qreq.ivsize are 'unsigned int'. Make change to use UINT_MAX instead of ULONG_MAX. CRs-fixed: 1050970 Change-Id: I3782ea7ed2eaacdcad15b34e047a4699bf4f9e4f Signed-off-by: Zhen Kong --- drivers/crypto/msm/qcrypto.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c index 40a410555cd7e..2d833049ea921 100644 --- a/drivers/crypto/msm/qcrypto.c +++ b/drivers/crypto/msm/qcrypto.c @@ -1870,12 +1870,12 @@ static int _qcrypto_process_aead(struct crypto_engine *pengine, * include assoicated data, ciphering data stream, * generated MAC, and CCM padding. */ - if ((MAX_ALIGN_SIZE * 2 > ULONG_MAX - req->assoclen) || + if ((MAX_ALIGN_SIZE * 2 > UINT_MAX - req->assoclen) || ((MAX_ALIGN_SIZE * 2 + req->assoclen) > - ULONG_MAX - qreq.ivsize) || + UINT_MAX - qreq.ivsize) || ((MAX_ALIGN_SIZE * 2 + req->assoclen + qreq.ivsize) - > ULONG_MAX - req->cryptlen)) { + > UINT_MAX - req->cryptlen)) { pr_err("Integer overflow on aead req length.\n"); return -EINVAL; } From cc95d644ee8a043f2883d65dda20e16f95041de3 Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Tue, 16 Aug 2016 12:46:12 -0700 Subject: [PATCH 209/320] msm: crypto: Fix integer over flow check in qcrypto driver Integer overflow check is invalid when ULONG_MAX is used, as ULONG_MAX has typeof 'unsigned long', while req->assoclen, req->crytlen, and qreq.ivsize are 'unsigned int'. Make change to use UINT_MAX instead of ULONG_MAX. CRs-fixed: 1050970 Change-Id: I3782ea7ed2eaacdcad15b34e047a4699bf4f9e4f Signed-off-by: Zhen Kong --- drivers/crypto/msm/qcrypto.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c index 40a410555cd7e..2d833049ea921 100644 --- a/drivers/crypto/msm/qcrypto.c +++ b/drivers/crypto/msm/qcrypto.c @@ -1870,12 +1870,12 @@ static int _qcrypto_process_aead(struct crypto_engine *pengine, * include assoicated data, ciphering data stream, * generated MAC, and CCM padding. */ - if ((MAX_ALIGN_SIZE * 2 > ULONG_MAX - req->assoclen) || + if ((MAX_ALIGN_SIZE * 2 > UINT_MAX - req->assoclen) || ((MAX_ALIGN_SIZE * 2 + req->assoclen) > - ULONG_MAX - qreq.ivsize) || + UINT_MAX - qreq.ivsize) || ((MAX_ALIGN_SIZE * 2 + req->assoclen + qreq.ivsize) - > ULONG_MAX - req->cryptlen)) { + > UINT_MAX - req->cryptlen)) { pr_err("Integer overflow on aead req length.\n"); return -EINVAL; } From 5e6c4e0c52a2e353b339650c432cda52ea79640e Mon Sep 17 00:00:00 2001 From: Archana Sathyakumar Date: Wed, 29 Jun 2016 11:47:47 -0600 Subject: [PATCH 210/320] msm-core: debug: Fix the number of arguments for sysfs nodes Ptable and enable node parses the input arguments incorrectly. Parse the input message into exact number of arguments that are required for the respective nodes. CRs-fixed: 1032875 Change-Id: I881f18217b703a497efa4799288dee39a28ea8ab Signed-off-by: Archana Sathyakumar --- drivers/power/qcom/debug_core.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/power/qcom/debug_core.c b/drivers/power/qcom/debug_core.c index 51feae8849ebb..e1375ff95ee53 100644 --- a/drivers/power/qcom/debug_core.c +++ b/drivers/power/qcom/debug_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -21,6 +21,8 @@ #include #define MAX_PSTATES 20 +#define NUM_OF_PENTRY 3 /* number of variables for ptable node */ +#define NUM_OF_EENTRY 2 /* number of variables for enable node */ enum arg_offset { CPU_OFFSET, @@ -130,13 +132,15 @@ static void add_to_ptable(uint64_t *arg) node->ptr->len = node->len; } -static int split_ptable_args(char *line, uint64_t *arg) +static int split_ptable_args(char *line, uint64_t *arg, uint32_t n) { char *args; int i; int ret = 0; - for (i = 0; line; i++) { + for (i = 0; i < n; i++) { + if (!line) + break; args = strsep(&line, " "); ret = kstrtoull(args, 10, &arg[i]); } @@ -162,7 +166,7 @@ static ssize_t msm_core_ptable_write(struct file *file, goto done; } kbuf[len] = '\0'; - ret = split_ptable_args(kbuf, arg); + ret = split_ptable_args(kbuf, arg, NUM_OF_PENTRY); if (!ret) { add_to_ptable(arg); ret = len; @@ -226,7 +230,7 @@ static ssize_t msm_core_enable_write(struct file *file, goto done; } kbuf[len] = '\0'; - ret = split_ptable_args(kbuf, arg); + ret = split_ptable_args(kbuf, arg, NUM_OF_EENTRY); if (ret) goto done; cpu = arg[CPU_OFFSET]; From 973a92a5efe1bb759e1798920428891ff4158cdc Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 29 Nov 2015 19:37:57 -0800 Subject: [PATCH 211/320] ipv6: add complete rcu protection around np->opt [ Upstream commit 45f6fad84cc305103b28d73482b344d7f5b76f39 ] This patch addresses multiple problems : UDP/RAW sendmsg() need to get a stable struct ipv6_txoptions while socket is not locked : Other threads can change np->opt concurrently. Dmitry posted a syzkaller (http://github.com/google/syzkaller) program desmonstrating use-after-free. Starting with TCP/DCCP lockless listeners, tcp_v6_syn_recv_sock() and dccp_v6_request_recv_sock() also need to use RCU protection to dereference np->opt once (before calling ipv6_dup_options()) This patch adds full RCU protection to np->opt b/28746669 Reported-by: Dmitry Vyukov Signed-off-by: Eric Dumazet Acked-by: Hannes Frederic Sowa Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Dennis Cagle Git-commit: 45f6fad84cc305103b28d73482b344d7f5b76f39 Git-repo: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git (cherry picked from commit 46ddb98e2018a5a62cefa75b3c80882850c91e39) Change-Id: Ie893308ab0950d8d5494c090e04b8971940a2549 --- include/linux/ipv6.h | 2 +- include/net/ipv6.h | 20 +++++++++++++++++- net/dccp/ipv6.c | 33 ++++++++++++++++++----------- net/ipv6/af_inet6.c | 13 ++++++++---- net/ipv6/datagram.c | 4 +++- net/ipv6/exthdrs.c | 3 ++- net/ipv6/inet6_connection_sock.c | 11 +++++++--- net/ipv6/ipv6_sockglue.c | 36 +++++++++++++++++++++----------- net/ipv6/raw.c | 10 ++++++--- net/ipv6/syncookies.c | 2 +- net/ipv6/tcp_ipv6.c | 28 +++++++++++++++---------- net/ipv6/udp.c | 8 +++++-- net/l2tp/l2tp_ip6.c | 8 +++++-- 13 files changed, 124 insertions(+), 54 deletions(-) diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index a6c5471822d38..c7972a6b2205a 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -220,7 +220,7 @@ struct ipv6_pinfo { struct ipv6_ac_socklist *ipv6_ac_list; struct ipv6_fl_socklist __rcu *ipv6_fl_list; - struct ipv6_txoptions *opt; + struct ipv6_txoptions __rcu *opt; struct sk_buff *pktoptions; struct sk_buff *rxpmtu; struct { diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 67b43806b6228..d90de07e0f5d1 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -203,6 +203,7 @@ extern rwlock_t ip6_ra_lock; */ struct ipv6_txoptions { + atomic_t refcnt; /* Length of this structure */ int tot_len; @@ -215,7 +216,7 @@ struct ipv6_txoptions { struct ipv6_opt_hdr *dst0opt; struct ipv6_rt_hdr *srcrt; /* Routing Header */ struct ipv6_opt_hdr *dst1opt; - + struct rcu_head rcu; /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */ }; @@ -254,6 +255,23 @@ extern void fl6_free_socklist(struct sock *sk); extern int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen); extern int ip6_flowlabel_init(void); extern void ip6_flowlabel_cleanup(void); +static inline struct ipv6_txoptions *txopt_get(const struct ipv6_pinfo *np) +{ + struct ipv6_txoptions *opt; + + rcu_read_lock(); + opt = rcu_dereference(np->opt); + if (opt && !atomic_inc_not_zero(&opt->refcnt)) + opt = NULL; + rcu_read_unlock(); + return opt; +} + +static inline void txopt_put(struct ipv6_txoptions *opt) +{ + if (opt && atomic_dec_and_test(&opt->refcnt)) + kfree_rcu(opt, rcu); +} static inline void fl6_sock_release(struct ip6_flowlabel *fl) { diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 6cf9f7782ad42..86eedbaf037ff 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -235,7 +235,9 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req) security_req_classify_flow(req, flowi6_to_flowi(&fl6)); - final_p = fl6_update_dst(&fl6, np->opt, &final); + rcu_read_lock(); + final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final); + rcu_read_unlock(); dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); if (IS_ERR(dst)) { @@ -252,7 +254,10 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req) &ireq6->loc_addr, &ireq6->rmt_addr); fl6.daddr = ireq6->rmt_addr; - err = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); + rcu_read_lock(); + err = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt), + np->tclass); + rcu_read_unlock(); err = net_xmit_eval(err); } @@ -448,6 +453,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, { struct inet6_request_sock *ireq6 = inet6_rsk(req); struct ipv6_pinfo *newnp, *np = inet6_sk(sk); + struct ipv6_txoptions *opt; struct inet_sock *newinet; struct dccp6_sock *newdp6; struct sock *newsk; @@ -571,13 +577,15 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, * Yes, keeping reference count would be much more clever, but we make * one more one thing there: reattach optmem to newsk. */ - if (np->opt != NULL) - newnp->opt = ipv6_dup_options(newsk, np->opt); - + opt = rcu_dereference(np->opt); + if (opt) { + opt = ipv6_dup_options(newsk, opt); + RCU_INIT_POINTER(newnp->opt, opt); + } inet_csk(newsk)->icsk_ext_hdr_len = 0; - if (newnp->opt != NULL) - inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen + - newnp->opt->opt_flen); + if (opt) + inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen + + opt->opt_flen; dccp_sync_mss(newsk, dst_mtu(dst)); @@ -829,6 +837,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, struct ipv6_pinfo *np = inet6_sk(sk); struct dccp_sock *dp = dccp_sk(sk); struct in6_addr *saddr = NULL, *final_p, final; + struct ipv6_txoptions *opt; struct flowi6 fl6; struct dst_entry *dst; int addr_type; @@ -931,7 +940,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, fl6.fl6_sport = inet->inet_sport; security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); - final_p = fl6_update_dst(&fl6, np->opt, &final); + opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); + final_p = fl6_update_dst(&fl6, opt, &final); dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true); if (IS_ERR(dst)) { @@ -951,9 +961,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, __ip6_dst_store(sk, dst, NULL, NULL); icsk->icsk_ext_hdr_len = 0; - if (np->opt != NULL) - icsk->icsk_ext_hdr_len = (np->opt->opt_flen + - np->opt->opt_nflen); + if (opt) + icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen; inet->inet_dport = usin->sin6_port; diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index d29ae19ae698f..04e88b508d4e8 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -448,9 +448,11 @@ void inet6_destroy_sock(struct sock *sk) /* Free tx options */ - opt = xchg(&np->opt, NULL); - if (opt != NULL) - sock_kfree_s(sk, opt, opt->tot_len); + opt = xchg((__force struct ipv6_txoptions **)&np->opt, NULL); + if (opt) { + atomic_sub(opt->tot_len, &sk->sk_omem_alloc); + txopt_put(opt); + } } EXPORT_SYMBOL_GPL(inet6_destroy_sock); @@ -697,7 +699,10 @@ int inet6_sk_rebuild_header(struct sock *sk) fl6.flowi6_uid = sock_i_uid(sk); security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); - final_p = fl6_update_dst(&fl6, np->opt, &final); + rcu_read_lock(); + final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), + &final); + rcu_read_unlock(); dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); if (IS_ERR(dst)) { diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index e9a8ca614aaea..58e6cf78ad42c 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -169,8 +169,10 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); - opt = flowlabel ? flowlabel->opt : np->opt; + rcu_read_lock(); + opt = flowlabel ? flowlabel->opt : rcu_dereference(np->opt); final_p = fl6_update_dst(&fl6, opt, &final); + rcu_read_unlock(); dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true); err = 0; diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 8d67900aa0036..33dbd6c1a00df 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -727,6 +727,7 @@ ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt) *((char **)&opt2->dst1opt) += dif; if (opt2->srcrt) *((char **)&opt2->srcrt) += dif; + atomic_set(&opt2->refcnt, 1); } return opt2; } @@ -790,7 +791,7 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt, return ERR_PTR(-ENOBUFS); memset(opt2, 0, tot_len); - + atomic_set(&opt2->refcnt, 1); opt2->tot_len = tot_len; p = (char *)(opt2 + 1); diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 329985bb067b7..f92676cb879f5 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -78,7 +78,9 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk, memset(fl6, 0, sizeof(*fl6)); fl6->flowi6_proto = IPPROTO_TCP; fl6->daddr = treq->rmt_addr; - final_p = fl6_update_dst(fl6, np->opt, &final); + rcu_read_lock(); + final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); + rcu_read_unlock(); fl6->saddr = treq->loc_addr; fl6->flowi6_oif = treq->iif; fl6->flowi6_mark = inet_rsk(req)->ir_mark; @@ -214,7 +216,9 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk, fl6->fl6_dport = inet->inet_dport; security_sk_classify_flow(sk, flowi6_to_flowi(fl6)); - final_p = fl6_update_dst(fl6, np->opt, &final); + rcu_read_lock(); + final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); + rcu_read_unlock(); dst = __inet6_csk_dst_check(sk, np->dst_cookie); if (!dst) { @@ -248,7 +252,8 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) /* Restore final destination back after routing done */ fl6.daddr = np->daddr; - res = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); + res = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt), + np->tclass); rcu_read_unlock(); return res; } diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index d1e2e8ef29c54..f4d2412d9c608 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -110,10 +110,12 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk, icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen; icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie); } - opt = xchg(&inet6_sk(sk)->opt, opt); + opt = xchg((__force struct ipv6_txoptions **)&inet6_sk(sk)->opt, + opt); } else { spin_lock(&sk->sk_dst_lock); - opt = xchg(&inet6_sk(sk)->opt, opt); + opt = xchg((__force struct ipv6_txoptions **)&inet6_sk(sk)->opt, + opt); spin_unlock(&sk->sk_dst_lock); } sk_dst_reset(sk); @@ -213,9 +215,12 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, sk->sk_socket->ops = &inet_dgram_ops; sk->sk_family = PF_INET; } - opt = xchg(&np->opt, NULL); - if (opt) - sock_kfree_s(sk, opt, opt->tot_len); + opt = xchg((__force struct ipv6_txoptions **)&np->opt, + NULL); + if (opt) { + atomic_sub(opt->tot_len, &sk->sk_omem_alloc); + txopt_put(opt); + } pktopt = xchg(&np->pktoptions, NULL); kfree_skb(pktopt); @@ -385,7 +390,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, if (optname != IPV6_RTHDR && !ns_capable(net->user_ns, CAP_NET_RAW)) break; - opt = ipv6_renew_options(sk, np->opt, optname, + opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); + opt = ipv6_renew_options(sk, opt, optname, (struct ipv6_opt_hdr __user *)optval, optlen); if (IS_ERR(opt)) { @@ -414,8 +420,10 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, retv = 0; opt = ipv6_update_options(sk, opt); sticky_done: - if (opt) - sock_kfree_s(sk, opt, opt->tot_len); + if (opt) { + atomic_sub(opt->tot_len, &sk->sk_omem_alloc); + txopt_put(opt); + } break; } @@ -468,6 +476,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, break; memset(opt, 0, sizeof(*opt)); + atomic_set(&opt->refcnt, 1); opt->tot_len = sizeof(*opt) + optlen; retv = -EFAULT; if (copy_from_user(opt+1, optval, optlen)) @@ -484,8 +493,10 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, retv = 0; opt = ipv6_update_options(sk, opt); done: - if (opt) - sock_kfree_s(sk, opt, opt->tot_len); + if (opt) { + atomic_sub(opt->tot_len, &sk->sk_omem_alloc); + txopt_put(opt); + } break; } case IPV6_UNICAST_HOPS: @@ -1085,10 +1096,11 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, case IPV6_RTHDR: case IPV6_DSTOPTS: { + struct ipv6_txoptions *opt; lock_sock(sk); - len = ipv6_getsockopt_sticky(sk, np->opt, - optname, optval, len); + opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); + len = ipv6_getsockopt_sticky(sk, opt, optname, optval, len); release_sock(sk); /* check if ipv6_getsockopt_sticky() returns err code */ if (len < 0) diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index a9db8d252c9b4..27e974fdf2b76 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -726,6 +726,7 @@ static int rawv6_probe_proto_opt(struct flowi6 *fl6, struct msghdr *msg) static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t len) { + struct ipv6_txoptions *opt_to_free = NULL; struct ipv6_txoptions opt_space; struct sockaddr_in6 * sin6 = (struct sockaddr_in6 *) msg->msg_name; struct in6_addr *daddr, *final_p, final; @@ -833,8 +834,10 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, if (!(opt->opt_nflen|opt->opt_flen)) opt = NULL; } - if (opt == NULL) - opt = np->opt; + if (!opt) { + opt = txopt_get(np); + opt_to_free = opt; + } if (flowlabel) opt = fl6_merge_options(&opt_space, flowlabel, opt); opt = ipv6_fixup_options(&opt_space, opt); @@ -901,7 +904,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, dst_release(dst); out: fl6_sock_release(flowlabel); - return err<0?err:len; + txopt_put(opt_to_free); + return err < 0 ? err : len; do_confirm: dst_confirm(dst); if (!(msg->msg_flags & MSG_PROBE) || len) diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index ba8622daffd7e..701d0656a4021 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c @@ -237,7 +237,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_proto = IPPROTO_TCP; fl6.daddr = ireq6->rmt_addr; - final_p = fl6_update_dst(&fl6, np->opt, &final); + final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final); fl6.saddr = ireq6->loc_addr; fl6.flowi6_oif = sk->sk_bound_dev_if; fl6.flowi6_mark = ireq->ir_mark; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 9c2f2b9c17e6b..a522724aa890d 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -133,6 +133,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, struct ipv6_pinfo *np = inet6_sk(sk); struct tcp_sock *tp = tcp_sk(sk); struct in6_addr *saddr = NULL, *final_p, final; + struct ipv6_txoptions *opt; struct rt6_info *rt; struct flowi6 fl6; struct dst_entry *dst; @@ -254,7 +255,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, fl6.fl6_sport = inet->inet_sport; fl6.flowi6_uid = sock_i_uid(sk); - final_p = fl6_update_dst(&fl6, np->opt, &final); + opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); + final_p = fl6_update_dst(&fl6, opt, &final); security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); @@ -283,9 +285,9 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, tcp_fetch_timewait_stamp(sk, dst); icsk->icsk_ext_hdr_len = 0; - if (np->opt) - icsk->icsk_ext_hdr_len = (np->opt->opt_flen + - np->opt->opt_nflen); + if (opt) + icsk->icsk_ext_hdr_len = opt->opt_flen + + opt->opt_nflen; tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); @@ -481,7 +483,8 @@ static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst, fl6->daddr = treq->rmt_addr; skb_set_queue_mapping(skb, queue_mapping); - err = ip6_xmit(sk, skb, fl6, np->opt, np->tclass); + err = ip6_xmit(sk, skb, fl6, rcu_dereference(np->opt), + np->tclass); err = net_xmit_eval(err); } @@ -1090,6 +1093,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, struct inet6_request_sock *treq; struct ipv6_pinfo *newnp, *np = inet6_sk(sk); struct tcp6_sock *newtcp6sk; + struct ipv6_txoptions *opt; struct inet_sock *newinet; struct tcp_sock *newtp; struct sock *newsk; @@ -1223,13 +1227,15 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, but we make one more one thing there: reattach optmem to newsk. */ - if (np->opt) - newnp->opt = ipv6_dup_options(newsk, np->opt); - + opt = rcu_dereference(np->opt); + if (opt) { + opt = ipv6_dup_options(newsk, opt); + RCU_INIT_POINTER(newnp->opt, opt); + } inet_csk(newsk)->icsk_ext_hdr_len = 0; - if (newnp->opt) - inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen + - newnp->opt->opt_flen); + if (opt) + inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen + + opt->opt_flen; tcp_mtup_init(newsk); tcp_sync_mss(newsk, dst_mtu(dst)); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index c23a919331c5a..b01d23d2ec8ae 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1017,6 +1017,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) msg->msg_name; struct in6_addr *daddr, *final_p, final; struct ipv6_txoptions *opt = NULL; + struct ipv6_txoptions *opt_to_free = NULL; struct ip6_flowlabel *flowlabel = NULL; struct flowi6 fl6; struct dst_entry *dst; @@ -1171,8 +1172,10 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, opt = NULL; connected = 0; } - if (opt == NULL) - opt = np->opt; + if (!opt) { + opt = txopt_get(np); + opt_to_free = opt; + } if (flowlabel) opt = fl6_merge_options(&opt_space, flowlabel, opt); opt = ipv6_fixup_options(&opt_space, opt); @@ -1273,6 +1276,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, out: dst_release(dst); fl6_sock_release(flowlabel); + txopt_put(opt_to_free); if (!err) return len; /* diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index e6e8408c9e367..3b61ddd6e4a67 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c @@ -485,6 +485,7 @@ static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk, (struct sockaddr_l2tpip6 *) msg->msg_name; struct in6_addr *daddr, *final_p, final; struct ipv6_pinfo *np = inet6_sk(sk); + struct ipv6_txoptions *opt_to_free = NULL; struct ipv6_txoptions *opt = NULL; struct ip6_flowlabel *flowlabel = NULL; struct dst_entry *dst = NULL; @@ -575,8 +576,10 @@ static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk, opt = NULL; } - if (opt == NULL) - opt = np->opt; + if (!opt) { + opt = txopt_get(np); + opt_to_free = opt; + } if (flowlabel) opt = fl6_merge_options(&opt_space, flowlabel, opt); opt = ipv6_fixup_options(&opt_space, opt); @@ -637,6 +640,7 @@ static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk, dst_release(dst); out: fl6_sock_release(flowlabel); + txopt_put(opt_to_free); return err < 0 ? err : len; From 2a2852d920eb087f3cec2664970cccabeef373ac Mon Sep 17 00:00:00 2001 From: Ravinder Konka Date: Wed, 17 Jun 2015 01:37:32 +0530 Subject: [PATCH 212/320] defconfig: msm: Enable kernel configs for vpn support Enabling INET_IPCOMP and NET_KEY configs in msm_defconfig (8952 64 bit) and msm8916_defconfig (8952 32 bit defconfig) for supporting VPN in 8952 Change-Id: I00e400c2729fea2b7fa4a32ceeb509bc5287b638 CRs-Fixed: 855124 Signed-off-by: Ravinder Konka --- arch/arm/configs/msm8916-perf_defconfig | 2 ++ arch/arm/configs/msm8916_defconfig | 2 ++ arch/arm64/configs/msm-perf_defconfig | 2 ++ arch/arm64/configs/msm_defconfig | 2 ++ 4 files changed, 8 insertions(+) diff --git a/arch/arm/configs/msm8916-perf_defconfig b/arch/arm/configs/msm8916-perf_defconfig index cd18ab7677e80..e477fbeb816a0 100644 --- a/arch/arm/configs/msm8916-perf_defconfig +++ b/arch/arm/configs/msm8916-perf_defconfig @@ -82,6 +82,7 @@ CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=y CONFIG_INET=y +CONFIG_INET_IPCOMP=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y @@ -122,6 +123,7 @@ CONFIG_NF_CONNTRACK_SANE=y CONFIG_NF_CONNTRACK_SIP=y CONFIG_NF_CONNTRACK_TFTP=y CONFIG_NF_CT_NETLINK=y +CONFIG_NET_KEY=y CONFIG_NETFILTER_TPROXY=y CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y CONFIG_NETFILTER_XT_TARGET_CONNMARK=y diff --git a/arch/arm/configs/msm8916_defconfig b/arch/arm/configs/msm8916_defconfig index 0609e27fe5a0e..e4b32ed8b58c3 100755 --- a/arch/arm/configs/msm8916_defconfig +++ b/arch/arm/configs/msm8916_defconfig @@ -85,6 +85,7 @@ CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=y CONFIG_INET=y +CONFIG_INET_IPCOMP=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y @@ -125,6 +126,7 @@ CONFIG_NF_CONNTRACK_SANE=y CONFIG_NF_CONNTRACK_SIP=y CONFIG_NF_CONNTRACK_TFTP=y CONFIG_NF_CT_NETLINK=y +CONFIG_NET_KEY=y CONFIG_NETFILTER_TPROXY=y CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y CONFIG_NETFILTER_XT_TARGET_CONNMARK=y diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig index 6d371dc25176a..5b6e5bc61bc6e 100644 --- a/arch/arm64/configs/msm-perf_defconfig +++ b/arch/arm64/configs/msm-perf_defconfig @@ -64,6 +64,7 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y CONFIG_INET=y +CONFIG_INET_IPCOMP=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y @@ -173,6 +174,7 @@ CONFIG_L2TP_V3=y CONFIG_L2TP_IP=y CONFIG_L2TP_ETH=y CONFIG_BRIDGE=y +CONFIG_NET_KEY=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_HTB=y CONFIG_NET_SCH_PRIO=y diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig index cc666ceb2bb15..2293060a636b3 100644 --- a/arch/arm64/configs/msm_defconfig +++ b/arch/arm64/configs/msm_defconfig @@ -68,6 +68,7 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y CONFIG_INET=y +CONFIG_INET_IPCOMP=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y @@ -177,6 +178,7 @@ CONFIG_L2TP_V3=y CONFIG_L2TP_IP=y CONFIG_L2TP_ETH=y CONFIG_BRIDGE=y +CONFIG_NET_KEY=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_HTB=y CONFIG_NET_SCH_PRIO=y From 56071dc87ffc02ebfe2c55b6cbc98fd525248a4a Mon Sep 17 00:00:00 2001 From: Karthikeyan Ramasubramanian Date: Tue, 16 Aug 2016 11:24:00 -0600 Subject: [PATCH 213/320] soc: qcom: smp2p: Fix kernel address leak Change format string to %pK instead of %p in the debug statements. This change fixes kernel address leaks from the usage of %p. CRs-Fixed: 1052825 Change-Id: Ib95f691919a2977f5436cd4c6ac4a002d70dd729 Signed-off-by: Chris Lew Signed-off-by: Karthikeyan Ramasubramanian --- drivers/gpio/gpio-msm-smp2p.c | 2 +- drivers/soc/qcom/smp2p.c | 6 +++--- drivers/soc/qcom/smp2p_debug.c | 4 ++-- drivers/soc/qcom/smp2p_test_common.h | 5 +++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpio/gpio-msm-smp2p.c b/drivers/gpio/gpio-msm-smp2p.c index 57e21975e9801..1a83d8ad45733 100644 --- a/drivers/gpio/gpio-msm-smp2p.c +++ b/drivers/gpio/gpio-msm-smp2p.c @@ -338,7 +338,7 @@ static int smp2p_irq_map(struct irq_domain *domain_ptr, unsigned int virq, chip = domain_ptr->host_data; if (!chip) { - SMP2P_ERR("%s: invalid domain ptr %p\n", __func__, domain_ptr); + SMP2P_ERR("%s: invalid domain ptr\n", __func__); return -ENODEV; } diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c index 1910104ba19d4..7db27dcd4dd83 100644 --- a/drivers/soc/qcom/smp2p.c +++ b/drivers/soc/qcom/smp2p.c @@ -1,6 +1,6 @@ /* drivers/soc/qcom/smp2p.c * - * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -513,8 +513,8 @@ static void smp2p_find_entry_v1(struct smp2p_smem __iomem *item, char entry_name[SMP2P_MAX_ENTRY_NAME]; if (!item || !name || !entry_ptr) { - SMP2P_ERR("%s: invalid arguments %p, %p, %p\n", - __func__, item, name, entry_ptr); + SMP2P_ERR("%s: invalid arguments %d %d %d\n", + __func__, !item, !name, !entry_ptr); return; } diff --git a/drivers/soc/qcom/smp2p_debug.c b/drivers/soc/qcom/smp2p_debug.c index 4deb05a081391..8d98d07c1adf4 100644 --- a/drivers/soc/qcom/smp2p_debug.c +++ b/drivers/soc/qcom/smp2p_debug.c @@ -1,6 +1,6 @@ /* drivers/soc/qcom/smp2p_debug.c * - * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -41,7 +41,7 @@ static void smp2p_int_stats(struct seq_file *s) pid != SMP2P_REMOTE_MOCK_PROC) continue; - seq_printf(s, "| %5s (%d) | %11u | %10u | %10u | %p | %08x |\n", + seq_printf(s, "| %5s (%d) | %11u | %10u | %10u | %pK | %08x |\n", int_cfg[pid].name, pid, int_cfg[pid].in_int_id, int_cfg[pid].in_interrupt_count, diff --git a/drivers/soc/qcom/smp2p_test_common.h b/drivers/soc/qcom/smp2p_test_common.h index 8fe0e186061bc..888de40609ece 100644 --- a/drivers/soc/qcom/smp2p_test_common.h +++ b/drivers/soc/qcom/smp2p_test_common.h @@ -1,6 +1,6 @@ /* drivers/soc/qcom/smp2p_test_common.h * - * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -49,7 +49,8 @@ void *a_tmp = (a); \ void *b_tmp = (b); \ if (!((a_tmp)cmp(b_tmp))) { \ - seq_printf(s, "%s:%d Fail: " #a "(%p) " #cmp " " #b "(%p)\n", \ + seq_printf(s, "%s:%d Fail: " #a "(%pK) " #cmp \ + " " #b "(%pK)\n", \ __func__, __LINE__, \ a_tmp, b_tmp); \ failed = 1; \ From 82bc8704872be40f808465b4460bcc61d85f82c8 Mon Sep 17 00:00:00 2001 From: Karthikeyan Ramasubramanian Date: Tue, 16 Aug 2016 11:24:00 -0600 Subject: [PATCH 214/320] soc: qcom: smp2p: Fix kernel address leak Change format string to %pK instead of %p in the debug statements. This change fixes kernel address leaks from the usage of %p. CRs-Fixed: 1052825 Change-Id: Ib95f691919a2977f5436cd4c6ac4a002d70dd729 Signed-off-by: Chris Lew Signed-off-by: Karthikeyan Ramasubramanian --- drivers/gpio/gpio-msm-smp2p.c | 2 +- drivers/soc/qcom/smp2p.c | 6 +++--- drivers/soc/qcom/smp2p_debug.c | 4 ++-- drivers/soc/qcom/smp2p_test_common.h | 5 +++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpio/gpio-msm-smp2p.c b/drivers/gpio/gpio-msm-smp2p.c index 57e21975e9801..1a83d8ad45733 100644 --- a/drivers/gpio/gpio-msm-smp2p.c +++ b/drivers/gpio/gpio-msm-smp2p.c @@ -338,7 +338,7 @@ static int smp2p_irq_map(struct irq_domain *domain_ptr, unsigned int virq, chip = domain_ptr->host_data; if (!chip) { - SMP2P_ERR("%s: invalid domain ptr %p\n", __func__, domain_ptr); + SMP2P_ERR("%s: invalid domain ptr\n", __func__); return -ENODEV; } diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c index 1910104ba19d4..7db27dcd4dd83 100644 --- a/drivers/soc/qcom/smp2p.c +++ b/drivers/soc/qcom/smp2p.c @@ -1,6 +1,6 @@ /* drivers/soc/qcom/smp2p.c * - * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -513,8 +513,8 @@ static void smp2p_find_entry_v1(struct smp2p_smem __iomem *item, char entry_name[SMP2P_MAX_ENTRY_NAME]; if (!item || !name || !entry_ptr) { - SMP2P_ERR("%s: invalid arguments %p, %p, %p\n", - __func__, item, name, entry_ptr); + SMP2P_ERR("%s: invalid arguments %d %d %d\n", + __func__, !item, !name, !entry_ptr); return; } diff --git a/drivers/soc/qcom/smp2p_debug.c b/drivers/soc/qcom/smp2p_debug.c index 4deb05a081391..8d98d07c1adf4 100644 --- a/drivers/soc/qcom/smp2p_debug.c +++ b/drivers/soc/qcom/smp2p_debug.c @@ -1,6 +1,6 @@ /* drivers/soc/qcom/smp2p_debug.c * - * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -41,7 +41,7 @@ static void smp2p_int_stats(struct seq_file *s) pid != SMP2P_REMOTE_MOCK_PROC) continue; - seq_printf(s, "| %5s (%d) | %11u | %10u | %10u | %p | %08x |\n", + seq_printf(s, "| %5s (%d) | %11u | %10u | %10u | %pK | %08x |\n", int_cfg[pid].name, pid, int_cfg[pid].in_int_id, int_cfg[pid].in_interrupt_count, diff --git a/drivers/soc/qcom/smp2p_test_common.h b/drivers/soc/qcom/smp2p_test_common.h index 8fe0e186061bc..888de40609ece 100644 --- a/drivers/soc/qcom/smp2p_test_common.h +++ b/drivers/soc/qcom/smp2p_test_common.h @@ -1,6 +1,6 @@ /* drivers/soc/qcom/smp2p_test_common.h * - * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -49,7 +49,8 @@ void *a_tmp = (a); \ void *b_tmp = (b); \ if (!((a_tmp)cmp(b_tmp))) { \ - seq_printf(s, "%s:%d Fail: " #a "(%p) " #cmp " " #b "(%p)\n", \ + seq_printf(s, "%s:%d Fail: " #a "(%pK) " #cmp \ + " " #b "(%pK)\n", \ __func__, __LINE__, \ a_tmp, b_tmp); \ failed = 1; \ From cb53a1ff2b6bcfb7cde80257c6830519b6b824de Mon Sep 17 00:00:00 2001 From: Shubhraprakash Das Date: Mon, 10 Nov 2014 15:12:53 -0800 Subject: [PATCH 215/320] iommu: msm: Ensure secure buffer mapping at 1MB Secure buffer mappings should be 1MB aligned. Add checks for this. CRs-Fixed: 755014 Change-Id: I377e7beaeb21cce9a828590bab20cc1cf41fd8c6 Signed-off-by: Shubhraprakash Das --- drivers/iommu/msm_iommu_sec.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/msm_iommu_sec.c b/drivers/iommu/msm_iommu_sec.c index 9d09f27736d5b..b0ec8c6dfa66d 100644 --- a/drivers/iommu/msm_iommu_sec.c +++ b/drivers/iommu/msm_iommu_sec.c @@ -517,6 +517,9 @@ static int msm_iommu_sec_ptbl_map(struct msm_iommu_drvdata *iommu_drvdata, phys_addr_t flush_pa; int ret = 0; + if (!IS_ALIGNED(va, SZ_1M) || !IS_ALIGNED(len, SZ_1M) || + !IS_ALIGNED(pa, SZ_1M)) + return -EINVAL; map.plist.list = virt_to_phys(&pa); map.plist.list_size = 1; map.plist.size = len; @@ -568,22 +571,36 @@ static int msm_iommu_sec_ptbl_map_range(struct msm_iommu_drvdata *iommu_drvdata, unsigned int offset = 0, chunk_offset = 0; int ret; + if (!IS_ALIGNED(va, SZ_1M) || !IS_ALIGNED(len, SZ_1M)) + return -EINVAL; + map.info.id = iommu_drvdata->sec_id; map.info.ctx_id = ctx_drvdata->num; map.info.va = va; map.info.size = len; if (sg->length == len) { + /* + * physical address for secure mapping needs + * to be 1MB aligned + */ pa = get_phys_addr(sg); + if (!IS_ALIGNED(pa, SZ_1M)) + return -EINVAL; map.plist.list = virt_to_phys(&pa); map.plist.list_size = 1; map.plist.size = len; flush_va = &pa; } else { sgiter = sg; + if (!IS_ALIGNED(sgiter->length, SZ_1M)) + return -EINVAL; cnt = sg->length / SZ_1M; - while ((sgiter = sg_next(sgiter))) + while ((sgiter = sg_next(sgiter))) { + if (!IS_ALIGNED(sgiter->length, SZ_1M)) + return -EINVAL; cnt += sgiter->length / SZ_1M; + } pa_list = kmalloc(cnt * sizeof(*pa_list), GFP_KERNEL); if (!pa_list) @@ -592,6 +609,10 @@ static int msm_iommu_sec_ptbl_map_range(struct msm_iommu_drvdata *iommu_drvdata, sgiter = sg; cnt = 0; pa = get_phys_addr(sgiter); + if (!IS_ALIGNED(pa, SZ_1M)) { + kfree(pa_list); + return -EINVAL; + } while (offset < len) { pa += chunk_offset; pa_list[cnt] = pa; @@ -638,6 +659,8 @@ static int msm_iommu_sec_ptbl_unmap(struct msm_iommu_drvdata *iommu_drvdata, int ret, scm_ret; struct scm_desc desc = {0}; + if (!IS_ALIGNED(va, SZ_1M) || !IS_ALIGNED(len, SZ_1M)) + return -EINVAL; desc.args[0] = unmap.info.id = iommu_drvdata->sec_id; desc.args[1] = unmap.info.ctx_id = ctx_drvdata->num; desc.args[2] = unmap.info.va = va; @@ -878,6 +901,9 @@ static int msm_iommu_unmap_range(struct iommu_domain *domain, unsigned int va, struct msm_iommu_ctx_drvdata *ctx_drvdata; int ret = -EINVAL; + if (!IS_ALIGNED(va, SZ_1M) || !IS_ALIGNED(len, SZ_1M)) + return -EINVAL; + iommu_access_ops->iommu_lock_acquire(0); ret = get_drvdata(domain, &iommu_drvdata, &ctx_drvdata); From a82a94adc9426991e72c83c909aa48111cf8c78d Mon Sep 17 00:00:00 2001 From: chenx Date: Tue, 16 Aug 2016 10:11:35 +0800 Subject: [PATCH 216/320] Sensor driver of bmi160 and mmc3x30 Signed-off-by: chenx (cherry picked from commit 4a06814b2801814a539c6c334505f5b43beed981) Change-Id: Ifd7076387bd367011b2cd22b0459cadf2cbbe878 Signed-off-by: Shaoqing Liu --- drivers/input/misc/bmi160.c | 18752 +++++++++++++++++++++++++++ drivers/input/misc/bmi160.h | 11814 +++++++++++++++++ drivers/input/misc/bmi160_driver.c | 4843 +++++++ drivers/input/misc/bmi160_driver.h | 390 + drivers/input/misc/bmi160_i2c.c | 365 + drivers/input/misc/mmc3x30.c | 1268 ++ include/linux/i2c/mmc3x30.h | 143 + 7 files changed, 37575 insertions(+) create mode 100755 drivers/input/misc/bmi160.c create mode 100755 drivers/input/misc/bmi160.h create mode 100755 drivers/input/misc/bmi160_driver.c create mode 100755 drivers/input/misc/bmi160_driver.h create mode 100755 drivers/input/misc/bmi160_i2c.c create mode 100755 drivers/input/misc/mmc3x30.c create mode 100755 include/linux/i2c/mmc3x30.h diff --git a/drivers/input/misc/bmi160.c b/drivers/input/misc/bmi160.c new file mode 100755 index 0000000000000..286b975a2a1d2 --- /dev/null +++ b/drivers/input/misc/bmi160.c @@ -0,0 +1,18752 @@ +/* +* @section LICENSE + * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved + * + * This software program is licensed subject to the GNU General + * Public License (GPL).Version 2,June 1991, + * available at http://www.fsf.org/copyleft/gpl.html +* +* @filename bmi160.c +* @Date: 2015/04/02 +* @id "2e89046" +* @Revision: 2.0.9 $ +* +* Usage: Sensor Driver for BMI160 sensor +* +**************************************************************************** +* \section Disclaimer +* +* Common: +* Bosch Sensortec products are developed for the consumer goods industry. +* They may only be used within the parameters of the respective valid +* product data sheet. Bosch Sensortec products are provided with the +* express understanding that there is no warranty of fitness for a +* particular purpose.They are not fit for use in life-sustaining, +* safety or security sensitive systems or any system or device +* that may lead to bodily harm or property damage if the system +* or device malfunctions. In addition,Bosch Sensortec products are +* not fit for use in products which interact with motor vehicle systems. +* The resale and or use of products are at the purchasers own risk and +* his own responsibility. The examination of fitness for the intended use +* is the sole responsibility of the Purchaser. +* +* The purchaser shall indemnify Bosch Sensortec from all third party +* claims, including any claims for incidental, or consequential damages, +* arising from any product use not covered by the parameters of +* the respective valid product data sheet or not approved by +* Bosch Sensortec and reimburse Bosch Sensortec for all costs in +* connection with such claims. +* +* The purchaser must monitor the market for the purchased products, +* particularly with regard to product safety and inform Bosch Sensortec +* without delay of all security relevant incidents. +* +* Engineering Samples are marked with an asterisk (*) or (e). +* Samples may vary from the valid technical specifications of the product +* series. They are therefore not intended or fit for resale to third +* parties or for use in end products. Their sole purpose is internal +* client testing. The testing of an engineering sample may in no way +* replace the testing of a product series. Bosch Sensortec assumes +* no liability for the use of engineering samples. +* By accepting the engineering samples, the Purchaser agrees to indemnify +* Bosch Sensortec from all claims arising from the use of engineering +* samples. +* +* Special: +* This software module (hereinafter called "Software") and any information +* on application-sheets (hereinafter called "Information") is provided +* free of charge for the sole purpose to support your application work. +* The Software and Information is subject to the following +* terms and conditions: +* +* The Software is specifically designed for the exclusive use for +* Bosch Sensortec products by personnel who have special experience +* and training. Do not use this Software if you do not have the +* proper experience or training. +* +* This Software package is provided `` as is `` and without any expressed +* or implied warranties,including without limitation, the implied warranties +* of merchantability and fitness for a particular purpose. +* +* Bosch Sensortec and their representatives and agents deny any liability +* for the functional impairment +* of this Software in terms of fitness, performance and safety. +* Bosch Sensortec and their representatives and agents shall not be liable +* for any direct or indirect damages or injury, except as +* otherwise stipulated in mandatory applicable law. +* +* The Information provided is believed to be accurate and reliable. +* Bosch Sensortec assumes no responsibility for the consequences of use +* of such Information nor for any infringement of patents or +* other rights of third parties which may result from its use. +* No license is granted by implication or otherwise under any patent or +* patent rights of Bosch. Specifications mentioned in the Information are +* subject to change without notice. +**************************************************************************/ +/*! file + brief */ +#include "bmi160.h" +#include + +/* user defined code to be added here ... */ +struct bmi160_t *p_bmi160; +/* used for reading the mag trim values for compensation*/ +struct trim_data_t mag_trim; +/* the following variable used for avoiding the selecting of auto mode +when it is running in the manual mode of BMM150 mag interface*/ +u8 V_bmm150_maual_auto_condition_u8 = BMI160_INIT_VALUE; +/* used for reading the AKM compensating data */ +struct bst_akm_sensitivity_data_t akm_asa_data; +/* Assign the fifo time */ +u32 V_fifo_time_U32 = BMI160_INIT_VALUE; + +/* FIFO data read for 1024 bytes of data */ +u8 v_fifo_data_u8[FIFO_FRAME] = {BMI160_INIT_VALUE}; +/* YAMAHA-YAS532*/ +/* value of coeff*/ +static const int yas532_version_ac_coef[] = {YAS532_VERSION_AC_COEF_X, +YAS532_VERSION_AC_COEF_Y1, YAS532_VERSION_AC_COEF_Y2}; +/* used for reading the yas532 calibration data*/ +struct yas532_t yas532_data; +/* used for reading the yas537 calibration data*/ +struct yas537_t yas537_data; +/*! + * @brief + * This function is used for initialize + * bus read and bus write functions + * assign the chip id and device address + * chip id is read in the register 0x00 bit from 0 to 7 + * + * @param bmi160 : structure pointer + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * @note + * While changing the parameter of the bmi160_t + * consider the following point: + * Changing the reference value of the parameter + * will changes the local copy or local reference + * make sure your changes will not + * affect the reference value of the parameter + * (Better case don't change the reference value of the parameter) + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_init(struct bmi160_t *bmi160) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + u8 v_pmu_data_u8 = BMI160_INIT_VALUE; + /* assign bmi160 ptr */ + p_bmi160 = bmi160; + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_CHIP_ID__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + /* read Chip Id */ + p_bmi160->chip_id = v_data_u8; + /* To avoid gyro wakeup it is required to write 0x00 to 0x6C*/ + com_rslt += bmi160_write_reg(BMI160_USER_PMU_TRIGGER_ADDR, + &v_pmu_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + return com_rslt; +} +/*! + * @brief + * This API write the data to + * the given register + * + * + * @param v_addr_u8 -> Address of the register + * @param v_data_u8 -> The data from the register + * @param v_len_u8 -> no of bytes to read + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_write_reg(u8 v_addr_u8, +u8 *v_data_u8, u8 v_len_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write data from register*/ + com_rslt = + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->dev_addr, + v_addr_u8, v_data_u8, v_len_u8); + } + return com_rslt; +} +/*! + * @brief + * This API reads the data from + * the given register + * + * + * @param v_addr_u8 -> Address of the register + * @param v_data_u8 -> The data from the register + * @param v_len_u8 -> no of bytes to read + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_reg(u8 v_addr_u8, +u8 *v_data_u8, u8 v_len_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* Read data from register*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + v_addr_u8, v_data_u8, v_len_u8); + } + return com_rslt; +} +/*! + * @brief This API used to reads the fatal error + * from the Register 0x02 bit 0 + * This flag will be reset only by power-on-reset and soft reset + * + * + * @param v_fatal_err_u8 : The status of fatal error + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fatal_err(u8 +*v_fatal_err_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* reading the fatal error status*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FATAL_ERR__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_fatal_err_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_FATAL_ERR); + } + return com_rslt; +} +/*! + * @brief This API used to read the error code + * from register 0x02 bit 1 to 4 + * + * + * @param v_err_code_u8 : The status of error codes + * error_code | description + * ------------|--------------- + * 0x00 |no error + * 0x01 |ACC_CONF error (accel ODR and bandwidth not compatible) + * 0x02 |GYR_CONF error (Gyroscope ODR and bandwidth not compatible) + * 0x03 |Under sampling mode and interrupt uses pre filtered data + * 0x04 |reserved + * 0x05 |Selected trigger-readout offset in + * - |MAG_IF greater than selected ODR + * 0x06 |FIFO configuration error for header less mode + * 0x07 |Under sampling mode and pre filtered data as FIFO source + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_err_code(u8 +*v_err_code_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_ERR_CODE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_err_code_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_ERR_CODE); + } + return com_rslt; +} +/*! + * @brief This API Reads the i2c error code from the + * Register 0x02 bit 5. + * This error occurred in I2C master detected + * + * @param v_i2c_err_code_u8 : The status of i2c fail error + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_i2c_fail_err(u8 +*v_i2c_err_code_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_I2C_FAIL_ERR__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_i2c_err_code_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_I2C_FAIL_ERR); + } + return com_rslt; +} + /*! + * @brief This API Reads the dropped command error + * from the register 0x02 bit 6 + * + * + * @param v_drop_cmd_err_u8 : The status of drop command error + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_drop_cmd_err(u8 +*v_drop_cmd_err_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_DROP_CMD_ERR__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_drop_cmd_err_u8 = BMI160_GET_BITSLICE( + v_data_u8, + BMI160_USER_DROP_CMD_ERR); + } + return com_rslt; +} +/*! + * @brief This API reads the magnetometer data ready + * interrupt not active. + * It reads from the error register 0x0x2 bit 7 + * + * + * + * + * @param v_mag_data_rdy_err_u8 : The status of mag data ready interrupt + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_dada_rdy_err( +u8 *v_mag_data_rdy_err_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_MAG_DADA_RDY_ERR__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_mag_data_rdy_err_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_MAG_DADA_RDY_ERR); + } + return com_rslt; +} +/*! + * @brief This API reads the error status + * from the error register 0x02 bit 0 to 7 + * + * @param v_mag_data_rdy_err_u8 : The status of mag data ready interrupt + * @param v_fatal_er_u8r : The status of fatal error + * @param v_err_code_u8 : The status of error code + * @param v_i2c_fail_err_u8 : The status of I2C fail error + * @param v_drop_cmd_err_u8 : The status of drop command error + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_error_status(u8 *v_fatal_er_u8r, +u8 *v_err_code_u8, u8 *v_i2c_fail_err_u8, +u8 *v_drop_cmd_err_u8, u8 *v_mag_data_rdy_err_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the error codes*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_ERR_STAT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + /* fatal error*/ + *v_fatal_er_u8r = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_FATAL_ERR); + /* user error*/ + *v_err_code_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_ERR_CODE); + /* i2c fail error*/ + *v_i2c_fail_err_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_I2C_FAIL_ERR); + /* drop command error*/ + *v_drop_cmd_err_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_DROP_CMD_ERR); + /* mag data ready error*/ + *v_mag_data_rdy_err_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_MAG_DADA_RDY_ERR); + } + return com_rslt; +} +/*! + * @brief This API reads the magnetometer power mode from + * PMU status register 0x03 bit 0 and 1 + * + * @param v_mag_power_mode_stat_u8 : The value of mag power mode + * mag_powermode | value + * ------------------|---------- + * SUSPEND | 0x00 + * NORMAL | 0x01 + * LOW POWER | 0x02 + * + * + * @note The power mode of mag set by the 0x7E command register + * @note using the function "bmi160_set_command_register()" + * value | mode + * ---------|---------------- + * 0x18 | MAG_MODE_SUSPEND + * 0x19 | MAG_MODE_NORMAL + * 0x1A | MAG_MODE_LOWPOWER + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_power_mode_stat(u8 +*v_mag_power_mode_stat_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_MAG_POWER_MODE_STAT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_mag_power_mode_stat_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_MAG_POWER_MODE_STAT); + } + return com_rslt; +} +/*! + * @brief This API reads the gyroscope power mode from + * PMU status register 0x03 bit 2 and 3 + * + * @param v_gyro_power_mode_stat_u8 : The value of gyro power mode + * gyro_powermode | value + * ------------------|---------- + * SUSPEND | 0x00 + * NORMAL | 0x01 + * FAST POWER UP | 0x03 + * + * @note The power mode of gyro set by the 0x7E command register + * @note using the function "bmi160_set_command_register()" + * value | mode + * ---------|---------------- + * 0x14 | GYRO_MODE_SUSPEND + * 0x15 | GYRO_MODE_NORMAL + * 0x17 | GYRO_MODE_FASTSTARTUP + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_power_mode_stat(u8 +*v_gyro_power_mode_stat_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_GYRO_POWER_MODE_STAT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_gyro_power_mode_stat_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_GYRO_POWER_MODE_STAT); + } + return com_rslt; +} +/*! + * @brief This API reads the accelerometer power mode from + * PMU status register 0x03 bit 4 and 5 + * + * + * @param v_accel_power_mode_stat_u8 : The value of accel power mode + * accel_powermode | value + * ------------------|---------- + * SUSPEND | 0x00 + * NORMAL | 0x01 + * LOW POWER | 0x02 + * + * @note The power mode of accel set by the 0x7E command register + * @note using the function "bmi160_set_command_register()" + * value | mode + * ---------|---------------- + * 0x11 | ACCEL_MODE_NORMAL + * 0x12 | ACCEL_LOWPOWER + * 0x10 | ACCEL_SUSPEND + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_power_mode_stat(u8 +*v_accel_power_mode_stat_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_ACCEL_POWER_MODE_STAT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_accel_power_mode_stat_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_ACCEL_POWER_MODE_STAT); + } + return com_rslt; +} +/*! + * @brief This API switch mag interface to normal mode + * and confirm whether the mode switching done successfully or not +* + * @return results of bus communication function and current MAG_PMU result + * @retval 0 -> Success + * @retval -1 -> Error + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_interface_normal(void) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = BMI160_INIT_VALUE; + /* aim to check the result of switching mag normal */ + u8 v_try_times_u8 = BMI160_MAG_NOAMRL_SWITCH_TIMES; + u8 v_mag_pum_status_u8 = BMI160_INIT_VALUE; + + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt = bmi160_set_command_register(MAG_MODE_NORMAL); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + while (v_try_times_u8) { + com_rslt = bmi160_get_mag_power_mode_stat(&v_mag_pum_status_u8); + if (v_mag_pum_status_u8 == MAG_INTERFACE_PMU_ENABLE) + break; + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + v_try_times_u8--; + } + if (v_mag_pum_status_u8 == MAG_INTERFACE_PMU_ENABLE) + com_rslt += SUCCESS; + else + com_rslt += E_BMI160_COMM_RES; + + return com_rslt; +} +/*! + * @brief This API reads magnetometer data X values + * from the register 0x04 and 0x05 + * @brief The mag sensor data read form auxiliary mag + * + * @param v_mag_x_s16 : The value of mag x + * @param v_sensor_select_u8 : Mag selection value + * value | sensor + * ---------|---------------- + * 0 | BMM150 + * 1 | AKM09911 or AKM09912 + * + * @note For mag data output rate configuration use the following function + * @note bmi160_set_mag_output_data_rate() + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_x(s16 *v_mag_x_s16, +u8 v_sensor_select_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Array contains the mag X lSB and MSB data + v_data_u8[0] - LSB + v_data_u8[1] - MSB*/ + u8 v_data_u8[BMI160_MAG_X_DATA_SIZE] = {BMI160_INIT_VALUE, + BMI160_INIT_VALUE}; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_sensor_select_u8) { + case BST_BMM: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_DATA_MAG_X_LSB__REG, + v_data_u8, BMI160_MAG_X_DATA_LENGTH); + /* X axis*/ + v_data_u8[BMI160_MAG_X_LSB_BYTE] = + BMI160_GET_BITSLICE(v_data_u8[BMI160_MAG_X_LSB_BYTE], + BMI160_USER_DATA_MAG_X_LSB); + *v_mag_x_s16 = (s16) + ((((s32)((s8)v_data_u8[BMI160_MAG_X_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_05_BITS) | + (v_data_u8[BMI160_MAG_X_LSB_BYTE])); + break; + case BST_AKM: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_DATA_0_MAG_X_LSB__REG, + v_data_u8, BMI160_MAG_X_DATA_LENGTH); + *v_mag_x_s16 = (s16) + ((((s32)((s8)v_data_u8[BMI160_MAG_X_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | + (v_data_u8[BMI160_MAG_X_LSB_BYTE])); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief This API reads magnetometer data Y values + * from the register 0x06 and 0x07 + * @brief The mag sensor data read form auxiliary mag + * + * @param v_mag_y_s16 : The value of mag y + * @param v_sensor_select_u8 : Mag selection value + * value | sensor + * ---------|---------------- + * 0 | BMM150 + * 1 | AKM09911 or AKM09912 + * + * @note For mag data output rate configuration use the following function + * @note bmi160_set_mag_output_data_rate() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_y(s16 *v_mag_y_s16, +u8 v_sensor_select_u8) +{ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_OUT_OF_RANGE; + /* Array contains the mag Y lSB and MSB data + v_data_u8[0] - LSB + v_data_u8[1] - MSB*/ + u8 v_data_u8[BMI160_MAG_Y_DATA_SIZE] = {BMI160_INIT_VALUE, + BMI160_INIT_VALUE}; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_sensor_select_u8) { + case BST_BMM: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_DATA_MAG_Y_LSB__REG, + v_data_u8, BMI160_MAG_Y_DATA_LENGTH); + /*Y-axis lsb value shifting*/ + v_data_u8[BMI160_MAG_Y_LSB_BYTE] = + BMI160_GET_BITSLICE(v_data_u8[BMI160_MAG_Y_LSB_BYTE], + BMI160_USER_DATA_MAG_Y_LSB); + *v_mag_y_s16 = (s16) + ((((s32)((s8)v_data_u8[BMI160_MAG_Y_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_05_BITS) | + (v_data_u8[BMI160_MAG_Y_LSB_BYTE])); + break; + case BST_AKM: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_DATA_2_MAG_Y_LSB__REG, + v_data_u8, BMI160_MAG_Y_DATA_LENGTH); + *v_mag_y_s16 = (s16) + ((((s32)((s8)v_data_u8[BMI160_MAG_Y_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | + (v_data_u8[BMI160_MAG_Y_LSB_BYTE])); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief This API reads magnetometer data Z values + * from the register 0x08 and 0x09 + * @brief The mag sensor data read form auxiliary mag + * + * @param v_mag_z_s16 : The value of mag z + * @param v_sensor_select_u8 : Mag selection value + * value | sensor + * ---------|---------------- + * 0 | BMM150 + * 1 | AKM09911 or AKM09912 + * + * @note For mag data output rate configuration use the following function + * @note bmi160_set_mag_output_data_rate() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_z(s16 *v_mag_z_s16, +u8 v_sensor_select_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Array contains the mag Z lSB and MSB data + v_data_u8[0] - LSB + v_data_u8[1] - MSB*/ + u8 v_data_u8[BMI160_MAG_Z_DATA_SIZE] = {BMI160_INIT_VALUE, + BMI160_INIT_VALUE}; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_sensor_select_u8) { + case BST_BMM: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_DATA_MAG_Z_LSB__REG, + v_data_u8, BMI160_MAG_Z_DATA_LENGTH); + /*Z-axis lsb value shifting*/ + v_data_u8[BMI160_MAG_Z_LSB_BYTE] = + BMI160_GET_BITSLICE(v_data_u8[BMI160_MAG_Z_LSB_BYTE], + BMI160_USER_DATA_MAG_Z_LSB); + *v_mag_z_s16 = (s16) + ((((s32)((s8)v_data_u8[BMI160_MAG_Z_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_07_BITS) | + (v_data_u8[BMI160_MAG_Z_LSB_BYTE])); + break; + case BST_AKM: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_DATA_4_MAG_Z_LSB__REG, + v_data_u8, BMI160_MAG_Z_DATA_LENGTH); + *v_mag_z_s16 = (s16) + ((((s32)((s8)v_data_u8[BMI160_MAG_Z_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | ( + v_data_u8[BMI160_MAG_Z_LSB_BYTE])); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief This API reads magnetometer data RHALL values + * from the register 0x0A and 0x0B + * + * + * @param v_mag_r_s16 : The value of BMM150 r data + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_r(s16 *v_mag_r_s16) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Array contains the mag R lSB and MSB data + v_data_u8[0] - LSB + v_data_u8[1] - MSB*/ + u8 v_data_u8[BMI160_MAG_R_DATA_SIZE] = {BMI160_INIT_VALUE, + BMI160_INIT_VALUE}; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_DATA_6_RHALL_LSB__REG, + v_data_u8, BMI160_MAG_R_DATA_LENGTH); + /*R-axis lsb value shifting*/ + v_data_u8[BMI160_MAG_R_LSB_BYTE] = + BMI160_GET_BITSLICE(v_data_u8[BMI160_MAG_R_LSB_BYTE], + BMI160_USER_DATA_MAG_R_LSB); + *v_mag_r_s16 = (s16) + ((((s32)((s8)v_data_u8[BMI160_MAG_R_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_06_BITS) | + (v_data_u8[BMI160_MAG_R_LSB_BYTE])); + } + return com_rslt; +} +/*! + * @brief This API reads magnetometer data X,Y,Z values + * from the register 0x04 to 0x09 + * + * @brief The mag sensor data read form auxiliary mag + * + * @param mag : The value of mag xyz data + * @param v_sensor_select_u8 : Mag selection value + * value | sensor + * ---------|---------------- + * 0 | BMM150 + * 1 | AKM09911 or AKM09912 + * + * @note For mag data output rate configuration use the following function + * @note bmi160_set_mag_output_data_rate() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_xyz( +struct bmi160_mag_t *mag, u8 v_sensor_select_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Array contains the mag XYZ lSB and MSB data + v_data_u8[0] - X-LSB + v_data_u8[1] - X-MSB + v_data_u8[0] - Y-LSB + v_data_u8[1] - Y-MSB + v_data_u8[0] - Z-LSB + v_data_u8[1] - Z-MSB + */ + u8 v_data_u8[BMI160_MAG_XYZ_DATA_SIZE] = { + BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE}; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_sensor_select_u8) { + case BST_BMM: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_DATA_MAG_X_LSB__REG, + v_data_u8, BMI160_MAG_XYZ_DATA_LENGTH); + /*X-axis lsb value shifting*/ + v_data_u8[BMI160_DATA_FRAME_MAG_X_LSB_BYTE] = + BMI160_GET_BITSLICE( + v_data_u8[BMI160_DATA_FRAME_MAG_X_LSB_BYTE], + BMI160_USER_DATA_MAG_X_LSB); + /* Data X */ + mag->x = (s16) + ((((s32)((s8)v_data_u8[ + BMI160_DATA_FRAME_MAG_X_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_05_BITS) | + (v_data_u8[BMI160_DATA_FRAME_MAG_X_LSB_BYTE])); + /* Data Y */ + /*Y-axis lsb value shifting*/ + v_data_u8[BMI160_DATA_FRAME_MAG_Y_LSB_BYTE] = + BMI160_GET_BITSLICE( + v_data_u8[BMI160_DATA_FRAME_MAG_Y_LSB_BYTE], + BMI160_USER_DATA_MAG_Y_LSB); + mag->y = (s16) + ((((s32)((s8)v_data_u8[ + BMI160_DATA_FRAME_MAG_Y_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_05_BITS) | + (v_data_u8[BMI160_DATA_FRAME_MAG_Y_LSB_BYTE])); + + /* Data Z */ + /*Z-axis lsb value shifting*/ + v_data_u8[BMI160_DATA_FRAME_MAG_Z_LSB_BYTE] + = BMI160_GET_BITSLICE( + v_data_u8[BMI160_DATA_FRAME_MAG_Z_LSB_BYTE], + BMI160_USER_DATA_MAG_Z_LSB); + mag->z = (s16) + ((((s32)((s8)v_data_u8[ + BMI160_DATA_FRAME_MAG_Z_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_07_BITS) | + (v_data_u8[BMI160_DATA_FRAME_MAG_Z_LSB_BYTE])); + break; + case BST_AKM: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_DATA_0_MAG_X_LSB__REG, + v_data_u8, BMI160_MAG_XYZ_DATA_LENGTH); + /* Data X */ + mag->x = (s16) + ((((s32)((s8)v_data_u8[ + BMI160_DATA_FRAME_MAG_X_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | + (v_data_u8[BMI160_DATA_FRAME_MAG_X_LSB_BYTE])); + /* Data Y */ + mag->y = ((((s32)((s8)v_data_u8[ + BMI160_DATA_FRAME_MAG_Y_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | + (v_data_u8[BMI160_DATA_FRAME_MAG_Y_LSB_BYTE])); + /* Data Z */ + mag->z = (s16) + ((((s32)((s8)v_data_u8[ + BMI160_DATA_FRAME_MAG_Z_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | + (v_data_u8[BMI160_DATA_FRAME_MAG_Z_LSB_BYTE])); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} + /*!* + * @brief This API reads magnetometer data X,Y,Z,r + * values from the register 0x04 to 0x0B + * + * @brief The mag sensor data read form auxiliary mag + * + * @param mag : The value of mag-BMM150 xyzr data + * + * @note For mag data output rate configuration use the following function + * @note bmi160_set_mag_output_data_rate() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_xyzr( +struct bmi160_mag_xyzr_t *mag) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8[BMI160_MAG_XYZR_DATA_SIZE] = { + BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE}; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_DATA_MAG_X_LSB__REG, + v_data_u8, BMI160_MAG_XYZR_DATA_LENGTH); + + /* Data X */ + /*X-axis lsb value shifting*/ + v_data_u8[BMI160_DATA_FRAME_MAG_X_LSB_BYTE] + = BMI160_GET_BITSLICE( + v_data_u8[BMI160_DATA_FRAME_MAG_X_LSB_BYTE], + BMI160_USER_DATA_MAG_X_LSB); + mag->x = (s16) + ((((s32)((s8)v_data_u8[ + BMI160_DATA_FRAME_MAG_X_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_05_BITS) + | (v_data_u8[BMI160_DATA_FRAME_MAG_X_LSB_BYTE])); + /* Data Y */ + /*Y-axis lsb value shifting*/ + v_data_u8[BMI160_DATA_FRAME_MAG_Y_LSB_BYTE] + = BMI160_GET_BITSLICE( + v_data_u8[BMI160_DATA_FRAME_MAG_Y_LSB_BYTE], + BMI160_USER_DATA_MAG_Y_LSB); + mag->y = (s16) + ((((s32)((s8)v_data_u8[ + BMI160_DATA_FRAME_MAG_Y_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_05_BITS) + | (v_data_u8[ + BMI160_DATA_FRAME_MAG_Y_LSB_BYTE])); + + /* Data Z */ + /*Z-axis lsb value shifting*/ + v_data_u8[BMI160_DATA_FRAME_MAG_Z_LSB_BYTE] + = BMI160_GET_BITSLICE( + v_data_u8[BMI160_DATA_FRAME_MAG_Z_LSB_BYTE], + BMI160_USER_DATA_MAG_Z_LSB); + mag->z = (s16) + ((((s32)((s8)v_data_u8[ + BMI160_DATA_FRAME_MAG_Z_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_07_BITS) + | (v_data_u8[BMI160_DATA_FRAME_MAG_Z_LSB_BYTE])); + + /* RHall */ + /*R-axis lsb value shifting*/ + v_data_u8[BMI160_DATA_FRAME_MAG_R_LSB_BYTE] + = BMI160_GET_BITSLICE( + v_data_u8[BMI160_DATA_FRAME_MAG_R_LSB_BYTE], + BMI160_USER_DATA_MAG_R_LSB); + mag->r = (s16) + ((((s32)((s8)v_data_u8[ + BMI160_DATA_FRAME_MAG_R_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_06_BITS) + | (v_data_u8[BMI160_DATA_FRAME_MAG_R_LSB_BYTE])); + } + return com_rslt; +} +/*! + * @brief This API reads gyro data X values + * form the register 0x0C and 0x0D + * + * + * + * + * @param v_gyro_x_s16 : The value of gyro x data + * + * @note Gyro Configuration use the following function + * @note bmi160_set_gyro_output_data_rate() + * @note bmi160_set_gyro_bw() + * @note bmi160_set_gyro_range() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_gyro_x(s16 *v_gyro_x_s16) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Array contains the gyro X lSB and MSB data + v_data_u8[0] - LSB + v_data_u8[MSB_ONE] - MSB*/ + u8 v_data_u8[BMI160_GYRO_X_DATA_SIZE] = {BMI160_INIT_VALUE, + BMI160_INIT_VALUE}; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_DATA_8_GYRO_X_LSB__REG, + v_data_u8, BMI160_GYRO_DATA_LENGTH); + + *v_gyro_x_s16 = (s16) + ((((s32)((s8)v_data_u8[BMI160_GYRO_X_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) + | (v_data_u8[BMI160_GYRO_X_LSB_BYTE])); + } + return com_rslt; +} +/*! + * @brief This API reads gyro data Y values + * form the register 0x0E and 0x0F + * + * + * + * + * @param v_gyro_y_s16 : The value of gyro y data + * + * @note Gyro Configuration use the following function + * @note bmi160_set_gyro_output_data_rate() + * @note bmi160_set_gyro_bw() + * @note bmi160_set_gyro_range() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error result of communication routines + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_gyro_y(s16 *v_gyro_y_s16) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Array contains the gyro Y lSB and MSB data + v_data_u8[LSB_ZERO] - LSB + v_data_u8[MSB_ONE] - MSB*/ + u8 v_data_u8[BMI160_GYRO_Y_DATA_SIZE] = {BMI160_INIT_VALUE, + BMI160_INIT_VALUE}; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read gyro y data*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_DATA_10_GYRO_Y_LSB__REG, + v_data_u8, BMI160_GYRO_DATA_LENGTH); + + *v_gyro_y_s16 = (s16) + ((((s32)((s8)v_data_u8[BMI160_GYRO_Y_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) + | (v_data_u8[BMI160_GYRO_Y_LSB_BYTE])); + } + return com_rslt; +} +/*! + * @brief This API reads gyro data Z values + * form the register 0x10 and 0x11 + * + * + * + * + * @param v_gyro_z_s16 : The value of gyro z data + * + * @note Gyro Configuration use the following function + * @note bmi160_set_gyro_output_data_rate() + * @note bmi160_set_gyro_bw() + * @note bmi160_set_gyro_range() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_gyro_z(s16 *v_gyro_z_s16) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Array contains the gyro Z lSB and MSB data + v_data_u8[LSB_ZERO] - LSB + v_data_u8[MSB_ONE] - MSB*/ + u8 v_data_u8[BMI160_GYRO_Z_DATA_SIZE] = {BMI160_INIT_VALUE, + BMI160_INIT_VALUE}; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read gyro z data */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_DATA_12_GYRO_Z_LSB__REG, + v_data_u8, BMI160_GYRO_DATA_LENGTH); + + *v_gyro_z_s16 = (s16) + ((((s32)((s8)v_data_u8[BMI160_GYRO_Z_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) + | (v_data_u8[BMI160_GYRO_Z_LSB_BYTE])); + } + return com_rslt; +} +/*! + * @brief This API reads gyro data X,Y,Z values + * from the register 0x0C to 0x11 + * + * + * + * + * @param gyro : The value of gyro xyz + * + * @note Gyro Configuration use the following function + * @note bmi160_set_gyro_output_data_rate() + * @note bmi160_set_gyro_bw() + * @note bmi160_set_gyro_range() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_gyro_xyz(struct bmi160_gyro_t *gyro) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Array contains the mag XYZ lSB and MSB data + v_data_u8[0] - X-LSB + v_data_u8[1] - X-MSB + v_data_u8[0] - Y-LSB + v_data_u8[1] - Y-MSB + v_data_u8[0] - Z-LSB + v_data_u8[1] - Z-MSB + */ + u8 v_data_u8[BMI160_GYRO_XYZ_DATA_SIZE] = { + BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE}; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the gyro xyz data*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_DATA_8_GYRO_X_LSB__REG, + v_data_u8, BMI160_GYRO_XYZ_DATA_LENGTH); + + /* Data X */ + gyro->x = (s16) + ((((s32)((s8)v_data_u8[ + BMI160_DATA_FRAME_GYRO_X_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) + | (v_data_u8[BMI160_DATA_FRAME_GYRO_X_LSB_BYTE])); + /* Data Y */ + gyro->y = (s16) + ((((s32)((s8)v_data_u8[ + BMI160_DATA_FRAME_GYRO_Y_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) + | (v_data_u8[BMI160_DATA_FRAME_GYRO_Y_LSB_BYTE])); + + /* Data Z */ + gyro->z = (s16) + ((((s32)((s8)v_data_u8[ + BMI160_DATA_FRAME_GYRO_Z_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) + | (v_data_u8[BMI160_DATA_FRAME_GYRO_Z_LSB_BYTE])); + } + return com_rslt; +} +/*! + * @brief This API reads accelerometer data X values + * form the register 0x12 and 0x13 + * + * + * + * + * @param v_accel_x_s16 : The value of accel x + * + * @note For accel configuration use the following functions + * @note bmi160_set_accel_output_data_rate() + * @note bmi160_set_accel_bw() + * @note bmi160_set_accel_under_sampling_parameter() + * @note bmi160_set_accel_range() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_accel_x(s16 *v_accel_x_s16) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Array contains the accel X lSB and MSB data + v_data_u8[0] - LSB + v_data_u8[1] - MSB*/ + u8 v_data_u8[BMI160_ACCEL_X_DATA_SIZE] = {BMI160_INIT_VALUE, + BMI160_INIT_VALUE}; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_DATA_14_ACCEL_X_LSB__REG, + v_data_u8, BMI160_ACCEL_DATA_LENGTH); + + *v_accel_x_s16 = (s16) + ((((s32)((s8)v_data_u8[BMI160_ACCEL_X_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) + | (v_data_u8[BMI160_ACCEL_X_LSB_BYTE])); + } + return com_rslt; +} +/*! + * @brief This API reads accelerometer data Y values + * form the register 0x14 and 0x15 + * + * + * + * + * @param v_accel_y_s16 : The value of accel y + * + * @note For accel configuration use the following functions + * @note bmi160_set_accel_output_data_rate() + * @note bmi160_set_accel_bw() + * @note bmi160_set_accel_under_sampling_parameter() + * @note bmi160_set_accel_range() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_accel_y(s16 *v_accel_y_s16) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Array contains the accel Y lSB and MSB data + v_data_u8[0] - LSB + v_data_u8[1] - MSB*/ + u8 v_data_u8[BMI160_ACCEL_Y_DATA_SIZE] = {BMI160_INIT_VALUE, + BMI160_INIT_VALUE}; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_DATA_16_ACCEL_Y_LSB__REG, + v_data_u8, BMI160_ACCEL_DATA_LENGTH); + + *v_accel_y_s16 = (s16) + ((((s32)((s8)v_data_u8[BMI160_ACCEL_Y_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) + | (v_data_u8[BMI160_ACCEL_Y_LSB_BYTE])); + } + return com_rslt; +} +/*! + * @brief This API reads accelerometer data Z values + * form the register 0x16 and 0x17 + * + * + * + * + * @param v_accel_z_s16 : The value of accel z + * + * @note For accel configuration use the following functions + * @note bmi160_set_accel_output_data_rate() + * @note bmi160_set_accel_bw() + * @note bmi160_set_accel_under_sampling_parameter() + * @note bmi160_set_accel_range() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_accel_z(s16 *v_accel_z_s16) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Array contains the accel Z lSB and MSB data + a_data_u8r[LSB_ZERO] - LSB + a_data_u8r[MSB_ONE] - MSB*/ + u8 a_data_u8r[BMI160_ACCEL_Z_DATA_SIZE] = { + BMI160_INIT_VALUE, BMI160_INIT_VALUE}; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_DATA_18_ACCEL_Z_LSB__REG, + a_data_u8r, BMI160_ACCEL_DATA_LENGTH); + + *v_accel_z_s16 = (s16) + ((((s32)((s8)a_data_u8r[BMI160_ACCEL_Z_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) + | (a_data_u8r[BMI160_ACCEL_Z_LSB_BYTE])); + } + return com_rslt; +} +/*! + * @brief This API reads accelerometer data X,Y,Z values + * from the register 0x12 to 0x17 + * + * + * + * + * @param accel :The value of accel xyz + * + * @note For accel configuration use the following functions + * @note bmi160_set_accel_output_data_rate() + * @note bmi160_set_accel_bw() + * @note bmi160_set_accel_under_sampling_parameter() + * @note bmi160_set_accel_range() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_accel_xyz( +struct bmi160_accel_t *accel) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Array contains the accel XYZ lSB and MSB data + a_data_u8r[0] - X-LSB + a_data_u8r[1] - X-MSB + a_data_u8r[0] - Y-LSB + a_data_u8r[1] - Y-MSB + a_data_u8r[0] - Z-LSB + a_data_u8r[1] - Z-MSB + */ + u8 a_data_u8r[BMI160_ACCEL_XYZ_DATA_SIZE] = { + BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE}; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_DATA_14_ACCEL_X_LSB__REG, + a_data_u8r, BMI160_ACCEL_XYZ_DATA_LENGTH); + + /* Data X */ + accel->x = (s16) + ((((s32)((s8)a_data_u8r[ + BMI160_DATA_FRAME_ACCEL_X_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) + | (a_data_u8r[BMI160_DATA_FRAME_ACCEL_X_LSB_BYTE])); + /* Data Y */ + accel->y = (s16) + ((((s32)((s8)a_data_u8r[ + BMI160_DATA_FRAME_ACCEL_Y_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) + | (a_data_u8r[BMI160_DATA_FRAME_ACCEL_Y_LSB_BYTE])); + + /* Data Z */ + accel->z = (s16) + ((((s32)((s8)a_data_u8r[ + BMI160_DATA_FRAME_ACCEL_Z_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) + | (a_data_u8r[BMI160_DATA_FRAME_ACCEL_Z_LSB_BYTE])); + } + return com_rslt; +} +/*! + * @brief This API reads sensor_time from the register + * 0x18 to 0x1A + * + * + * @param v_sensor_time_u32 : The value of sensor time + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_sensor_time(u32 *v_sensor_time_u32) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Array contains the sensor time it is 32 bit data + a_data_u8r[0] - sensor time + a_data_u8r[1] - sensor time + a_data_u8r[0] - sensor time + */ + u8 a_data_u8r[BMI160_SENSOR_TIME_DATA_SIZE] = {BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE}; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_SENSORTIME_0_SENSOR_TIME_LSB__REG, + a_data_u8r, BMI160_SENSOR_TIME_LENGTH); + + *v_sensor_time_u32 = (u32) + ((((u32)a_data_u8r[BMI160_SENSOR_TIME_MSB_BYTE]) + << BMI160_SHIFT_BIT_POSITION_BY_16_BITS) + |(((u32)a_data_u8r[BMI160_SENSOR_TIME_XLSB_BYTE]) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) + | (a_data_u8r[BMI160_SENSOR_TIME_LSB_BYTE])); + } + return com_rslt; +} +/*! + * @brief This API reads the Gyroscope self test + * status from the register 0x1B bit 1 + * + * + * @param v_gyro_selftest_u8 : The value of gyro self test status + * value | status + * ---------|---------------- + * 0 | Gyroscope self test is running or failed + * 1 | Gyroscope self test completed successfully + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_selftest(u8 +*v_gyro_selftest_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_STAT_GYRO_SELFTEST_OK__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_gyro_selftest_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_STAT_GYRO_SELFTEST_OK); + } + return com_rslt; +} +/*! + * @brief This API reads the status of + * mag manual interface operation form the register 0x1B bit 2 + * + * + * + * @param v_mag_manual_stat_u8 : The value of mag manual operation status + * value | status + * ---------|---------------- + * 0 | Indicates no manual magnetometer + * - | interface operation is ongoing + * 1 | Indicates manual magnetometer + * - | interface operation is ongoing + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_manual_operation_stat(u8 +*v_mag_manual_stat_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read manual operation*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_STAT_MAG_MANUAL_OPERATION__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_mag_manual_stat_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_STAT_MAG_MANUAL_OPERATION); + } + return com_rslt; +} +/*! + * @brief This API reads the fast offset compensation + * status form the register 0x1B bit 3 + * + * + * @param v_foc_rdy_u8 : The status of fast compensation + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_rdy(u8 +*v_foc_rdy_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the FOC status*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_STAT_FOC_RDY__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_foc_rdy_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_STAT_FOC_RDY); + } + return com_rslt; +} +/*! + * @brief This API Reads the nvm_rdy status from the + * resister 0x1B bit 4 + * + * + * @param v_nvm_rdy_u8 : The value of NVM ready status + * value | status + * ---------|---------------- + * 0 | NVM write operation in progress + * 1 | NVM is ready to accept a new write trigger + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_nvm_rdy(u8 +*v_nvm_rdy_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the nvm ready status*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_STAT_NVM_RDY__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_nvm_rdy_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_STAT_NVM_RDY); + } + return com_rslt; +} +/*! + * @brief This API reads the status of mag data ready + * from the register 0x1B bit 5 + * The status get reset when one mag data register is read out + * + * @param v_data_rdy_u8 : The value of mag data ready status + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_data_rdy_mag(u8 +*v_data_rdy_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_STAT_DATA_RDY_MAG__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_data_rdy_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_STAT_DATA_RDY_MAG); + } + return com_rslt; +} +/*! + * @brief This API reads the status of gyro data ready form the + * register 0x1B bit 6 + * The status get reset when gyro data register read out + * + * + * @param v_data_rdy_u8 : The value of gyro data ready + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_data_rdy(u8 +*v_data_rdy_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_STAT_DATA_RDY_GYRO__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_data_rdy_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_STAT_DATA_RDY_GYRO); + } + return com_rslt; +} +/*! + * @brief This API reads the status of accel data ready form the + * register 0x1B bit 7 + * The status get reset when accel data register read out + * + * + * @param v_data_rdy_u8 : The value of accel data ready status + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_data_rdy(u8 +*v_data_rdy_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /*reads the status of accel data ready*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_STAT_DATA_RDY_ACCEL__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_data_rdy_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_STAT_DATA_RDY_ACCEL); + } + return com_rslt; +} +/*! + * @brief This API reads the step detector interrupt status + * from the register 0x1C bit 0 + * flag is associated with a specific interrupt function. + * It is set when the single tab interrupt triggers. The + * setting of INT_LATCH controls if the interrupt + * signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_step_intr_u8 : The status of step detector interrupt + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_step_intr(u8 +*v_step_intr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_0_STEP_INTR__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_step_intr_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_0_STEP_INTR); + } + return com_rslt; +} +/*! + * @brief This API reads the + * significant motion interrupt status + * from the register 0x1C bit 1 + * flag is associated with a specific interrupt function. + * It is set when the single tab interrupt triggers. The + * setting of INT_LATCH controls if the interrupt + * signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * + * @param v_significant_intr_u8 : The status of step + * motion interrupt + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_significant_intr(u8 +*v_significant_intr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_0_SIGNIFICANT_INTR__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_significant_intr_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_0_SIGNIFICANT_INTR); + } + return com_rslt; +} + /*! + * @brief This API reads the any motion interrupt status + * from the register 0x1C bit 2 + * flag is associated with a specific interrupt function. + * It is set when the single tab interrupt triggers. The + * setting of INT_LATCH controls if the interrupt + * signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * @param v_any_motion_intr_u8 : The status of any-motion interrupt + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_any_motion_intr(u8 +*v_any_motion_intr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_0_ANY_MOTION__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_any_motion_intr_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_0_ANY_MOTION); + } + return com_rslt; +} +/*! + * @brief This API reads the power mode trigger interrupt status + * from the register 0x1C bit 3 + * flag is associated with a specific interrupt function. + * It is set when the single tab interrupt triggers. The + * setting of INT_LATCH controls if the interrupt + * signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * + * @param v_pmu_trigger_intr_u8 : The status of power mode trigger interrupt + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_pmu_trigger_intr(u8 +*v_pmu_trigger_intr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_0_PMU_TRIGGER__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_pmu_trigger_intr_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_0_PMU_TRIGGER); + } + return com_rslt; +} +/*! + * @brief This API reads the double tab status + * from the register 0x1C bit 4 + * flag is associated with a specific interrupt function. + * It is set when the single tab interrupt triggers. The + * setting of INT_LATCH controls if the interrupt + * signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_double_tap_intr_u8 :The status of double tab interrupt + * + * @note Double tap interrupt can be configured by the following functions + * @note INTERRUPT MAPPING + * @note bmi160_set_intr_double_tap() + * @note AXIS MAPPING + * @note bmi160_get_stat2_tap_first_x() + * @note bmi160_get_stat2_tap_first_y() + * @note bmi160_get_stat2_tap_first_z() + * @note DURATION + * @note bmi160_set_intr_tap_durn() + * @note THRESHOLD + * @note bmi160_set_intr_tap_thres() + * @note TAP QUIET + * @note bmi160_set_intr_tap_quiet() + * @note TAP SHOCK + * @note bmi160_set_intr_tap_shock() + * @note TAP SOURCE + * @note bmi160_set_intr_tap_source() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_double_tap_intr(u8 +*v_double_tap_intr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_0_DOUBLE_TAP_INTR__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_double_tap_intr_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_0_DOUBLE_TAP_INTR); + } + return com_rslt; +} +/*! + * @brief This API reads the single tab status + * from the register 0x1C bit 5 + * flag is associated with a specific interrupt function. + * It is set when the single tab interrupt triggers. The + * setting of INT_LATCH controls if the interrupt + * signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_single_tap_intr_u8 :The status of single tap interrupt + * + * @note Single tap interrupt can be configured by the following functions + * @note INTERRUPT MAPPING + * @note bmi160_set_intr_single_tap() + * @note AXIS MAPPING + * @note bmi160_get_stat2_tap_first_x() + * @note bmi160_get_stat2_tap_first_y() + * @note bmi160_get_stat2_tap_first_z() + * @note DURATION + * @note bmi160_set_intr_tap_durn() + * @note THRESHOLD + * @note bmi160_set_intr_tap_thres() + * @note TAP QUIET + * @note bmi160_set_intr_tap_quiet() + * @note TAP SHOCK + * @note bmi160_set_intr_tap_shock() + * @note TAP SOURCE + * @note bmi160_set_intr_tap_source() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_single_tap_intr(u8 +*v_single_tap_intr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_0_SINGLE_TAP_INTR__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_single_tap_intr_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_0_SINGLE_TAP_INTR); + } + return com_rslt; +} +/*! + * @brief This API reads the orient status + * from the register 0x1C bit 6 + * flag is associated with a specific interrupt function. + * It is set when the orient interrupt triggers. The + * setting of INT_LATCH controls if the + * interrupt signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_orient_intr_u8 : The status of orient interrupt + * + * @note For orient interrupt configuration use the following functions + * @note STATUS + * @note bmi160_get_stat0_orient_intr() + * @note AXIS MAPPING + * @note bmi160_get_stat3_orient_xy() + * @note bmi160_get_stat3_orient_z() + * @note bmi160_set_intr_orient_axes_enable() + * @note INTERRUPT MAPPING + * @note bmi160_set_intr_orient() + * @note INTERRUPT OUTPUT + * @note bmi160_set_intr_orient_ud_enable() + * @note THETA + * @note bmi160_set_intr_orient_theta() + * @note HYSTERESIS + * @note bmi160_set_intr_orient_hyst() + * @note BLOCKING + * @note bmi160_set_intr_orient_blocking() + * @note MODE + * @note bmi160_set_intr_orient_mode() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_orient_intr(u8 +*v_orient_intr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_0_ORIENT__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_orient_intr_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_0_ORIENT); + } + return com_rslt; +} +/*! + * @brief This API reads the flat interrupt status + * from the register 0x1C bit 7 + * flag is associated with a specific interrupt function. + * It is set when the flat interrupt triggers. The + * setting of INT_LATCH controls if the + * interrupt signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_flat_intr_u8 : The status of flat interrupt + * + * @note For flat configuration use the following functions + * @note STATS + * @note bmi160_get_stat0_flat_intr() + * @note bmi160_get_stat3_flat() + * @note INTERRUPT MAPPING + * @note bmi160_set_intr_flat() + * @note THETA + * @note bmi160_set_intr_flat_theta() + * @note HOLD TIME + * @note bmi160_set_intr_flat_hold() + * @note HYSTERESIS + * @note bmi160_set_intr_flat_hyst() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_flat_intr(u8 +*v_flat_intr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_0_FLAT__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_flat_intr_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_0_FLAT); + } + return com_rslt; +} +/*! + * @brief This API reads the high_g interrupt status + * from the register 0x1D bit 2 + * flag is associated with a specific interrupt function. + * It is set when the high g interrupt triggers. The + * setting of INT_LATCH controls if the interrupt signal and hence the + * respective interrupt flag will be permanently + * latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_high_g_intr_u8 : The status of high_g interrupt + * + * @note High_g interrupt configured by following functions + * @note STATUS + * @note bmi160_get_stat1_high_g_intr() + * @note AXIS MAPPING + * @note bmi160_get_stat3_high_g_first_x() + * @note bmi160_get_stat3_high_g_first_y() + * @note bmi160_get_stat3_high_g_first_z() + * @note SIGN MAPPING + * @note bmi160_get_stat3_high_g_first_sign() + * @note INTERRUPT MAPPING + * @note bmi160_set_intr_high_g() + * @note HYSTERESIS + * @note bmi160_set_intr_high_g_hyst() + * @note DURATION + * @note bmi160_set_intr_high_g_durn() + * @note THRESHOLD + * @note bmi160_set_intr_high_g_thres() + * @note SOURCE + * @note bmi160_set_intr_low_high_source() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_high_g_intr(u8 +*v_high_g_intr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_1_HIGH_G_INTR__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_high_g_intr_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_1_HIGH_G_INTR); + } + return com_rslt; +} +/*! + * @brief This API reads the low g interrupt status + * from the register 0x1D bit 3 + * flag is associated with a specific interrupt function. + * It is set when the low g interrupt triggers. The + * setting of INT_LATCH controls if the interrupt signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_low_g_intr_u8 : The status of low_g interrupt + * + * @note Low_g interrupt configured by following functions + * @note STATUS + * @note bmi160_get_stat1_low_g_intr() + * @note INTERRUPT MAPPING + * @note bmi160_set_intr_low_g() + * @note SOURCE + * @note bmi160_set_intr_low_high_source() + * @note DURATION + * @note bmi160_set_intr_low_g_durn() + * @note THRESHOLD + * @note bmi160_set_intr_low_g_thres() + * @note HYSTERESIS + * @note bmi160_set_intr_low_g_hyst() + * @note MODE + * @note bmi160_set_intr_low_g_mode() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_low_g_intr(u8 +*v_low_g_intr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_1_LOW_G_INTR__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_low_g_intr_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_1_LOW_G_INTR); + } + return com_rslt; +} +/*! + * @brief This API reads data ready interrupt status + * from the register 0x1D bit 4 + * flag is associated with a specific interrupt function. + * It is set when the data ready interrupt triggers. The + * setting of INT_LATCH controls if the interrupt signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_data_rdy_intr_u8 : The status of data ready interrupt + * + * @note Data ready interrupt configured by following functions + * @note STATUS + * @note bmi160_get_stat1_data_rdy_intr() + * @note INTERRUPT MAPPING + * @note bmi160_set_intr_data_rdy() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_data_rdy_intr(u8 +*v_data_rdy_intr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_1_DATA_RDY_INTR__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_data_rdy_intr_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_1_DATA_RDY_INTR); + } + return com_rslt; +} +/*! + * @brief This API reads data ready FIFO full interrupt status + * from the register 0x1D bit 5 + * flag is associated with a specific interrupt function. + * It is set when the FIFO full interrupt triggers. The + * setting of INT_LATCH controls if the + * interrupt signal and hence the + * respective interrupt flag will + * be permanently latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_fifo_full_intr_u8 : The status of fifo full interrupt + * + * @note FIFO full interrupt can be configured by following functions + * @note bmi160_set_intr_fifo_full() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_fifo_full_intr(u8 +*v_fifo_full_intr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_1_FIFO_FULL_INTR__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_fifo_full_intr_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_1_FIFO_FULL_INTR); + } + return com_rslt; +} +/*! + * @brief This API reads data + * ready FIFO watermark interrupt status + * from the register 0x1D bit 6 + * flag is associated with a specific interrupt function. + * It is set when the FIFO watermark interrupt triggers. The + * setting of INT_LATCH controls if the + * interrupt signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_fifo_wm_intr_u8 : The status of fifo water mark interrupt + * + * @note FIFO full interrupt can be configured by following functions + * @note bmi160_set_intr_fifo_wm() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_fifo_wm_intr(u8 +*v_fifo_wm_intr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_1_FIFO_WM_INTR__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_fifo_wm_intr_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_1_FIFO_WM_INTR); + } + return com_rslt; +} +/*! + * @brief This API reads data ready no motion interrupt status + * from the register 0x1D bit 7 + * flag is associated with a specific interrupt function. + * It is set when the no motion interrupt triggers. The + * setting of INT_LATCH controls if the interrupt signal and hence the + * respective interrupt flag will be permanently + * latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_nomotion_intr_u8 : The status of no motion interrupt + * + * @note No motion interrupt can be configured by following function + * @note STATUS + * @note bmi160_get_stat1_nomotion_intr() + * @note INTERRUPT MAPPING + * @note bmi160_set_intr_nomotion() + * @note DURATION + * @note bmi160_set_intr_slow_no_motion_durn() + * @note THRESHOLD + * @note bmi160_set_intr_slow_no_motion_thres() + * @note SLOW/NO MOTION SELECT + * @note bmi160_set_intr_slow_no_motion_select() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_nomotion_intr(u8 +*v_nomotion_intr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the no motion interrupt*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_1_NOMOTION_INTR__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_nomotion_intr_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_1_NOMOTION_INTR); + } + return com_rslt; +} +/*! + *@brief This API reads the status of any motion first x + * from the register 0x1E bit 0 + * + * + *@param v_anymotion_first_x_u8 : The status of any motion first x interrupt + * value | status + * -----------|------------- + * 0 | not triggered + * 1 | triggered by x axis + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_any_motion_first_x(u8 +*v_anymotion_first_x_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the any motion first x interrupt*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_anymotion_first_x_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_X); + } + return com_rslt; +} +/*! + * @brief This API reads the status of any motion first y interrupt + * from the register 0x1E bit 1 + * + * + * + *@param v_any_motion_first_y_u8 : The status of any motion first y interrupt + * value | status + * -----------|------------- + * 0 | not triggered + * 1 | triggered by y axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_any_motion_first_y(u8 +*v_any_motion_first_y_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the any motion first y interrupt*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_any_motion_first_y_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y); + } + return com_rslt; +} +/*! + * @brief This API reads the status of any motion first z interrupt + * from the register 0x1E bit 2 + * + * + * + * + *@param v_any_motion_first_z_u8 : The status of any motion first z interrupt + * value | status + * -----------|------------- + * 0 | not triggered + * 1 | triggered by y axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_any_motion_first_z(u8 +*v_any_motion_first_z_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the any motion first z interrupt*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_any_motion_first_z_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z); + } + return com_rslt; +} +/*! + * @brief This API reads the any motion sign status from the + * register 0x1E bit 3 + * + * + * + * + * @param v_anymotion_sign_u8 : The status of any motion sign + * value | sign + * -----------|------------- + * 0 | positive + * 1 | negative + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_any_motion_sign(u8 +*v_anymotion_sign_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read any motion sign interrupt status */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_2_ANY_MOTION_SIGN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_anymotion_sign_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_2_ANY_MOTION_SIGN); + } + return com_rslt; +} +/*! + * @brief This API reads the any motion tap first x status from the + * register 0x1E bit 4 + * + * + * + * + * @param v_tap_first_x_u8 :The status of any motion tap first x + * value | status + * -----------|------------- + * 0 | not triggered + * 1 | triggered by x axis + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_tap_first_x(u8 +*v_tap_first_x_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read tap first x interrupt status */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_2_TAP_FIRST_X__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_tap_first_x_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_2_TAP_FIRST_X); + } + return com_rslt; +} +/*! + * @brief This API reads the tap first y interrupt status from the + * register 0x1E bit 5 + * + * + * + * + * @param v_tap_first_y_u8 :The status of tap first y interrupt + * value | status + * -----------|------------- + * 0 | not triggered + * 1 | triggered by y axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_tap_first_y(u8 +*v_tap_first_y_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read tap first y interrupt status */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_2_TAP_FIRST_Y__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_tap_first_y_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_2_TAP_FIRST_Y); + } + return com_rslt; +} +/*! + * @brief This API reads the tap first z interrupt status from the + * register 0x1E bit 6 + * + * + * + * + * @param v_tap_first_z_u8 :The status of tap first z interrupt + * value | status + * -----------|------------- + * 0 | not triggered + * 1 | triggered by z axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_tap_first_z(u8 +*v_tap_first_z_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read tap first z interrupt status */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_2_TAP_FIRST_Z__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_tap_first_z_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_2_TAP_FIRST_Z); + } + return com_rslt; +} +/*! + * @brief This API reads the tap sign status from the + * register 0x1E bit 7 + * + * + * + * + * @param v_tap_sign_u8 : The status of tap sign + * value | sign + * -----------|------------- + * 0 | positive + * 1 | negative + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_tap_sign(u8 +*v_tap_sign_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read tap_sign interrupt status */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_2_TAP_SIGN__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_tap_sign_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_2_TAP_SIGN); + } + return com_rslt; +} +/*! + * @brief This API reads the high_g first x status from the + * register 0x1F bit 0 + * + * + * + * + * @param v_high_g_first_x_u8 :The status of high_g first x + * value | status + * -----------|------------- + * 0 | not triggered + * 1 | triggered by x axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_high_g_first_x(u8 +*v_high_g_first_x_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read highg_x interrupt status */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_X__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_high_g_first_x_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_X); + } + return com_rslt; +} +/*! + * @brief This API reads the high_g first y status from the + * register 0x1F bit 1 + * + * + * + * + * @param v_high_g_first_y_u8 : The status of high_g first y + * value | status + * -----------|------------- + * 0 | not triggered + * 1 | triggered by y axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_high_g_first_y(u8 +*v_high_g_first_y_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read highg_y interrupt status */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Y__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_high_g_first_y_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Y); + } + return com_rslt; +} +/*! + * @brief This API reads the high_g first z status from the + * register 0x1F bit 3 + * + * + * + * + * @param v_high_g_first_z_u8 : The status of high_g first z + * value | status + * -----------|------------- + * 0 | not triggered + * 1 | triggered by z axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_high_g_first_z(u8 +*v_high_g_first_z_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read highg_z interrupt status */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Z__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_high_g_first_z_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Z); + } + return com_rslt; +} +/*! + * @brief This API reads the high sign status from the + * register 0x1F bit 3 + * + * + * + * + * @param v_high_g_sign_u8 :The status of high sign + * value | sign + * -----------|------------- + * 0 | positive + * 1 | negative + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_high_g_sign(u8 +*v_high_g_sign_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read highg_sign interrupt status */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_3_HIGH_G_SIGN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_high_g_sign_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_3_HIGH_G_SIGN); + } + return com_rslt; +} +/*! + * @brief This API reads the status of orient_xy plane + * from the register 0x1F bit 4 and 5 + * + * + * @param v_orient_xy_u8 :The status of orient_xy plane + * value | status + * -----------|------------- + * 0x00 | portrait upright + * 0x01 | portrait upside down + * 0x02 | landscape left + * 0x03 | landscape right + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_orient_xy(u8 +*v_orient_xy_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read orient plane xy interrupt status */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_3_ORIENT_XY__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_orient_xy_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_3_ORIENT_XY); + } + return com_rslt; +} +/*! + * @brief This API reads the status of orient z plane + * from the register 0x1F bit 6 + * + * + * @param v_orient_z_u8 :The status of orient z + * value | status + * -----------|------------- + * 0x00 | upward looking + * 0x01 | downward looking + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_orient_z(u8 +*v_orient_z_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read orient z plane interrupt status */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_3_ORIENT_Z__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_orient_z_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_3_ORIENT_Z); + } + return com_rslt; +} +/*! + * @brief This API reads the flat status from the register + * 0x1F bit 7 + * + * + * @param v_flat_u8 : The status of flat interrupt + * value | status + * -----------|------------- + * 0x00 | non flat + * 0x01 | flat position + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_flat(u8 +*v_flat_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read flat interrupt status */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_INTR_STAT_3_FLAT__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_flat_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_STAT_3_FLAT); + } + return com_rslt; +} +/*! + * @brief This API reads the temperature of the sensor + * from the register 0x21 bit 0 to 7 + * + * + * + * @param v_temp_s16 : The value of temperature + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_temp(s16 +*v_temp_s16) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Array contains the temperature lSB and MSB data + v_data_u8[0] - LSB + v_data_u8[1] - MSB*/ + u8 v_data_u8[BMI160_TEMP_DATA_SIZE] = {BMI160_INIT_VALUE, + BMI160_INIT_VALUE}; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read temperature data */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_TEMP_LSB_VALUE__REG, v_data_u8, + BMI160_TEMP_DATA_LENGTH); + *v_temp_s16 = + (s16)(((s32)((s8) (v_data_u8[BMI160_TEMP_MSB_BYTE]) << + BMI160_SHIFT_BIT_POSITION_BY_08_BITS)) + | v_data_u8[BMI160_TEMP_LSB_BYTE]); + } + return com_rslt; +} +/*! + * @brief This API reads the of the sensor + * form the register 0x23 and 0x24 bit 0 to 7 and 0 to 2 + * @brief this byte counter is updated each time a complete frame + * was read or writtern + * + * + * @param v_fifo_length_u32 : The value of fifo byte counter + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_fifo_length(u32 *v_fifo_length_u32) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Array contains the fifo length data + v_data_u8[0] - fifo length + v_data_u8[1] - fifo length*/ + u8 a_data_u8r[BMI160_FIFO_DATA_SIZE] = {BMI160_INIT_VALUE, + BMI160_INIT_VALUE}; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read fifo length*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_BYTE_COUNTER_LSB__REG, a_data_u8r, + BMI160_FIFO_DATA_LENGTH); + + a_data_u8r[BMI160_FIFO_LENGTH_MSB_BYTE] = + BMI160_GET_BITSLICE( + a_data_u8r[BMI160_FIFO_LENGTH_MSB_BYTE], + BMI160_USER_FIFO_BYTE_COUNTER_MSB); + + *v_fifo_length_u32 = + (u32)(((u32)((u8) ( + a_data_u8r[BMI160_FIFO_LENGTH_MSB_BYTE]) << + BMI160_SHIFT_BIT_POSITION_BY_08_BITS)) + | a_data_u8r[BMI160_FIFO_LENGTH_LSB_BYTE]); + } + return com_rslt; +} +/*! + * @brief This API reads the fifo data of the sensor + * from the register 0x24 + * @brief Data format depends on the setting of register FIFO_CONFIG + * + * + * + * @param v_fifodata_u8 : Pointer holding the fifo data + * @param fifo_length_u16 : The value of fifo length maximum + * 1024 + * + * @note For reading FIFO data use the following functions + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_fifo_data( +u8 *v_fifodata_u8, u16 v_fifo_length_u16) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read fifo data*/ + com_rslt = + p_bmi160->BMI160_BURST_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_DATA__REG, + v_fifodata_u8, v_fifo_length_u16); + + } + return com_rslt; +} +/*! + * @brief This API is used to get the + * accel output date rate form the register 0x40 bit 0 to 3 + * + * + * @param v_output_data_rate_u8 :The value of accel output date rate + * value | output data rate + * -------|-------------------------- + * 0 | BMI160_ACCEL_OUTPUT_DATA_RATE_RESERVED + * 1 | BMI160_ACCEL_OUTPUT_DATA_RATE_0_78HZ + * 2 | BMI160_ACCEL_OUTPUT_DATA_RATE_1_56HZ + * 3 | BMI160_ACCEL_OUTPUT_DATA_RATE_3_12HZ + * 4 | BMI160_ACCEL_OUTPUT_DATA_RATE_6_25HZ + * 5 | BMI160_ACCEL_OUTPUT_DATA_RATE_12_5HZ + * 6 | BMI160_ACCEL_OUTPUT_DATA_RATE_25HZ + * 7 | BMI160_ACCEL_OUTPUT_DATA_RATE_50HZ + * 8 | BMI160_ACCEL_OUTPUT_DATA_RATE_100HZ + * 9 | BMI160_ACCEL_OUTPUT_DATA_RATE_200HZ + * 10 | BMI160_ACCEL_OUTPUT_DATA_RATE_400HZ + * 11 | BMI160_ACCEL_OUTPUT_DATA_RATE_800HZ + * 12 | BMI160_ACCEL_OUTPUT_DATA_RATE_1600HZ + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_output_data_rate( +u8 *v_output_data_rate_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the accel output data rate*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_output_data_rate_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE); + } + return com_rslt; +} +/*! + * @brief This API is used to set the + * accel output date rate form the register 0x40 bit 0 to 3 + * + * + * @param v_output_data_rate_u8 :The value of accel output date rate + * value | output data rate + * -------|-------------------------- + * 0 | BMI160_ACCEL_OUTPUT_DATA_RATE_RESERVED + * 1 | BMI160_ACCEL_OUTPUT_DATA_RATE_0_78HZ + * 2 | BMI160_ACCEL_OUTPUT_DATA_RATE_1_56HZ + * 3 | BMI160_ACCEL_OUTPUT_DATA_RATE_3_12HZ + * 4 | BMI160_ACCEL_OUTPUT_DATA_RATE_6_25HZ + * 5 | BMI160_ACCEL_OUTPUT_DATA_RATE_12_5HZ + * 6 | BMI160_ACCEL_OUTPUT_DATA_RATE_25HZ + * 7 | BMI160_ACCEL_OUTPUT_DATA_RATE_50HZ + * 8 | BMI160_ACCEL_OUTPUT_DATA_RATE_100HZ + * 9 | BMI160_ACCEL_OUTPUT_DATA_RATE_200HZ + * 10 | BMI160_ACCEL_OUTPUT_DATA_RATE_400HZ + * 11 | BMI160_ACCEL_OUTPUT_DATA_RATE_800HZ + * 12 | BMI160_ACCEL_OUTPUT_DATA_RATE_1600HZ + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_output_data_rate( +u8 v_output_data_rate_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* accel output data rate selection */ + if ((v_output_data_rate_u8 != BMI160_INIT_VALUE) && + (v_output_data_rate_u8 <= BMI160_MAX_ACCEL_OUTPUT_DATA_RATE)) { + /* write accel output data rate */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE, + v_output_data_rate_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API is used to get the + * accel bandwidth from the register 0x40 bit 4 to 6 + * @brief bandwidth parameter determines filter configuration(acc_us=0) + * and averaging for under sampling mode(acc_us=1) + * + * + * @param v_bw_u8 : The value of accel bandwidth + * + * @note accel bandwidth depends on under sampling parameter + * @note under sampling parameter cab be set by the function + * "BMI160_SET_ACCEL_UNDER_SAMPLING_PARAMETER" + * + * @note Filter configuration + * accel_us | Filter configuration + * -----------|--------------------- + * 0x00 | OSR4 mode + * 0x01 | OSR2 mode + * 0x02 | normal mode + * 0x03 | CIC mode + * 0x04 | Reserved + * 0x05 | Reserved + * 0x06 | Reserved + * 0x07 | Reserved + * + * @note accel under sampling mode + * accel_us | Under sampling mode + * -----------|--------------------- + * 0x00 | no averaging + * 0x01 | average 2 samples + * 0x02 | average 4 samples + * 0x03 | average 8 samples + * 0x04 | average 16 samples + * 0x05 | average 32 samples + * 0x06 | average 64 samples + * 0x07 | average 128 samples + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_bw(u8 *v_bw_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the accel bandwidth */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_ACCEL_CONFIG_ACCEL_BW__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_bw_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_ACCEL_CONFIG_ACCEL_BW); + } + return com_rslt; +} +/*! + * @brief This API is used to set the + * accel bandwidth from the register 0x40 bit 4 to 6 + * @brief bandwidth parameter determines filter configuration(acc_us=0) + * and averaging for under sampling mode(acc_us=1) + * + * + * @param v_bw_u8 : The value of accel bandwidth + * + * @note accel bandwidth depends on under sampling parameter + * @note under sampling parameter cab be set by the function + * "BMI160_SET_ACCEL_UNDER_SAMPLING_PARAMETER" + * + * @note Filter configuration + * accel_us | Filter configuration + * -----------|--------------------- + * 0x00 | OSR4 mode + * 0x01 | OSR2 mode + * 0x02 | normal mode + * 0x03 | CIC mode + * 0x04 | Reserved + * 0x05 | Reserved + * 0x06 | Reserved + * 0x07 | Reserved + * + * @note accel under sampling mode + * accel_us | Under sampling mode + * -----------|--------------------- + * 0x00 | no averaging + * 0x01 | average 2 samples + * 0x02 | average 4 samples + * 0x03 | average 8 samples + * 0x04 | average 16 samples + * 0x05 | average 32 samples + * 0x06 | average 64 samples + * 0x07 | average 128 samples + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_bw(u8 v_bw_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* select accel bandwidth*/ + if (v_bw_u8 <= BMI160_MAX_ACCEL_BW) { + /* write accel bandwidth*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_ACCEL_CONFIG_ACCEL_BW__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_ACCEL_CONFIG_ACCEL_BW, + v_bw_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_ACCEL_CONFIG_ACCEL_BW__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API is used to get the accel + * under sampling parameter form the register 0x40 bit 7 + * + * + * + * + * @param v_accel_under_sampling_u8 : The value of accel under sampling + * value | under_sampling + * ----------|--------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_under_sampling_parameter( +u8 *v_accel_under_sampling_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the accel under sampling parameter */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_accel_under_sampling_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING); + } + return com_rslt; +} +/*! + * @brief This API is used to set the accel + * under sampling parameter form the register 0x40 bit 7 + * + * + * + * + * @param v_accel_under_sampling_u8 : The value of accel under sampling + * value | under_sampling + * ----------|--------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_under_sampling_parameter( +u8 v_accel_under_sampling_u8) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_accel_under_sampling_u8 <= BMI160_MAX_UNDER_SAMPLING) { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + /* write the accel under sampling parameter */ + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING, + v_accel_under_sampling_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } +} +return com_rslt; +} +/*! + * @brief This API is used to get the ranges + * (g values) of the accel from the register 0x41 bit 0 to 3 + * + * + * + * + * @param v_range_u8 : The value of accel g range + * value | g_range + * ----------|----------- + * 0x03 | BMI160_ACCEL_RANGE_2G + * 0x05 | BMI160_ACCEL_RANGE_4G + * 0x08 | BMI160_ACCEL_RANGE_8G + * 0x0C | BMI160_ACCEL_RANGE_16G + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_range( +u8 *v_range_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the accel range*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_ACCEL_RANGE__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_range_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_ACCEL_RANGE); + } + return com_rslt; +} +/*! + * @brief This API is used to set the ranges + * (g values) of the accel from the register 0x41 bit 0 to 3 + * + * + * + * + * @param v_range_u8 : The value of accel g range + * value | g_range + * ----------|----------- + * 0x03 | BMI160_ACCEL_RANGE_2G + * 0x05 | BMI160_ACCEL_RANGE_4G + * 0x08 | BMI160_ACCEL_RANGE_8G + * 0x0C | BMI160_ACCEL_RANGE_16G + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_range(u8 v_range_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if ((v_range_u8 == BMI160_ACCEL_RANGE0) || + (v_range_u8 == BMI160_ACCEL_RANGE1) || + (v_range_u8 == BMI160_ACCEL_RANGE3) || + (v_range_u8 == BMI160_ACCEL_RANGE4)) { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_ACCEL_RANGE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE( + v_data_u8, BMI160_USER_ACCEL_RANGE, + v_range_u8); + /* write the accel range*/ + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_ACCEL_RANGE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API is used to get the + * gyroscope output data rate from the register 0x42 bit 0 to 3 + * + * + * + * + * @param v_output_data_rate_u8 :The value of gyro output data rate + * value | gyro output data rate + * -----------|----------------------------- + * 0x00 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x01 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x02 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x03 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x04 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x05 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x06 | BMI160_GYRO_OUTPUT_DATA_RATE_25HZ + * 0x07 | BMI160_GYRO_OUTPUT_DATA_RATE_50HZ + * 0x08 | BMI160_GYRO_OUTPUT_DATA_RATE_100HZ + * 0x09 | BMI160_GYRO_OUTPUT_DATA_RATE_200HZ + * 0x0A | BMI160_GYRO_OUTPUT_DATA_RATE_400HZ + * 0x0B | BMI160_GYRO_OUTPUT_DATA_RATE_800HZ + * 0x0C | BMI160_GYRO_OUTPUT_DATA_RATE_1600HZ + * 0x0D | BMI160_GYRO_OUTPUT_DATA_RATE_3200HZ + * 0x0E | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x0F | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_output_data_rate( +u8 *v_output_data_rate_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the gyro output data rate*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_output_data_rate_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_GYRO_CONFIG_OUTPUT_DATA_RATE); + } + return com_rslt; +} +/*! + * @brief This API is used to set the + * gyroscope output data rate from the register 0x42 bit 0 to 3 + * + * + * + * + * @param v_output_data_rate_u8 :The value of gyro output data rate + * value | gyro output data rate + * -----------|----------------------------- + * 0x00 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x01 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x02 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x03 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x04 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x05 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x06 | BMI160_GYRO_OUTPUT_DATA_RATE_25HZ + * 0x07 | BMI160_GYRO_OUTPUT_DATA_RATE_50HZ + * 0x08 | BMI160_GYRO_OUTPUT_DATA_RATE_100HZ + * 0x09 | BMI160_GYRO_OUTPUT_DATA_RATE_200HZ + * 0x0A | BMI160_GYRO_OUTPUT_DATA_RATE_400HZ + * 0x0B | BMI160_GYRO_OUTPUT_DATA_RATE_800HZ + * 0x0C | BMI160_GYRO_OUTPUT_DATA_RATE_1600HZ + * 0x0D | BMI160_GYRO_OUTPUT_DATA_RATE_3200HZ + * 0x0E | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x0F | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_output_data_rate( +u8 v_output_data_rate_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* select the gyro output data rate*/ + if ((v_output_data_rate_u8 < BMI160_OUTPUT_DATA_RATE6) && + (v_output_data_rate_u8 != BMI160_INIT_VALUE) + && (v_output_data_rate_u8 != BMI160_OUTPUT_DATA_RATE1) + && (v_output_data_rate_u8 != BMI160_OUTPUT_DATA_RATE2) + && (v_output_data_rate_u8 != BMI160_OUTPUT_DATA_RATE3) + && (v_output_data_rate_u8 != BMI160_OUTPUT_DATA_RATE4) + && (v_output_data_rate_u8 != BMI160_OUTPUT_DATA_RATE5) + && (v_output_data_rate_u8 != BMI160_OUTPUT_DATA_RATE6) + && (v_output_data_rate_u8 != BMI160_OUTPUT_DATA_RATE7)) { + /* write the gyro output data rate */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_GYRO_CONFIG_OUTPUT_DATA_RATE, + v_output_data_rate_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API is used to get the + * data of gyro from the register 0x42 bit 4 to 5 + * + * + * + * + * @param v_bw_u8 : The value of gyro bandwidth + * value | gyro bandwidth + * ----------|---------------- + * 0x00 | BMI160_GYRO_OSR4_MODE + * 0x01 | BMI160_GYRO_OSR2_MODE + * 0x02 | BMI160_GYRO_NORMAL_MODE + * 0x03 | BMI160_GYRO_CIC_MODE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_bw(u8 *v_bw_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read gyro bandwidth*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_GYRO_CONFIG_BW__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_bw_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_GYRO_CONFIG_BW); + } + return com_rslt; +} +/*! + * @brief This API is used to set the + * data of gyro from the register 0x42 bit 4 to 5 + * + * + * + * + * @param v_bw_u8 : The value of gyro bandwidth + * value | gyro bandwidth + * ----------|---------------- + * 0x00 | BMI160_GYRO_OSR4_MODE + * 0x01 | BMI160_GYRO_OSR2_MODE + * 0x02 | BMI160_GYRO_NORMAL_MODE + * 0x03 | BMI160_GYRO_CIC_MODE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_bw(u8 v_bw_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_bw_u8 <= BMI160_MAX_GYRO_BW) { + /* write the gyro bandwidth*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_GYRO_CONFIG_BW__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_GYRO_CONFIG_BW, v_bw_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_GYRO_CONFIG_BW__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API reads the range + * of gyro from the register 0x43 bit 0 to 2 + * + * @param v_range_u8 : The value of gyro range + * value | range + * ----------|------------------------------- + * 0x00 | BMI160_GYRO_RANGE_2000_DEG_SEC + * 0x01 | BMI160_GYRO_RANGE_1000_DEG_SEC + * 0x02 | BMI160_GYRO_RANGE_500_DEG_SEC + * 0x03 | BMI160_GYRO_RANGE_250_DEG_SEC + * 0x04 | BMI160_GYRO_RANGE_125_DEG_SEC + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_range(u8 *v_range_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the gyro range */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_GYRO_RANGE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_range_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_GYRO_RANGE); + } + return com_rslt; +} +/*! + * @brief This API set the range + * of gyro from the register 0x43 bit 0 to 2 + * + * @param v_range_u8 : The value of gyro range + * value | range + * ----------|------------------------------- + * 0x00 | BMI160_GYRO_RANGE_2000_DEG_SEC + * 0x01 | BMI160_GYRO_RANGE_1000_DEG_SEC + * 0x02 | BMI160_GYRO_RANGE_500_DEG_SEC + * 0x03 | BMI160_GYRO_RANGE_250_DEG_SEC + * 0x04 | BMI160_GYRO_RANGE_125_DEG_SEC + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_range(u8 v_range_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_range_u8 <= BMI160_MAX_GYRO_RANGE) { + /* write the gyro range value */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_GYRO_RANGE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_GYRO_RANGE, + v_range_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_GYRO_RANGE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API is used to get the + * output data rate of magnetometer from the register 0x44 bit 0 to 3 + * + * + * + * + * @param v_output_data_rat_u8e : The value of mag output data rate + * value | mag output data rate + * ---------|--------------------------- + * 0x00 |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED + * 0x01 |BMI160_MAG_OUTPUT_DATA_RATE_0_78HZ + * 0x02 |BMI160_MAG_OUTPUT_DATA_RATE_1_56HZ + * 0x03 |BMI160_MAG_OUTPUT_DATA_RATE_3_12HZ + * 0x04 |BMI160_MAG_OUTPUT_DATA_RATE_6_25HZ + * 0x05 |BMI160_MAG_OUTPUT_DATA_RATE_12_5HZ + * 0x06 |BMI160_MAG_OUTPUT_DATA_RATE_25HZ + * 0x07 |BMI160_MAG_OUTPUT_DATA_RATE_50HZ + * 0x08 |BMI160_MAG_OUTPUT_DATA_RATE_100HZ + * 0x09 |BMI160_MAG_OUTPUT_DATA_RATE_200HZ + * 0x0A |BMI160_MAG_OUTPUT_DATA_RATE_400HZ + * 0x0B |BMI160_MAG_OUTPUT_DATA_RATE_800HZ + * 0x0C |BMI160_MAG_OUTPUT_DATA_RATE_1600HZ + * 0x0D |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED0 + * 0x0E |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED1 + * 0x0F |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED2 + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_output_data_rate( +u8 *v_output_data_rat_u8e) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the mag data output rate*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_MAG_CONFIG_OUTPUT_DATA_RATE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_output_data_rat_u8e = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_MAG_CONFIG_OUTPUT_DATA_RATE); + } + return com_rslt; +} +/*! + * @brief This API is used to set the + * output data rate of magnetometer from the register 0x44 bit 0 to 3 + * + * + * + * + * @param v_output_data_rat_u8e : The value of mag output data rate + * value | mag output data rate + * ---------|--------------------------- + * 0x00 |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED + * 0x01 |BMI160_MAG_OUTPUT_DATA_RATE_0_78HZ + * 0x02 |BMI160_MAG_OUTPUT_DATA_RATE_1_56HZ + * 0x03 |BMI160_MAG_OUTPUT_DATA_RATE_3_12HZ + * 0x04 |BMI160_MAG_OUTPUT_DATA_RATE_6_25HZ + * 0x05 |BMI160_MAG_OUTPUT_DATA_RATE_12_5HZ + * 0x06 |BMI160_MAG_OUTPUT_DATA_RATE_25HZ + * 0x07 |BMI160_MAG_OUTPUT_DATA_RATE_50HZ + * 0x08 |BMI160_MAG_OUTPUT_DATA_RATE_100HZ + * 0x09 |BMI160_MAG_OUTPUT_DATA_RATE_200HZ + * 0x0A |BMI160_MAG_OUTPUT_DATA_RATE_400HZ + * 0x0B |BMI160_MAG_OUTPUT_DATA_RATE_800HZ + * 0x0C |BMI160_MAG_OUTPUT_DATA_RATE_1600HZ + * 0x0D |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED0 + * 0x0E |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED1 + * 0x0F |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED2 + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_output_data_rate( +u8 v_output_data_rat_u8e) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* select the mag data output rate*/ + if ((v_output_data_rat_u8e + <= BMI160_MAX_ACCEL_OUTPUT_DATA_RATE) + && (v_output_data_rat_u8e + != BMI160_OUTPUT_DATA_RATE0) + && (v_output_data_rat_u8e + != BMI160_OUTPUT_DATA_RATE6) + && (v_output_data_rat_u8e + != BMI160_OUTPUT_DATA_RATE7)) { + /* write the mag data output rate*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_MAG_CONFIG_OUTPUT_DATA_RATE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_MAG_CONFIG_OUTPUT_DATA_RATE, + v_output_data_rat_u8e); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_MAG_CONFIG_OUTPUT_DATA_RATE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} + /*! + * @brief This API is used to read Down sampling + * for gyro (2**downs_gyro) in the register 0x45 bit 0 to 2 + * + * + * + * + * @param v_fifo_down_gyro_u8 :The value of gyro fifo down + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_down_gyro( +u8 *v_fifo_down_gyro_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the gyro fifo down*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_DOWN_GYRO__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_fifo_down_gyro_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_DOWN_GYRO); + } + return com_rslt; +} + /*! + * @brief This API is used to set Down sampling + * for gyro (2**downs_gyro) in the register 0x45 bit 0 to 2 + * + * + * + * + * @param v_fifo_down_gyro_u8 :The value of gyro fifo down + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_down_gyro( +u8 v_fifo_down_gyro_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write the gyro fifo down*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_DOWN_GYRO__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE( + v_data_u8, + BMI160_USER_FIFO_DOWN_GYRO, + v_fifo_down_gyro_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FIFO_DOWN_GYRO__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } + return com_rslt; +} +/*! + * @brief This API is used to read gyro fifo filter data + * from the register 0x45 bit 3 + * + * + * + * @param v_gyro_fifo_filter_data_u8 :The value of gyro filter data + * value | gyro_fifo_filter_data + * ------------|------------------------- + * 0x00 | Unfiltered data + * 0x01 | Filtered data + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_fifo_filter_data( +u8 *v_gyro_fifo_filter_data_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the gyro fifo filter data */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_FILTER_GYRO__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_gyro_fifo_filter_data_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_FILTER_GYRO); + } + return com_rslt; +} +/*! + * @brief This API is used to set gyro fifo filter data + * from the register 0x45 bit 3 + * + * + * + * @param v_gyro_fifo_filter_data_u8 :The value of gyro filter data + * value | gyro_fifo_filter_data + * ------------|------------------------- + * 0x00 | Unfiltered data + * 0x01 | Filtered data + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_fifo_filter_data( +u8 v_gyro_fifo_filter_data_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_gyro_fifo_filter_data_u8 + <= BMI160_MAX_VALUE_FIFO_FILTER) { + /* write the gyro fifo filter data */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_FILTER_GYRO__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE( + v_data_u8, + BMI160_USER_FIFO_FILTER_GYRO, + v_gyro_fifo_filter_data_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FIFO_FILTER_GYRO__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API is used to read Down sampling + * for accel (2*downs_accel) from the register 0x45 bit 4 to 6 + * + * + * + * + * @param v_fifo_down_u8 :The value of accel fifo down + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_down_accel( +u8 *v_fifo_down_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the accel fifo down data */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_DOWN_ACCEL__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_fifo_down_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_DOWN_ACCEL); + } + return com_rslt; +} + /*! + * @brief This API is used to set Down sampling + * for accel (2*downs_accel) from the register 0x45 bit 4 to 6 + * + * + * + * + * @param v_fifo_down_u8 :The value of accel fifo down + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_down_accel( +u8 v_fifo_down_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write the accel fifo down data */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_DOWN_ACCEL__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_DOWN_ACCEL, v_fifo_down_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FIFO_DOWN_ACCEL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } + return com_rslt; +} +/*! + * @brief This API is used to read accel fifo filter data + * from the register 0x45 bit 7 + * + * + * + * @param v_accel_fifo_filter_u8 :The value of accel filter data + * value | accel_fifo_filter_data + * ------------|------------------------- + * 0x00 | Unfiltered data + * 0x01 | Filtered data + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_fifo_filter_data( +u8 *v_accel_fifo_filter_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the accel fifo filter data */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_FILTER_ACCEL__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_accel_fifo_filter_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_FILTER_ACCEL); + } + return com_rslt; +} +/*! + * @brief This API is used to set accel fifo filter data + * from the register 0x45 bit 7 + * + * + * + * @param v_accel_fifo_filter_u8 :The value of accel filter data + * value | accel_fifo_filter_data + * ------------|------------------------- + * 0x00 | Unfiltered data + * 0x01 | Filtered data + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_fifo_filter_data( +u8 v_accel_fifo_filter_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_accel_fifo_filter_u8 <= BMI160_MAX_VALUE_FIFO_FILTER) { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_FILTER_ACCEL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + /* write accel fifo filter data */ + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_FILTER_ACCEL, + v_accel_fifo_filter_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FIFO_FILTER_ACCEL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API is used to Trigger an interrupt + * when FIFO contains water mark level from the register 0x46 bit 0 to 7 + * + * + * + * @param v_fifo_wm_u8 : The value of fifo water mark level + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_wm( +u8 *v_fifo_wm_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the fifo water mark level*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_WM__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_fifo_wm_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_WM); + } + return com_rslt; +} +/*! + * @brief This API is used to Trigger an interrupt + * when FIFO contains water mark level from the register 0x46 bit 0 to 7 + * + * + * + * @param v_fifo_wm_u8 : The value of fifo water mark level + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_wm( +u8 v_fifo_wm_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write the fifo water mark level*/ + com_rslt = + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_WM__REG, + &v_fifo_wm_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + return com_rslt; +} +/*! + * @brief This API reads fifo sensor time + * frame after the last valid data frame form the register 0x47 bit 1 + * + * + * + * + * @param v_fifo_time_enable_u8 : The value of sensor time + * value | fifo sensor time + * ------------|------------------------- + * 0x00 | do not return sensortime frame + * 0x01 | return sensortime frame + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_time_enable( +u8 *v_fifo_time_enable_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the fifo sensor time*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_TIME_ENABLE__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_fifo_time_enable_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_TIME_ENABLE); + } + return com_rslt; +} +/*! + * @brief This API set fifo sensor time + * frame after the last valid data frame form the register 0x47 bit 1 + * + * + * + * + * @param v_fifo_time_enable_u8 : The value of sensor time + * value | fifo sensor time + * ------------|------------------------- + * 0x00 | do not return sensortime frame + * 0x01 | return sensortime frame + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_time_enable( +u8 v_fifo_time_enable_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_fifo_time_enable_u8 <= BMI160_MAX_VALUE_FIFO_TIME) { + /* write the fifo sensor time*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_TIME_ENABLE__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_TIME_ENABLE, + v_fifo_time_enable_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FIFO_TIME_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API reads FIFO tag interrupt2 enable status + * from the resister 0x47 bit 2 + * + * @param v_fifo_tag_intr2_u8 : The value of fifo tag interrupt + * value | fifo tag interrupt + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_tag_intr2_enable( +u8 *v_fifo_tag_intr2_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the fifo tag interrupt2*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_TAG_INTR2_ENABLE__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_fifo_tag_intr2_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_TAG_INTR2_ENABLE); + } + return com_rslt; +} +/*! + * @brief This API set FIFO tag interrupt2 enable status + * from the resister 0x47 bit 2 + * + * @param v_fifo_tag_intr2_u8 : The value of fifo tag interrupt + * value | fifo tag interrupt + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_tag_intr2_enable( +u8 v_fifo_tag_intr2_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_fifo_tag_intr2_u8 <= BMI160_MAX_VALUE_FIFO_INTR) { + /* write the fifo tag interrupt2*/ + com_rslt = bmi160_set_input_enable(1, + v_fifo_tag_intr2_u8); + com_rslt += + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_TAG_INTR2_ENABLE__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_TAG_INTR2_ENABLE, + v_fifo_tag_intr2_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FIFO_TAG_INTR2_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API get FIFO tag interrupt1 enable status + * from the resister 0x47 bit 3 + * + * @param v_fifo_tag_intr1_u8 :The value of fifo tag interrupt1 + * value | fifo tag interrupt + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_tag_intr1_enable( +u8 *v_fifo_tag_intr1_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read fifo tag interrupt*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_TAG_INTR1_ENABLE__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_fifo_tag_intr1_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_TAG_INTR1_ENABLE); + } + return com_rslt; +} +/*! + * @brief This API set FIFO tag interrupt1 enable status + * from the resister 0x47 bit 3 + * + * @param v_fifo_tag_intr1_u8 :The value of fifo tag interrupt1 + * value | fifo tag interrupt + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_tag_intr1_enable( +u8 v_fifo_tag_intr1_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_fifo_tag_intr1_u8 <= BMI160_MAX_VALUE_FIFO_INTR) { + /* write the fifo tag interrupt*/ + com_rslt = bmi160_set_input_enable(BMI160_INIT_VALUE, + v_fifo_tag_intr1_u8); + com_rslt += + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_TAG_INTR1_ENABLE__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_TAG_INTR1_ENABLE, + v_fifo_tag_intr1_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FIFO_TAG_INTR1_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API reads FIFO frame + * header enable from the register 0x47 bit 4 + * + * @param v_fifo_header_u8 :The value of fifo header + * value | fifo header + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_header_enable( +u8 *v_fifo_header_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read fifo header */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_HEADER_ENABLE__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_fifo_header_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_HEADER_ENABLE); + } + return com_rslt; +} +/*! + * @brief This API set FIFO frame + * header enable from the register 0x47 bit 4 + * + * @param v_fifo_header_u8 :The value of fifo header + * value | fifo header + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_header_enable( +u8 v_fifo_header_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_fifo_header_u8 <= BMI160_MAX_VALUE_FIFO_HEADER) { + /* write the fifo header */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_HEADER_ENABLE__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_HEADER_ENABLE, + v_fifo_header_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FIFO_HEADER_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API is used to read stored + * magnetometer data in FIFO (all 3 axes) from the register 0x47 bit 5 + * + * @param v_fifo_mag_u8 : The value of fifo mag enble + * value | fifo mag + * ----------|------------------- + * 0x00 | no magnetometer data is stored + * 0x01 | magnetometer data is stored + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_mag_enable( +u8 *v_fifo_mag_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the fifo mag enable*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_MAG_ENABLE__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_fifo_mag_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_MAG_ENABLE); + } + return com_rslt; +} +/*! + * @brief This API is used to set stored + * magnetometer data in FIFO (all 3 axes) from the register 0x47 bit 5 + * + * @param v_fifo_mag_u8 : The value of fifo mag enble + * value | fifo mag + * ----------|------------------- + * 0x00 | no magnetometer data is stored + * 0x01 | magnetometer data is stored + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_mag_enable( +u8 v_fifo_mag_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_fifo_mag_u8 <= BMI160_MAX_VALUE_FIFO_MAG) { + /* write the fifo mag enable*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_FIFO_MAG_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_MAG_ENABLE, + v_fifo_mag_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_FIFO_MAG_ENABLE__REG, + &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API is used to read stored + * accel data in FIFO (all 3 axes) from the register 0x47 bit 6 + * + * @param v_fifo_accel_u8 : The value of fifo accel enble + * value | fifo accel + * ----------|------------------- + * 0x00 | no accel data is stored + * 0x01 | accel data is stored + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_accel_enable( +u8 *v_fifo_accel_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the accel fifo enable*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_ACCEL_ENABLE__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_fifo_accel_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_ACCEL_ENABLE); + } + return com_rslt; +} +/*! + * @brief This API is used to set stored + * accel data in FIFO (all 3 axes) from the register 0x47 bit 6 + * + * @param v_fifo_accel_u8 : The value of fifo accel enble + * value | fifo accel + * ----------|------------------- + * 0x00 | no accel data is stored + * 0x01 | accel data is stored + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_accel_enable( +u8 v_fifo_accel_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_fifo_accel_u8 <= BMI160_MAX_VALUE_FIFO_ACCEL) { + /* write the fifo mag enables*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_ACCEL_ENABLE__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_ACCEL_ENABLE, v_fifo_accel_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FIFO_ACCEL_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API is used to read stored + * gyro data in FIFO (all 3 axes) from the resister 0x47 bit 7 + * + * + * @param v_fifo_gyro_u8 : The value of fifo gyro enble + * value | fifo gyro + * ----------|------------------- + * 0x00 | no gyro data is stored + * 0x01 | gyro data is stored + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_gyro_enable( +u8 *v_fifo_gyro_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read fifo gyro enable */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_GYRO_ENABLE__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_fifo_gyro_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_GYRO_ENABLE); + } + return com_rslt; +} +/*! + * @brief This API is used to set stored + * gyro data in FIFO (all 3 axes) from the resister 0x47 bit 7 + * + * + * @param v_fifo_gyro_u8 : The value of fifo gyro enble + * value | fifo gyro + * ----------|------------------- + * 0x00 | no gyro data is stored + * 0x01 | gyro data is stored + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_gyro_enable( +u8 v_fifo_gyro_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_fifo_gyro_u8 <= BMI160_MAX_VALUE_FIFO_GYRO) { + /* write fifo gyro enable*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_FIFO_GYRO_ENABLE__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_FIFO_GYRO_ENABLE, v_fifo_gyro_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FIFO_GYRO_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API is used to read + * I2C device address of auxiliary mag from the register 0x4B bit 1 to 7 + * + * + * + * + * @param v_i2c_device_addr_u8 : The value of mag I2C device address + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_i2c_device_addr( +u8 *v_i2c_device_addr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the mag I2C device address*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_I2C_DEVICE_ADDR__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_i2c_device_addr_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_I2C_DEVICE_ADDR); + } + return com_rslt; +} +/*! + * @brief This API is used to set + * I2C device address of auxiliary mag from the register 0x4B bit 1 to 7 + * + * + * + * + * @param v_i2c_device_addr_u8 : The value of mag I2C device address + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_i2c_device_addr( +u8 v_i2c_device_addr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write the mag I2C device address*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_I2C_DEVICE_ADDR__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_I2C_DEVICE_ADDR, + v_i2c_device_addr_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_I2C_DEVICE_ADDR__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } + return com_rslt; +} +/*! + * @brief This API is used to read + * Burst data length (1,2,6,8 byte) from the register 0x4C bit 0 to 1 + * + * + * + * + * @param v_mag_burst_u8 : The data of mag burst read lenth + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_burst( +u8 *v_mag_burst_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read mag burst mode length*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_MAG_BURST__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_mag_burst_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_MAG_BURST); + } + return com_rslt; +} +/*! + * @brief This API is used to set + * Burst data length (1,2,6,8 byte) from the register 0x4C bit 0 to 1 + * + * + * + * + * @param v_mag_burst_u8 : The data of mag burst read lenth + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_burst( +u8 v_mag_burst_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write mag burst mode length*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_MAG_BURST__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_MAG_BURST, v_mag_burst_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_MAG_BURST__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } + return com_rslt; +} +/*! + * @brief This API is used to read + * trigger-readout offset in units of 2.5 ms. If set to zero, + * the offset is maximum, i.e. after readout a trigger + * is issued immediately. from the register 0x4C bit 2 to 5 + * + * + * + * + * @param v_mag_offset_u8 : The value of mag offset + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_offset( +u8 *v_mag_offset_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_MAG_OFFSET__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_mag_offset_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_MAG_OFFSET); + } + return com_rslt; +} +/*! + * @brief This API is used to set + * trigger-readout offset in units of 2.5 ms. If set to zero, + * the offset is maximum, i.e. after readout a trigger + * is issued immediately. from the register 0x4C bit 2 to 5 + * + * + * + * + * @param v_mag_offset_u8 : The value of mag offset + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_offset( +u8 v_mag_offset_u8) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_MAG_OFFSET__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_MAG_OFFSET, v_mag_offset_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->dev_addr, + BMI160_USER_MAG_OFFSET__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } +return com_rslt; +} +/*! + * @brief This API is used to read + * Enable register access on MAG_IF[2] or MAG_IF[3] writes. + * This implies that the DATA registers are not updated with + * magnetometer values. Accessing magnetometer requires + * the magnetometer in normal mode in PMU_STATUS. + * from the register 0x4C bit 7 + * + * + * + * @param v_mag_manual_u8 : The value of mag manual enable + * value | mag manual + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_manual_enable( +u8 *v_mag_manual_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read mag manual */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_MAG_MANUAL_ENABLE__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_mag_manual_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_MAG_MANUAL_ENABLE); + } + return com_rslt; +} +/*! + * @brief This API is used to set + * Enable register access on MAG_IF[2] or MAG_IF[3] writes. + * This implies that the DATA registers are not updated with + * magnetometer values. Accessing magnetometer requires + * the magnetometer in normal mode in PMU_STATUS. + * from the register 0x4C bit 7 + * + * + * + * @param v_mag_manual_u8 : The value of mag manual enable + * value | mag manual + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_manual_enable( +u8 v_mag_manual_u8) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = BMI160_INIT_VALUE; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write the mag manual*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_MAG_MANUAL_ENABLE__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + if (com_rslt == SUCCESS) { + /* set the bit of mag manual enable*/ + v_data_u8 = + BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_MAG_MANUAL_ENABLE, v_mag_manual_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->dev_addr, + BMI160_USER_MAG_MANUAL_ENABLE__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + if (com_rslt == SUCCESS) + p_bmi160->mag_manual_enable = v_mag_manual_u8; + else + p_bmi160->mag_manual_enable = E_BMI160_COMM_RES; + } +return com_rslt; +} +/*! + * @brief This API is used to read data + * magnetometer address to read from the register 0x4D bit 0 to 7 + * @brief It used to provide mag read address of auxiliary mag + * + * + * + * + * @param v_mag_read_addr_u8 : The value of address need to be read + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_read_addr( +u8 *v_mag_read_addr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the written address*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_READ_ADDR__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_mag_read_addr_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_READ_ADDR); + } + return com_rslt; +} +/*! + * @brief This API is used to set + * magnetometer write address from the register 0x4D bit 0 to 7 + * @brief mag write address writes the address of auxiliary mag to write + * + * + * + * @param v_mag_read_addr_u8: + * The data of auxiliary mag address to write data + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_read_addr( +u8 v_mag_read_addr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write the mag read address*/ + com_rslt = + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->dev_addr, + BMI160_USER_READ_ADDR__REG, &v_mag_read_addr_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + return com_rslt; +} +/*! + * @brief This API is used to read + * magnetometer write address from the register 0x4E bit 0 to 7 + * @brief mag write address writes the address of auxiliary mag to write + * + * + * + * @param v_mag_write_addr_u8: + * The data of auxiliary mag address to write data + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_write_addr( +u8 *v_mag_write_addr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the address of last written */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_WRITE_ADDR__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_mag_write_addr_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_WRITE_ADDR); + } + return com_rslt; +} +/*! + * @brief This API is used to set + * magnetometer write address from the register 0x4E bit 0 to 7 + * @brief mag write address writes the address of auxiliary mag to write + * + * + * + * @param v_mag_write_addr_u8: + * The data of auxiliary mag address to write data + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_write_addr( +u8 v_mag_write_addr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write the data of mag address to write data */ + com_rslt = + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->dev_addr, + BMI160_USER_WRITE_ADDR__REG, &v_mag_write_addr_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + return com_rslt; +} +/*! + * @brief This API is used to read magnetometer write data + * form the resister 0x4F bit 0 to 7 + * @brief This writes the data will be wrote to mag + * + * + * + * @param v_mag_write_data_u8: The value of mag data + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_write_data( +u8 *v_mag_write_data_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_WRITE_DATA__REG, &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_mag_write_data_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_WRITE_DATA); + } + return com_rslt; +} +/*! + * @brief This API is used to set magnetometer write data + * form the resister 0x4F bit 0 to 7 + * @brief This writes the data will be wrote to mag + * + * + * + * @param v_mag_write_data_u8: The value of mag data + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_write_data( +u8 v_mag_write_data_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->dev_addr, + BMI160_USER_WRITE_DATA__REG, &v_mag_write_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + return com_rslt; +} +/*! + * @brief This API is used to read + * interrupt enable from the register 0x50 bit 0 to 7 + * + * + * + * + * @param v_enable_u8 : Value to decided to select interrupt + * v_enable_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_ANY_MOTION_X_ENABLE + * 1 | BMI160_ANY_MOTION_Y_ENABLE + * 2 | BMI160_ANY_MOTION_Z_ENABLE + * 3 | BMI160_DOUBLE_TAP_ENABLE + * 4 | BMI160_SINGLE_TAP_ENABLE + * 5 | BMI160_ORIENT_ENABLE + * 6 | BMI160_FLAT_ENABLE + * + * @param v_intr_enable_zero_u8 : The interrupt enable value + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_enable_0( +u8 v_enable_u8, u8 *v_intr_enable_zero_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* select interrupt to read*/ + switch (v_enable_u8) { + case BMI160_ANY_MOTION_X_ENABLE: + /* read the any motion interrupt x data */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_enable_zero_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE); + break; + case BMI160_ANY_MOTION_Y_ENABLE: + /* read the any motion interrupt y data */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_enable_zero_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE); + break; + case BMI160_ANY_MOTION_Z_ENABLE: + /* read the any motion interrupt z data */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_enable_zero_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE); + break; + case BMI160_DOUBLE_TAP_ENABLE: + /* read the double tap interrupt data */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_enable_zero_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE); + break; + case BMI160_SINGLE_TAP_ENABLE: + /* read the single tap interrupt data */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_enable_zero_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE); + break; + case BMI160_ORIENT_ENABLE: + /* read the orient interrupt data */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_ENABLE_0_ORIENT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_enable_zero_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_0_ORIENT_ENABLE); + break; + case BMI160_FLAT_ENABLE: + /* read the flat interrupt data */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_ENABLE_0_FLAT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_enable_zero_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_0_FLAT_ENABLE); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief This API is used to set + * interrupt enable from the register 0x50 bit 0 to 7 + * + * + * + * + * @param v_enable_u8 : Value to decided to select interrupt + * v_enable_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_ANY_MOTION_X_ENABLE + * 1 | BMI160_ANY_MOTION_Y_ENABLE + * 2 | BMI160_ANY_MOTION_Z_ENABLE + * 3 | BMI160_DOUBLE_TAP_ENABLE + * 4 | BMI160_SINGLE_TAP_ENABLE + * 5 | BMI160_ORIENT_ENABLE + * 6 | BMI160_FLAT_ENABLE + * + * @param v_intr_enable_zero_u8 : The interrupt enable value + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_enable_0( +u8 v_enable_u8, u8 v_intr_enable_zero_u8) +{ +/* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_enable_u8) { + case BMI160_ANY_MOTION_X_ENABLE: + /* write any motion x*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE, + v_intr_enable_zero_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_ANY_MOTION_Y_ENABLE: + /* write any motion y*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE, + v_intr_enable_zero_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_ANY_MOTION_Z_ENABLE: + /* write any motion z*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE, + v_intr_enable_zero_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_DOUBLE_TAP_ENABLE: + /* write double tap*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE, + v_intr_enable_zero_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_SINGLE_TAP_ENABLE: + /* write single tap */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE, + v_intr_enable_zero_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_ORIENT_ENABLE: + /* write orient interrupt*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_ENABLE_0_ORIENT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_0_ORIENT_ENABLE, + v_intr_enable_zero_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_0_ORIENT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_FLAT_ENABLE: + /* write flat interrupt*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_ENABLE_0_FLAT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_0_FLAT_ENABLE, + v_intr_enable_zero_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_0_FLAT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } +} +return com_rslt; +} +/*! + * @brief This API is used to read + * interrupt enable byte1 from the register 0x51 bit 0 to 6 + * @brief It read the high_g_x,high_g_y,high_g_z,low_g_enable + * data ready, fifo full and fifo water mark. + * + * + * + * @param v_enable_u8 : The value of interrupt enable + * @param v_enable_u8 : Value to decided to select interrupt + * v_enable_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_HIGH_G_X_ENABLE + * 1 | BMI160_HIGH_G_Y_ENABLE + * 2 | BMI160_HIGH_G_Z_ENABLE + * 3 | BMI160_LOW_G_ENABLE + * 4 | BMI160_DATA_RDY_ENABLE + * 5 | BMI160_FIFO_FULL_ENABLE + * 6 | BMI160_FIFO_WM_ENABLE + * + * @param v_intr_enable_1_u8 : The interrupt enable value + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_enable_1( +u8 v_enable_u8, u8 *v_intr_enable_1_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_enable_u8) { + case BMI160_HIGH_G_X_ENABLE: + /* read high_g_x interrupt*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_enable_1_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE); + break; + case BMI160_HIGH_G_Y_ENABLE: + /* read high_g_y interrupt*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_enable_1_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE); + break; + case BMI160_HIGH_G_Z_ENABLE: + /* read high_g_z interrupt*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_enable_1_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE); + break; + case BMI160_LOW_G_ENABLE: + /* read low_g interrupt */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_enable_1_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE); + break; + case BMI160_DATA_RDY_ENABLE: + /* read data ready interrupt */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_enable_1_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_1_DATA_RDY_ENABLE); + break; + case BMI160_FIFO_FULL_ENABLE: + /* read fifo full interrupt */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_enable_1_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE); + break; + case BMI160_FIFO_WM_ENABLE: + /* read fifo water mark interrupt */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_enable_1_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_1_FIFO_WM_ENABLE); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief This API is used to set + * interrupt enable byte1 from the register 0x51 bit 0 to 6 + * @brief It read the high_g_x,high_g_y,high_g_z,low_g_enable + * data ready, fifo full and fifo water mark. + * + * + * + * @param v_enable_u8 : The value of interrupt enable + * @param v_enable_u8 : Value to decided to select interrupt + * v_enable_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_HIGH_G_X_ENABLE + * 1 | BMI160_HIGH_G_Y_ENABLE + * 2 | BMI160_HIGH_G_Z_ENABLE + * 3 | BMI160_LOW_G_ENABLE + * 4 | BMI160_DATA_RDY_ENABLE + * 5 | BMI160_FIFO_FULL_ENABLE + * 6 | BMI160_FIFO_WM_ENABLE + * + * @param v_intr_enable_1_u8 : The interrupt enable value + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_enable_1( +u8 v_enable_u8, u8 v_intr_enable_1_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_enable_u8) { + case BMI160_HIGH_G_X_ENABLE: + /* write high_g_x interrupt*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE, + v_intr_enable_1_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_HIGH_G_Y_ENABLE: + /* write high_g_y interrupt*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE, + v_intr_enable_1_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_HIGH_G_Z_ENABLE: + /* write high_g_z interrupt*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE, + v_intr_enable_1_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_LOW_G_ENABLE: + /* write low_g interrupt*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE, + v_intr_enable_1_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_DATA_RDY_ENABLE: + /* write data ready interrupt*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_1_DATA_RDY_ENABLE, + v_intr_enable_1_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_FIFO_FULL_ENABLE: + /* write fifo full interrupt*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE, + v_intr_enable_1_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_FIFO_WM_ENABLE: + /* write fifo water mark interrupt*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_1_FIFO_WM_ENABLE, + v_intr_enable_1_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief This API is used to read + * interrupt enable byte2 from the register bit 0x52 bit 0 to 3 + * @brief It reads no motion x,y and z + * + * + * + * @param v_enable_u8: The value of interrupt enable + * v_enable_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_NOMOTION_X_ENABLE + * 1 | BMI160_NOMOTION_Y_ENABLE + * 2 | BMI160_NOMOTION_Z_ENABLE + * + * @param v_intr_enable_2_u8 : The interrupt enable value + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_enable_2( +u8 v_enable_u8, u8 *v_intr_enable_2_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_enable_u8) { + case BMI160_NOMOTION_X_ENABLE: + /* read no motion x */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_enable_2_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE); + break; + case BMI160_NOMOTION_Y_ENABLE: + /* read no motion y */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_enable_2_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE); + break; + case BMI160_NOMOTION_Z_ENABLE: + /* read no motion z */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_enable_2_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief This API is used to set + * interrupt enable byte2 from the register bit 0x52 bit 0 to 3 + * @brief It reads no motion x,y and z + * + * + * + * @param v_enable_u8: The value of interrupt enable + * v_enable_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_NOMOTION_X_ENABLE + * 1 | BMI160_NOMOTION_Y_ENABLE + * 2 | BMI160_NOMOTION_Z_ENABLE + * + * @param v_intr_enable_2_u8 : The interrupt enable value + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_enable_2( +u8 v_enable_u8, u8 v_intr_enable_2_u8) +{ +/* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_enable_u8) { + case BMI160_NOMOTION_X_ENABLE: + /* write no motion x */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE, + v_intr_enable_2_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_NOMOTION_Y_ENABLE: + /* write no motion y */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE, + v_intr_enable_2_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_NOMOTION_Z_ENABLE: + /* write no motion z */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE, + v_intr_enable_2_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } +} +return com_rslt; +} + /*! + * @brief This API is used to read + * interrupt enable step detector interrupt from + * the register bit 0x52 bit 3 + * + * + * + * + * @param v_step_intr_u8 : The value of step detector interrupt enable + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_step_detector_enable( +u8 *v_step_intr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the step detector interrupt*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_step_intr_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE); + } + return com_rslt; +} + /*! + * @brief This API is used to set + * interrupt enable step detector interrupt from + * the register bit 0x52 bit 3 + * + * + * + * + * @param v_step_intr_u8 : The value of step detector interrupt enable + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_step_detector_enable( +u8 v_step_intr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE, + v_step_intr_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } + return com_rslt; +} +/*! + * @brief Configure trigger condition of interrupt1 + * and interrupt2 pin from the register 0x53 + * @brief interrupt1 - bit 0 + * @brief interrupt2 - bit 4 + * + * @param v_channel_u8: The value of edge trigger selection + * v_channel_u8 | Edge trigger + * ---------------|--------------- + * 0 | BMI160_INTR1_EDGE_CTRL + * 1 | BMI160_INTR2_EDGE_CTRL + * + * @param v_intr_edge_ctrl_u8 : The value of edge trigger enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_EDGE + * 0x00 | BMI160_LEVEL + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_edge_ctrl( +u8 v_channel_u8, u8 *v_intr_edge_ctrl_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + case BMI160_INTR1_EDGE_CTRL: + /* read the edge trigger interrupt1*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR1_EDGE_CTRL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_edge_ctrl_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR1_EDGE_CTRL); + break; + case BMI160_INTR2_EDGE_CTRL: + /* read the edge trigger interrupt2*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR2_EDGE_CTRL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_edge_ctrl_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR2_EDGE_CTRL); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief Configure trigger condition of interrupt1 + * and interrupt2 pin from the register 0x53 + * @brief interrupt1 - bit 0 + * @brief interrupt2 - bit 4 + * + * @param v_channel_u8: The value of edge trigger selection + * v_channel_u8 | Edge trigger + * ---------------|--------------- + * 0 | BMI160_INTR1_EDGE_CTRL + * 1 | BMI160_INTR2_EDGE_CTRL + * + * @param v_intr_edge_ctrl_u8 : The value of edge trigger enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_EDGE + * 0x00 | BMI160_LEVEL + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_edge_ctrl( +u8 v_channel_u8, u8 v_intr_edge_ctrl_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + case BMI160_INTR1_EDGE_CTRL: + /* write the edge trigger interrupt1*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR1_EDGE_CTRL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR1_EDGE_CTRL, + v_intr_edge_ctrl_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR1_EDGE_CTRL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_INTR2_EDGE_CTRL: + /* write the edge trigger interrupt2*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR2_EDGE_CTRL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR2_EDGE_CTRL, + v_intr_edge_ctrl_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR2_EDGE_CTRL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief API used for get the Configure level condition of interrupt1 + * and interrupt2 pin form the register 0x53 + * @brief interrupt1 - bit 1 + * @brief interrupt2 - bit 5 + * + * @param v_channel_u8: The value of level condition selection + * v_channel_u8 | level selection + * ---------------|--------------- + * 0 | BMI160_INTR1_LEVEL + * 1 | BMI160_INTR2_LEVEL + * + * @param v_intr_level_u8 : The value of level of interrupt enable + * value | Behaviour + * ----------|------------------- + * 0x01 | BMI160_LEVEL_HIGH + * 0x00 | BMI160_LEVEL_LOW + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_level( +u8 v_channel_u8, u8 *v_intr_level_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + case BMI160_INTR1_LEVEL: + /* read the interrupt1 level*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR1_LEVEL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_level_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR1_LEVEL); + break; + case BMI160_INTR2_LEVEL: + /* read the interrupt2 level*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR2_LEVEL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_level_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR2_LEVEL); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief API used for set the Configure level condition of interrupt1 + * and interrupt2 pin form the register 0x53 + * @brief interrupt1 - bit 1 + * @brief interrupt2 - bit 5 + * + * @param v_channel_u8: The value of level condition selection + * v_channel_u8 | level selection + * ---------------|--------------- + * 0 | BMI160_INTR1_LEVEL + * 1 | BMI160_INTR2_LEVEL + * + * @param v_intr_level_u8 : The value of level of interrupt enable + * value | Behaviour + * ----------|------------------- + * 0x01 | BMI160_LEVEL_HIGH + * 0x00 | BMI160_LEVEL_LOW + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_level( +u8 v_channel_u8, u8 v_intr_level_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + case BMI160_INTR1_LEVEL: + /* write the interrupt1 level*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR1_LEVEL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR1_LEVEL, v_intr_level_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR1_LEVEL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_INTR2_LEVEL: + /* write the interrupt2 level*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR2_LEVEL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR2_LEVEL, v_intr_level_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR2_LEVEL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief API used to get configured output enable of interrupt1 + * and interrupt2 from the register 0x53 + * @brief interrupt1 - bit 2 + * @brief interrupt2 - bit 6 + * + * + * @param v_channel_u8: The value of output type enable selection + * v_channel_u8 | level selection + * ---------------|--------------- + * 0 | BMI160_INTR1_OUTPUT_TYPE + * 1 | BMI160_INTR2_OUTPUT_TYPE + * + * @param v_intr_output_type_u8 : + * The value of output type of interrupt enable + * value | Behaviour + * ----------|------------------- + * 0x01 | BMI160_OPEN_DRAIN + * 0x00 | BMI160_PUSH_PULL + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_output_type( +u8 v_channel_u8, u8 *v_intr_output_type_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + case BMI160_INTR1_OUTPUT_TYPE: + /* read the output type of interrupt1*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR1_OUTPUT_TYPE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_output_type_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR1_OUTPUT_TYPE); + break; + case BMI160_INTR2_OUTPUT_TYPE: + /* read the output type of interrupt2*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR2_OUTPUT_TYPE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_output_type_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR2_OUTPUT_TYPE); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief API used to set output enable of interrupt1 + * and interrupt2 from the register 0x53 + * @brief interrupt1 - bit 2 + * @brief interrupt2 - bit 6 + * + * + * @param v_channel_u8: The value of output type enable selection + * v_channel_u8 | level selection + * ---------------|--------------- + * 0 | BMI160_INTR1_OUTPUT_TYPE + * 1 | BMI160_INTR2_OUTPUT_TYPE + * + * @param v_intr_output_type_u8 : + * The value of output type of interrupt enable + * value | Behaviour + * ----------|------------------- + * 0x01 | BMI160_OPEN_DRAIN + * 0x00 | BMI160_PUSH_PULL + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_output_type( +u8 v_channel_u8, u8 v_intr_output_type_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + case BMI160_INTR1_OUTPUT_TYPE: + /* write the output type of interrupt1*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR1_OUTPUT_TYPE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR1_OUTPUT_TYPE, + v_intr_output_type_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR1_OUTPUT_TYPE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_INTR2_OUTPUT_TYPE: + /* write the output type of interrupt2*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR2_OUTPUT_TYPE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR2_OUTPUT_TYPE, + v_intr_output_type_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR2_OUTPUT_TYPE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} + /*! + * @brief API used to get the Output enable for interrupt1 + * and interrupt1 pin from the register 0x53 + * @brief interrupt1 - bit 3 + * @brief interrupt2 - bit 7 + * + * @param v_channel_u8: The value of output enable selection + * v_channel_u8 | level selection + * ---------------|--------------- + * 0 | BMI160_INTR1_OUTPUT_TYPE + * 1 | BMI160_INTR2_OUTPUT_TYPE + * + * @param v_output_enable_u8 : + * The value of output enable of interrupt enable + * value | Behaviour + * ----------|------------------- + * 0x01 | BMI160_INPUT + * 0x00 | BMI160_OUTPUT + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_output_enable( +u8 v_channel_u8, u8 *v_output_enable_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + case BMI160_INTR1_OUTPUT_ENABLE: + /* read the output enable of interrupt1*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR1_OUTPUT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_output_enable_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR1_OUTPUT_ENABLE); + break; + case BMI160_INTR2_OUTPUT_ENABLE: + /* read the output enable of interrupt2*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR2_OUTPUT_EN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_output_enable_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR2_OUTPUT_EN); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} + /*! + * @brief API used to set the Output enable for interrupt1 + * and interrupt1 pin from the register 0x53 + * @brief interrupt1 - bit 3 + * @brief interrupt2 - bit 7 + * + * @param v_channel_u8: The value of output enable selection + * v_channel_u8 | level selection + * ---------------|--------------- + * 0 | BMI160_INTR1_OUTPUT_TYPE + * 1 | BMI160_INTR2_OUTPUT_TYPE + * + * @param v_output_enable_u8 : + * The value of output enable of interrupt enable + * value | Behaviour + * ----------|------------------- + * 0x01 | BMI160_INPUT + * 0x00 | BMI160_OUTPUT + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_output_enable( +u8 v_channel_u8, u8 v_output_enable_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + case BMI160_INTR1_OUTPUT_ENABLE: + /* write the output enable of interrupt1*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR1_OUTPUT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR1_OUTPUT_ENABLE, + v_output_enable_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR1_OUTPUT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_INTR2_OUTPUT_ENABLE: + /* write the output enable of interrupt2*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR2_OUTPUT_EN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR2_OUTPUT_EN, + v_output_enable_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR2_OUTPUT_EN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! +* @brief This API is used to get the latch duration +* from the register 0x54 bit 0 to 3 +* @brief This latch selection is not applicable for data ready, +* orientation and flat interrupts. +* +* +* +* @param v_latch_intr_u8 : The value of latch duration +* Latch Duration | value +* --------------------------------------|------------------ +* BMI160_LATCH_DUR_NONE | 0x00 +* BMI160_LATCH_DUR_312_5_MICRO_SEC | 0x01 +* BMI160_LATCH_DUR_625_MICRO_SEC | 0x02 +* BMI160_LATCH_DUR_1_25_MILLI_SEC | 0x03 +* BMI160_LATCH_DUR_2_5_MILLI_SEC | 0x04 +* BMI160_LATCH_DUR_5_MILLI_SEC | 0x05 +* BMI160_LATCH_DUR_10_MILLI_SEC | 0x06 +* BMI160_LATCH_DUR_20_MILLI_SEC | 0x07 +* BMI160_LATCH_DUR_40_MILLI_SEC | 0x08 +* BMI160_LATCH_DUR_80_MILLI_SEC | 0x09 +* BMI160_LATCH_DUR_160_MILLI_SEC | 0x0A +* BMI160_LATCH_DUR_320_MILLI_SEC | 0x0B +* BMI160_LATCH_DUR_640_MILLI_SEC | 0x0C +* BMI160_LATCH_DUR_1_28_SEC | 0x0D +* BMI160_LATCH_DUR_2_56_SEC | 0x0E +* BMI160_LATCHED | 0x0F +* +* +* +* @return results of bus communication function +* @retval 0 -> Success +* @retval -1 -> Error +* +* +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_latch_intr( +u8 *v_latch_intr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the latch duration value */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_LATCH__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_latch_intr_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_LATCH); + } + return com_rslt; +} +/*! +* @brief This API is used to set the latch duration +* from the register 0x54 bit 0 to 3 +* @brief This latch selection is not applicable for data ready, +* orientation and flat interrupts. +* +* +* +* @param v_latch_intr_u8 : The value of latch duration +* Latch Duration | value +* --------------------------------------|------------------ +* BMI160_LATCH_DUR_NONE | 0x00 +* BMI160_LATCH_DUR_312_5_MICRO_SEC | 0x01 +* BMI160_LATCH_DUR_625_MICRO_SEC | 0x02 +* BMI160_LATCH_DUR_1_25_MILLI_SEC | 0x03 +* BMI160_LATCH_DUR_2_5_MILLI_SEC | 0x04 +* BMI160_LATCH_DUR_5_MILLI_SEC | 0x05 +* BMI160_LATCH_DUR_10_MILLI_SEC | 0x06 +* BMI160_LATCH_DUR_20_MILLI_SEC | 0x07 +* BMI160_LATCH_DUR_40_MILLI_SEC | 0x08 +* BMI160_LATCH_DUR_80_MILLI_SEC | 0x09 +* BMI160_LATCH_DUR_160_MILLI_SEC | 0x0A +* BMI160_LATCH_DUR_320_MILLI_SEC | 0x0B +* BMI160_LATCH_DUR_640_MILLI_SEC | 0x0C +* BMI160_LATCH_DUR_1_28_SEC | 0x0D +* BMI160_LATCH_DUR_2_56_SEC | 0x0E +* BMI160_LATCHED | 0x0F +* +* +* + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error +* +* +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_latch_intr(u8 v_latch_intr_u8) +{ + u8 v_data_u8 = BMI160_INIT_VALUE; + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_latch_intr_u8 <= BMI160_MAX_LATCH_INTR) { + /* write the latch duration value */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_LATCH__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_LATCH, v_latch_intr_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_LATCH__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief API used to get input enable for interrupt1 + * and interrupt2 pin from the register 0x54 + * @brief interrupt1 - bit 4 + * @brief interrupt2 - bit 5 + * + * @param v_channel_u8: The value of input enable selection + * v_channel_u8 | input selection + * ---------------|--------------- + * 0 | BMI160_INTR1_INPUT_ENABLE + * 1 | BMI160_INTR2_INPUT_ENABLE + * + * @param v_input_en_u8 : + * The value of input enable of interrupt enable + * value | Behaviour + * ----------|------------------- + * 0x01 | BMI160_INPUT + * 0x00 | BMI160_OUTPUT + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_input_enable( +u8 v_channel_u8, u8 *v_input_en_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* read input enable of interrup1 and interrupt2*/ + case BMI160_INTR1_INPUT_ENABLE: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR1_INPUT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_input_en_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR1_INPUT_ENABLE); + break; + case BMI160_INTR2_INPUT_ENABLE: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR2_INPUT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_input_en_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR2_INPUT_ENABLE); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief API used to set input enable for interrupt1 + * and interrupt2 pin from the register 0x54 + * @brief interrupt1 - bit 4 + * @brief interrupt2 - bit 5 + * + * @param v_channel_u8: The value of input enable selection + * v_channel_u8 | input selection + * ---------------|--------------- + * 0 | BMI160_INTR1_INPUT_ENABLE + * 1 | BMI160_INTR2_INPUT_ENABLE + * + * @param v_input_en_u8 : + * The value of input enable of interrupt enable + * value | Behaviour + * ----------|------------------- + * 0x01 | BMI160_INPUT + * 0x00 | BMI160_OUTPUT + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_input_enable( +u8 v_channel_u8, u8 v_input_en_u8) +{ +/* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* write input enable of interrup1 and interrupt2*/ + case BMI160_INTR1_INPUT_ENABLE: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR1_INPUT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR1_INPUT_ENABLE, v_input_en_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR1_INPUT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_INTR2_INPUT_ENABLE: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR2_INPUT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR2_INPUT_ENABLE, v_input_en_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR2_INPUT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } +} +return com_rslt; +} + /*! + * @brief reads the Low g interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 0 in the register 0x55 + * @brief interrupt2 bit 0 in the register 0x57 + * + * + * @param v_channel_u8: The value of low_g selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_LOW_G + * 1 | BMI160_INTR2_MAP_LOW_G + * + * @param v_intr_low_g_u8 : The value of low_g enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g( +u8 v_channel_u8, u8 *v_intr_low_g_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* read the low_g interrupt */ + case BMI160_INTR1_MAP_LOW_G: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_LOW_G__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_low_g_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_0_INTR1_LOW_G); + break; + case BMI160_INTR2_MAP_LOW_G: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_LOW_G__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_low_g_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_2_INTR2_LOW_G); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} + /*! + * @brief set the Low g interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 0 in the register 0x55 + * @brief interrupt2 bit 0 in the register 0x57 + * + * + * @param v_channel_u8: The value of low_g selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_LOW_G + * 1 | BMI160_INTR2_MAP_LOW_G + * + * @param v_intr_low_g_u8 : The value of low_g enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g( +u8 v_channel_u8, u8 v_intr_low_g_u8) +{ +/* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +u8 v_step_cnt_stat_u8 = BMI160_INIT_VALUE; +u8 v_step_det_stat_u8 = BMI160_INIT_VALUE; + +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* check the step detector interrupt enable status*/ + com_rslt = bmi160_get_step_detector_enable(&v_step_det_stat_u8); + /* disable the step detector interrupt */ + if (v_step_det_stat_u8 != BMI160_INIT_VALUE) + com_rslt += bmi160_set_step_detector_enable(BMI160_INIT_VALUE); + /* check the step counter interrupt enable status*/ + com_rslt += bmi160_get_step_counter_enable(&v_step_cnt_stat_u8); + /* disable the step counter interrupt */ + if (v_step_cnt_stat_u8 != BMI160_INIT_VALUE) + com_rslt += bmi160_set_step_counter_enable( + BMI160_INIT_VALUE); + switch (v_channel_u8) { + /* write the low_g interrupt*/ + case BMI160_INTR1_MAP_LOW_G: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_LOW_G__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_0_INTR1_LOW_G, v_intr_low_g_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_LOW_G__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_INTR2_MAP_LOW_G: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_LOW_G__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_2_INTR2_LOW_G, v_intr_low_g_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_LOW_G__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } +} +return com_rslt; +} +/*! + * @brief Reads the HIGH g interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 1 in the register 0x55 + * @brief interrupt2 bit 1 in the register 0x57 + * + * + * @param v_channel_u8: The value of high_g selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_HIGH_G + * 1 | BMI160_INTR2_MAP_HIGH_G + * + * @param v_intr_high_g_u8 : The value of high_g enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_high_g( +u8 v_channel_u8, u8 *v_intr_high_g_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the high_g interrupt*/ + switch (v_channel_u8) { + case BMI160_INTR1_MAP_HIGH_G: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_HIGH_G__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_high_g_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_0_INTR1_HIGH_G); + break; + case BMI160_INTR2_MAP_HIGH_G: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_HIGH_G__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_high_g_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_2_INTR2_HIGH_G); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief Write the HIGH g interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 1 in the register 0x55 + * @brief interrupt2 bit 1 in the register 0x57 + * + * + * @param v_channel_u8: The value of high_g selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_HIGH_G + * 1 | BMI160_INTR2_MAP_HIGH_G + * + * @param v_intr_high_g_u8 : The value of high_g enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_high_g( +u8 v_channel_u8, u8 v_intr_high_g_u8) +{ +/* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* write the high_g interrupt*/ + case BMI160_INTR1_MAP_HIGH_G: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_HIGH_G__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_0_INTR1_HIGH_G, v_intr_high_g_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_HIGH_G__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_INTR2_MAP_HIGH_G: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_HIGH_G__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_2_INTR2_HIGH_G, v_intr_high_g_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_HIGH_G__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } +} +return com_rslt; +} +/*! + * @brief Reads the Any motion interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 2 in the register 0x55 + * @brief interrupt2 bit 2 in the register 0x57 + * + * + * @param v_channel_u8: The value of any motion selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_ANY_MOTION + * 1 | BMI160_INTR2_MAP_ANY_MOTION + * + * @param v_intr_any_motion_u8 : The value of any motion enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_any_motion( +u8 v_channel_u8, u8 *v_intr_any_motion_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* read the any motion interrupt */ + case BMI160_INTR1_MAP_ANY_MOTION: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_any_motion_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION); + break; + case BMI160_INTR2_MAP_ANY_MOTION: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_any_motion_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief Write the Any motion interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 2 in the register 0x55 + * @brief interrupt2 bit 2 in the register 0x57 + * + * + * @param v_channel_u8: The value of any motion selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_ANY_MOTION + * 1 | BMI160_INTR2_MAP_ANY_MOTION + * + * @param v_intr_any_motion_u8 : The value of any motion enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_any_motion( +u8 v_channel_u8, u8 v_intr_any_motion_u8) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +u8 sig_mot_stat = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the status of significant motion interrupt */ + com_rslt = bmi160_get_intr_significant_motion_select(&sig_mot_stat); + /* disable the significant motion interrupt */ + if (sig_mot_stat != BMI160_INIT_VALUE) + com_rslt += bmi160_set_intr_significant_motion_select( + BMI160_INIT_VALUE); + switch (v_channel_u8) { + /* write the any motion interrupt */ + case BMI160_INTR1_MAP_ANY_MOTION: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION, + v_intr_any_motion_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_INTR2_MAP_ANY_MOTION: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION, + v_intr_any_motion_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } +} +return com_rslt; +} +/*! + * @brief Reads the No motion interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 3 in the register 0x55 + * @brief interrupt2 bit 3 in the register 0x57 + * + * + * @param v_channel_u8: The value of no motion selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_NOMO + * 1 | BMI160_INTR2_MAP_NOMO + * + * @param v_intr_nomotion_u8 : The value of no motion enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_nomotion( +u8 v_channel_u8, u8 *v_intr_nomotion_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* read the no motion interrupt*/ + case BMI160_INTR1_MAP_NOMO: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_NOMOTION__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_nomotion_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_0_INTR1_NOMOTION); + break; + case BMI160_INTR2_MAP_NOMO: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_NOMOTION__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_nomotion_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_2_INTR2_NOMOTION); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief Write the No motion interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 3 in the register 0x55 + * @brief interrupt2 bit 3 in the register 0x57 + * + * + * @param v_channel_u8: The value of no motion selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_NOMO + * 1 | BMI160_INTR2_MAP_NOMO + * + * @param v_intr_nomotion_u8 : The value of no motion enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_nomotion( +u8 v_channel_u8, u8 v_intr_nomotion_u8) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* write the no motion interrupt*/ + case BMI160_INTR1_MAP_NOMO: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_NOMOTION__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_0_INTR1_NOMOTION, + v_intr_nomotion_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_NOMOTION__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_INTR2_MAP_NOMO: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_NOMOTION__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_2_INTR2_NOMOTION, + v_intr_nomotion_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_NOMOTION__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } +} +return com_rslt; +} +/*! + * @brief Reads the Double Tap interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 4 in the register 0x55 + * @brief interrupt2 bit 4 in the register 0x57 + * + * + * @param v_channel_u8: The value of double tap interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_DOUBLE_TAP + * 1 | BMI160_INTR2_MAP_DOUBLE_TAP + * + * @param v_intr_double_tap_u8 : The value of double tap enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_double_tap( +u8 v_channel_u8, u8 *v_intr_double_tap_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + case BMI160_INTR1_MAP_DOUBLE_TAP: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_double_tap_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_0_INTR1_DOUBLE_TAP); + break; + case BMI160_INTR2_MAP_DOUBLE_TAP: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_double_tap_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_2_INTR2_DOUBLE_TAP); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief Write the Double Tap interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 4 in the register 0x55 + * @brief interrupt2 bit 4 in the register 0x57 + * + * + * @param v_channel_u8: The value of double tap interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_DOUBLE_TAP + * 1 | BMI160_INTR2_MAP_DOUBLE_TAP + * + * @param v_intr_double_tap_u8 : The value of double tap enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_double_tap( +u8 v_channel_u8, u8 v_intr_double_tap_u8) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* set the double tap interrupt */ + case BMI160_INTR1_MAP_DOUBLE_TAP: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_0_INTR1_DOUBLE_TAP, + v_intr_double_tap_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_INTR2_MAP_DOUBLE_TAP: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_2_INTR2_DOUBLE_TAP, + v_intr_double_tap_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } +} +return com_rslt; +} +/*! + * @brief Reads the Single Tap interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 5 in the register 0x55 + * @brief interrupt2 bit 5 in the register 0x57 + * + * + * @param v_channel_u8: The value of single tap interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_SINGLE_TAP + * 1 | BMI160_INTR2_MAP_SINGLE_TAP + * + * @param v_intr_single_tap_u8 : The value of single tap enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_single_tap( +u8 v_channel_u8, u8 *v_intr_single_tap_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* reads the single tap interrupt*/ + case BMI160_INTR1_MAP_SINGLE_TAP: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_SINGLE_TAP__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_single_tap_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_0_INTR1_SINGLE_TAP); + break; + case BMI160_INTR2_MAP_SINGLE_TAP: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_SINGLE_TAP__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_single_tap_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_2_INTR2_SINGLE_TAP); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief Write the Single Tap interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 5 in the register 0x55 + * @brief interrupt2 bit 5 in the register 0x57 + * + * + * @param v_channel_u8: The value of single tap interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_SINGLE_TAP + * 1 | BMI160_INTR2_MAP_SINGLE_TAP + * + * @param v_intr_single_tap_u8 : The value of single tap enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_single_tap( +u8 v_channel_u8, u8 v_intr_single_tap_u8) +{ +/* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* write the single tap interrupt */ + case BMI160_INTR1_MAP_SINGLE_TAP: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_SINGLE_TAP__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_0_INTR1_SINGLE_TAP, + v_intr_single_tap_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_SINGLE_TAP__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_INTR2_MAP_SINGLE_TAP: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_SINGLE_TAP__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_2_INTR2_SINGLE_TAP, + v_intr_single_tap_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_SINGLE_TAP__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } +} +return com_rslt; +} +/*! + * @brief Reads the Orient interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 6 in the register 0x55 + * @brief interrupt2 bit 6 in the register 0x57 + * + * + * @param v_channel_u8: The value of orient interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_ORIENT + * 1 | BMI160_INTR2_MAP_ORIENT + * + * @param v_intr_orient_u8 : The value of orient enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient( +u8 v_channel_u8, u8 *v_intr_orient_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* read the orientation interrupt*/ + case BMI160_INTR1_MAP_ORIENT: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_ORIENT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_orient_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_0_INTR1_ORIENT); + break; + case BMI160_INTR2_MAP_ORIENT: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_ORIENT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_orient_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_2_INTR2_ORIENT); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief Write the Orient interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 6 in the register 0x55 + * @brief interrupt2 bit 6 in the register 0x57 + * + * + * @param v_channel_u8: The value of orient interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_ORIENT + * 1 | BMI160_INTR2_MAP_ORIENT + * + * @param v_intr_orient_u8 : The value of orient enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient( +u8 v_channel_u8, u8 v_intr_orient_u8) +{ +/* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* write the orientation interrupt*/ + case BMI160_INTR1_MAP_ORIENT: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_ORIENT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_0_INTR1_ORIENT, v_intr_orient_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_ORIENT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_INTR2_MAP_ORIENT: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_ORIENT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_2_INTR2_ORIENT, v_intr_orient_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_ORIENT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } +} +return com_rslt; +} + /*! + * @brief Reads the Flat interrupt + * mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 7 in the register 0x55 + * @brief interrupt2 bit 7 in the register 0x57 + * + * + * @param v_channel_u8: The value of flat interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_FLAT + * 1 | BMI160_INTR2_MAP_FLAT + * + * @param v_intr_flat_u8 : The value of flat enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_flat( +u8 v_channel_u8, u8 *v_intr_flat_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* read the flat interrupt*/ + case BMI160_INTR1_MAP_FLAT: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_FLAT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_flat_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_0_INTR1_FLAT); + break; + case BMI160_INTR2_MAP_FLAT: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_FLAT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_flat_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_2_INTR2_FLAT); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} + /*! + * @brief Write the Flat interrupt + * mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 7 in the register 0x55 + * @brief interrupt2 bit 7 in the register 0x57 + * + * + * @param v_channel_u8: The value of flat interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_FLAT + * 1 | BMI160_INTR2_MAP_FLAT + * + * @param v_intr_flat_u8 : The value of flat enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_flat( +u8 v_channel_u8, u8 v_intr_flat_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* write the flat interrupt */ + case BMI160_INTR1_MAP_FLAT: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_0_INTR1_FLAT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_0_INTR1_FLAT, + v_intr_flat_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_MAP_0_INTR1_FLAT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_INTR2_MAP_FLAT: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_2_INTR2_FLAT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_2_INTR2_FLAT, + v_intr_flat_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_MAP_2_INTR2_FLAT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief Reads PMU trigger interrupt mapped to interrupt1 + * and interrupt2 form the register 0x56 bit 0 and 4 + * @brief interrupt1 bit 0 in the register 0x56 + * @brief interrupt2 bit 4 in the register 0x56 + * + * + * @param v_channel_u8: The value of pmu trigger selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_PMUTRIG + * 1 | BMI160_INTR2_MAP_PMUTRIG + * + * @param v_intr_pmu_trig_u8 : The value of pmu trigger enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_pmu_trig( +u8 v_channel_u8, u8 *v_intr_pmu_trig_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* read the pmu trigger interrupt*/ + case BMI160_INTR1_MAP_PMUTRIG: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR1_PMU_TRIG__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_pmu_trig_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_1_INTR1_PMU_TRIG); + break; + case BMI160_INTR2_MAP_PMUTRIG: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR2_PMU_TRIG__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_pmu_trig_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_1_INTR2_PMU_TRIG); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief Write PMU trigger interrupt mapped to interrupt1 + * and interrupt2 form the register 0x56 bit 0 and 4 + * @brief interrupt1 bit 0 in the register 0x56 + * @brief interrupt2 bit 4 in the register 0x56 + * + * + * @param v_channel_u8: The value of pmu trigger selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_PMUTRIG + * 1 | BMI160_INTR2_MAP_PMUTRIG + * + * @param v_intr_pmu_trig_u8 : The value of pmu trigger enable + * value | trigger enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_pmu_trig( +u8 v_channel_u8, u8 v_intr_pmu_trig_u8) +{ +/* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* write the pmu trigger interrupt */ + case BMI160_INTR1_MAP_PMUTRIG: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR1_PMU_TRIG__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_1_INTR1_PMU_TRIG, + v_intr_pmu_trig_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR1_PMU_TRIG__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_INTR2_MAP_PMUTRIG: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR2_PMU_TRIG__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_1_INTR2_PMU_TRIG, + v_intr_pmu_trig_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR2_PMU_TRIG__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } +} +return com_rslt; +} +/*! + * @brief Reads FIFO Full interrupt mapped to interrupt1 + * and interrupt2 form the register 0x56 bit 5 and 1 + * @brief interrupt1 bit 5 in the register 0x56 + * @brief interrupt2 bit 1 in the register 0x56 + * + * + * @param v_channel_u8: The value of fifo full interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_FIFO_FULL + * 1 | BMI160_INTR2_MAP_FIFO_FULL + * + * @param v_intr_fifo_full_u8 : The value of fifo full interrupt enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_fifo_full( +u8 v_channel_u8, u8 *v_intr_fifo_full_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* read the fifo full interrupt */ + case BMI160_INTR1_MAP_FIFO_FULL: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR1_FIFO_FULL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_fifo_full_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_1_INTR1_FIFO_FULL); + break; + case BMI160_INTR2_MAP_FIFO_FULL: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR2_FIFO_FULL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_fifo_full_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_1_INTR2_FIFO_FULL); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief Write FIFO Full interrupt mapped to interrupt1 + * and interrupt2 form the register 0x56 bit 5 and 1 + * @brief interrupt1 bit 5 in the register 0x56 + * @brief interrupt2 bit 1 in the register 0x56 + * + * + * @param v_channel_u8: The value of fifo full interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_FIFO_FULL + * 1 | BMI160_INTR2_MAP_FIFO_FULL + * + * @param v_intr_fifo_full_u8 : The value of fifo full interrupt enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_fifo_full( +u8 v_channel_u8, u8 v_intr_fifo_full_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* write the fifo full interrupt */ + case BMI160_INTR1_MAP_FIFO_FULL: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR1_FIFO_FULL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_1_INTR1_FIFO_FULL, + v_intr_fifo_full_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_MAP_1_INTR1_FIFO_FULL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_INTR2_MAP_FIFO_FULL: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR2_FIFO_FULL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_1_INTR2_FIFO_FULL, + v_intr_fifo_full_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_MAP_1_INTR2_FIFO_FULL__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief Reads FIFO Watermark interrupt mapped to interrupt1 + * and interrupt2 form the register 0x56 bit 6 and 2 + * @brief interrupt1 bit 6 in the register 0x56 + * @brief interrupt2 bit 2 in the register 0x56 + * + * + * @param v_channel_u8: The value of fifo Watermark interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_FIFO_WM + * 1 | BMI160_INTR2_MAP_FIFO_WM + * + * @param v_intr_fifo_wm_u8 : The value of fifo Watermark interrupt enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_fifo_wm( +u8 v_channel_u8, u8 *v_intr_fifo_wm_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* read the fifo water mark interrupt */ + case BMI160_INTR1_MAP_FIFO_WM: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR1_FIFO_WM__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_fifo_wm_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_1_INTR1_FIFO_WM); + break; + case BMI160_INTR2_MAP_FIFO_WM: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR2_FIFO_WM__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_fifo_wm_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_1_INTR2_FIFO_WM); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief Write FIFO Watermark interrupt mapped to interrupt1 + * and interrupt2 form the register 0x56 bit 6 and 2 + * @brief interrupt1 bit 6 in the register 0x56 + * @brief interrupt2 bit 2 in the register 0x56 + * + * + * @param v_channel_u8: The value of fifo Watermark interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_FIFO_WM + * 1 | BMI160_INTR2_MAP_FIFO_WM + * + * @param v_intr_fifo_wm_u8 : The value of fifo Watermark interrupt enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_fifo_wm( +u8 v_channel_u8, u8 v_intr_fifo_wm_u8) +{ +/* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /* write the fifo water mark interrupt */ + case BMI160_INTR1_MAP_FIFO_WM: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR1_FIFO_WM__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_1_INTR1_FIFO_WM, + v_intr_fifo_wm_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_MAP_1_INTR1_FIFO_WM__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_INTR2_MAP_FIFO_WM: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR2_FIFO_WM__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_1_INTR2_FIFO_WM, + v_intr_fifo_wm_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, + BMI160_USER_INTR_MAP_1_INTR2_FIFO_WM__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief Reads Data Ready interrupt mapped to interrupt1 + * and interrupt2 form the register 0x56 + * @brief interrupt1 bit 7 in the register 0x56 + * @brief interrupt2 bit 3 in the register 0x56 + * + * + * @param v_channel_u8: The value of data ready interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_DATA_RDY + * 1 | BMI160_INTR2_MAP_DATA_RDY + * + * @param v_intr_data_rdy_u8 : The value of data ready interrupt enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_data_rdy( +u8 v_channel_u8, u8 *v_intr_data_rdy_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /*Read Data Ready interrupt*/ + case BMI160_INTR1_MAP_DATA_RDY: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR1_DATA_RDY__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_data_rdy_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_1_INTR1_DATA_RDY); + break; + case BMI160_INTR2_MAP_DATA_RDY: + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR2_DATA_RDY__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_data_rdy_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_1_INTR2_DATA_RDY); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + } + return com_rslt; +} +/*! + * @brief Write Data Ready interrupt mapped to interrupt1 + * and interrupt2 form the register 0x56 + * @brief interrupt1 bit 7 in the register 0x56 + * @brief interrupt2 bit 3 in the register 0x56 + * + * + * @param v_channel_u8: The value of data ready interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_DATA_RDY + * 1 | BMI160_INTR2_MAP_DATA_RDY + * + * @param v_intr_data_rdy_u8 : The value of data ready interrupt enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_data_rdy( +u8 v_channel_u8, u8 v_intr_data_rdy_u8) +{ +/* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + switch (v_channel_u8) { + /*Write Data Ready interrupt*/ + case BMI160_INTR1_MAP_DATA_RDY: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR1_DATA_RDY__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_1_INTR1_DATA_RDY, + v_intr_data_rdy_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR1_DATA_RDY__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + case BMI160_INTR2_MAP_DATA_RDY: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR2_DATA_RDY__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MAP_1_INTR2_DATA_RDY, + v_intr_data_rdy_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160-> + dev_addr, BMI160_USER_INTR_MAP_1_INTR2_DATA_RDY__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } +} +return com_rslt; +} + /*! + * @brief This API reads data source for the interrupt + * engine for the single and double tap interrupts from the register + * 0x58 bit 3 + * + * + * @param v_tap_source_u8 : The value of the tap source + * value | Description + * ----------|------------------- + * 0x01 | UNFILTER_DATA + * 0x00 | FILTER_DATA + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_source(u8 *v_tap_source_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the tap source interrupt */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_DATA_0_INTR_TAP_SOURCE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_tap_source_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_DATA_0_INTR_TAP_SOURCE); + } + return com_rslt; +} + /*! + * @brief This API write data source for the interrupt + * engine for the single and double tap interrupts from the register + * 0x58 bit 3 + * + * + * @param v_tap_source_u8 : The value of the tap source + * value | Description + * ----------|------------------- + * 0x01 | UNFILTER_DATA + * 0x00 | FILTER_DATA + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_source( +u8 v_tap_source_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_tap_source_u8 <= BMI160_MAX_VALUE_SOURCE_INTR) { + /* write the tap source interrupt */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_DATA_0_INTR_TAP_SOURCE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_DATA_0_INTR_TAP_SOURCE, + v_tap_source_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_DATA_0_INTR_TAP_SOURCE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} + /*! + * @brief This API Reads Data source for the + * interrupt engine for the low and high g interrupts + * from the register 0x58 bit 7 + * + * @param v_low_high_source_u8 : The value of the tap source + * value | Description + * ----------|------------------- + * 0x01 | UNFILTER_DATA + * 0x00 | FILTER_DATA + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_high_source( +u8 *v_low_high_source_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the high_low_g source interrupt */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_low_high_source_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE); + } + return com_rslt; +} +/*! + * @brief This API write Data source for the + * interrupt engine for the low and high g interrupts + * from the register 0x58 bit 7 + * + * @param v_low_high_source_u8 : The value of the tap source + * value | Description + * ----------|------------------- + * 0x01 | UNFILTER_DATA + * 0x00 | FILTER_DATA + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_high_source( +u8 v_low_high_source_u8) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_low_high_source_u8 <= BMI160_MAX_VALUE_SOURCE_INTR) { + /* write the high_low_g source interrupt */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE, + v_low_high_source_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } +} +return com_rslt; +} + /*! + * @brief This API reads Data source for the + * interrupt engine for the nomotion and anymotion interrupts + * from the register 0x59 bit 7 + * + * @param v_motion_source_u8 : + * The value of the any/no motion interrupt source + * value | Description + * ----------|------------------- + * 0x01 | UNFILTER_DATA + * 0x00 | FILTER_DATA + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_motion_source( +u8 *v_motion_source_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the any/no motion interrupt */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_DATA_1_INTR_MOTION_SOURCE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_motion_source_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_DATA_1_INTR_MOTION_SOURCE); + } + return com_rslt; +} + /*! + * @brief This API write Data source for the + * interrupt engine for the nomotion and anymotion interrupts + * from the register 0x59 bit 7 + * + * @param v_motion_source_u8 : + * The value of the any/no motion interrupt source + * value | Description + * ----------|------------------- + * 0x01 | UNFILTER_DATA + * 0x00 | FILTER_DATA + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_motion_source( +u8 v_motion_source_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_motion_source_u8 <= BMI160_MAX_VALUE_SOURCE_INTR) { + /* write the any/no motion interrupt */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_DATA_1_INTR_MOTION_SOURCE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_DATA_1_INTR_MOTION_SOURCE, + v_motion_source_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_DATA_1_INTR_MOTION_SOURCE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} + /*! + * @brief This API is used to read the low_g duration from register + * 0x5A bit 0 to 7 + * + * + * + * + * @param v_low_g_durn_u8 : The value of low_g duration + * + * @note Low_g duration trigger trigger delay according to + * "(v_low_g_durn_u8 * 2.5)ms" in a range from 2.5ms to 640ms. + * the default corresponds delay is 20ms + * @note When low_g data source of interrupt is unfiltered + * the sensor must not be in low power mode + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g_durn( +u8 *v_low_g_durn_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the low_g interrupt */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_low_g_durn_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_LOWHIGH_0_INTR_LOW_DURN); + } + return com_rslt; +} + /*! + * @brief This API is used to write the low_g duration from register + * 0x5A bit 0 to 7 + * + * + * + * + * @param v_low_g_durn_u8 : The value of low_g duration + * + * @note Low_g duration trigger trigger delay according to + * "(v_low_g_durn_u8 * 2.5)ms" in a range from 2.5ms to 640ms. + * the default corresponds delay is 20ms + * @note When low_g data source of interrupt is unfiltered + * the sensor must not be in low power mode + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g_durn(u8 v_low_g_durn_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write the low_g interrupt */ + com_rslt = p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__REG, + &v_low_g_durn_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + return com_rslt; +} +/*! + * @brief This API is used to read Threshold + * definition for the low-g interrupt from the register 0x5B bit 0 to 7 + * + * + * + * + * @param v_low_g_thres_u8 : The value of low_g threshold + * + * @note Low_g interrupt trigger threshold according to + * (v_low_g_thres_u8 * 7.81)mg for v_low_g_thres_u8 > 0 + * 3.91 mg for v_low_g_thres_u8 = 0 + * The threshold range is form 3.91mg to 2.000mg + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g_thres( +u8 *v_low_g_thres_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read low_g threshold */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_low_g_thres_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_LOWHIGH_1_INTR_LOW_THRES); + } + return com_rslt; +} +/*! + * @brief This API is used to write Threshold + * definition for the low-g interrupt from the register 0x5B bit 0 to 7 + * + * + * + * + * @param v_low_g_thres_u8 : The value of low_g threshold + * + * @note Low_g interrupt trigger threshold according to + * (v_low_g_thres_u8 * 7.81)mg for v_low_g_thres_u8 > 0 + * 3.91 mg for v_low_g_thres_u8 = 0 + * The threshold range is form 3.91mg to 2.000mg + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g_thres( +u8 v_low_g_thres_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write low_g threshold */ + com_rslt = p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__REG, + &v_low_g_thres_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + return com_rslt; +} + /*! + * @brief This API Reads Low-g interrupt hysteresis + * from the register 0x5C bit 0 to 1 + * + * @param v_low_hyst_u8 :The value of low_g hysteresis + * + * @note Low_g hysteresis calculated by v_low_hyst_u8*125 mg + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g_hyst( +u8 *v_low_hyst_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read low_g hysteresis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_low_hyst_u8 = BMI160_GET_BITSLICE( + v_data_u8, + BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST); + } + return com_rslt; +} + /*! + * @brief This API write Low-g interrupt hysteresis + * from the register 0x5C bit 0 to 1 + * + * @param v_low_hyst_u8 :The value of low_g hysteresis + * + * @note Low_g hysteresis calculated by v_low_hyst_u8*125 mg + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g_hyst( +u8 v_low_hyst_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write low_g hysteresis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST, + v_low_hyst_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } + return com_rslt; +} +/*! + * @brief This API reads Low-g interrupt mode + * from the register 0x5C bit 2 + * + * @param v_low_g_mode_u8 : The value of low_g mode + * Value | Description + * ----------|----------------- + * 0 | single-axis + * 1 | axis-summing + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g_mode(u8 *v_low_g_mode_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /*read Low-g interrupt mode*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_low_g_mode_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE); + } + return com_rslt; +} +/*! + * @brief This API write Low-g interrupt mode + * from the register 0x5C bit 2 + * + * @param v_low_g_mode_u8 : The value of low_g mode + * Value | Description + * ----------|----------------- + * 0 | single-axis + * 1 | axis-summing + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g_mode( +u8 v_low_g_mode_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_low_g_mode_u8 <= BMI160_MAX_VALUE_LOW_G_MODE) { + /*write Low-g interrupt mode*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE, + v_low_g_mode_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API reads High-g interrupt hysteresis + * from the register 0x5C bit 6 and 7 + * + * @param v_high_g_hyst_u8 : The value of high hysteresis + * + * @note High_g hysteresis changes according to accel g range + * accel g range can be set by the function "" + * accel_range | high_g hysteresis + * ----------------|--------------------- + * 2g | high_hy*125 mg + * 4g | high_hy*250 mg + * 8g | high_hy*500 mg + * 16g | high_hy*1000 mg + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_high_g_hyst( +u8 *v_high_g_hyst_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read high_g hysteresis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_high_g_hyst_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST); + } + return com_rslt; +} +/*! + * @brief This API write High-g interrupt hysteresis + * from the register 0x5C bit 6 and 7 + * + * @param v_high_g_hyst_u8 : The value of high hysteresis + * + * @note High_g hysteresis changes according to accel g range + * accel g range can be set by the function "" + * accel_range | high_g hysteresis + * ----------------|--------------------- + * 2g | high_hy*125 mg + * 4g | high_hy*250 mg + * 8g | high_hy*500 mg + * 16g | high_hy*1000 mg + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_high_g_hyst( +u8 v_high_g_hyst_u8) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write high_g hysteresis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST, + v_high_g_hyst_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } +return com_rslt; +} +/*! + * @brief This API is used to read Delay + * time definition for the high-g interrupt from the register + * 0x5D bit 0 to 7 + * + * + * + * @param v_high_g_durn_u8 : The value of high duration + * + * @note High_g interrupt delay triggered according to + * v_high_g_durn_u8 * 2.5ms in a range from 2.5ms to 640ms + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_high_g_durn( +u8 *v_high_g_durn_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read high_g duration*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_high_g_durn_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN); + } + return com_rslt; +} +/*! + * @brief This API is used to write Delay + * time definition for the high-g interrupt from the register + * 0x5D bit 0 to 7 + * + * + * + * @param v_high_g_durn_u8 : The value of high duration + * + * @note High_g interrupt delay triggered according to + * v_high_g_durn_u8 * 2.5ms in a range from 2.5ms to 640ms + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_high_g_durn( +u8 v_high_g_durn_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write high_g duration*/ + com_rslt = p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__REG, + &v_high_g_durn_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + return com_rslt; +} +/*! + * @brief This API is used to read Threshold + * definition for the high-g interrupt from the register 0x5E 0 to 7 + * + * + * + * + * @param v_high_g_thres_u8 : Pointer holding the value of Threshold + * @note High_g threshold changes according to accel g range + * accel g range can be set by the function "" + * accel_range | high_g threshold + * ----------------|--------------------- + * 2g | v_high_g_thres_u8*7.81 mg + * 4g | v_high_g_thres_u8*15.63 mg + * 8g | v_high_g_thres_u8*31.25 mg + * 16g | v_high_g_thres_u8*62.5 mg + * @note when v_high_g_thres_u8 = 0 + * accel_range | high_g threshold + * ----------------|--------------------- + * 2g | 3.91 mg + * 4g | 7.81 mg + * 8g | 15.63 mg + * 16g | 31.25 mg + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_high_g_thres( +u8 *v_high_g_thres_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_high_g_thres_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES); + } + return com_rslt; +} +/*! + * @brief This API is used to write Threshold + * definition for the high-g interrupt from the register 0x5E 0 to 7 + * + * + * + * + * @param v_high_g_thres_u8 : Pointer holding the value of Threshold + * @note High_g threshold changes according to accel g range + * accel g range can be set by the function "" + * accel_range | high_g threshold + * ----------------|--------------------- + * 2g | v_high_g_thres_u8*7.81 mg + * 4g | v_high_g_thres_u8*15.63 mg + * 8g | v_high_g_thres_u8*31.25 mg + * 16g | v_high_g_thres_u8*62.5 mg + * @note when v_high_g_thres_u8 = 0 + * accel_range | high_g threshold + * ----------------|--------------------- + * 2g | 3.91 mg + * 4g | 7.81 mg + * 8g | 15.63 mg + * 16g | 31.25 mg + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_high_g_thres( +u8 v_high_g_thres_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + com_rslt = p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__REG, + &v_high_g_thres_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + return com_rslt; +} +/*! + * @brief This API reads any motion duration + * from the register 0x5F bit 0 and 1 + * + * @param v_any_motion_durn_u8 : The value of any motion duration + * + * @note Any motion duration can be calculated by "v_any_motion_durn_u8 + 1" + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_any_motion_durn( +u8 *v_any_motion_durn_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read any motion duration*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_any_motion_durn_u8 = BMI160_GET_BITSLICE + (v_data_u8, + BMI160_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN); + } + return com_rslt; +} +/*! + * @brief This API write any motion duration + * from the register 0x5F bit 0 and 1 + * + * @param v_any_motion_durn_u8 : The value of any motion duration + * + * @note Any motion duration can be calculated by "v_any_motion_durn_u8 + 1" + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_any_motion_durn( +u8 v_any_motion_durn_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write any motion duration*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN, + v_any_motion_durn_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } + return com_rslt; +} + /*! + * @brief This API read Slow/no-motion + * interrupt trigger delay duration from the register 0x5F bit 2 to 7 + * + * @param v_slow_no_motion_u8 :The value of slow no motion duration + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * @note + * @note v_slow_no_motion_u8(5:4)=0b00 -> + * [v_slow_no_motion_u8(3:0) + 1] * 1.28s (1.28s-20.48s) + * @note v_slow_no_motion_u8(5:4)=1 -> + * [v_slow_no_motion_u8(3:0)+5] * 5.12s (25.6s-102.4s) + * @note v_slow_no_motion_u8(5)='1' -> + * [(v_slow_no_motion_u8:0)+11] * 10.24s (112.64s-430.08s); + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_slow_no_motion_durn( +u8 *v_slow_no_motion_u8) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read slow no motion duration*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_slow_no_motion_u8 = BMI160_GET_BITSLICE + (v_data_u8, + BMI160_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN); + } +return com_rslt; +} + /*! + * @brief This API write Slow/no-motion + * interrupt trigger delay duration from the register 0x5F bit 2 to 7 + * + * @param v_slow_no_motion_u8 :The value of slow no motion duration + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * @note + * @note v_slow_no_motion_u8(5:4)=0b00 -> + * [v_slow_no_motion_u8(3:0) + 1] * 1.28s (1.28s-20.48s) + * @note v_slow_no_motion_u8(5:4)=1 -> + * [v_slow_no_motion_u8(3:0)+5] * 5.12s (25.6s-102.4s) + * @note v_slow_no_motion_u8(5)='1' -> + * [(v_slow_no_motion_u8:0)+11] * 10.24s (112.64s-430.08s); + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_slow_no_motion_durn( +u8 v_slow_no_motion_u8) +{ +/* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write slow no motion duration*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE + (v_data_u8, + BMI160_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN, + v_slow_no_motion_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } +} +return com_rslt; +} +/*! + * @brief This API is used to read threshold + * definition for the any-motion interrupt + * from the register 0x60 bit 0 to 7 + * + * + * @param v_any_motion_thres_u8 : The value of any motion threshold + * + * @note any motion threshold changes according to accel g range + * accel g range can be set by the function "" + * accel_range | any motion threshold + * ----------------|--------------------- + * 2g | v_any_motion_thres_u8*3.91 mg + * 4g | v_any_motion_thres_u8*7.81 mg + * 8g | v_any_motion_thres_u8*15.63 mg + * 16g | v_any_motion_thres_u8*31.25 mg + * @note when v_any_motion_thres_u8 = 0 + * accel_range | any motion threshold + * ----------------|--------------------- + * 2g | 1.95 mg + * 4g | 3.91 mg + * 8g | 7.81 mg + * 16g | 15.63 mg + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_any_motion_thres( +u8 *v_any_motion_thres_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read any motion threshold*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_any_motion_thres_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES); + } + return com_rslt; +} +/*! + * @brief This API is used to write threshold + * definition for the any-motion interrupt + * from the register 0x60 bit 0 to 7 + * + * + * @param v_any_motion_thres_u8 : The value of any motion threshold + * + * @note any motion threshold changes according to accel g range + * accel g range can be set by the function "" + * accel_range | any motion threshold + * ----------------|--------------------- + * 2g | v_any_motion_thres_u8*3.91 mg + * 4g | v_any_motion_thres_u8*7.81 mg + * 8g | v_any_motion_thres_u8*15.63 mg + * 16g | v_any_motion_thres_u8*31.25 mg + * @note when v_any_motion_thres_u8 = 0 + * accel_range | any motion threshold + * ----------------|--------------------- + * 2g | 1.95 mg + * 4g | 3.91 mg + * 8g | 7.81 mg + * 16g | 15.63 mg + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_any_motion_thres( +u8 v_any_motion_thres_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write any motion threshold*/ + com_rslt = p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__REG, + &v_any_motion_thres_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + return com_rslt; +} + /*! + * @brief This API is used to read threshold + * for the slow/no-motion interrupt + * from the register 0x61 bit 0 to 7 + * + * + * + * + * @param v_slow_no_motion_thres_u8 : The value of slow no motion threshold + * @note slow no motion threshold changes according to accel g range + * accel g range can be set by the function "" + * accel_range | slow no motion threshold + * ----------------|--------------------- + * 2g | v_slow_no_motion_thres_u8*3.91 mg + * 4g | v_slow_no_motion_thres_u8*7.81 mg + * 8g | v_slow_no_motion_thres_u8*15.63 mg + * 16g | v_slow_no_motion_thres_u8*31.25 mg + * @note when v_slow_no_motion_thres_u8 = 0 + * accel_range | slow no motion threshold + * ----------------|--------------------- + * 2g | 1.95 mg + * 4g | 3.91 mg + * 8g | 7.81 mg + * 16g | 15.63 mg + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_slow_no_motion_thres( +u8 *v_slow_no_motion_thres_u8) +{ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read slow no motion threshold*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_slow_no_motion_thres_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES); + } +return com_rslt; +} + /*! + * @brief This API is used to write threshold + * for the slow/no-motion interrupt + * from the register 0x61 bit 0 to 7 + * + * + * + * + * @param v_slow_no_motion_thres_u8 : The value of slow no motion threshold + * @note slow no motion threshold changes according to accel g range + * accel g range can be set by the function "" + * accel_range | slow no motion threshold + * ----------------|--------------------- + * 2g | v_slow_no_motion_thres_u8*3.91 mg + * 4g | v_slow_no_motion_thres_u8*7.81 mg + * 8g | v_slow_no_motion_thres_u8*15.63 mg + * 16g | v_slow_no_motion_thres_u8*31.25 mg + * @note when v_slow_no_motion_thres_u8 = 0 + * accel_range | slow no motion threshold + * ----------------|--------------------- + * 2g | 1.95 mg + * 4g | 3.91 mg + * 8g | 7.81 mg + * 16g | 15.63 mg + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_slow_no_motion_thres( +u8 v_slow_no_motion_thres_u8) +{ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write slow no motion threshold*/ + com_rslt = p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__REG, + &v_slow_no_motion_thres_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } +return com_rslt; +} + /*! + * @brief This API is used to read + * the slow/no-motion selection from the register 0x62 bit 0 + * + * + * + * + * @param v_intr_slow_no_motion_select_u8 : + * The value of slow/no-motion select + * value | Behaviour + * ----------|------------------- + * 0x00 | SLOW_MOTION + * 0x01 | NO_MOTION + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_slow_no_motion_select( +u8 *v_intr_slow_no_motion_select_u8) +{ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read slow no motion select*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_slow_no_motion_select_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT); + } +return com_rslt; +} + /*! + * @brief This API is used to write + * the slow/no-motion selection from the register 0x62 bit 0 + * + * + * + * + * @param v_intr_slow_no_motion_select_u8 : + * The value of slow/no-motion select + * value | Behaviour + * ----------|------------------- + * 0x00 | SLOW_MOTION + * 0x01 | NO_MOTION + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_slow_no_motion_select( +u8 v_intr_slow_no_motion_select_u8) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; +} else { +if (v_intr_slow_no_motion_select_u8 <= BMI160_MAX_VALUE_NO_MOTION) { + /* write slow no motion select*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT, + v_intr_slow_no_motion_select_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } +} else { +com_rslt = E_BMI160_OUT_OF_RANGE; +} +} +return com_rslt; +} + /*! + * @brief This API is used to select + * the significant or any motion interrupt from the register 0x62 bit 1 + * + * + * + * + * @param v_intr_significant_motion_select_u8 : + * the value of significant or any motion interrupt selection + * value | Behaviour + * ----------|------------------- + * 0x00 | ANY_MOTION + * 0x01 | SIGNIFICANT_MOTION + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_significant_motion_select( +u8 *v_intr_significant_motion_select_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the significant or any motion interrupt*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_SIGNIFICATION_MOTION_SELECT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_intr_significant_motion_select_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_SIGNIFICATION_MOTION_SELECT); + } + return com_rslt; +} + /*! + * @brief This API is used to write, select + * the significant or any motion interrupt from the register 0x62 bit 1 + * + * + * + * + * @param v_intr_significant_motion_select_u8 : + * the value of significant or any motion interrupt selection + * value | Behaviour + * ----------|------------------- + * 0x00 | ANY_MOTION + * 0x01 | SIGNIFICANT_MOTION + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_significant_motion_select( +u8 v_intr_significant_motion_select_u8) +{ +/* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_intr_significant_motion_select_u8 <= + BMI160_MAX_VALUE_SIGNIFICANT_MOTION) { + /* write the significant or any motion interrupt*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_SIGNIFICATION_MOTION_SELECT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_SIGNIFICATION_MOTION_SELECT, + v_intr_significant_motion_select_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_SIGNIFICATION_MOTION_SELECT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } +} +return com_rslt; +} + /*! + * @brief This API is used to read + * the significant skip time from the register 0x62 bit 2 and 3 + * + * + * + * + * @param v_int_sig_mot_skip_u8 : the value of significant skip time + * value | Behaviour + * ----------|------------------- + * 0x00 | skip time 1.5 seconds + * 0x01 | skip time 3 seconds + * 0x02 | skip time 6 seconds + * 0x03 | skip time 12 seconds + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_significant_motion_skip( +u8 *v_int_sig_mot_skip_u8) +{ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read significant skip time*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_SIGNIFICANT_MOTION_SKIP__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_int_sig_mot_skip_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_SIGNIFICANT_MOTION_SKIP); + } + return com_rslt; +} + /*! + * @brief This API is used to write + * the significant skip time from the register 0x62 bit 2 and 3 + * + * + * + * + * @param v_int_sig_mot_skip_u8 : the value of significant skip time + * value | Behaviour + * ----------|------------------- + * 0x00 | skip time 1.5 seconds + * 0x01 | skip time 3 seconds + * 0x02 | skip time 6 seconds + * 0x03 | skip time 12 seconds + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_significant_motion_skip( +u8 v_int_sig_mot_skip_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_int_sig_mot_skip_u8 <= BMI160_MAX_UNDER_SIG_MOTION) { + /* write significant skip time*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_SIGNIFICANT_MOTION_SKIP__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_SIGNIFICANT_MOTION_SKIP, + v_int_sig_mot_skip_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_SIGNIFICANT_MOTION_SKIP__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} + /*! + * @brief This API is used to read + * the significant proof time from the register 0x62 bit 4 and 5 + * + * + * + * + * @param v_significant_motion_proof_u8 : + * the value of significant proof time + * value | Behaviour + * ----------|------------------- + * 0x00 | proof time 0.25 seconds + * 0x01 | proof time 0.5 seconds + * 0x02 | proof time 1 seconds + * 0x03 | proof time 2 seconds + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_significant_motion_proof( +u8 *v_significant_motion_proof_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read significant proof time */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_SIGNIFICANT_MOTION_PROOF__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_significant_motion_proof_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_SIGNIFICANT_MOTION_PROOF); + } + return com_rslt; +} + /*! + * @brief This API is used to write + * the significant proof time from the register 0x62 bit 4 and 5 + * + * + * + * + * @param v_significant_motion_proof_u8 : + * the value of significant proof time + * value | Behaviour + * ----------|------------------- + * 0x00 | proof time 0.25 seconds + * 0x01 | proof time 0.5 seconds + * 0x02 | proof time 1 seconds + * 0x03 | proof time 2 seconds + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_significant_motion_proof( +u8 v_significant_motion_proof_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_significant_motion_proof_u8 + <= BMI160_MAX_UNDER_SIG_MOTION) { + /* write significant proof time */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_SIGNIFICANT_MOTION_PROOF__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_SIGNIFICANT_MOTION_PROOF, + v_significant_motion_proof_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_SIGNIFICANT_MOTION_PROOF__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API is used to get the tap duration + * from the register 0x63 bit 0 to 2 + * + * + * + * @param v_tap_durn_u8 : The value of tap duration + * value | Behaviour + * ----------|------------------- + * 0x00 | BMI160_TAP_DURN_50MS + * 0x01 | BMI160_TAP_DURN_100MS + * 0x03 | BMI160_TAP_DURN_150MS + * 0x04 | BMI160_TAP_DURN_200MS + * 0x05 | BMI160_TAP_DURN_250MS + * 0x06 | BMI160_TAP_DURN_375MS + * 0x07 | BMI160_TAP_DURN_700MS + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_durn( +u8 *v_tap_durn_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read tap duration*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_TAP_0_INTR_TAP_DURN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_tap_durn_u8 = BMI160_GET_BITSLICE( + v_data_u8, + BMI160_USER_INTR_TAP_0_INTR_TAP_DURN); + } + return com_rslt; +} +/*! + * @brief This API is used to write the tap duration + * from the register 0x63 bit 0 to 2 + * + * + * + * @param v_tap_durn_u8 : The value of tap duration + * value | Behaviour + * ----------|------------------- + * 0x00 | BMI160_TAP_DURN_50MS + * 0x01 | BMI160_TAP_DURN_100MS + * 0x03 | BMI160_TAP_DURN_150MS + * 0x04 | BMI160_TAP_DURN_200MS + * 0x05 | BMI160_TAP_DURN_250MS + * 0x06 | BMI160_TAP_DURN_375MS + * 0x07 | BMI160_TAP_DURN_700MS + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_durn( +u8 v_tap_durn_u8) +{ + u8 v_data_u8 = BMI160_INIT_VALUE; + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_tap_durn_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_tap_durn_u8 <= BMI160_MAX_TAP_TURN) { + switch (v_tap_durn_u8) { + case BMI160_TAP_DURN_50MS: + v_data_tap_durn_u8 = BMI160_TAP_DURN_50MS; + break; + case BMI160_TAP_DURN_100MS: + v_data_tap_durn_u8 = BMI160_TAP_DURN_100MS; + break; + case BMI160_TAP_DURN_150MS: + v_data_tap_durn_u8 = BMI160_TAP_DURN_150MS; + break; + case BMI160_TAP_DURN_200MS: + v_data_tap_durn_u8 = BMI160_TAP_DURN_200MS; + break; + case BMI160_TAP_DURN_250MS: + v_data_tap_durn_u8 = BMI160_TAP_DURN_250MS; + break; + case BMI160_TAP_DURN_375MS: + v_data_tap_durn_u8 = BMI160_TAP_DURN_375MS; + break; + case BMI160_TAP_DURN_500MS: + v_data_tap_durn_u8 = BMI160_TAP_DURN_500MS; + break; + case BMI160_TAP_DURN_700MS: + v_data_tap_durn_u8 = BMI160_TAP_DURN_700MS; + break; + default: + break; + } + /* write tap duration*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_TAP_0_INTR_TAP_DURN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_TAP_0_INTR_TAP_DURN, + v_data_tap_durn_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_TAP_0_INTR_TAP_DURN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} + /*! + * @brief This API read the + * tap shock duration from the register 0x63 bit 2 + * + * @param v_tap_shock_u8 :The value of tap shock + * value | Behaviour + * ----------|------------------- + * 0x00 | BMI160_TAP_SHOCK_50MS + * 0x01 | BMI160_TAP_SHOCK_75MS + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_shock( +u8 *v_tap_shock_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read tap shock duration*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_TAP_0_INTR_TAP_SHOCK__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_tap_shock_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_TAP_0_INTR_TAP_SHOCK); + } + return com_rslt; +} + /*! + * @brief This API write the + * tap shock duration from the register 0x63 bit 2 + * + * @param v_tap_shock_u8 :The value of tap shock + * value | Behaviour + * ----------|------------------- + * 0x00 | BMI160_TAP_SHOCK_50MS + * 0x01 | BMI160_TAP_SHOCK_75MS + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_shock(u8 v_tap_shock_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_tap_shock_u8 <= BMI160_MAX_VALUE_TAP_SHOCK) { + /* write tap shock duration*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_TAP_0_INTR_TAP_SHOCK__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_TAP_0_INTR_TAP_SHOCK, + v_tap_shock_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_TAP_0_INTR_TAP_SHOCK__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API read + * tap quiet duration from the register 0x63 bit 7 + * + * + * @param v_tap_quiet_u8 : The value of tap quiet + * value | Behaviour + * ----------|------------------- + * 0x00 | BMI160_TAP_QUIET_30MS + * 0x01 | BMI160_TAP_QUIET_20MS + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_quiet( +u8 *v_tap_quiet_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read tap quiet duration*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_TAP_0_INTR_TAP_QUIET__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_tap_quiet_u8 = BMI160_GET_BITSLICE( + v_data_u8, + BMI160_USER_INTR_TAP_0_INTR_TAP_QUIET); + } + return com_rslt; +} +/*! + * @brief This API write + * tap quiet duration from the register 0x63 bit 7 + * + * + * @param v_tap_quiet_u8 : The value of tap quiet + * value | Behaviour + * ----------|------------------- + * 0x00 | BMI160_TAP_QUIET_30MS + * 0x01 | BMI160_TAP_QUIET_20MS + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_quiet(u8 v_tap_quiet_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_tap_quiet_u8 <= BMI160_MAX_VALUE_TAP_QUIET) { + /* write tap quiet duration*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_TAP_0_INTR_TAP_QUIET__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_TAP_0_INTR_TAP_QUIET, + v_tap_quiet_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_TAP_0_INTR_TAP_QUIET__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} + /*! + * @brief This API read Threshold of the + * single/double tap interrupt from the register 0x64 bit 0 to 4 + * + * + * @param v_tap_thres_u8 : The value of single/double tap threshold + * + * @note single/double tap threshold changes according to accel g range + * accel g range can be set by the function "" + * accel_range | single/double tap threshold + * ----------------|--------------------- + * 2g | ((v_tap_thres_u8 + 1) * 62.5)mg + * 4g | ((v_tap_thres_u8 + 1) * 125)mg + * 8g | ((v_tap_thres_u8 + 1) * 250)mg + * 16g | ((v_tap_thres_u8 + 1) * 500)mg + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_thres( +u8 *v_tap_thres_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read tap threshold*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_TAP_1_INTR_TAP_THRES__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_tap_thres_u8 = BMI160_GET_BITSLICE + (v_data_u8, + BMI160_USER_INTR_TAP_1_INTR_TAP_THRES); + } + return com_rslt; +} + /*! + * @brief This API write Threshold of the + * single/double tap interrupt from the register 0x64 bit 0 to 4 + * + * + * @param v_tap_thres_u8 : The value of single/double tap threshold + * + * @note single/double tap threshold changes according to accel g range + * accel g range can be set by the function "" + * accel_range | single/double tap threshold + * ----------------|--------------------- + * 2g | ((v_tap_thres_u8 + 1) * 62.5)mg + * 4g | ((v_tap_thres_u8 + 1) * 125)mg + * 8g | ((v_tap_thres_u8 + 1) * 250)mg + * 16g | ((v_tap_thres_u8 + 1) * 500)mg + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_thres( +u8 v_tap_thres_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write tap threshold*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_TAP_1_INTR_TAP_THRES__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_TAP_1_INTR_TAP_THRES, + v_tap_thres_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_TAP_1_INTR_TAP_THRES__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } + return com_rslt; +} + /*! + * @brief This API read the threshold for orientation interrupt + * from the register 0x65 bit 0 and 1 + * + * @param v_orient_mode_u8 : The value of threshold for orientation + * value | Behaviour + * ----------|------------------- + * 0x00 | symmetrical + * 0x01 | high-asymmetrical + * 0x02 | low-asymmetrical + * 0x03 | symmetrical + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_mode( +u8 *v_orient_mode_u8) +{ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read orientation threshold*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_orient_mode_u8 = BMI160_GET_BITSLICE + (v_data_u8, + BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_MODE); + } + return com_rslt; +} + /*! + * @brief This API write the threshold for orientation interrupt + * from the register 0x65 bit 0 and 1 + * + * @param v_orient_mode_u8 : The value of threshold for orientation + * value | Behaviour + * ----------|------------------- + * 0x00 | symmetrical + * 0x01 | high-asymmetrical + * 0x02 | low-asymmetrical + * 0x03 | symmetrical + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_mode( +u8 v_orient_mode_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_orient_mode_u8 <= BMI160_MAX_ORIENT_MODE) { + /* write orientation threshold*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_MODE, + v_orient_mode_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API read the orient blocking mode + * that is used for the generation of the orientation interrupt. + * from the register 0x65 bit 2 and 3 + * + * @param v_orient_blocking_u8 : The value of orient blocking mode + * value | Behaviour + * ----------|------------------- + * 0x00 | No blocking + * 0x01 | Theta blocking or acceleration in any axis > 1.5g + * 0x02 | Theta blocking or acceleration slope in any axis > + * - | 0.2g or acceleration in any axis > 1.5g + * 0x03 | Theta blocking or acceleration slope in any axis > + * - | 0.4g or acceleration in any axis > + * - | 1.5g and value of orient is not stable + * - | for at least 100 ms + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_blocking( +u8 *v_orient_blocking_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read orient blocking mode*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_orient_blocking_u8 = BMI160_GET_BITSLICE + (v_data_u8, + BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING); + } + return com_rslt; +} +/*! + * @brief This API write the orient blocking mode + * that is used for the generation of the orientation interrupt. + * from the register 0x65 bit 2 and 3 + * + * @param v_orient_blocking_u8 : The value of orient blocking mode + * value | Behaviour + * ----------|------------------- + * 0x00 | No blocking + * 0x01 | Theta blocking or acceleration in any axis > 1.5g + * 0x02 | Theta blocking or acceleration slope in any axis > + * - | 0.2g or acceleration in any axis > 1.5g + * 0x03 | Theta blocking or acceleration slope in any axis > + * - | 0.4g or acceleration in any axis > + * - | 1.5g and value of orient is not stable + * - | for at least 100 ms + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_blocking( +u8 v_orient_blocking_u8) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_orient_blocking_u8 <= BMI160_MAX_ORIENT_BLOCKING) { + /* write orient blocking mode*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING, + v_orient_blocking_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } +} +return com_rslt; +} +/*! + * @brief This API read Orient interrupt + * hysteresis, from the register 0x64 bit 4 to 7 + * + * + * + * @param v_orient_hyst_u8 : The value of orient hysteresis + * + * @note 1 LSB corresponds to 62.5 mg, + * irrespective of the selected accel range + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_hyst( +u8 *v_orient_hyst_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read orient hysteresis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_orient_hyst_u8 = BMI160_GET_BITSLICE + (v_data_u8, + BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_HYST); + } + return com_rslt; +} +/*! + * @brief This API write Orient interrupt + * hysteresis, from the register 0x64 bit 4 to 7 + * + * + * + * @param v_orient_hyst_u8 : The value of orient hysteresis + * + * @note 1 LSB corresponds to 62.5 mg, + * irrespective of the selected accel range + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_hyst( +u8 v_orient_hyst_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write orient hysteresis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_HYST, + v_orient_hyst_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } + return com_rslt; +} + /*! + * @brief This API read Orient + * blocking angle (0 to 44.8) from the register 0x66 bit 0 to 5 + * + * @param v_orient_theta_u8 : The value of Orient blocking angle + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_theta( +u8 *v_orient_theta_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read Orient blocking angle*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_orient_theta_u8 = BMI160_GET_BITSLICE + (v_data_u8, + BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_THETA); + } + return com_rslt; +} + /*! + * @brief This API write Orient + * blocking angle (0 to 44.8) from the register 0x66 bit 0 to 5 + * + * @param v_orient_theta_u8 : The value of Orient blocking angle + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_theta( +u8 v_orient_theta_u8) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_orient_theta_u8 <= BMI160_MAX_ORIENT_THETA) { + /* write Orient blocking angle*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_THETA, + v_orient_theta_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } +} +return com_rslt; +} +/*! + * @brief This API read orient change + * of up/down bit from the register 0x66 bit 6 + * + * @param v_orient_ud_u8 : The value of orient change of up/down + * value | Behaviour + * ----------|------------------- + * 0x00 | Is ignored + * 0x01 | Generates orientation interrupt + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_ud_enable( +u8 *v_orient_ud_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read orient up/down enable*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_orient_ud_u8 = BMI160_GET_BITSLICE + (v_data_u8, + BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE); + } + return com_rslt; +} +/*! + * @brief This API write orient change + * of up/down bit from the register 0x66 bit 6 + * + * @param v_orient_ud_u8 : The value of orient change of up/down + * value | Behaviour + * ----------|------------------- + * 0x00 | Is ignored + * 0x01 | Generates orientation interrupt + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_ud_enable( +u8 v_orient_ud_u8) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_orient_ud_u8 <= BMI160_MAX_VALUE_ORIENT_UD) { + /* write orient up/down enable */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE, + v_orient_ud_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } +} +return com_rslt; +} + /*! + * @brief This API read orientation axes changes + * from the register 0x66 bit 7 + * + * @param v_orient_axes_u8 : The value of orient axes assignment + * value | Behaviour | Name + * ----------|--------------------|------ + * 0x00 | x = x, y = y, z = z|orient_ax_noex + * 0x01 | x = y, y = z, z = x|orient_ax_ex + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_axes_enable( +u8 *v_orient_axes_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read orientation axes changes */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_orient_axes_u8 = BMI160_GET_BITSLICE + (v_data_u8, + BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX); + } + return com_rslt; +} + /*! + * @brief This API write orientation axes changes + * from the register 0x66 bit 7 + * + * @param v_orient_axes_u8 : The value of orient axes assignment + * value | Behaviour | Name + * ----------|--------------------|------ + * 0x00 | x = x, y = y, z = z|orient_ax_noex + * 0x01 | x = y, y = z, z = x|orient_ax_ex + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_axes_enable( +u8 v_orient_axes_u8) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_orient_axes_u8 <= BMI160_MAX_VALUE_ORIENT_AXES) { + /*write orientation axes changes */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX, + v_orient_axes_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } +} +return com_rslt; +} + /*! + * @brief This API read Flat angle (0 to 44.8) for flat interrupt + * from the register 0x67 bit 0 to 5 + * + * @param v_flat_theta_u8 : The value of flat angle + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_flat_theta( +u8 *v_flat_theta_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read Flat angle*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_FLAT_0_INTR_FLAT_THETA__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_flat_theta_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_FLAT_0_INTR_FLAT_THETA); + } + return com_rslt; +} + /*! + * @brief This API write Flat angle (0 to 44.8) for flat interrupt + * from the register 0x67 bit 0 to 5 + * + * @param v_flat_theta_u8 : The value of flat angle + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_flat_theta( +u8 v_flat_theta_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_flat_theta_u8 <= BMI160_MAX_FLAT_THETA) { + /* write Flat angle */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_FLAT_0_INTR_FLAT_THETA__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_FLAT_0_INTR_FLAT_THETA, + v_flat_theta_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_FLAT_0_INTR_FLAT_THETA__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API read Flat interrupt hold time; + * from the register 0x68 bit 4 and 5 + * + * @param v_flat_hold_u8 : The value of flat hold time + * value | Behaviour + * ----------|------------------- + * 0x00 | 0ms + * 0x01 | 512ms + * 0x01 | 1024ms + * 0x01 | 2048ms + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_flat_hold( +u8 *v_flat_hold_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read flat hold time*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_FLAT_1_INTR_FLAT_HOLD__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_flat_hold_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_INTR_FLAT_1_INTR_FLAT_HOLD); + } + return com_rslt; +} +/*! + * @brief This API write Flat interrupt hold time; + * from the register 0x68 bit 4 and 5 + * + * @param v_flat_hold_u8 : The value of flat hold time + * value | Behaviour + * ----------|------------------- + * 0x00 | 0ms + * 0x01 | 512ms + * 0x01 | 1024ms + * 0x01 | 2048ms + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_flat_hold( +u8 v_flat_hold_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_flat_hold_u8 <= BMI160_MAX_FLAT_HOLD) { + /* write flat hold time*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_FLAT_1_INTR_FLAT_HOLD__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_FLAT_1_INTR_FLAT_HOLD, + v_flat_hold_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_FLAT_1_INTR_FLAT_HOLD__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API read flat interrupt hysteresis + * from the register 0x68 bit 0 to 3 + * + * @param v_flat_hyst_u8 : The value of flat hysteresis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_flat_hyst( +u8 *v_flat_hyst_u8) +{ + /* variable used to return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the flat hysteresis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_INTR_FLAT_1_INTR_FLAT_HYST__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_flat_hyst_u8 = BMI160_GET_BITSLICE( + v_data_u8, + BMI160_USER_INTR_FLAT_1_INTR_FLAT_HYST); + } + return com_rslt; +} +/*! + * @brief This API write flat interrupt hysteresis + * from the register 0x68 bit 0 to 3 + * + * @param v_flat_hyst_u8 : The value of flat hysteresis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_flat_hyst( +u8 v_flat_hyst_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_flat_hyst_u8 <= BMI160_MAX_FLAT_HYST) { + /* read the flat hysteresis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_FLAT_1_INTR_FLAT_HYST__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_INTR_FLAT_1_INTR_FLAT_HYST, + v_flat_hyst_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_INTR_FLAT_1_INTR_FLAT_HYST__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} + /*! + * @brief This API read accel offset compensation + * target value for z-axis from the register 0x69 bit 0 and 1 + * + * @param v_foc_accel_z_u8 : the value of accel offset compensation z axis + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x01 | -1g + * 0x01 | 0g + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_accel_z(u8 *v_foc_accel_z_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the accel offset compensation for z axis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_Z__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_foc_accel_z_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_FOC_ACCEL_Z); + } + return com_rslt; +} + /*! + * @brief This API write accel offset compensation + * target value for z-axis from the register 0x69 bit 0 and 1 + * + * @param v_foc_accel_z_u8 : the value of accel offset compensation z axis + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x01 | -1g + * 0x01 | 0g + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_foc_accel_z( +u8 v_foc_accel_z_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write the accel offset compensation for z axis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_Z__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_FOC_ACCEL_Z, + v_foc_accel_z_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_Z__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } + return com_rslt; +} +/*! + * @brief This API read accel offset compensation + * target value for y-axis + * from the register 0x69 bit 2 and 3 + * + * @param v_foc_accel_y_u8 : the value of accel offset compensation y axis + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x01 | -1g + * 0x01 | 0g + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_accel_y(u8 *v_foc_accel_y_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the accel offset compensation for y axis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_Y__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_foc_accel_y_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_FOC_ACCEL_Y); + } + return com_rslt; +} +/*! + * @brief This API write accel offset compensation + * target value for y-axis + * from the register 0x69 bit 2 and 3 + * + * @param v_foc_accel_y_u8 : the value of accel offset compensation y axis + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x02 | -1g + * 0x03 | 0g + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_foc_accel_y(u8 v_foc_accel_y_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_foc_accel_y_u8 <= BMI160_MAX_ACCEL_FOC) { + /* write the accel offset compensation for y axis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_Y__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_FOC_ACCEL_Y, + v_foc_accel_y_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_Y__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API read accel offset compensation + * target value for x-axis is + * from the register 0x69 bit 4 and 5 + * + * @param v_foc_accel_x_u8 : the value of accel offset compensation x axis + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x02 | -1g + * 0x03 | 0g + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_accel_x(u8 *v_foc_accel_x_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the accel offset compensation for x axis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_X__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_foc_accel_x_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_FOC_ACCEL_X); + } + return com_rslt; +} +/*! + * @brief This API write accel offset compensation + * target value for x-axis is + * from the register 0x69 bit 4 and 5 + * + * @param v_foc_accel_x_u8 : the value of accel offset compensation x axis + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x01 | -1g + * 0x01 | 0g + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_foc_accel_x(u8 v_foc_accel_x_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_foc_accel_x_u8 <= BMI160_MAX_ACCEL_FOC) { + /* write the accel offset compensation for x axis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_X__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_FOC_ACCEL_X, + v_foc_accel_x_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_X__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API writes accel fast offset compensation + * from the register 0x69 bit 0 to 5 + * @brief This API writes each axis individually + * FOC_X_AXIS - bit 4 and 5 + * FOC_Y_AXIS - bit 2 and 3 + * FOC_Z_AXIS - bit 0 and 1 + * + * @param v_foc_accel_u8: The value of accel offset compensation + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x01 | -1g + * 0x01 | 0g + * + * @param v_axis_u8: The value of accel offset axis selection + * value | axis + * ----------|------------------- + * 0 | FOC_X_AXIS + * 1 | FOC_Y_AXIS + * 2 | FOC_Z_AXIS + * + * @param v_accel_offset_s8: The accel offset value + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_foc_trigger(u8 v_axis_u8, +u8 v_foc_accel_u8, s8 *v_accel_offset_s8) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +s8 v_status_s8 = SUCCESS; +u8 v_timeout_u8 = BMI160_INIT_VALUE; +s8 v_foc_accel_offset_x_s8 = BMI160_INIT_VALUE; +s8 v_foc_accel_offset_y_s8 = BMI160_INIT_VALUE; +s8 v_foc_accel_offset_z_s8 = BMI160_INIT_VALUE; +u8 focstatus = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; +} else { + v_status_s8 = bmi160_set_accel_offset_enable( + ACCEL_OFFSET_ENABLE); + if (v_status_s8 == SUCCESS) { + switch (v_axis_u8) { + case FOC_X_AXIS: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_X__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_FOC_ACCEL_X, + v_foc_accel_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_X__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + + /* trigger the + FOC need to write + 0x03 in the register 0x7e*/ + com_rslt += + bmi160_set_command_register( + START_FOC_ACCEL_GYRO); + + com_rslt += + bmi160_get_foc_rdy(&focstatus); + if ((com_rslt != SUCCESS) || + (focstatus != BMI160_FOC_STAT_HIGH)) { + while ((com_rslt != SUCCESS) || + (focstatus != BMI160_FOC_STAT_HIGH + && v_timeout_u8 < + BMI160_MAXIMUM_TIMEOUT)) { + p_bmi160->delay_msec( + BMI160_DELAY_SETTLING_TIME); + com_rslt = bmi160_get_foc_rdy( + &focstatus); + v_timeout_u8++; + } + } + if ((com_rslt == SUCCESS) && + (focstatus == BMI160_FOC_STAT_HIGH)) { + com_rslt += + bmi160_get_accel_offset_compensation_xaxis( + &v_foc_accel_offset_x_s8); + *v_accel_offset_s8 = + v_foc_accel_offset_x_s8; + } + break; + case FOC_Y_AXIS: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_Y__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_FOC_ACCEL_Y, + v_foc_accel_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_Y__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + + /* trigger the FOC + need to write 0x03 + in the register 0x7e*/ + com_rslt += + bmi160_set_command_register( + START_FOC_ACCEL_GYRO); + + com_rslt += + bmi160_get_foc_rdy(&focstatus); + if ((com_rslt != SUCCESS) || + (focstatus != BMI160_FOC_STAT_HIGH)) { + while ((com_rslt != SUCCESS) || + (focstatus != BMI160_FOC_STAT_HIGH + && v_timeout_u8 < + BMI160_MAXIMUM_TIMEOUT)) { + p_bmi160->delay_msec( + BMI160_DELAY_SETTLING_TIME); + com_rslt = bmi160_get_foc_rdy( + &focstatus); + v_timeout_u8++; + } + } + if ((com_rslt == SUCCESS) && + (focstatus == BMI160_FOC_STAT_HIGH)) { + com_rslt += + bmi160_get_accel_offset_compensation_yaxis( + &v_foc_accel_offset_y_s8); + *v_accel_offset_s8 = + v_foc_accel_offset_y_s8; + } + break; + case FOC_Z_AXIS: + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_Z__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_FOC_ACCEL_Z, + v_foc_accel_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_Z__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + + /* trigger the FOC need to write + 0x03 in the register 0x7e*/ + com_rslt += + bmi160_set_command_register( + START_FOC_ACCEL_GYRO); + + com_rslt += + bmi160_get_foc_rdy(&focstatus); + if ((com_rslt != SUCCESS) || + (focstatus != BMI160_FOC_STAT_HIGH)) { + while ((com_rslt != SUCCESS) || + (focstatus != BMI160_FOC_STAT_HIGH + && v_timeout_u8 < + BMI160_MAXIMUM_TIMEOUT)) { + p_bmi160->delay_msec( + BMI160_DELAY_SETTLING_TIME); + com_rslt = bmi160_get_foc_rdy( + &focstatus); + v_timeout_u8++; + } + } + if ((com_rslt == SUCCESS) && + (focstatus == BMI160_FOC_STAT_HIGH)) { + com_rslt += + bmi160_get_accel_offset_compensation_zaxis( + &v_foc_accel_offset_z_s8); + *v_accel_offset_s8 = + v_foc_accel_offset_z_s8; + } + break; + default: + break; + } + } else { + com_rslt = ERROR; + } +} +return com_rslt; +} +/*! + * @brief This API write fast accel offset compensation + * it writes all axis together.To the register 0x69 bit 0 to 5 + * FOC_X_AXIS - bit 4 and 5 + * FOC_Y_AXIS - bit 2 and 3 + * FOC_Z_AXIS - bit 0 and 1 + * + * @param v_foc_accel_x_u8: The value of accel offset x compensation + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x01 | -1g + * 0x01 | 0g + * + * @param v_foc_accel_y_u8: The value of accel offset y compensation + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x01 | -1g + * 0x01 | 0g + * + * @param v_foc_accel_z_u8: The value of accel offset z compensation + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x01 | -1g + * 0x01 | 0g + * + * @param v_accel_off_x_s8: The value of accel offset x axis + * @param v_accel_off_y_s8: The value of accel offset y axis + * @param v_accel_off_z_s8: The value of accel offset z axis + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_accel_foc_trigger_xyz(u8 v_foc_accel_x_u8, +u8 v_foc_accel_y_u8, u8 v_foc_accel_z_u8, s8 *v_accel_off_x_s8, +s8 *v_accel_off_y_s8, s8 *v_accel_off_z_s8) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 focx = BMI160_INIT_VALUE; +u8 focy = BMI160_INIT_VALUE; +u8 focz = BMI160_INIT_VALUE; +s8 v_foc_accel_offset_x_s8 = BMI160_INIT_VALUE; +s8 v_foc_accel_offset_y_s8 = BMI160_INIT_VALUE; +s8 v_foc_accel_offset_z_s8 = BMI160_INIT_VALUE; +u8 v_status_s8 = SUCCESS; +u8 v_timeout_u8 = BMI160_INIT_VALUE; +u8 focstatus = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + v_status_s8 = bmi160_set_accel_offset_enable( + ACCEL_OFFSET_ENABLE); + if (v_status_s8 == SUCCESS) { + /* foc x axis*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_X__REG, + &focx, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + focx = BMI160_SET_BITSLICE(focx, + BMI160_USER_FOC_ACCEL_X, + v_foc_accel_x_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_X__REG, + &focx, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + + /* foc y axis*/ + com_rslt += + p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_Y__REG, + &focy, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + focy = BMI160_SET_BITSLICE(focy, + BMI160_USER_FOC_ACCEL_Y, + v_foc_accel_y_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_Y__REG, + &focy, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + + /* foc z axis*/ + com_rslt += + p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_Z__REG, + &focz, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + focz = BMI160_SET_BITSLICE(focz, + BMI160_USER_FOC_ACCEL_Z, + v_foc_accel_z_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FOC_ACCEL_Z__REG, + &focz, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + + /* trigger the FOC need to + write 0x03 in the register 0x7e*/ + com_rslt += bmi160_set_command_register( + START_FOC_ACCEL_GYRO); + + com_rslt += bmi160_get_foc_rdy( + &focstatus); + if ((com_rslt != SUCCESS) || + (focstatus != BMI160_FOC_STAT_HIGH)) { + while ((com_rslt != SUCCESS) || + (focstatus != BMI160_FOC_STAT_HIGH + && v_timeout_u8 < + BMI160_MAXIMUM_TIMEOUT)) { + p_bmi160->delay_msec( + BMI160_DELAY_SETTLING_TIME); + com_rslt = bmi160_get_foc_rdy( + &focstatus); + v_timeout_u8++; + } + } + if ((com_rslt == SUCCESS) && + (focstatus == BMI160_GEN_READ_WRITE_DATA_LENGTH)) { + com_rslt += + bmi160_get_accel_offset_compensation_xaxis( + &v_foc_accel_offset_x_s8); + *v_accel_off_x_s8 = + v_foc_accel_offset_x_s8; + com_rslt += + bmi160_get_accel_offset_compensation_yaxis( + &v_foc_accel_offset_y_s8); + *v_accel_off_y_s8 = + v_foc_accel_offset_y_s8; + com_rslt += + bmi160_get_accel_offset_compensation_zaxis( + &v_foc_accel_offset_z_s8); + *v_accel_off_z_s8 = + v_foc_accel_offset_z_s8; + } + } else { + com_rslt = ERROR; + } + } +return com_rslt; +} +/*! + * @brief This API read gyro fast offset enable + * from the register 0x69 bit 6 + * + * @param v_foc_gyro_u8 : The value of gyro fast offset enable + * value | Description + * ----------|------------- + * 0 | fast offset compensation disabled + * 1 | fast offset compensation enabled + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_gyro_enable( +u8 *v_foc_gyro_u8) +{ + /* used for return the status of bus communication */ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the gyro fast offset enable*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_FOC_GYRO_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_foc_gyro_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_FOC_GYRO_ENABLE); + } + return com_rslt; +} +/*! + * @brief This API write gyro fast offset enable + * from the register 0x69 bit 6 + * + * @param v_foc_gyro_u8 : The value of gyro fast offset enable + * value | Description + * ----------|------------- + * 0 | fast offset compensation disabled + * 1 | fast offset compensation enabled + * + * @param v_gyro_off_x_s16 : The value of gyro fast offset x axis data + * @param v_gyro_off_y_s16 : The value of gyro fast offset y axis data + * @param v_gyro_off_z_s16 : The value of gyro fast offset z axis data + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_foc_gyro_enable( +u8 v_foc_gyro_u8, s16 *v_gyro_off_x_s16, +s16 *v_gyro_off_y_s16, s16 *v_gyro_off_z_s16) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +u8 v_status_s8 = SUCCESS; +u8 v_timeout_u8 = BMI160_INIT_VALUE; +s16 offsetx = BMI160_INIT_VALUE; +s16 offsety = BMI160_INIT_VALUE; +s16 offsetz = BMI160_INIT_VALUE; +u8 focstatus = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + v_status_s8 = bmi160_set_gyro_offset_enable( + GYRO_OFFSET_ENABLE); + if (v_status_s8 == SUCCESS) { + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_FOC_GYRO_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_FOC_GYRO_ENABLE, + v_foc_gyro_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_FOC_GYRO_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + + /* trigger the FOC need to write 0x03 + in the register 0x7e*/ + com_rslt += bmi160_set_command_register + (START_FOC_ACCEL_GYRO); + + com_rslt += bmi160_get_foc_rdy(&focstatus); + if ((com_rslt != SUCCESS) || + (focstatus != BMI160_FOC_STAT_HIGH)) { + while ((com_rslt != SUCCESS) || + (focstatus != BMI160_FOC_STAT_HIGH + && v_timeout_u8 < + BMI160_MAXIMUM_TIMEOUT)) { + p_bmi160->delay_msec( + BMI160_DELAY_SETTLING_TIME); + com_rslt = bmi160_get_foc_rdy( + &focstatus); + v_timeout_u8++; + } + } + if ((com_rslt == SUCCESS) && + (focstatus == BMI160_FOC_STAT_HIGH)) { + com_rslt += + bmi160_get_gyro_offset_compensation_xaxis + (&offsetx); + *v_gyro_off_x_s16 = offsetx; + + com_rslt += + bmi160_get_gyro_offset_compensation_yaxis + (&offsety); + *v_gyro_off_y_s16 = offsety; + + com_rslt += + bmi160_get_gyro_offset_compensation_zaxis( + &offsetz); + *v_gyro_off_z_s16 = offsetz; + } + } else { + com_rslt = ERROR; + } + } +return com_rslt; +} + /*! + * @brief This API read NVM program enable + * from the register 0x6A bit 1 + * + * @param v_nvm_prog_u8 : The value of NVM program enable + * Value | Description + * --------|------------- + * 0 | DISABLE + * 1 | ENABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_nvm_prog_enable( +u8 *v_nvm_prog_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read NVM program*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_CONFIG_NVM_PROG_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_nvm_prog_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_CONFIG_NVM_PROG_ENABLE); + } + return com_rslt; +} + /*! + * @brief This API write NVM program enable + * from the register 0x6A bit 1 + * + * @param v_nvm_prog_u8 : The value of NVM program enable + * Value | Description + * --------|------------- + * 0 | DISABLE + * 1 | ENABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_nvm_prog_enable( +u8 v_nvm_prog_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_nvm_prog_u8 <= BMI160_MAX_VALUE_NVM_PROG) { + /* write the NVM program*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_CONFIG_NVM_PROG_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_CONFIG_NVM_PROG_ENABLE, + v_nvm_prog_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_CONFIG_NVM_PROG_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API read to configure SPI + * Interface Mode for primary and OIS interface + * from the register 0x6B bit 0 + * + * @param v_spi3_u8 : The value of SPI mode selection + * Value | Description + * --------|------------- + * 0 | SPI 4-wire mode + * 1 | SPI 3-wire mode + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_spi3( +u8 *v_spi3_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read SPI mode*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_IF_CONFIG_SPI3__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_spi3_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_IF_CONFIG_SPI3); + } + return com_rslt; +} +/*! + * @brief This API write to configure SPI + * Interface Mode for primary and OIS interface + * from the register 0x6B bit 0 + * + * @param v_spi3_u8 : The value of SPI mode selection + * Value | Description + * --------|------------- + * 0 | SPI 4-wire mode + * 1 | SPI 3-wire mode + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_spi3( +u8 v_spi3_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_spi3_u8 <= BMI160_MAX_VALUE_SPI3) { + /* write SPI mode*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_IF_CONFIG_SPI3__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_IF_CONFIG_SPI3, + v_spi3_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_IF_CONFIG_SPI3__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API read I2C Watchdog timer + * from the register 0x70 bit 1 + * + * @param v_i2c_wdt_u8 : The value of I2C watch dog timer + * Value | Description + * --------|------------- + * 0 | I2C watchdog v_timeout_u8 after 1 ms + * 1 | I2C watchdog v_timeout_u8 after 50 ms + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_i2c_wdt_select( +u8 *v_i2c_wdt_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read I2C watch dog timer */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_IF_CONFIG_I2C_WDT_SELECT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_i2c_wdt_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_IF_CONFIG_I2C_WDT_SELECT); + } + return com_rslt; +} +/*! + * @brief This API write I2C Watchdog timer + * from the register 0x70 bit 1 + * + * @param v_i2c_wdt_u8 : The value of I2C watch dog timer + * Value | Description + * --------|------------- + * 0 | I2C watchdog v_timeout_u8 after 1 ms + * 1 | I2C watchdog v_timeout_u8 after 50 ms + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_i2c_wdt_select( +u8 v_i2c_wdt_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_i2c_wdt_u8 <= BMI160_MAX_VALUE_I2C_WDT) { + /* write I2C watch dog timer */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_IF_CONFIG_I2C_WDT_SELECT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_IF_CONFIG_I2C_WDT_SELECT, + v_i2c_wdt_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_IF_CONFIG_I2C_WDT_SELECT__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API read I2C watchdog enable + * from the register 0x70 bit 2 + * + * @param v_i2c_wdt_u8 : The value of I2C watchdog enable + * Value | Description + * --------|------------- + * 0 | DISABLE + * 1 | ENABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_i2c_wdt_enable( +u8 *v_i2c_wdt_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read i2c watch dog eneble */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_IF_CONFIG_I2C_WDT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_i2c_wdt_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_IF_CONFIG_I2C_WDT_ENABLE); + } + return com_rslt; +} +/*! + * @brief This API write I2C watchdog enable + * from the register 0x70 bit 2 + * + * @param v_i2c_wdt_u8 : The value of I2C watchdog enable + * Value | Description + * --------|------------- + * 0 | DISABLE + * 1 | ENABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_i2c_wdt_enable( +u8 v_i2c_wdt_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_i2c_wdt_u8 <= BMI160_MAX_VALUE_I2C_WDT) { + /* write i2c watch dog eneble */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_IF_CONFIG_I2C_WDT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_IF_CONFIG_I2C_WDT_ENABLE, + v_i2c_wdt_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_IF_CONFIG_I2C_WDT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API read I2C interface configuration(if) moe + * from the register 0x6B bit 4 and 5 + * + * @param v_if_mode_u8 : The value of interface configuration mode + * Value | Description + * --------|------------- + * 0x00 | Primary interface:autoconfig / secondary interface:off + * 0x01 | Primary interface:I2C / secondary interface:OIS + * 0x02 | Primary interface:autoconfig/secondary interface:Magnetometer + * 0x03 | Reserved + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_if_mode( +u8 *v_if_mode_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read if mode*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_IF_CONFIG_IF_MODE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_if_mode_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_IF_CONFIG_IF_MODE); + } + return com_rslt; +} +/*! + * @brief This API write I2C interface configuration(if) moe + * from the register 0x6B bit 4 and 5 + * + * @param v_if_mode_u8 : The value of interface configuration mode + * Value | Description + * --------|------------- + * 0x00 | Primary interface:autoconfig / secondary interface:off + * 0x01 | Primary interface:I2C / secondary interface:OIS + * 0x02 | Primary interface:autoconfig/secondary interface:Magnetometer + * 0x03 | Reserved + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_if_mode( +u8 v_if_mode_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_if_mode_u8 <= BMI160_MAX_IF_MODE) { + /* write if mode*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_IF_CONFIG_IF_MODE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_IF_CONFIG_IF_MODE, + v_if_mode_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_IF_CONFIG_IF_MODE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API read gyro sleep trigger + * from the register 0x6C bit 0 to 2 + * + * @param v_gyro_sleep_trigger_u8 : The value of gyro sleep trigger + * Value | Description + * --------|------------- + * 0x00 | nomotion: no / Not INT1 pin: no / INT2 pin: no + * 0x01 | nomotion: no / Not INT1 pin: no / INT2 pin: yes + * 0x02 | nomotion: no / Not INT1 pin: yes / INT2 pin: no + * 0x03 | nomotion: no / Not INT1 pin: yes / INT2 pin: yes + * 0x04 | nomotion: yes / Not INT1 pin: no / INT2 pin: no + * 0x05 | anymotion: yes / Not INT1 pin: no / INT2 pin: yes + * 0x06 | anymotion: yes / Not INT1 pin: yes / INT2 pin: no + * 0x07 | anymotion: yes / Not INT1 pin: yes / INT2 pin: yes + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_sleep_trigger( +u8 *v_gyro_sleep_trigger_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read gyro sleep trigger */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_GYRO_SLEEP_TRIGGER__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_gyro_sleep_trigger_u8 = + BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_GYRO_SLEEP_TRIGGER); + } + return com_rslt; +} +/*! + * @brief This API write gyro sleep trigger + * from the register 0x6C bit 0 to 2 + * + * @param v_gyro_sleep_trigger_u8 : The value of gyro sleep trigger + * Value | Description + * --------|------------- + * 0x00 | nomotion: no / Not INT1 pin: no / INT2 pin: no + * 0x01 | nomotion: no / Not INT1 pin: no / INT2 pin: yes + * 0x02 | nomotion: no / Not INT1 pin: yes / INT2 pin: no + * 0x03 | nomotion: no / Not INT1 pin: yes / INT2 pin: yes + * 0x04 | nomotion: yes / Not INT1 pin: no / INT2 pin: no + * 0x05 | anymotion: yes / Not INT1 pin: no / INT2 pin: yes + * 0x06 | anymotion: yes / Not INT1 pin: yes / INT2 pin: no + * 0x07 | anymotion: yes / Not INT1 pin: yes / INT2 pin: yes + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_sleep_trigger( +u8 v_gyro_sleep_trigger_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_gyro_sleep_trigger_u8 <= BMI160_MAX_GYRO_SLEEP_TIGGER) { + /* write gyro sleep trigger */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_GYRO_SLEEP_TRIGGER__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_GYRO_SLEEP_TRIGGER, + v_gyro_sleep_trigger_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_GYRO_SLEEP_TRIGGER__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API read gyro wakeup trigger + * from the register 0x6C bit 3 and 4 + * + * @param v_gyro_wakeup_trigger_u8 : The value of gyro wakeup trigger + * Value | Description + * --------|------------- + * 0x00 | anymotion: no / INT1 pin: no + * 0x01 | anymotion: no / INT1 pin: yes + * 0x02 | anymotion: yes / INT1 pin: no + * 0x03 | anymotion: yes / INT1 pin: yes + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_wakeup_trigger( +u8 *v_gyro_wakeup_trigger_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read gyro wakeup trigger */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_GYRO_WAKEUP_TRIGGER__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_gyro_wakeup_trigger_u8 = BMI160_GET_BITSLICE( + v_data_u8, + BMI160_USER_GYRO_WAKEUP_TRIGGER); + } + return com_rslt; +} +/*! + * @brief This API write gyro wakeup trigger + * from the register 0x6C bit 3 and 4 + * + * @param v_gyro_wakeup_trigger_u8 : The value of gyro wakeup trigger + * Value | Description + * --------|------------- + * 0x00 | anymotion: no / INT1 pin: no + * 0x01 | anymotion: no / INT1 pin: yes + * 0x02 | anymotion: yes / INT1 pin: no + * 0x03 | anymotion: yes / INT1 pin: yes + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_wakeup_trigger( +u8 v_gyro_wakeup_trigger_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_gyro_wakeup_trigger_u8 + <= BMI160_MAX_GYRO_WAKEUP_TRIGGER) { + /* write gyro wakeup trigger */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_GYRO_WAKEUP_TRIGGER__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_GYRO_WAKEUP_TRIGGER, + v_gyro_wakeup_trigger_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_GYRO_WAKEUP_TRIGGER__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API read Target state for gyro sleep mode + * from the register 0x6C bit 5 + * + * @param v_gyro_sleep_state_u8 : The value of gyro sleep mode + * Value | Description + * --------|------------- + * 0x00 | Sleep transition to fast wake up state + * 0x01 | Sleep transition to suspend state + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_sleep_state( +u8 *v_gyro_sleep_state_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read gyro sleep state*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_GYRO_SLEEP_STATE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_gyro_sleep_state_u8 = BMI160_GET_BITSLICE( + v_data_u8, + BMI160_USER_GYRO_SLEEP_STATE); + } + return com_rslt; +} +/*! + * @brief This API write Target state for gyro sleep mode + * from the register 0x6C bit 5 + * + * @param v_gyro_sleep_state_u8 : The value of gyro sleep mode + * Value | Description + * --------|------------- + * 0x00 | Sleep transition to fast wake up state + * 0x01 | Sleep transition to suspend state + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_sleep_state( +u8 v_gyro_sleep_state_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_gyro_sleep_state_u8 <= BMI160_MAX_VALUE_SLEEP_STATE) { + /* write gyro sleep state*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_GYRO_SLEEP_STATE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_GYRO_SLEEP_STATE, + v_gyro_sleep_state_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_GYRO_SLEEP_STATE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API read gyro wakeup interrupt + * from the register 0x6C bit 6 + * + * @param v_gyro_wakeup_intr_u8 : The valeu of gyro wakeup interrupt + * Value | Description + * --------|------------- + * 0x00 | DISABLE + * 0x01 | ENABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_wakeup_intr( +u8 *v_gyro_wakeup_intr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read gyro wakeup interrupt */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_GYRO_WAKEUP_INTR__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_gyro_wakeup_intr_u8 = BMI160_GET_BITSLICE( + v_data_u8, + BMI160_USER_GYRO_WAKEUP_INTR); + } + return com_rslt; +} +/*! + * @brief This API write gyro wakeup interrupt + * from the register 0x6C bit 6 + * + * @param v_gyro_wakeup_intr_u8 : The valeu of gyro wakeup interrupt + * Value | Description + * --------|------------- + * 0x00 | DISABLE + * 0x01 | ENABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_wakeup_intr( +u8 v_gyro_wakeup_intr_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_gyro_wakeup_intr_u8 <= BMI160_MAX_VALUE_WAKEUP_INTR) { + /* write gyro wakeup interrupt */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_GYRO_WAKEUP_INTR__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_GYRO_WAKEUP_INTR, + v_gyro_wakeup_intr_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_GYRO_WAKEUP_INTR__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API read accel select axis to be self-test + * + * @param v_accel_selftest_axis_u8 : + * The value of accel self test axis selection + * Value | Description + * --------|------------- + * 0x00 | disabled + * 0x01 | x-axis + * 0x02 | y-axis + * 0x03 | z-axis + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_selftest_axis( +u8 *v_accel_selftest_axis_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read accel self test axis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_ACCEL_SELFTEST_AXIS__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_accel_selftest_axis_u8 = BMI160_GET_BITSLICE( + v_data_u8, + BMI160_USER_ACCEL_SELFTEST_AXIS); + } + return com_rslt; +} +/*! + * @brief This API write accel select axis to be self-test + * + * @param v_accel_selftest_axis_u8 : + * The value of accel self test axis selection + * Value | Description + * --------|------------- + * 0x00 | disabled + * 0x01 | x-axis + * 0x02 | y-axis + * 0x03 | z-axis + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_selftest_axis( +u8 v_accel_selftest_axis_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_accel_selftest_axis_u8 + <= BMI160_MAX_ACCEL_SELFTEST_AXIS) { + /* write accel self test axis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_ACCEL_SELFTEST_AXIS__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_ACCEL_SELFTEST_AXIS, + v_accel_selftest_axis_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_ACCEL_SELFTEST_AXIS__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API read accel self test axis sign + * from the register 0x6D bit 2 + * + * @param v_accel_selftest_sign_u8: The value of accel self test axis sign + * Value | Description + * --------|------------- + * 0x00 | negative + * 0x01 | positive + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_selftest_sign( +u8 *v_accel_selftest_sign_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read accel self test axis sign*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_ACCEL_SELFTEST_SIGN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_accel_selftest_sign_u8 = BMI160_GET_BITSLICE( + v_data_u8, + BMI160_USER_ACCEL_SELFTEST_SIGN); + } + return com_rslt; +} +/*! + * @brief This API write accel self test axis sign + * from the register 0x6D bit 2 + * + * @param v_accel_selftest_sign_u8: The value of accel self test axis sign + * Value | Description + * --------|------------- + * 0x00 | negative + * 0x01 | positive + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_selftest_sign( +u8 v_accel_selftest_sign_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_accel_selftest_sign_u8 <= + BMI160_MAX_VALUE_SELFTEST_SIGN) { + /* write accel self test axis sign*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_ACCEL_SELFTEST_SIGN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_ACCEL_SELFTEST_SIGN, + v_accel_selftest_sign_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_ACCEL_SELFTEST_SIGN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API read accel self test amplitude + * from the register 0x6D bit 3 + * select amplitude of the selftest deflection: + * + * @param v_accel_selftest_amp_u8 : The value of accel self test amplitude + * Value | Description + * --------|------------- + * 0x00 | LOW + * 0x01 | HIGH + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_selftest_amp( +u8 *v_accel_selftest_amp_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read self test amplitude*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_SELFTEST_AMP__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_accel_selftest_amp_u8 = BMI160_GET_BITSLICE( + v_data_u8, + BMI160_USER_SELFTEST_AMP); + } + return com_rslt; +} +/*! + * @brief This API write accel self test amplitude + * from the register 0x6D bit 3 + * select amplitude of the selftest deflection: + * + * @param v_accel_selftest_amp_u8 : The value of accel self test amplitude + * Value | Description + * --------|------------- + * 0x00 | LOW + * 0x01 | HIGH + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_selftest_amp( +u8 v_accel_selftest_amp_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_accel_selftest_amp_u8 <= + BMI160_MAX_VALUE_SELFTEST_AMP) { + /* write self test amplitude*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_SELFTEST_AMP__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_SELFTEST_AMP, + v_accel_selftest_amp_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_SELFTEST_AMP__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief This API read gyro self test trigger + * + * @param v_gyro_selftest_start_u8: The value of gyro self test start + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_selftest_start( +u8 *v_gyro_selftest_start_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read gyro self test start */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_GYRO_SELFTEST_START__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_gyro_selftest_start_u8 = BMI160_GET_BITSLICE( + v_data_u8, + BMI160_USER_GYRO_SELFTEST_START); + } + return com_rslt; +} +/*! + * @brief This API write gyro self test trigger + * + * @param v_gyro_selftest_start_u8: The value of gyro self test start + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_selftest_start( +u8 v_gyro_selftest_start_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_gyro_selftest_start_u8 <= + BMI160_MAX_VALUE_SELFTEST_START) { + /* write gyro self test start */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_GYRO_SELFTEST_START__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_GYRO_SELFTEST_START, + v_gyro_selftest_start_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_GYRO_SELFTEST_START__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} + /*! + * @brief This API read primary interface selection I2C or SPI + * from the register 0x70 bit 0 + * + * @param v_spi_enable_u8: The value of Interface selection + * Value | Description + * --------|------------- + * 0x00 | I2C Enable + * 0x01 | I2C DISBALE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_spi_enable(u8 *v_spi_enable_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read interface section*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_NV_CONFIG_SPI_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_spi_enable_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_NV_CONFIG_SPI_ENABLE); + } + return com_rslt; +} + /*! + * @brief This API write primary interface selection I2C or SPI + * from the register 0x70 bit 0 + * + * @param v_spi_enable_u8: The value of Interface selection + * Value | Description + * --------|------------- + * 0x00 | I2C Enable + * 0x01 | I2C DISBALE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_spi_enable(u8 v_spi_enable_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write interface section*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_NV_CONFIG_SPI_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_NV_CONFIG_SPI_ENABLE, + v_spi_enable_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_NV_CONFIG_SPI_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } + return com_rslt; +} + /*! + * @brief This API read the spare zero + * form register 0x70 bit 3 + * + * + * @param v_spare0_trim_u8: The value of spare zero + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_spare0_trim(u8 *v_spare0_trim_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read spare zero*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_NV_CONFIG_SPARE0__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_spare0_trim_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_NV_CONFIG_SPARE0); + } + return com_rslt; +} + /*! + * @brief This API write the spare zero + * form register 0x70 bit 3 + * + * + * @param v_spare0_trim_u8: The value of spare zero + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_spare0_trim(u8 v_spare0_trim_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write spare zero*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_NV_CONFIG_SPARE0__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_NV_CONFIG_SPARE0, + v_spare0_trim_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_NV_CONFIG_SPARE0__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } + return com_rslt; +} + /*! + * @brief This API read the NVM counter + * form register 0x70 bit 4 to 7 + * + * + * @param v_nvm_counter_u8: The value of NVM counter + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_nvm_counter(u8 *v_nvm_counter_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read NVM counter*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_NV_CONFIG_NVM_COUNTER__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_nvm_counter_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_NV_CONFIG_NVM_COUNTER); + } + return com_rslt; +} + /*! + * @brief This API write the NVM counter + * form register 0x70 bit 4 to 7 + * + * + * @param v_nvm_counter_u8: The value of NVM counter + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_nvm_counter( +u8 v_nvm_counter_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write NVM counter*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_NV_CONFIG_NVM_COUNTER__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_NV_CONFIG_NVM_COUNTER, + v_nvm_counter_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_NV_CONFIG_NVM_COUNTER__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } + return com_rslt; +} +/*! + * @brief This API read accel manual offset compensation of x axis + * from the register 0x71 bit 0 to 7 + * + * + * + * @param v_accel_off_x_s8: + * The value of accel manual offset compensation of x axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_offset_compensation_xaxis( +s8 *v_accel_off_x_s8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read accel manual offset compensation of x axis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_0_ACCEL_OFF_X__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_accel_off_x_s8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_OFFSET_0_ACCEL_OFF_X); + } + return com_rslt; +} +/*! + * @brief This API write accel manual offset compensation of x axis + * from the register 0x71 bit 0 to 7 + * + * + * + * @param v_accel_off_x_s8: + * The value of accel manual offset compensation of x axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_offset_compensation_xaxis( +s8 v_accel_off_x_s8) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +u8 v_status_s8 = SUCCESS; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* enable accel offset */ + v_status_s8 = bmi160_set_accel_offset_enable( + ACCEL_OFFSET_ENABLE); + if (v_status_s8 == SUCCESS) { + /* write accel manual offset compensation of x axis*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_0_ACCEL_OFF_X__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE( + v_data_u8, + BMI160_USER_OFFSET_0_ACCEL_OFF_X, + v_accel_off_x_s8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_0_ACCEL_OFF_X__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = ERROR; + } + } + return com_rslt; +} +/*! + * @brief This API read accel manual offset compensation of y axis + * from the register 0x72 bit 0 to 7 + * + * + * + * @param v_accel_off_y_s8: + * The value of accel manual offset compensation of y axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_offset_compensation_yaxis( +s8 *v_accel_off_y_s8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read accel manual offset compensation of y axis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_1_ACCEL_OFF_Y__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_accel_off_y_s8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_OFFSET_1_ACCEL_OFF_Y); + } + return com_rslt; +} +/*! + * @brief This API write accel manual offset compensation of y axis + * from the register 0x72 bit 0 to 7 + * + * + * + * @param v_accel_off_y_s8: + * The value of accel manual offset compensation of y axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_offset_compensation_yaxis( +s8 v_accel_off_y_s8) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +u8 v_status_s8 = SUCCESS; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* enable accel offset */ + v_status_s8 = bmi160_set_accel_offset_enable( + ACCEL_OFFSET_ENABLE); + if (v_status_s8 == SUCCESS) { + /* write accel manual offset compensation of y axis*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_1_ACCEL_OFF_Y__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE( + v_data_u8, + BMI160_USER_OFFSET_1_ACCEL_OFF_Y, + v_accel_off_y_s8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_1_ACCEL_OFF_Y__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = ERROR; + } + } + return com_rslt; +} +/*! + * @brief This API read accel manual offset compensation of z axis + * from the register 0x73 bit 0 to 7 + * + * + * + * @param v_accel_off_z_s8: + * The value of accel manual offset compensation of z axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_offset_compensation_zaxis( +s8 *v_accel_off_z_s8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read accel manual offset compensation of z axis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_2_ACCEL_OFF_Z__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_accel_off_z_s8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_OFFSET_2_ACCEL_OFF_Z); + } + return com_rslt; +} +/*! + * @brief This API write accel manual offset compensation of z axis + * from the register 0x73 bit 0 to 7 + * + * + * + * @param v_accel_off_z_s8: + * The value of accel manual offset compensation of z axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_offset_compensation_zaxis( +s8 v_accel_off_z_s8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + u8 v_status_s8 = SUCCESS; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* enable accel offset */ + v_status_s8 = bmi160_set_accel_offset_enable( + ACCEL_OFFSET_ENABLE); + if (v_status_s8 == SUCCESS) { + /* write accel manual offset + compensation of z axis*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_2_ACCEL_OFF_Z__REG, + &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_OFFSET_2_ACCEL_OFF_Z, + v_accel_off_z_s8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_2_ACCEL_OFF_Z__REG, + &v_data_u8, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = ERROR; + } + } + return com_rslt; +} +/*! + * @brief This API read gyro manual offset compensation of x axis + * from the register 0x74 bit 0 to 7 and 0x77 bit 0 and 1 + * + * + * + * @param v_gyro_off_x_s16: + * The value of gyro manual offset compensation of x axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_offset_compensation_xaxis( +s16 *v_gyro_off_x_s16) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data1_u8r = BMI160_INIT_VALUE; + u8 v_data2_u8r = BMI160_INIT_VALUE; + s16 v_data3_u8r, v_data4_u8r = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read gyro offset x*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_3_GYRO_OFF_X__REG, + &v_data1_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + v_data1_u8r = BMI160_GET_BITSLICE(v_data1_u8r, + BMI160_USER_OFFSET_3_GYRO_OFF_X); + com_rslt += p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_6_GYRO_OFF_X__REG, + &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + v_data2_u8r = BMI160_GET_BITSLICE(v_data2_u8r, + BMI160_USER_OFFSET_6_GYRO_OFF_X); + v_data3_u8r = v_data2_u8r + << BMI160_SHIFT_BIT_POSITION_BY_14_BITS; + v_data4_u8r = v_data1_u8r + << BMI160_SHIFT_BIT_POSITION_BY_06_BITS; + v_data3_u8r = v_data3_u8r | v_data4_u8r; + *v_gyro_off_x_s16 = v_data3_u8r + >> BMI160_SHIFT_BIT_POSITION_BY_06_BITS; + } + return com_rslt; +} +/*! + * @brief This API write gyro manual offset compensation of x axis + * from the register 0x74 bit 0 to 7 and 0x77 bit 0 and 1 + * + * + * + * @param v_gyro_off_x_s16: + * The value of gyro manual offset compensation of x axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_offset_compensation_xaxis( +s16 v_gyro_off_x_s16) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data1_u8r, v_data2_u8r = BMI160_INIT_VALUE; +u16 v_data3_u8r = BMI160_INIT_VALUE; +u8 v_status_s8 = SUCCESS; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write gyro offset x*/ + v_status_s8 = bmi160_set_gyro_offset_enable( + GYRO_OFFSET_ENABLE); + if (v_status_s8 == SUCCESS) { + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_3_GYRO_OFF_X__REG, + &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data1_u8r = + ((s8) (v_gyro_off_x_s16 & + BMI160_GYRO_MANUAL_OFFSET_0_7)); + v_data2_u8r = BMI160_SET_BITSLICE( + v_data2_u8r, + BMI160_USER_OFFSET_3_GYRO_OFF_X, + v_data1_u8r); + /* write 0x74 bit 0 to 7*/ + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_3_GYRO_OFF_X__REG, + &v_data2_u8r, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + + com_rslt += p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_6_GYRO_OFF_X__REG, + &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data3_u8r = + (u16) (v_gyro_off_x_s16 & + BMI160_GYRO_MANUAL_OFFSET_8_9); + v_data1_u8r = (u8)(v_data3_u8r + >> BMI160_SHIFT_BIT_POSITION_BY_08_BITS); + v_data2_u8r = BMI160_SET_BITSLICE( + v_data2_u8r, + BMI160_USER_OFFSET_6_GYRO_OFF_X, + v_data1_u8r); + /* write 0x77 bit 0 and 1*/ + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_6_GYRO_OFF_X__REG, + &v_data2_u8r, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + return ERROR; + } + } +return com_rslt; +} +/*! + * @brief This API read gyro manual offset compensation of y axis + * from the register 0x75 bit 0 to 7 and 0x77 bit 2 and 3 + * + * + * + * @param v_gyro_off_y_s16: + * The value of gyro manual offset compensation of y axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_offset_compensation_yaxis( +s16 *v_gyro_off_y_s16) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data1_u8r = BMI160_INIT_VALUE; + u8 v_data2_u8r = BMI160_INIT_VALUE; + s16 v_data3_u8r, v_data4_u8r = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read gyro offset y*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_4_GYRO_OFF_Y__REG, + &v_data1_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + v_data1_u8r = BMI160_GET_BITSLICE(v_data1_u8r, + BMI160_USER_OFFSET_4_GYRO_OFF_Y); + com_rslt += p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_OFFSET_6_GYRO_OFF_Y__REG, + &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + v_data2_u8r = BMI160_GET_BITSLICE(v_data2_u8r, + BMI160_USER_OFFSET_6_GYRO_OFF_Y); + v_data3_u8r = v_data2_u8r + << BMI160_SHIFT_BIT_POSITION_BY_14_BITS; + v_data4_u8r = v_data1_u8r + << BMI160_SHIFT_BIT_POSITION_BY_06_BITS; + v_data3_u8r = v_data3_u8r | v_data4_u8r; + *v_gyro_off_y_s16 = v_data3_u8r + >> BMI160_SHIFT_BIT_POSITION_BY_06_BITS; + } + return com_rslt; +} +/*! + * @brief This API write gyro manual offset compensation of y axis + * from the register 0x75 bit 0 to 7 and 0x77 bit 2 and 3 + * + * + * + * @param v_gyro_off_y_s16: + * The value of gyro manual offset compensation of y axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_offset_compensation_yaxis( +s16 v_gyro_off_y_s16) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data1_u8r, v_data2_u8r = BMI160_INIT_VALUE; +u16 v_data3_u8r = BMI160_INIT_VALUE; +u8 v_status_s8 = SUCCESS; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* enable gyro offset bit */ + v_status_s8 = bmi160_set_gyro_offset_enable( + GYRO_OFFSET_ENABLE); + /* write gyro offset y*/ + if (v_status_s8 == SUCCESS) { + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_OFFSET_4_GYRO_OFF_Y__REG, + &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data1_u8r = + ((s8) (v_gyro_off_y_s16 & + BMI160_GYRO_MANUAL_OFFSET_0_7)); + v_data2_u8r = BMI160_SET_BITSLICE( + v_data2_u8r, + BMI160_USER_OFFSET_4_GYRO_OFF_Y, + v_data1_u8r); + /* write 0x75 bit 0 to 7*/ + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_OFFSET_4_GYRO_OFF_Y__REG, + &v_data2_u8r, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + + com_rslt += p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_OFFSET_6_GYRO_OFF_Y__REG, + &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data3_u8r = + (u16) (v_gyro_off_y_s16 & + BMI160_GYRO_MANUAL_OFFSET_8_9); + v_data1_u8r = (u8)(v_data3_u8r + >> BMI160_SHIFT_BIT_POSITION_BY_08_BITS); + v_data2_u8r = BMI160_SET_BITSLICE( + v_data2_u8r, + BMI160_USER_OFFSET_6_GYRO_OFF_Y, + v_data1_u8r); + /* write 0x77 bit 2 and 3*/ + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_OFFSET_6_GYRO_OFF_Y__REG, + &v_data2_u8r, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + return ERROR; + } + } +return com_rslt; +} +/*! + * @brief This API read gyro manual offset compensation of z axis + * from the register 0x76 bit 0 to 7 and 0x77 bit 4 and 5 + * + * + * + * @param v_gyro_off_z_s16: + * The value of gyro manual offset compensation of z axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_offset_compensation_zaxis( +s16 *v_gyro_off_z_s16) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data1_u8r = BMI160_INIT_VALUE; + u8 v_data2_u8r = BMI160_INIT_VALUE; + s16 v_data3_u8r, v_data4_u8r = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read gyro manual offset z axis*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_OFFSET_5_GYRO_OFF_Z__REG, + &v_data1_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + v_data1_u8r = BMI160_GET_BITSLICE + (v_data1_u8r, + BMI160_USER_OFFSET_5_GYRO_OFF_Z); + com_rslt += + p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_OFFSET_6_GYRO_OFF_Z__REG, + &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + v_data2_u8r = BMI160_GET_BITSLICE( + v_data2_u8r, + BMI160_USER_OFFSET_6_GYRO_OFF_Z); + v_data3_u8r = v_data2_u8r + << BMI160_SHIFT_BIT_POSITION_BY_14_BITS; + v_data4_u8r = v_data1_u8r + << BMI160_SHIFT_BIT_POSITION_BY_06_BITS; + v_data3_u8r = v_data3_u8r | v_data4_u8r; + *v_gyro_off_z_s16 = v_data3_u8r + >> BMI160_SHIFT_BIT_POSITION_BY_06_BITS; + } + return com_rslt; +} +/*! + * @brief This API write gyro manual offset compensation of z axis + * from the register 0x76 bit 0 to 7 and 0x77 bit 4 and 5 + * + * + * + * @param v_gyro_off_z_s16: + * The value of gyro manual offset compensation of z axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_offset_compensation_zaxis( +s16 v_gyro_off_z_s16) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data1_u8r, v_data2_u8r = BMI160_INIT_VALUE; +u16 v_data3_u8r = BMI160_INIT_VALUE; +u8 v_status_s8 = SUCCESS; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* enable gyro offset*/ + v_status_s8 = bmi160_set_gyro_offset_enable( + GYRO_OFFSET_ENABLE); + /* write gyro manual offset z axis*/ + if (v_status_s8 == SUCCESS) { + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_OFFSET_5_GYRO_OFF_Z__REG, + &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data1_u8r = + ((u8) (v_gyro_off_z_s16 & + BMI160_GYRO_MANUAL_OFFSET_0_7)); + v_data2_u8r = BMI160_SET_BITSLICE( + v_data2_u8r, + BMI160_USER_OFFSET_5_GYRO_OFF_Z, + v_data1_u8r); + /* write 0x76 bit 0 to 7*/ + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_OFFSET_5_GYRO_OFF_Z__REG, + &v_data2_u8r, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + + com_rslt += p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_OFFSET_6_GYRO_OFF_Z__REG, + &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data3_u8r = + (u16) (v_gyro_off_z_s16 & + BMI160_GYRO_MANUAL_OFFSET_8_9); + v_data1_u8r = (u8)(v_data3_u8r + >> BMI160_SHIFT_BIT_POSITION_BY_08_BITS); + v_data2_u8r = BMI160_SET_BITSLICE( + v_data2_u8r, + BMI160_USER_OFFSET_6_GYRO_OFF_Z, + v_data1_u8r); + /* write 0x77 bit 4 and 5*/ + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_OFFSET_6_GYRO_OFF_Z__REG, + &v_data2_u8r, + BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + return ERROR; + } + } +return com_rslt; +} +/*! + * @brief This API read the accel offset enable bit + * from the register 0x77 bit 6 + * + * + * + * @param v_accel_off_enable_u8: The value of accel offset enable + * value | Description + * ----------|-------------- + * 0x01 | ENABLE + * 0x00 | DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_offset_enable( +u8 *v_accel_off_enable_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read accel offset enable */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_OFFSET_6_ACCEL_OFF_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_accel_off_enable_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_OFFSET_6_ACCEL_OFF_ENABLE); + } + return com_rslt; +} +/*! + * @brief This API write the accel offset enable bit + * from the register 0x77 bit 6 + * + * + * + * @param v_accel_off_enable_u8: The value of accel offset enable + * value | Description + * ----------|-------------- + * 0x01 | ENABLE + * 0x00 | DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_offset_enable( +u8 v_accel_off_enable_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write accel offset enable */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_6_ACCEL_OFF_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_OFFSET_6_ACCEL_OFF_ENABLE, + v_accel_off_enable_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_6_ACCEL_OFF_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } + return com_rslt; +} +/*! + * @brief This API read the accel offset enable bit + * from the register 0x77 bit 7 + * + * + * + * @param v_gyro_off_enable_u8: The value of gyro offset enable + * value | Description + * ----------|-------------- + * 0x01 | ENABLE + * 0x00 | DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_offset_enable( +u8 *v_gyro_off_enable_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read gyro offset*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_6_GYRO_OFF_EN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_gyro_off_enable_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_OFFSET_6_GYRO_OFF_EN); + } + return com_rslt; +} +/*! + * @brief This API write the accel offset enable bit + * from the register 0x77 bit 7 + * + * + * + * @param v_gyro_off_enable_u8: The value of gyro offset enable + * value | Description + * ----------|-------------- + * 0x01 | ENABLE + * 0x00 | DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_offset_enable( +u8 v_gyro_off_enable_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write gyro offset*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_6_GYRO_OFF_EN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_OFFSET_6_GYRO_OFF_EN, + v_gyro_off_enable_u8); + com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_USER_OFFSET_6_GYRO_OFF_EN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } + return com_rslt; +} +/*! + * @brief This API reads step counter value + * form the register 0x78 and 0x79 + * + * + * + * + * @param v_step_cnt_s16 : The value of step counter + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_step_count(s16 *v_step_cnt_s16) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* array having the step counter LSB and MSB data + v_data_u8[0] - LSB + v_data_u8[1] - MSB*/ + u8 a_data_u8r[BMI160_STEP_COUNT_DATA_SIZE] = {BMI160_INIT_VALUE, + BMI160_INIT_VALUE}; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read step counter */ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_STEP_COUNT_LSB__REG, + a_data_u8r, BMI160_STEP_COUNTER_LENGTH); + + *v_step_cnt_s16 = (s16) + ((((s32)((s8)a_data_u8r[BMI160_STEP_COUNT_MSB_BYTE])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) + | (a_data_u8r[BMI160_STEP_COUNT_LSB_BYTE])); + } + return com_rslt; +} + /*! + * @brief This API Reads + * step counter configuration + * from the register 0x7A bit 0 to 7 + * and from the register 0x7B bit 0 to 2 and 4 to 7 + * + * + * @param v_step_config_u16 : The value of step configuration + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_step_config( +u16 *v_step_config_u16) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data1_u8r = BMI160_INIT_VALUE; + u8 v_data2_u8r = BMI160_INIT_VALUE; + u16 v_data3_u8r = BMI160_INIT_VALUE; + /* Read the 0 to 7 bit*/ + com_rslt = + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_STEP_CONFIG_ZERO__REG, + &v_data1_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + /* Read the 8 to 10 bit*/ + com_rslt += + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_STEP_CONFIG_ONE_CNF1__REG, + &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + v_data2_u8r = BMI160_GET_BITSLICE(v_data2_u8r, + BMI160_USER_STEP_CONFIG_ONE_CNF1); + v_data3_u8r = ((u16)((((u32) + ((u8)v_data2_u8r)) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | (v_data1_u8r))); + /* Read the 11 to 14 bit*/ + com_rslt += + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_STEP_CONFIG_ONE_CNF2__REG, + &v_data1_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + v_data1_u8r = BMI160_GET_BITSLICE(v_data1_u8r, + BMI160_USER_STEP_CONFIG_ONE_CNF2); + *v_step_config_u16 = ((u16)((((u32) + ((u8)v_data1_u8r)) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | (v_data3_u8r))); + + return com_rslt; +} + /*! + * @brief This API write + * step counter configuration + * from the register 0x7A bit 0 to 7 + * and from the register 0x7B bit 0 to 2 and 4 to 7 + * + * + * @param v_step_config_u16 : + * the value of Enable step configuration + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_step_config( +u16 v_step_config_u16) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data1_u8r = BMI160_INIT_VALUE; + u8 v_data2_u8r = BMI160_INIT_VALUE; + u16 v_data3_u16 = BMI160_INIT_VALUE; + + /* write the 0 to 7 bit*/ + v_data1_u8r = (u8)(v_step_config_u16 & + BMI160_STEP_CONFIG_0_7); + p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_STEP_CONFIG_ZERO__REG, + &v_data1_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + /* write the 8 to 10 bit*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_STEP_CONFIG_ONE_CNF1__REG, + &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data3_u16 = (u16) (v_step_config_u16 & + BMI160_STEP_CONFIG_8_10); + v_data1_u8r = (u8)(v_data3_u16 + >> BMI160_SHIFT_BIT_POSITION_BY_08_BITS); + v_data2_u8r = BMI160_SET_BITSLICE(v_data2_u8r, + BMI160_USER_STEP_CONFIG_ONE_CNF1, v_data1_u8r); + p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_STEP_CONFIG_ONE_CNF1__REG, + &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + /* write the 11 to 14 bit*/ + com_rslt += p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_STEP_CONFIG_ONE_CNF2__REG, + &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data3_u16 = (u16) (v_step_config_u16 & + BMI160_STEP_CONFIG_11_14); + v_data1_u8r = (u8)(v_data3_u16 + >> BMI160_SHIFT_BIT_POSITION_BY_12_BITS); + v_data2_u8r = BMI160_SET_BITSLICE(v_data2_u8r, + BMI160_USER_STEP_CONFIG_ONE_CNF2, v_data1_u8r); + p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_STEP_CONFIG_ONE_CNF2__REG, + &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + + return com_rslt; +} + /*! + * @brief This API read enable step counter + * from the register 0x7B bit 3 + * + * + * @param v_step_counter_u8 : The value of step counter enable + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_step_counter_enable( +u8 *v_step_counter_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the step counter */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_step_counter_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE); + } + return com_rslt; +} + /*! + * @brief This API write enable step counter + * from the register 0x7B bit 3 + * + * + * @param v_step_counter_u8 : The value of step counter enable + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_step_counter_enable(u8 v_step_counter_u8) +{ +/* variable used for return the status of communication result*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_data_u8 = BMI160_INIT_VALUE; +/* check the p_bmi160 structure as NULL*/ +if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; +} else { + if (v_step_counter_u8 <= BMI160_MAX_GYRO_STEP_COUNTER) { + /* write the step counter */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE(v_data_u8, + BMI160_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE, + v_step_counter_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } +} + return com_rslt; +} + /*! + * @brief This API set Step counter modes + * + * + * @param v_step_mode_u8 : The value of step counter mode + * value | mode + * ----------|----------- + * 0 | BMI160_STEP_NORMAL_MODE + * 1 | BMI160_STEP_SENSITIVE_MODE + * 2 | BMI160_STEP_ROBUST_MODE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_step_mode(u8 v_step_mode_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + + switch (v_step_mode_u8) { + case BMI160_STEP_NORMAL_MODE: + com_rslt = bmi160_set_step_config( + STEP_CONFIG_NORMAL); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + break; + case BMI160_STEP_SENSITIVE_MODE: + com_rslt = bmi160_set_step_config( + STEP_CONFIG_SENSITIVE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + break; + case BMI160_STEP_ROBUST_MODE: + com_rslt = bmi160_set_step_config( + STEP_CONFIG_ROBUST); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + + return com_rslt; +} +/*! + * @brief This API used to trigger the signification motion + * interrupt + * + * + * @param v_significant_u8 : The value of interrupt selection + * value | interrupt + * ----------|----------- + * 0 | BMI160_MAP_INTR1 + * 1 | BMI160_MAP_INTR2 + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_map_significant_motion_intr( +u8 v_significant_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_sig_motion_u8 = BMI160_INIT_VALUE; + u8 v_data_u8 = BMI160_INIT_VALUE; + u8 v_any_motion_intr1_stat_u8 = BMI160_ENABLE_ANY_MOTION_INTR1; + u8 v_any_motion_intr2_stat_u8 = BMI160_ENABLE_ANY_MOTION_INTR2; + u8 v_any_motion_axis_stat_u8 = BMI160_ENABLE_ANY_MOTION_AXIS; + /* enable the significant motion interrupt */ + com_rslt = bmi160_get_intr_significant_motion_select(&v_sig_motion_u8); + if (v_sig_motion_u8 != BMI160_SIG_MOTION_STAT_HIGH) + com_rslt += bmi160_set_intr_significant_motion_select( + BMI160_SIG_MOTION_INTR_ENABLE); + switch (v_significant_u8) { + case BMI160_MAP_INTR1: + /* interrupt */ + com_rslt += bmi160_read_reg( + BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + v_data_u8 |= v_any_motion_intr1_stat_u8; + /* map the signification interrupt to any-motion interrupt1*/ + com_rslt += bmi160_write_reg( + BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* axis*/ + com_rslt = bmi160_read_reg(BMI160_USER_INTR_ENABLE_0_ADDR, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + v_data_u8 |= v_any_motion_axis_stat_u8; + com_rslt += bmi160_write_reg( + BMI160_USER_INTR_ENABLE_0_ADDR, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + break; + + case BMI160_MAP_INTR2: + /* map the signification interrupt to any-motion interrupt2*/ + com_rslt += bmi160_read_reg( + BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + v_data_u8 |= v_any_motion_intr2_stat_u8; + com_rslt += bmi160_write_reg( + BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* axis*/ + com_rslt = bmi160_read_reg(BMI160_USER_INTR_ENABLE_0_ADDR, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + v_data_u8 |= v_any_motion_axis_stat_u8; + com_rslt += bmi160_write_reg( + BMI160_USER_INTR_ENABLE_0_ADDR, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + break; + + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + + } + return com_rslt; +} +/*! + * @brief This API used to trigger the step detector + * interrupt + * + * + * @param v_step_detector_u8 : The value of interrupt selection + * value | interrupt + * ----------|----------- + * 0 | BMI160_MAP_INTR1 + * 1 | BMI160_MAP_INTR2 + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_map_step_detector_intr( +u8 v_step_detector_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_step_det_u8 = BMI160_INIT_VALUE; + u8 v_data_u8 = BMI160_INIT_VALUE; + u8 v_low_g_intr_u81_stat_u8 = BMI160_LOW_G_INTR_STAT; + u8 v_low_g_intr_u82_stat_u8 = BMI160_LOW_G_INTR_STAT; + u8 v_low_g_enable_u8 = BMI160_ENABLE_LOW_G; + /* read the v_status_s8 of step detector interrupt*/ + com_rslt = bmi160_get_step_detector_enable(&v_step_det_u8); + if (v_step_det_u8 != BMI160_STEP_DET_STAT_HIGH) + com_rslt += bmi160_set_step_detector_enable( + BMI160_STEP_DETECT_INTR_ENABLE); + switch (v_step_detector_u8) { + case BMI160_MAP_INTR1: + com_rslt += bmi160_read_reg( + BMI160_USER_INTR_MAP_0_INTR1_LOW_G__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + v_data_u8 |= v_low_g_intr_u81_stat_u8; + /* map the step detector interrupt + to Low-g interrupt 1*/ + com_rslt += bmi160_write_reg( + BMI160_USER_INTR_MAP_0_INTR1_LOW_G__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* Enable the Low-g interrupt*/ + com_rslt = bmi160_read_reg( + BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + v_data_u8 |= v_low_g_enable_u8; + com_rslt += bmi160_write_reg( + BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + break; + case BMI160_MAP_INTR2: + /* map the step detector interrupt + to Low-g interrupt 1*/ + com_rslt += bmi160_read_reg( + BMI160_USER_INTR_MAP_2_INTR2_LOW_G__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + v_data_u8 |= v_low_g_intr_u82_stat_u8; + + com_rslt += bmi160_write_reg( + BMI160_USER_INTR_MAP_2_INTR2_LOW_G__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* Enable the Low-g interrupt*/ + com_rslt = bmi160_read_reg( + BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + v_data_u8 |= v_low_g_enable_u8; + com_rslt += bmi160_write_reg( + BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + return com_rslt; +} + /*! + * @brief This API used to clear the step counter interrupt + * interrupt + * + * + * @param : None + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_clear_step_counter(void) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* clear the step counter*/ + com_rslt = bmi160_set_command_register(RESET_STEP_COUNTER); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + + return com_rslt; + +} + /*! + * @brief This API writes value to the register 0x7E bit 0 to 7 + * + * + * @param v_command_reg_u8 : The value to write command register + * value | Description + * ---------|-------------------------------------------------------- + * 0x00 | Reserved + * 0x03 | Starts fast offset calibration for the accel and gyro + * 0x10 | Sets the PMU mode for the Accelerometer to suspend + * 0x11 | Sets the PMU mode for the Accelerometer to normal + * 0x12 | Sets the PMU mode for the Accelerometer Lowpower + * 0x14 | Sets the PMU mode for the Gyroscope to suspend + * 0x15 | Sets the PMU mode for the Gyroscope to normal + * 0x16 | Reserved + * 0x17 | Sets the PMU mode for the Gyroscope to fast start-up + * 0x18 | Sets the PMU mode for the Magnetometer to suspend + * 0x19 | Sets the PMU mode for the Magnetometer to normal + * 0x1A | Sets the PMU mode for the Magnetometer to Lowpower + * 0xB0 | Clears all data in the FIFO + * 0xB1 | Resets the interrupt engine + * 0xB2 | step_cnt_clr Clears the step counter + * 0xB6 | Triggers a reset + * 0x37 | See extmode_en_last + * 0x9A | See extmode_en_last + * 0xC0 | Enable the extended mode + * 0xC4 | Erase NVM cell + * 0xC8 | Load NVM cell + * 0xF0 | Reset acceleration data path + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_command_register(u8 v_command_reg_u8) +{ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write command register */ + com_rslt = p_bmi160->BMI160_BUS_WRITE_FUNC( + p_bmi160->dev_addr, + BMI160_CMD_COMMANDS__REG, + &v_command_reg_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + return com_rslt; +} + /*! + * @brief This API read target page from the register 0x7F bit 4 and 5 + * + * @param v_target_page_u8: The value of target page + * value | page + * ---------|----------- + * 0 | User data/configure page + * 1 | Chip level trim/test page + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_target_page(u8 *v_target_page_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the page*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_CMD_TARGET_PAGE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_target_page_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_CMD_TARGET_PAGE); + } + return com_rslt; +} + /*! + * @brief This API write target page from the register 0x7F bit 4 and 5 + * + * @param v_target_page_u8: The value of target page + * value | page + * ---------|----------- + * 0 | User data/configure page + * 1 | Chip level trim/test page + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_target_page(u8 v_target_page_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_target_page_u8 <= BMI160_MAX_TARGET_PAGE) { + /* write the page*/ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_CMD_TARGET_PAGE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE(v_data_u8, + BMI160_CMD_TARGET_PAGE, + v_target_page_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_CMD_TARGET_PAGE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} + /*! + * @brief This API read page enable from the register 0x7F bit 7 + * + * + * + * @param v_page_enable_u8: The value of page enable + * value | page + * ---------|----------- + * 0 | DISABLE + * 1 | ENABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_paging_enable(u8 *v_page_enable_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the page enable */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_CMD_PAGING_EN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_page_enable_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_CMD_PAGING_EN); + } + return com_rslt; +} + /*! + * @brief This API write page enable from the register 0x7F bit 7 + * + * + * + * @param v_page_enable_u8: The value of page enable + * value | page + * ---------|----------- + * 0 | DISABLE + * 1 | ENABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_paging_enable( +u8 v_page_enable_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + if (v_page_enable_u8 <= BMI160_MAX_VALUE_PAGE) { + /* write the page enable */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_CMD_PAGING_EN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE(v_data_u8, + BMI160_CMD_PAGING_EN, + v_page_enable_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_CMD_PAGING_EN__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BMI160_OUT_OF_RANGE; + } + } + return com_rslt; +} + /*! + * @brief This API read + * pull up configuration from the register 0X85 bit 4 an 5 + * + * + * + * @param v_control_pullup_u8: The value of pull up register + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_pullup_configuration( +u8 *v_control_pullup_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read pull up value */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC( + p_bmi160->dev_addr, + BMI160_COM_C_TRIM_FIVE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + *v_control_pullup_u8 = BMI160_GET_BITSLICE(v_data_u8, + BMI160_COM_C_TRIM_FIVE); + } + return com_rslt; + +} + /*! + * @brief This API write + * pull up configuration from the register 0X85 bit 4 an 5 + * + * + * + * @param v_control_pullup_u8: The value of pull up register + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_pullup_configuration( +u8 v_control_pullup_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* write pull up value */ + com_rslt = p_bmi160->BMI160_BUS_READ_FUNC + (p_bmi160->dev_addr, + BMI160_COM_C_TRIM_FIVE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + v_data_u8 = + BMI160_SET_BITSLICE(v_data_u8, + BMI160_COM_C_TRIM_FIVE, + v_control_pullup_u8); + com_rslt += + p_bmi160->BMI160_BUS_WRITE_FUNC + (p_bmi160->dev_addr, + BMI160_COM_C_TRIM_FIVE__REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + } + } + return com_rslt; +} + +/*! + * @brief This function used for read the compensated value of mag + * Before start reading the mag compensated data's + * make sure the following two points are addressed + * @note + * 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note + * 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_compensate_xyz( +struct bmi160_mag_xyz_s32_t *mag_comp_xyz) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + struct bmi160_mag_xyzr_t mag_xyzr; + com_rslt = bmi160_read_mag_xyzr(&mag_xyzr); + if (com_rslt) + return com_rslt; + /* Compensation for X axis */ + mag_comp_xyz->x = bmi160_bmm150_mag_compensate_X( + mag_xyzr.x, mag_xyzr.r); + + /* Compensation for Y axis */ + mag_comp_xyz->y = bmi160_bmm150_mag_compensate_Y( + mag_xyzr.y, mag_xyzr.r); + + /* Compensation for Z axis */ + mag_comp_xyz->z = bmi160_bmm150_mag_compensate_Z( + mag_xyzr.z, mag_xyzr.r); + + return com_rslt; +} + +/*! + * @brief This function used for read the compensated value of mag + * Before start reading the mag compensated data's + * make sure the following two points are addressed + * @note + * 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note + * 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_compensate_xyz_raw( +struct bmi160_mag_xyz_s32_t *mag_comp_xyz, struct bmi160_mag_xyzr_t mag_xyzr) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + + /* Compensation for X axis */ + mag_comp_xyz->x = bmi160_bmm150_mag_compensate_X( + mag_xyzr.x, mag_xyzr.r); + + /* Compensation for Y axis */ + mag_comp_xyz->y = bmi160_bmm150_mag_compensate_Y( + mag_xyzr.y, mag_xyzr.r); + + /* Compensation for Z axis */ + mag_comp_xyz->z = bmi160_bmm150_mag_compensate_Z( + mag_xyzr.z, mag_xyzr.r); + + return com_rslt; +} +/*! + * @brief This API used to get the compensated BMM150-X data + * the out put of X as s32 + * Before start reading the mag compensated X data + * make sure the following two points are addressed + * @note + * 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note + * 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * + * @param v_mag_data_x_s16 : The value of mag raw X data + * @param v_data_r_u16 : The value of mag R data + * + * @return results of compensated X data value output as s32 + * + */ +s32 bmi160_bmm150_mag_compensate_X(s16 v_mag_data_x_s16, u16 v_data_r_u16) +{ +s32 inter_retval = BMI160_INIT_VALUE; +/* no overflow */ +if (v_mag_data_x_s16 != BMI160_MAG_FLIP_OVERFLOW_ADCVAL) { + if ((v_data_r_u16 != 0) + && (mag_trim.dig_xyz1 != 0)) { + inter_retval = ((s32)(((u16) + ((((s32)mag_trim.dig_xyz1) + << BMI160_SHIFT_BIT_POSITION_BY_14_BITS)/ + (v_data_r_u16 != 0 ? + v_data_r_u16 : mag_trim.dig_xyz1))) - + ((u16)0x4000))); + } else { + inter_retval = BMI160_MAG_OVERFLOW_OUTPUT; + return inter_retval; + } + inter_retval = ((s32)((((s32)v_mag_data_x_s16) * + ((((((((s32)mag_trim.dig_xy2) * + ((((s32)inter_retval) * + ((s32)inter_retval)) + >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS)) + + (((s32)inter_retval) * + ((s32)(((s16)mag_trim.dig_xy1) + << BMI160_SHIFT_BIT_POSITION_BY_07_BITS)))) + >> BMI160_SHIFT_BIT_POSITION_BY_09_BITS) + + ((s32)0x100000)) * + ((s32)(((s16)mag_trim.dig_x2) + + ((s16)0xA0)))) + >> BMI160_SHIFT_BIT_POSITION_BY_12_BITS)) + >> BMI160_SHIFT_BIT_POSITION_BY_13_BITS)) + + (((s16)mag_trim.dig_x1) + << BMI160_SHIFT_BIT_POSITION_BY_03_BITS); + /* check the overflow output */ + if (inter_retval == (s32)BMI160_MAG_OVERFLOW_OUTPUT) + inter_retval = BMI160_MAG_OVERFLOW_OUTPUT_S32; +} else { + /* overflow */ + inter_retval = BMI160_MAG_OVERFLOW_OUTPUT; +} +return inter_retval; +} +/*! + * @brief This API used to get the compensated BMM150-Y data + * the out put of Y as s32 + * Before start reading the mag compensated Y data + * make sure the following two points are addressed + * @note + * 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note + * 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * + * @param v_mag_data_y_s16 : The value of mag raw Y data + * @param v_data_r_u16 : The value of mag R data + * + * @return results of compensated Y data value output as s32 + */ +s32 bmi160_bmm150_mag_compensate_Y(s16 v_mag_data_y_s16, u16 v_data_r_u16) +{ +s32 inter_retval = BMI160_INIT_VALUE; +/* no overflow */ +if (v_mag_data_y_s16 != BMI160_MAG_FLIP_OVERFLOW_ADCVAL) { + if ((v_data_r_u16 != 0) + && (mag_trim.dig_xyz1 != 0)) { + inter_retval = ((s32)(((u16)((( + (s32)mag_trim.dig_xyz1) + << BMI160_SHIFT_BIT_POSITION_BY_14_BITS) / + (v_data_r_u16 != 0 ? + v_data_r_u16 : mag_trim.dig_xyz1))) - + ((u16)0x4000))); + } else { + inter_retval = BMI160_MAG_OVERFLOW_OUTPUT; + return inter_retval; + } + inter_retval = ((s32)((((s32)v_mag_data_y_s16) * ((((((((s32) + mag_trim.dig_xy2) * ((((s32) inter_retval) * + ((s32)inter_retval)) >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS)) + + (((s32)inter_retval) * + ((s32)(((s16)mag_trim.dig_xy1) + << BMI160_SHIFT_BIT_POSITION_BY_07_BITS)))) + >> BMI160_SHIFT_BIT_POSITION_BY_09_BITS) + + ((s32)0x100000)) + * ((s32)(((s16)mag_trim.dig_y2) + + ((s16)0xA0)))) + >> BMI160_SHIFT_BIT_POSITION_BY_12_BITS)) + >> BMI160_SHIFT_BIT_POSITION_BY_13_BITS)) + + (((s16)mag_trim.dig_y1) + << BMI160_SHIFT_BIT_POSITION_BY_03_BITS); + /* check the overflow output */ + if (inter_retval == (s32)BMI160_MAG_OVERFLOW_OUTPUT) + inter_retval = BMI160_MAG_OVERFLOW_OUTPUT_S32; +} else { + /* overflow */ + inter_retval = BMI160_MAG_OVERFLOW_OUTPUT; +} +return inter_retval; +} +/*! + * @brief This API used to get the compensated BMM150-Z data + * the out put of Z as s32 + * Before start reading the mag compensated Z data + * make sure the following two points are addressed + * @note + * 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note + * 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * + * @param v_mag_data_z_s16 : The value of mag raw Z data + * @param v_data_r_u16 : The value of mag R data + * + * @return results of compensated Z data value output as s32 + */ +s32 bmi160_bmm150_mag_compensate_Z(s16 v_mag_data_z_s16, u16 v_data_r_u16) +{ + s32 retval = BMI160_INIT_VALUE; + + if (v_mag_data_z_s16 != BMI160_MAG_HALL_OVERFLOW_ADCVAL) { + if ((v_data_r_u16 != 0) + && (mag_trim.dig_z2 != 0) + /* && (mag_trim.dig_z3 != 0)*/ + && (mag_trim.dig_z1 != 0) + && (mag_trim.dig_xyz1 != 0)) { + retval = (((((s32)(v_mag_data_z_s16 - mag_trim.dig_z4)) + << BMI160_SHIFT_BIT_POSITION_BY_15_BITS) - + ((((s32)mag_trim.dig_z3) * + ((s32)(((s16)v_data_r_u16) - + ((s16)mag_trim.dig_xyz1)))) + >> BMI160_SHIFT_BIT_POSITION_BY_02_BITS))/ + (mag_trim.dig_z2 + + ((s16)(((((s32)mag_trim.dig_z1) * + ((((s16)v_data_r_u16) + << BMI160_SHIFT_BIT_POSITION_BY_01_BIT))) + + (1 << BMI160_SHIFT_BIT_POSITION_BY_15_BITS)) + >> BMI160_SHIFT_BIT_POSITION_BY_16_BITS)))); + } + } else { + retval = BMI160_MAG_OVERFLOW_OUTPUT; + } + return retval; +} + /*! + * @brief This function used for initialize the bmm150 sensor + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_interface_init(void) +{ + /* This variable used for provide the communication + results*/ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = BMI160_INIT_VALUE; + u8 v_pull_value_u8 = BMI160_INIT_VALUE; + u8 v_data_u8 = BMI160_INIT_VALUE; + /* accel operation mode to normal*/ + com_rslt = bmi160_set_command_register(ACCEL_MODE_NORMAL); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* write the mag power mode as NORMAL*/ + com_rslt += bmi160_set_mag_interface_normal(); + + /* register 0x7E write the 0x37, 0x9A and 0x30*/ + com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_ONE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_TWO); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_THREE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /*switch the page1*/ + com_rslt += bmi160_set_target_page(BMI160_WRITE_TARGET_PAGE1); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + bmi160_get_target_page(&v_data_u8); + com_rslt += bmi160_set_paging_enable(BMI160_WRITE_ENABLE_PAGE1); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + bmi160_get_paging_enable(&v_data_u8); + /* enable the pullup configuration from + the register 0x05 bit 4 and 5 as 10*/ + bmi160_get_pullup_configuration(&v_pull_value_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + v_pull_value_u8 = v_pull_value_u8 | BMI160_PULL_UP_DATA; + com_rslt += bmi160_set_pullup_configuration(v_pull_value_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /*switch the page0*/ + com_rslt += bmi160_set_target_page(BMI160_WRITE_TARGET_PAGE0); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + bmi160_get_target_page(&v_data_u8); + /* Write the BMM150 i2c address*/ + com_rslt += bmi160_set_i2c_device_addr(BMI160_AUX_BMM150_I2C_ADDRESS); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* enable the mag interface to manual mode*/ + com_rslt += bmi160_set_mag_manual_enable(BMI160_MANUAL_ENABLE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + bmi160_get_mag_manual_enable(&v_data_u8); + /*Enable the MAG interface */ + com_rslt += bmi160_set_if_mode(BMI160_ENABLE_MAG_IF_MODE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + bmi160_get_if_mode(&v_data_u8); + /* Mag normal mode*/ + com_rslt += bmi160_bmm150_mag_wakeup(); + printk(KERN_INFO "com_rslt:%d, <%s><%d>\n", + com_rslt, __func__, __LINE__); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* Read the BMM150 device id is 0x32*/ + /*com_rslt += bmi160_set_mag_read_addr(BMI160_BMM150_CHIP_ID);*/ + /*p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);*/ + /*com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);*/ + /**v_chip_id_u8 = v_data_u8;*/ + /*p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);*/ + /* write the power mode register*/ + com_rslt += bmi160_set_mag_write_data(BMI160_BMM_POWER_MODE_REG); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /*write 0x4C register to write set power mode to normal*/ + com_rslt += bmi160_set_mag_write_addr( + BMI160_BMM150_POWE_MODE_REG); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* read the mag trim values*/ + com_rslt += bmi160_read_bmm150_mag_trim(); + printk(KERN_INFO "com_rslt:%d, <%s><%d>\n", + com_rslt, __func__, __LINE__); + /* To avoid the auto mode enable when manual mode operation running*/ + V_bmm150_maual_auto_condition_u8 = BMI160_MANUAL_ENABLE; + /* write the XY and Z repetitions*/ + com_rslt += bmi160_set_bmm150_mag_presetmode( + BMI160_MAG_PRESETMODE_REGULAR); + printk(KERN_INFO "com_rslt:%d, <%s><%d>\n", + com_rslt, __func__, __LINE__); + /* To avoid the auto mode enable when manual mode operation running*/ + V_bmm150_maual_auto_condition_u8 = BMI160_MANUAL_DISABLE; + /* Set the power mode of mag as force mode*/ + /* The data have to write for the register + It write the value in the register 0x4F */ + com_rslt += bmi160_set_mag_write_data(BMI160_BMM150_FORCE_MODE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + printk(KERN_INFO "com_rslt:%d, <%s><%d>\n", + com_rslt, __func__, __LINE__); + /* write into power mode register*/ + com_rslt += bmi160_set_mag_write_addr( + BMI160_BMM150_POWE_MODE_REG); + /* write the mag v_data_bw_u8 as 25Hz*/ + com_rslt += bmi160_set_mag_output_data_rate( + BMI160_MAG_OUTPUT_DATA_RATE_25HZ); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + + /* When mag interface is auto mode - The mag read address + starts the register 0x42*/ + com_rslt += bmi160_set_mag_read_addr( + BMI160_BMM150_DATA_REG); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* enable mag interface to auto mode*/ + com_rslt += bmi160_set_mag_manual_enable(BMI160_MANUAL_DISABLE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + bmi160_get_mag_manual_enable(&v_data_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + + return com_rslt; +} + /*! + * @brief This function used for set the mag power control + * bit enable + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_wakeup(void) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = BMI160_INIT_VALUE; + u8 v_try_times_u8 = BMI160_BMM150_MAX_RETRY_WAKEUP; + u8 v_power_control_bit_u8 = BMI160_INIT_VALUE; + u8 i = BMI160_INIT_VALUE; + + for (i = BMI160_INIT_VALUE; i < v_try_times_u8; i++) { + com_rslt = bmi160_set_mag_write_data(BMI160_BMM150_POWER_ON); + p_bmi160->delay_msec(BMI160_BMM150_WAKEUP_DELAY1); + /*write 0x4B register to enable power control bit*/ + com_rslt += bmi160_set_mag_write_addr( + BMI160_BMM150_POWE_CONTROL_REG); + p_bmi160->delay_msec(BMI160_BMM150_WAKEUP_DELAY2); + com_rslt += bmi160_set_mag_read_addr( + BMI160_BMM150_POWE_CONTROL_REG); + /* 0x04 is secondary read mag x lsb register */ + p_bmi160->delay_msec(BMI160_BMM150_WAKEUP_DELAY3); + com_rslt += bmi160_read_reg(BMI160_USER_DATA_0_ADDR, + &v_power_control_bit_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + v_power_control_bit_u8 = BMI160_BMM150_SET_POWER_CONTROL + & v_power_control_bit_u8; + if (v_power_control_bit_u8 == BMI160_BMM150_POWER_ON) + break; + } + com_rslt = (i >= v_try_times_u8) ? + BMI160_BMM150_POWER_ON_FAIL : BMI160_BMM150_POWER_ON_SUCCESS; + return com_rslt; +} + /*! + * @brief This function used for set the magnetometer + * power mode. + * @note + * Before set the mag power mode + * make sure the following two point is addressed + * Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * + * @param v_mag_sec_if_pow_mode_u8 : The value of mag power mode + * value | mode + * ----------|------------ + * 0 | BMI160_MAG_FORCE_MODE + * 1 | BMI160_MAG_SUSPEND_MODE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_bmm150_mag_and_secondary_if_power_mode( +u8 v_mag_sec_if_pow_mode_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = BMI160_INIT_VALUE; + /* set the accel power mode to NORMAL*/ + com_rslt = bmi160_set_command_register(ACCEL_MODE_NORMAL); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n", + com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__); + /* set mag interface manual mode*/ + if (p_bmi160->mag_manual_enable != BMI160_MANUAL_ENABLE) { + com_rslt += bmi160_set_mag_manual_enable( + BMI160_MANUAL_ENABLE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + } + printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n", + com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__); + + switch (v_mag_sec_if_pow_mode_u8) { + case BMI160_MAG_FORCE_MODE: + /* set the secondary mag power mode as NORMAL*/ + com_rslt += bmi160_set_mag_interface_normal(); + printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n", + com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__); + /* set the mag power mode as FORCE mode*/ + com_rslt += bmi160_bmm150_mag_set_power_mode(FORCE_MODE); + printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n", + com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + break; + case BMI160_MAG_SUSPEND_MODE: + /* set the mag power mode as SUSPEND mode*/ + printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n", + com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__); + com_rslt += bmi160_bmm150_mag_set_power_mode(SUSPEND_MODE); + printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n", + com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* set the secondary mag power mode as SUSPEND*/ + com_rslt += bmi160_set_command_register(MAG_MODE_SUSPEND); + printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n", + com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + if (p_bmi160->mag_manual_enable == BMI160_MANUAL_ENABLE) { + /* set mag interface auto mode*/ + com_rslt += bmi160_set_mag_manual_enable( + BMI160_MANUAL_DISABLE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + } + printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n", + com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__); + return com_rslt; +} +/*! + * @brief This function used for set the magnetometer + * power mode. + * @note + * Before set the mag power mode + * make sure the following two points are addressed + * @note + * 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note + * 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * @param v_mag_pow_mode_u8 : The value of mag power mode + * value | mode + * ----------|------------ + * 0 | FORCE_MODE + * 1 | SUSPEND_MODE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_set_power_mode( +u8 v_mag_pow_mode_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = BMI160_INIT_VALUE; + u8 manual_enable_status = 0; + /* set mag interface manual mode*/ + if (p_bmi160->mag_manual_enable != BMI160_MANUAL_ENABLE) { + com_rslt = bmi160_set_mag_manual_enable( + BMI160_MANUAL_ENABLE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_get_mag_manual_enable(&manual_enable_status); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + printk(KERN_INFO "1com_rslt:%d, manual:%d, manual_read:%d\n", + com_rslt, p_bmi160->mag_manual_enable, manual_enable_status); + } + printk(KERN_INFO "2com_rslt:%d, manual:%d, manual_read:%d\n", + com_rslt, p_bmi160->mag_manual_enable, manual_enable_status); + + switch (v_mag_pow_mode_u8) { + case FORCE_MODE: + /* Set the power control bit enabled */ + com_rslt = bmi160_bmm150_mag_wakeup(); + /* write the mag power mode as FORCE mode*/ + com_rslt += bmi160_set_mag_write_data( + BMI160_BMM150_FORCE_MODE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr( + BMI160_BMM150_POWE_MODE_REG); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + /* To avoid the auto mode enable when manual + mode operation running*/ + V_bmm150_maual_auto_condition_u8 = BMI160_MANUAL_ENABLE; + /* set the preset mode */ + com_rslt += bmi160_set_bmm150_mag_presetmode( + BMI160_MAG_PRESETMODE_REGULAR); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* To avoid the auto mode enable when manual + mode operation running*/ + V_bmm150_maual_auto_condition_u8 = BMI160_MANUAL_DISABLE; + /* set the mag read address to data registers*/ + com_rslt += bmi160_set_mag_read_addr( + BMI160_BMM150_DATA_REG); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + break; + case SUSPEND_MODE: + printk(KERN_INFO "3com_rslt:%d, manual:%d, read_manual:%d\n", + com_rslt, p_bmi160->mag_manual_enable, manual_enable_status); + /* Set the power mode of mag as suspend mode*/ + com_rslt += bmi160_set_mag_write_data( + BMI160_BMM150_POWER_OFF); + printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n", + com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr( + BMI160_BMM150_POWE_CONTROL_REG); + printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n", + com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + printk(KERN_INFO "4com_rslt:%d, manual:%d, manual_read:%d\n", + com_rslt, p_bmi160->mag_manual_enable, manual_enable_status); + /* set mag interface auto mode*/ + if (p_bmi160->mag_manual_enable == BMI160_MANUAL_ENABLE) { + com_rslt += bmi160_set_mag_manual_enable( + BMI160_MANUAL_DISABLE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_get_mag_manual_enable(&manual_enable_status); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + } + printk(KERN_INFO "5com_rslt:%d, manual:%d, manual_read:%d\n", + com_rslt, p_bmi160->mag_manual_enable, manual_enable_status); + return com_rslt; +} +/*! + * @brief This API used to set the pre-set modes of bmm150 + * The pre-set mode setting is depend on data rate and xy and z repetitions + * + * @note + * Before set the mag preset mode + * make sure the following two points are addressed + * @note + * 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note + * 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * @param v_mode_u8: The value of pre-set mode selection value + * value | pre_set mode + * ----------|------------ + * 1 | BMI160_MAG_PRESETMODE_LOWPOWER + * 2 | BMI160_MAG_PRESETMODE_REGULAR + * 3 | BMI160_MAG_PRESETMODE_HIGHACCURACY + * 4 | BMI160_MAG_PRESETMODE_ENHANCED + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_bmm150_mag_presetmode(u8 v_mode_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + switch (v_mode_u8) { + case BMI160_MAG_PRESETMODE_LOWPOWER: + /* write the XY and Z repetitions*/ + /* The v_data_u8 have to write for the register + It write the value in the register 0x4F*/ + com_rslt = bmi160_set_mag_write_data( + BMI160_MAG_LOWPOWER_REPXY); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr( + BMI160_BMM150_XY_REP); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* write the Z repetitions*/ + /* The v_data_u8 have to write for the register + It write the value in the register 0x4F*/ + com_rslt += bmi160_set_mag_write_data( + BMI160_MAG_LOWPOWER_REPZ); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr( + BMI160_BMM150_Z_REP); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* set the mag v_data_u8 rate as 10 to the register 0x4C*/ + com_rslt += bmi160_set_mag_write_data( + BMI160_MAG_LOWPOWER_DR); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr( + BMI160_BMM150_POWE_MODE_REG); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + break; + case BMI160_MAG_PRESETMODE_REGULAR: + /* write the XY and Z repetitions*/ + /* The v_data_u8 have to write for the register + It write the value in the register 0x4F*/ + com_rslt = bmi160_set_mag_write_data( + BMI160_MAG_REGULAR_REPXY); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr( + BMI160_BMM150_XY_REP); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* write the Z repetitions*/ + /* The v_data_u8 have to write for the register + It write the value in the register 0x4F*/ + com_rslt += bmi160_set_mag_write_data( + BMI160_MAG_REGULAR_REPZ); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr( + BMI160_BMM150_Z_REP); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* set the mag v_data_u8 rate as 10 to the register 0x4C*/ + com_rslt += bmi160_set_mag_write_data( + BMI160_MAG_REGULAR_DR); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr( + BMI160_BMM150_POWE_MODE_REG); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + break; + case BMI160_MAG_PRESETMODE_HIGHACCURACY: + /* write the XY and Z repetitions*/ + /* The v_data_u8 have to write for the register + It write the value in the register 0x4F*/ + com_rslt = bmi160_set_mag_write_data( + BMI160_MAG_HIGHACCURACY_REPXY); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr( + BMI160_BMM150_XY_REP); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* write the Z repetitions*/ + /* The v_data_u8 have to write for the register + It write the value in the register 0x4F*/ + com_rslt += bmi160_set_mag_write_data( + BMI160_MAG_HIGHACCURACY_REPZ); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr( + BMI160_BMM150_Z_REP); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* set the mag v_data_u8 rate as 20 to the register 0x4C*/ + com_rslt += bmi160_set_mag_write_data( + BMI160_MAG_HIGHACCURACY_DR); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr( + BMI160_BMM150_POWE_MODE_REG); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + break; + case BMI160_MAG_PRESETMODE_ENHANCED: + /* write the XY and Z repetitions*/ + /* The v_data_u8 have to write for the register + It write the value in the register 0x4F*/ + com_rslt = bmi160_set_mag_write_data( + BMI160_MAG_ENHANCED_REPXY); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr( + BMI160_BMM150_XY_REP); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* write the Z repetitions*/ + /* The v_data_u8 have to write for the register + It write the value in the register 0x4F*/ + com_rslt += bmi160_set_mag_write_data( + BMI160_MAG_ENHANCED_REPZ); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr( + BMI160_BMM150_Z_REP); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* set the mag v_data_u8 rate as 10 to the register 0x4C*/ + com_rslt += bmi160_set_mag_write_data( + BMI160_MAG_ENHANCED_DR); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr( + BMI160_BMM150_POWE_MODE_REG); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + + return com_rslt; +} + /*! + * @brief This function used for read the trim values of magnetometer + * + * @note + * Before reading the mag trimming values + * make sure the following two points are addressed + * @note + * 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note + * 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_bmm150_mag_trim(void) +{ + /* This variable used for provide the communication + results*/ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Array holding the bmm150 trim data + */ + u8 v_data_u8[BMI160_MAG_TRIM_DATA_SIZE] = { + BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE}; + /* read dig_x1 value */ + com_rslt = bmi160_set_mag_read_addr( + BMI160_MAG_DIG_X1); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[BMI160_BMM150_DIG_X1], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + mag_trim.dig_x1 = v_data_u8[BMI160_BMM150_DIG_X1]; + /* read dig_y1 value */ + com_rslt += bmi160_set_mag_read_addr( + BMI160_MAG_DIG_Y1); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[BMI160_BMM150_DIG_Y1], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + mag_trim.dig_y1 = v_data_u8[BMI160_BMM150_DIG_Y1]; + + /* read dig_x2 value */ + com_rslt += bmi160_set_mag_read_addr( + BMI160_MAG_DIG_X2); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[BMI160_BMM150_DIG_X2], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + mag_trim.dig_x2 = v_data_u8[BMI160_BMM150_DIG_X2]; + /* read dig_y2 value */ + com_rslt += bmi160_set_mag_read_addr( + BMI160_MAG_DIG_Y2); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[BMI160_BMM150_DIG_Y3], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + mag_trim.dig_y2 = v_data_u8[BMI160_BMM150_DIG_Y3]; + + /* read dig_xy1 value */ + com_rslt += bmi160_set_mag_read_addr( + BMI160_MAG_DIG_XY1); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[BMI160_BMM150_DIG_XY1], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + mag_trim.dig_xy1 = v_data_u8[BMI160_BMM150_DIG_XY1]; + /* read dig_xy2 value */ + com_rslt += bmi160_set_mag_read_addr( + BMI160_MAG_DIG_XY2); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is v_mag_x_s16 ls register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[BMI160_BMM150_DIG_XY2], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + mag_trim.dig_xy2 = v_data_u8[BMI160_BMM150_DIG_XY2]; + + /* read dig_z1 lsb value */ + com_rslt += bmi160_set_mag_read_addr( + BMI160_MAG_DIG_Z1_LSB); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[BMI160_BMM150_DIG_Z1_LSB], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* read dig_z1 msb value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_MAG_DIG_Z1_MSB); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is v_mag_x_s16 msb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[BMI160_BMM150_DIG_Z1_MSB], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + mag_trim.dig_z1 = + (u16)((((u32)((u8)v_data_u8[BMI160_BMM150_DIG_Z1_MSB])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | + (v_data_u8[BMI160_BMM150_DIG_Z1_LSB])); + + /* read dig_z2 lsb value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_MAG_DIG_Z2_LSB); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[BMI160_BMM150_DIG_Z2_LSB], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* read dig_z2 msb value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_MAG_DIG_Z2_MSB); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is v_mag_x_s16 msb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[BMI160_BMM150_DIG_Z2_MSB], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + mag_trim.dig_z2 = + (s16)((((s32)((s8)v_data_u8[BMI160_BMM150_DIG_Z2_MSB])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | + (v_data_u8[BMI160_BMM150_DIG_Z2_LSB])); + + /* read dig_z3 lsb value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_MAG_DIG_Z3_LSB); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[BMI160_BMM150_DIG_DIG_Z3_LSB], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* read dig_z3 msb value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_MAG_DIG_Z3_MSB); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is v_mag_x_s16 msb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[BMI160_BMM150_DIG_DIG_Z3_MSB], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + mag_trim.dig_z3 = + (s16)((((s32)((s8)v_data_u8[BMI160_BMM150_DIG_DIG_Z3_MSB])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | + (v_data_u8[BMI160_BMM150_DIG_DIG_Z3_LSB])); + + /* read dig_z4 lsb value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_MAG_DIG_Z4_LSB); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[BMI160_BMM150_DIG_DIG_Z4_LSB], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* read dig_z4 msb value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_MAG_DIG_Z4_MSB); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is v_mag_x_s16 msb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[BMI160_BMM150_DIG_DIG_Z4_MSB], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + mag_trim.dig_z4 = + (s16)((((s32)((s8)v_data_u8[BMI160_BMM150_DIG_DIG_Z4_MSB])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | + (v_data_u8[BMI160_BMM150_DIG_DIG_Z4_LSB])); + + /* read dig_xyz1 lsb value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_MAG_DIG_XYZ1_LSB); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[BMI160_BMM150_DIG_DIG_XYZ1_LSB], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* read dig_xyz1 msb value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_MAG_DIG_XYZ1_MSB); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is v_mag_x_s16 msb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[BMI160_BMM150_DIG_DIG_XYZ1_MSB], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + mag_trim.dig_xyz1 = + (u16)((((u32)((u8)v_data_u8[BMI160_BMM150_DIG_DIG_XYZ1_MSB])) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | + (v_data_u8[BMI160_BMM150_DIG_DIG_XYZ1_LSB])); + + return com_rslt; +} + /*! + * @brief This function used for initialize + * the AKM09911 and AKM09912 sensor + * + * + * @param v_akm_i2c_address_u8: The value of device address + * AKM sensor | Slave address + * --------------|--------------------- + * AKM09911 | AKM09911_I2C_ADDR_1 + * - | and AKM09911_I2C_ADDR_2 + * AKM09912 | AKM09912_I2C_ADDR_1 + * - | AKM09912_I2C_ADDR_2 + * - | AKM09912_I2C_ADDR_3 + * - | AKM09912_I2C_ADDR_4 + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm_mag_interface_init( +u8 v_akm_i2c_address_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_pull_value_u8 = BMI160_INIT_VALUE; + u8 v_data_u8 = BMI160_INIT_VALUE; + u8 v_akm_chip_id_u8 = BMI160_INIT_VALUE; + /* accel operation mode to normal*/ + com_rslt = bmi160_set_command_register(ACCEL_MODE_NORMAL); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_command_register(MAG_MODE_NORMAL); + p_bmi160->delay_msec(BMI160_AKM_INIT_DELAY); + bmi160_get_mag_power_mode_stat(&v_data_u8); + /* register 0x7E write the 0x37, 0x9A and 0x30*/ + com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_ONE); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_TWO); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_THREE); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + /*switch the page1*/ + com_rslt += bmi160_set_target_page(BMI160_WRITE_TARGET_PAGE1); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + bmi160_get_target_page(&v_data_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_paging_enable(BMI160_WRITE_ENABLE_PAGE1); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + bmi160_get_paging_enable(&v_data_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* enable the pullup configuration from + the register 0x05 bit 4 and 5 to 10*/ + bmi160_get_pullup_configuration(&v_pull_value_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + v_pull_value_u8 = v_pull_value_u8 | BMI160_PULL_UP_DATA; + com_rslt += bmi160_set_pullup_configuration(v_pull_value_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + + /*switch the page0*/ + com_rslt += bmi160_set_target_page(BMI160_WRITE_TARGET_PAGE0); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + bmi160_get_target_page(&v_data_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* Write the AKM09911 0r AKM09912 i2c address*/ + com_rslt += bmi160_set_i2c_device_addr(v_akm_i2c_address_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* enable the mag interface to manual mode*/ + com_rslt += bmi160_set_mag_manual_enable(BMI160_MANUAL_ENABLE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + bmi160_get_mag_manual_enable(&v_data_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /*Enable the MAG interface */ + com_rslt += bmi160_set_if_mode(BMI160_ENABLE_MAG_IF_MODE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + bmi160_get_if_mode(&v_data_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + + /* Set the AKM Fuse ROM mode */ + /* Set value for fuse ROM mode*/ + com_rslt += bmi160_set_mag_write_data(AKM_FUSE_ROM_MODE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* AKM mode address is 0x31*/ + com_rslt += bmi160_set_mag_write_addr(AKM_POWER_MODE_REG); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + /* Read the Fuse ROM v_data_u8 from registers + 0x60,0x61 and 0x62*/ + /* ASAX v_data_u8 */ + com_rslt += bmi160_read_bst_akm_sensitivity_data(); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + /* read the device id of the AKM sensor + if device id is 0x05 - AKM09911 + if device id is 0x04 - AKM09912*/ + com_rslt += bmi160_set_mag_read_addr(AKM09912_CHIP_ID_REG); + /* 0x04 is mag_x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_akm_chip_id_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + printk(KERN_INFO "bmi160,addr:0x%x, akm_chip_id:0x%x", + v_akm_i2c_address_u8, v_akm_chip_id_u8); + /* Set value power down mode mode*/ + com_rslt += bmi160_set_mag_write_data(AKM_POWER_DOWN_MODE_DATA); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* AKM mode address is 0x31*/ + com_rslt += bmi160_set_mag_write_addr(AKM_POWER_MODE_REG); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + /* Set AKM Force mode*/ + com_rslt += bmi160_set_mag_write_data( + AKM_SINGLE_MEASUREMENT_MODE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* AKM mode address is 0x31*/ + com_rslt += bmi160_set_mag_write_addr(AKM_POWER_MODE_REG); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + /* Set the AKM read xyz v_data_u8 address*/ + com_rslt += bmi160_set_mag_read_addr(AKM_DATA_REGISTER); + /* write the mag v_data_bw_u8 as 25Hz*/ + com_rslt += bmi160_set_mag_output_data_rate( + BMI160_MAG_OUTPUT_DATA_RATE_25HZ); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* Enable mag interface to auto mode*/ + com_rslt += bmi160_set_mag_manual_enable(BMI160_MANUAL_DISABLE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + bmi160_get_mag_manual_enable(&v_data_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + + return com_rslt; +} + /*! + * @brief This function used for read the sensitivity data of + * AKM09911 and AKM09912 + * + * @note Before reading the mag sensitivity values + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_bst_akm_sensitivity_data(void) +{ + /* This variable used for provide the communication + results*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Array holding the sensitivity ax,ay and az data*/ + u8 v_data_u8[BMI160_AKM_SENSITIVITY_DATA_SIZE] = { + BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE}; + /* read asax value */ + com_rslt = bmi160_set_mag_read_addr(BMI160_BST_AKM_ASAX); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[AKM_ASAX], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + akm_asa_data.asax = v_data_u8[AKM_ASAX]; + /* read asay value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_BST_AKM_ASAY); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[AKM_ASAY], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + akm_asa_data.asay = v_data_u8[AKM_ASAY]; + /* read asaz value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_BST_AKM_ASAZ); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[AKM_ASAZ], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + akm_asa_data.asaz = v_data_u8[AKM_ASAZ]; + + return com_rslt; +} +/*! + * @brief This API used to get the compensated X data + * of AKM09911 the out put of X as s32 + * @note Before start reading the mag compensated X data + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * @param v_bst_akm_x_s16 : The value of X data + * + * @return results of compensated X data value output as s32 + * + */ +s32 bmi160_bst_akm09911_compensate_X(s16 v_bst_akm_x_s16) +{ + /*Return value of AKM x compensated v_data_u8*/ + s32 retval = BMI160_INIT_VALUE; + /* Convert raw v_data_u8 into compensated v_data_u8*/ + retval = (v_bst_akm_x_s16 * + ((akm_asa_data.asax/AKM09911_SENSITIVITY_DIV) + + BMI160_GEN_READ_WRITE_DATA_LENGTH)); + return retval; +} +/*! + * @brief This API used to get the compensated Y data + * of AKM09911 the out put of Y as s32 + * @note Before start reading the mag compensated Y data + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * @param v_bst_akm_y_s16 : The value of Y data + * + * @return results of compensated Y data value output as s32 + * + */ +s32 bmi160_bst_akm09911_compensate_Y(s16 v_bst_akm_y_s16) +{ + /*Return value of AKM y compensated v_data_u8*/ + s32 retval = BMI160_INIT_VALUE; + /* Convert raw v_data_u8 into compensated v_data_u8*/ + retval = (v_bst_akm_y_s16 * + ((akm_asa_data.asay/AKM09911_SENSITIVITY_DIV) + + BMI160_GEN_READ_WRITE_DATA_LENGTH)); + return retval; +} +/*! + * @brief This API used to get the compensated Z data + * of AKM09911 the out put of Z as s32 + * @note Before start reading the mag compensated Z data + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * @param v_bst_akm_z_s16 : The value of Z data + * + * @return results of compensated Z data value output as s32 + * + */ +s32 bmi160_bst_akm09911_compensate_Z(s16 v_bst_akm_z_s16) +{ + /*Return value of AKM z compensated v_data_u8*/ + s32 retval = BMI160_INIT_VALUE; + /* Convert raw v_data_u8 into compensated v_data_u8*/ + retval = (v_bst_akm_z_s16 * + ((akm_asa_data.asaz/AKM09911_SENSITIVITY_DIV) + + BMI160_GEN_READ_WRITE_DATA_LENGTH)); + return retval; +} +/*! + * @brief This API used to get the compensated X data + * of AKM09912 the out put of X as s32 + * @note Before start reading the mag compensated X data + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * @param v_bst_akm_x_s16 : The value of X data + * + * @return results of compensated X data value output as s32 + * + */ +s32 bmi160_bst_akm09912_compensate_X(s16 v_bst_akm_x_s16) +{ + /*Return value of AKM x compensated data*/ + s32 retval = BMI160_INIT_VALUE; + /* Convert raw data into compensated data*/ + retval = v_bst_akm_x_s16 * + (akm_asa_data.asax + AKM09912_SENSITIVITY) + / AKM09912_SENSITIVITY_DIV; + return retval; +} +/*! + * @brief This API used to get the compensated Y data + * of AKM09912 the out put of Y as s32 + * @note Before start reading the mag compensated Y data + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * @param v_bst_akm_y_s16 : The value of Y data + * + * @return results of compensated Y data value output as s32 + * + */ +s32 bmi160_bst_akm09912_compensate_Y(s16 v_bst_akm_y_s16) +{ + /*Return value of AKM y compensated data*/ + s32 retval = BMI160_INIT_VALUE; + /* Convert raw data into compensated data*/ + retval = v_bst_akm_y_s16 * + (akm_asa_data.asax + AKM09912_SENSITIVITY) + / AKM09912_SENSITIVITY_DIV; + return retval; +} +/*! + * @brief This API used to get the compensated Z data + * of AKM09912 the out put of Z as s32 + * @note Before start reading the mag compensated Z data + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * @param v_bst_akm_z_s16 : The value of Z data + * + * @return results of compensated Z data value output as s32 + * + */ +s32 bmi160_bst_akm09912_compensate_Z(s16 v_bst_akm_z_s16) +{ + /*Return value of AKM z compensated data*/ + s32 retval = BMI160_INIT_VALUE; + /* Convert raw data into compensated data*/ + retval = v_bst_akm_z_s16 * + (akm_asa_data.asax + AKM09912_SENSITIVITY) + / AKM09912_SENSITIVITY_DIV; + return retval; +} + /*! + * @brief This function used for read the compensated value of + * AKM09911 + * @note Before start reading the mag compensated data's + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm09911_compensate_xyz( +struct bmi160_mag_xyz_s32_t *bst_akm_xyz) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + struct bmi160_mag_t mag_xyz; + + com_rslt = bmi160_read_mag_xyz(&mag_xyz, BST_AKM); + /* Compensation for X axis */ + bst_akm_xyz->x = bmi160_bst_akm09911_compensate_X(mag_xyz.x); + + /* Compensation for Y axis */ + bst_akm_xyz->y = bmi160_bst_akm09911_compensate_Y(mag_xyz.y); + + /* Compensation for Z axis */ + bst_akm_xyz->z = bmi160_bst_akm09911_compensate_Z(mag_xyz.z); + + return com_rslt; +} + /*! + * @brief This function used for read the compensated value of + * AKM09912 + * @note Before start reading the mag compensated data's + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm09912_compensate_xyz( +struct bmi160_mag_xyz_s32_t *bst_akm_xyz) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + struct bmi160_mag_t mag_xyz; + + com_rslt = bmi160_read_mag_xyz(&mag_xyz, BST_AKM); + printk(KERN_INFO "akm09912_raw_x:%d, %d, %d, <%s>,<%d>", + mag_xyz.x, mag_xyz.y, mag_xyz.z, __func__, __LINE__); + /* Compensation for X axis */ + bst_akm_xyz->x = bmi160_bst_akm09912_compensate_X(mag_xyz.x); + + /* Compensation for Y axis */ + bst_akm_xyz->y = bmi160_bst_akm09912_compensate_Y(mag_xyz.y); + + /* Compensation for Z axis */ + bst_akm_xyz->z = bmi160_bst_akm09912_compensate_Z(mag_xyz.z); + return com_rslt; +} + /*! + * @brief This function used for read the compensated value of + * AKM09912 + * @note Before start reading the mag compensated data's + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm09912_compensate_xyz_raw( +struct bmi160_mag_xyz_s32_t *bst_akm_xyz) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Compensation for X axis */ + bst_akm_xyz->x = bmi160_bst_akm09912_compensate_X(bst_akm_xyz->x); + + /* Compensation for Y axis */ + bst_akm_xyz->y = bmi160_bst_akm09912_compensate_Y(bst_akm_xyz->y); + + /* Compensation for Z axis */ + bst_akm_xyz->z = bmi160_bst_akm09912_compensate_Z(bst_akm_xyz->z); + + return com_rslt; +} +/*! + * @brief This function used for set the AKM09911 and AKM09912 + * power mode. + * @note Before set the AKM power mode + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * @param v_akm_pow_mode_u8 : The value of akm power mode + * value | Description + * ---------|-------------------- + * 0 | AKM_POWER_DOWN_MODE + * 1 | AKM_SINGLE_MEAS_MODE + * 2 | FUSE_ROM_MODE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm_set_powermode( +u8 v_akm_pow_mode_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = BMI160_INIT_VALUE; + /* set mag interface manual mode*/ + if (p_bmi160->mag_manual_enable != BMI160_MANUAL_ENABLE) { + com_rslt = bmi160_set_mag_manual_enable( + BMI160_MANUAL_ENABLE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + } + printk(KERN_INFO "com_rslt:%d, manual:%d, <%s>\n", + com_rslt, p_bmi160->mag_manual_enable, __func__); + switch (v_akm_pow_mode_u8) { + case AKM_POWER_DOWN_MODE: + /* Set the power mode of AKM as power down mode*/ + com_rslt += bmi160_set_mag_write_data(AKM_POWER_DOWN_MODE_DATA); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr(AKM_POWER_MODE_REG); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + break; + case AKM_SINGLE_MEAS_MODE: + /* Set the power mode of AKM as + single measurement mode*/ + com_rslt += bmi160_set_mag_write_data + (AKM_SINGLE_MEASUREMENT_MODE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr(AKM_POWER_MODE_REG); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_read_addr(AKM_DATA_REGISTER); + break; + case FUSE_ROM_MODE: + /* Set the power mode of AKM as + Fuse ROM mode*/ + com_rslt += bmi160_set_mag_write_data(AKM_FUSE_ROM_MODE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr(AKM_POWER_MODE_REG); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + /* Sensitivity v_data_u8 */ + com_rslt += bmi160_read_bst_akm_sensitivity_data(); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + /* power down mode*/ + com_rslt += bmi160_set_mag_write_data(AKM_POWER_DOWN_MODE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr(AKM_POWER_MODE_REG); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + /* set mag interface auto mode*/ + if (p_bmi160->mag_manual_enable == BMI160_MANUAL_ENABLE) { + com_rslt += bmi160_set_mag_manual_enable( + BMI160_MANUAL_DISABLE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + } + printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n", + com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__); + return com_rslt; +} + /*! + * @brief This function used for set the magnetometer + * power mode of AKM09911 and AKM09912 + * @note Before set the mag power mode + * make sure the following two point is addressed + * Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * + * @param v_mag_sec_if_pow_mode_u8 : The value of secondary if power mode + * value | Description + * ---------|-------------------- + * 0 | BMI160_MAG_FORCE_MODE + * 1 | BMI160_MAG_SUSPEND_MODE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_bst_akm_and_secondary_if_powermode( +u8 v_mag_sec_if_pow_mode_u8) +{ + /* variable used for return the status of communication result*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* accel operation mode to normal*/ + com_rslt = bmi160_set_command_register(ACCEL_MODE_NORMAL); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* set mag interface manual mode*/ + if (p_bmi160->mag_manual_enable != BMI160_MANUAL_ENABLE) { + com_rslt = bmi160_set_mag_manual_enable( + BMI160_MANUAL_ENABLE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + } + printk(KERN_ERR "com_rslt:%d, manual:%d,after setacc normal mode\n", + com_rslt, p_bmi160->mag_manual_enable); + switch (v_mag_sec_if_pow_mode_u8) { + case BMI160_MAG_FORCE_MODE: + /* set the secondary mag power mode as NORMAL*/ + com_rslt += bmi160_set_mag_interface_normal(); + /* set the akm power mode as single measurement mode*/ + com_rslt += bmi160_bst_akm_set_powermode(AKM_SINGLE_MEAS_MODE); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_read_addr(AKM_DATA_REGISTER); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + break; + case BMI160_MAG_SUSPEND_MODE: + /* set the akm power mode as power down mode*/ + com_rslt += bmi160_bst_akm_set_powermode(AKM_POWER_DOWN_MODE); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + /* set the secondary mag power mode as SUSPEND*/ + com_rslt += bmi160_set_command_register(MAG_MODE_SUSPEND); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + break; + default: + com_rslt = E_BMI160_OUT_OF_RANGE; + break; + } + /* set mag interface auto mode*/ + if (p_bmi160->mag_manual_enable == BMI160_MANUAL_ENABLE) + com_rslt += bmi160_set_mag_manual_enable( + BMI160_MANUAL_DISABLE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + return com_rslt; +} +/*! + * @brief This function used for read the YAMAH-YAS532 init + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas532_mag_interface_init( +void) +{ + /* This variable used for provide the communication + results*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + u8 v_pull_value_u8 = BMI160_INIT_VALUE; + u8 v_data_u8 = BMI160_INIT_VALUE; + u8 i = BMI160_INIT_VALUE; + /* accel operation mode to normal*/ + com_rslt = bmi160_set_command_register(ACCEL_MODE_NORMAL); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* write mag power mode as NORMAL*/ + com_rslt += bmi160_set_mag_interface_normal(); + /* register 0x7E write the 0x37, 0x9A and 0x30*/ + com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_ONE); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_TWO); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_THREE); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + /*switch the page1*/ + com_rslt += bmi160_set_target_page(BMI160_WRITE_TARGET_PAGE1); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + bmi160_get_target_page(&v_data_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_paging_enable(BMI160_WRITE_ENABLE_PAGE1); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + bmi160_get_paging_enable(&v_data_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* enable the pullup configuration from + the register 0x05 bit 4 and 5 as 10*/ + bmi160_get_pullup_configuration(&v_pull_value_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + v_pull_value_u8 = v_pull_value_u8 | BMI160_PULL_UP_DATA; + com_rslt += bmi160_set_pullup_configuration(v_pull_value_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /*switch the page0*/ + com_rslt += bmi160_set_target_page(BMI160_WRITE_TARGET_PAGE0); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + bmi160_get_target_page(&v_data_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* Write the YAS532 i2c address*/ + com_rslt += bmi160_set_i2c_device_addr(BMI160_AUX_YAS532_I2C_ADDRESS); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* enable the mag interface to manual mode*/ + com_rslt += bmi160_set_mag_manual_enable(BMI160_MANUAL_ENABLE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + bmi160_get_mag_manual_enable(&v_data_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /*Enable the MAG interface */ + com_rslt += bmi160_set_if_mode(BMI160_ENABLE_MAG_IF_MODE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + bmi160_get_if_mode(&v_data_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + v_data_u8 = BMI160_MANUAL_DISABLE; + /* Read the YAS532 device id is 0x02*/ + com_rslt += bmi160_set_mag_read_addr(BMI160_YAS_DEVICE_ID_REG); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* Read the YAS532 calibration data*/ + com_rslt += bmi160_bst_yamaha_yas532_calib_values(); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + /* Assign the data acquisition mode*/ + yas532_data.measure_state = YAS532_MAG_STATE_INIT_COIL; + /* Set the default offset as invalid offset*/ + set_vector(yas532_data.v_hard_offset_s8, INVALID_OFFSET); + /* set the transform to zero */ + yas532_data.transform = BMI160_NULL; + /* Assign overflow as zero*/ + yas532_data.overflow = 0; + #if YAS532_MAG_LOG < YAS532_MAG_TEMPERATURE_LOG + yas532_data.temp_data.num = + yas532_data.temp_data.idx = 0; + #endif + /* Assign the coef value*/ + for (i = 0; i < 3; i++) { + yas532_data.coef[i] = yas532_version_ac_coef[i]; + yas532_data.last_raw[i] = 0; + } + yas532_data.last_raw[3] = 0; + /* Set the initial values of yas532*/ + com_rslt += bmi160_bst_yas532_set_initial_values(); + /* write the mag v_data_bw_u8 as 25Hz*/ + com_rslt += bmi160_set_mag_output_data_rate( + BMI160_MAG_OUTPUT_DATA_RATE_25HZ); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* Enable mag interface to auto mode*/ + com_rslt += bmi160_set_mag_manual_enable( + BMI160_MANUAL_DISABLE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + bmi160_get_mag_manual_enable(&v_data_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + + return com_rslt; +} +/*! + * @brief This function used to set the YAS532 initial values + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_set_initial_values(void) +{ +/* This variable used for provide the communication + results*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* write testr1 as 0x00*/ + com_rslt = bmi160_set_mag_write_data( + BMI160_YAS532_WRITE_TESTR1); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr(BMI160_YAS532_TESTR1); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + /* write testr2 as 0x00*/ + com_rslt += bmi160_set_mag_write_data( + BMI160_YAS532_WRITE_TESTR2); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr(BMI160_YAS532_TESTR2); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + /* write Rcoil as 0x00*/ + com_rslt += bmi160_set_mag_write_data( + BMI160_YAS532_WRITE_RCOIL); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr(BMI160_YAS532_RCOIL); + p_bmi160->delay_msec(BMI160_YAS532_SET_INITIAL_VALUE_DELAY); + /* check the valid offset*/ + if (is_valid_offset(yas532_data.v_hard_offset_s8)) { + com_rslt += bmi160_bst_yas532_set_offset( + yas532_data.v_hard_offset_s8); + yas532_data.measure_state = YAS532_MAG_STATE_NORMAL; + } else { + /* set the default offset as invalid offset*/ + set_vector(yas532_data.v_hard_offset_s8, INVALID_OFFSET); + /*Set the default measure state for offset correction*/ + yas532_data.measure_state = YAS532_MAG_STATE_MEASURE_OFFSET; + } + return com_rslt; +} +/*! + * @brief This function used for YAS532 offset correction + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_magnetic_measure_set_offset( +void) +{ + /* This variable used for provide the communication + results*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* used for offset value set to the offset register*/ + s8 v_hard_offset_s8[BMI160_HARD_OFFSET_DATA_SIZE] = { + BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE}; + /* offset correction factors*/ + static const u8 v_correct_u8[BMI160_YAS_CORRECT_DATA_SIZE] = { + 16, 8, 4, 2, 1}; + /* used for the temperature */ + u16 v_temp_u16 = BMI160_INIT_VALUE; + /* used for the xy1y2 read*/ + u16 v_xy1y2_u16[BMI160_YAS_XY1Y2_DATA_SIZE] = {BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE}; + /* local flag for assign the values*/ + s32 v_flag_s32[BMI160_YAS_FLAG_DATA_SIZE] = {BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE}; + u8 i, j, v_busy_u8, v_overflow_u8 = BMI160_INIT_VALUE; + + for (i = 0; i < 5; i++) { + /* set the offset values*/ + com_rslt = bmi160_bst_yas532_set_offset(v_hard_offset_s8); + /* read the sensor data*/ + com_rslt += bmi160_bst_yas532_normal_measurement_data( + BMI160_YAS532_ACQ_START, &v_busy_u8, &v_temp_u16, + v_xy1y2_u16, &v_overflow_u8); + /* check the sensor busy status*/ + if (v_busy_u8) + return E_BMI160_BUSY; + /* calculate the magnetic correction with + offset and assign the values + to the offset register */ + for (j = 0; j < 3; j++) { + if (YAS532_DATA_CENTER == v_xy1y2_u16[j]) + v_flag_s32[j] = 0; + if (YAS532_DATA_CENTER < v_xy1y2_u16[j]) + v_flag_s32[j] = 1; + if (v_xy1y2_u16[j] < YAS532_DATA_CENTER) + v_flag_s32[j] = -1; + } + for (j = 0; j < 3; j++) { + if (v_flag_s32[j]) + v_hard_offset_s8[j] = (s8)(v_hard_offset_s8[j] + + v_flag_s32[j] * v_correct_u8[i]); + } + } + /* set the offset */ + com_rslt += bmi160_bst_yas532_set_offset(v_hard_offset_s8); + return com_rslt; +} +/*! + * @brief This function used for read the + * YAMAHA YAS532 calibration data + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas532_calib_values(void) +{ + /* This variable used for provide the communication + results*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Array holding the YAS532 calibration values */ + u8 v_data_u8[BMI160_YAS532_CALIB_DATA_SIZE] = { + BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE}; + /* Read the DX value */ + com_rslt = bmi160_set_mag_read_addr(BMI160_YAS532_CALIB_CX); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[0], BMI160_GEN_READ_WRITE_DATA_LENGTH); + yas532_data.calib_yas532.cx = (s32)((v_data_u8[0] + * 10) - 1280); + /* Read the DY1 value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB_CY1); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[1], BMI160_GEN_READ_WRITE_DATA_LENGTH); + yas532_data.calib_yas532.cy1 = + (s32)((v_data_u8[1] * 10) - 1280); + /* Read the DY2 value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB_CY2); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[2], BMI160_GEN_READ_WRITE_DATA_LENGTH); + yas532_data.calib_yas532.cy2 = + (s32)((v_data_u8[2] * 10) - 1280); + /* Read the D2 and D3 value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB1); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[3], BMI160_GEN_READ_WRITE_DATA_LENGTH); + yas532_data.calib_yas532.a2 = + (s32)(((v_data_u8[3] >> + BMI160_SHIFT_BIT_POSITION_BY_02_BITS) + & 0x03F) - 32); + /* Read the D3 and D4 value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB2); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[4], BMI160_GEN_READ_WRITE_DATA_LENGTH); + /* calculate a3*/ + yas532_data.calib_yas532.a3 = (s32)((((v_data_u8[3] << + BMI160_SHIFT_BIT_POSITION_BY_02_BITS) & 0x0C) | + ((v_data_u8[4] + >> BMI160_SHIFT_BIT_POSITION_BY_06_BITS) + & 0x03)) - 8); + /* calculate a4*/ + yas532_data.calib_yas532.a4 = (s32)((v_data_u8[4] + & 0x3F) - 32); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* Read the D5 and D6 value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB3); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[5], BMI160_GEN_READ_WRITE_DATA_LENGTH); + /* calculate a5*/ + yas532_data.calib_yas532.a5 = + (s32)(((v_data_u8[5] + >> BMI160_SHIFT_BIT_POSITION_BY_02_BITS) + & 0x3F) + 38); + /* Read the D6 and D7 value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB4); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[6], BMI160_GEN_READ_WRITE_DATA_LENGTH); + /* calculate a6*/ + yas532_data.calib_yas532.a6 = + (s32)((((v_data_u8[5] + << BMI160_SHIFT_BIT_POSITION_BY_04_BITS) + & 0x30) | ((v_data_u8[6] >> + BMI160_SHIFT_BIT_POSITION_BY_04_BITS) + & 0x0F)) - 32); + /* Read the D7 and D8 value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB5); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[7], BMI160_GEN_READ_WRITE_DATA_LENGTH); + /* calculate a7*/ + yas532_data.calib_yas532.a7 = (s32)((((v_data_u8[6] + << BMI160_SHIFT_BIT_POSITION_BY_03_BITS) + & 0x78) | + ((v_data_u8[7] + >> BMI160_SHIFT_BIT_POSITION_BY_05_BITS) & + 0x07)) - 64); + /* Read the D8 and D9 value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CLAIB6); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[8], BMI160_GEN_READ_WRITE_DATA_LENGTH); + /* calculate a8*/ + yas532_data.calib_yas532.a8 = (s32)((((v_data_u8[7] << + BMI160_GEN_READ_WRITE_DATA_LENGTH) & 0x3E) | + ((v_data_u8[8] >> + BMI160_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01)) - + 32); + + /* Read the D8 and D9 value */ + com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB7); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[9], BMI160_GEN_READ_WRITE_DATA_LENGTH); + /* calculate a9*/ + yas532_data.calib_yas532.a9 = (s32)(((v_data_u8[8] << + BMI160_GEN_READ_WRITE_DATA_LENGTH) & 0xFE) | + ((v_data_u8[9] >> + BMI160_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01)); + /* calculate k*/ + yas532_data.calib_yas532.k = (s32)((v_data_u8[9] >> + BMI160_SHIFT_BIT_POSITION_BY_02_BITS) & 0x1F); + /* Read the value from register 0x9A*/ + com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB8); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[10], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + /* Read the value from register 0x9B*/ + com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIIB9); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[11], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + /* Read the value from register 0x9C*/ + com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB10); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[12], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + /* Read the value from register 0x9D*/ + com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB11); + /* 0x04 is secondary read mag x lsb register */ + com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, + &v_data_u8[13], + BMI160_GEN_READ_WRITE_DATA_LENGTH); + /* Calculate the fxy1y2 and rxy1y1*/ + yas532_data.calib_yas532.fxy1y2[0] = + (u8)(((v_data_u8[10] + & 0x01) + << BMI160_SHIFT_BIT_POSITION_BY_01_BIT) + | ((v_data_u8[11] >> + BMI160_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01)); + yas532_data.calib_yas532.rxy1y2[0] = + ((s8)(((v_data_u8[10] + >> BMI160_SHIFT_BIT_POSITION_BY_01_BIT) & 0x3F) + << BMI160_SHIFT_BIT_POSITION_BY_02_BITS)) + >> BMI160_SHIFT_BIT_POSITION_BY_02_BITS; + yas532_data.calib_yas532.fxy1y2[1] = + (u8)(((v_data_u8[11] & 0x01) + << BMI160_SHIFT_BIT_POSITION_BY_01_BIT) + | ((v_data_u8[12] >> + BMI160_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01)); + yas532_data.calib_yas532.rxy1y2[1] = + ((s8)(((v_data_u8[11] + >> BMI160_SHIFT_BIT_POSITION_BY_01_BIT) & 0x3F) + << BMI160_SHIFT_BIT_POSITION_BY_02_BITS)) + >> BMI160_SHIFT_BIT_POSITION_BY_02_BITS; + yas532_data.calib_yas532.fxy1y2[2] = + (u8)(((v_data_u8[12] & 0x01) + << BMI160_SHIFT_BIT_POSITION_BY_01_BIT) + | ((v_data_u8[13] + >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01)); + yas532_data.calib_yas532.rxy1y2[2] = + ((s8)(((v_data_u8[12] + >> BMI160_SHIFT_BIT_POSITION_BY_01_BIT) & 0x3F) + << BMI160_SHIFT_BIT_POSITION_BY_02_BITS)) + >> BMI160_SHIFT_BIT_POSITION_BY_02_BITS; + + return com_rslt; +} +/*! + * @brief This function used for calculate the + * YAS532 read the linear data + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_xy1y2_to_linear( +u16 *v_xy1y2_u16, s32 *xy1y2_linear) +{ + /* This variable used for provide the communication + results*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = SUCCESS; + static const u16 v_calib_data[] = { + 3721, 3971, 4221, 4471}; + u8 i = BMI160_INIT_VALUE; + + for (i = 0; i < 3; i++) + xy1y2_linear[i] = v_xy1y2_u16[i] - + v_calib_data[yas532_data.calib_yas532.fxy1y2[i]] + + (yas532_data.v_hard_offset_s8[i] - + yas532_data.calib_yas532.rxy1y2[i]) + * yas532_data.coef[i]; + return com_rslt; +} +/*! + * @brief This function used for read the YAS532 sensor data + * @param v_acquisition_command_u8: used to set the data acquisition + * acquisition_command | operation + * ---------------------|------------------------- + * 0x17 | turn on the acquisition coil + * - | set direction of the coil + * _ | (x and y as minus(-)) + * _ | Deferred acquisition mode + * 0x07 | turn on the acquisition coil + * _ | set direction of the coil + * _ | (x and y as minus(-)) + * _ | Normal acquisition mode + * 0x11 | turn OFF the acquisition coil + * _ | set direction of the coil + * _ | (x and y as plus(+)) + * _ | Deferred acquisition mode + * 0x01 | turn OFF the acquisition coil + * _ | set direction of the coil + * _ | (x and y as plus(+)) + * _ | Normal acquisition mode + * + * @param v_busy_u8 : used to get the busy flay for sensor data read + * @param v_temp_u16 : used to get the temperature data + * @param v_xy1y2_u16 : used to get the sensor xy1y2 data + * @param v_overflow_u8 : used to get the overflow data + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_normal_measurement_data( +u8 v_acquisition_command_u8, u8 *v_busy_u8, +u16 *v_temp_u16, u16 *v_xy1y2_u16, u8 *v_overflow_u8) +{ + /* This variable used for provide the communication + results*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = BMI160_INIT_VALUE; + /* Array holding the YAS532 xyy1 data*/ + u8 v_data_u8[BMI160_YAS_XY1Y2T_DATA_SIZE] = { + BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE}; + u8 i = BMI160_INIT_VALUE; + /* check the p_bmi160 structure as NULL*/ + if (p_bmi160 == BMI160_NULL) { + return E_BMI160_NULL_PTR; + } else { + /* read the sensor data */ + com_rslt = bmi160_bst_yas532_acquisition_command_register( + v_acquisition_command_u8); + com_rslt += + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_DATA_MAG_X_LSB__REG, + v_data_u8, BMI160_MAG_YAS_DATA_LENGTH); + /* read the xyy1 data*/ + *v_busy_u8 = + ((v_data_u8[0] + >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01); + *v_temp_u16 = + (u16)((((s32)v_data_u8[0] + << BMI160_SHIFT_BIT_POSITION_BY_03_BITS) + & 0x3F8) | ((v_data_u8[1] + >> BMI160_SHIFT_BIT_POSITION_BY_05_BITS) & 0x07)); + v_xy1y2_u16[0] = + (u16)((((s32)v_data_u8[2] + << BMI160_SHIFT_BIT_POSITION_BY_06_BITS) & 0x1FC0) + | ((v_data_u8[3] >> + BMI160_SHIFT_BIT_POSITION_BY_02_BITS) & 0x3F)); + v_xy1y2_u16[1] = + (u16)((((s32)v_data_u8[4] + << BMI160_SHIFT_BIT_POSITION_BY_06_BITS) + & 0x1FC0) + | ((v_data_u8[5] + >> BMI160_SHIFT_BIT_POSITION_BY_02_BITS) & 0x3F)); + v_xy1y2_u16[2] = + (u16)((((s32)v_data_u8[6] + << BMI160_SHIFT_BIT_POSITION_BY_06_BITS) + & 0x1FC0) + | ((v_data_u8[7] + >> BMI160_SHIFT_BIT_POSITION_BY_02_BITS) & 0x3F)); + *v_overflow_u8 = 0; + for (i = 0; i < 3; i++) { + if (v_xy1y2_u16[i] == YAS532_DATA_OVERFLOW) + *v_overflow_u8 |= (1 << (i * 2)); + if (v_xy1y2_u16[i] == YAS532_DATA_UNDERFLOW) + *v_overflow_u8 |= (1 << (i * 2 + 1)); + } + } + return com_rslt; +} +/*! + * @brief This function used for YAS532 sensor data + * @param v_acquisition_command_u8 : the value of CMDR + * acquisition_command | operation + * ---------------------|------------------------- + * 0x17 | turn on the acquisition coil + * - | set direction of the coil + * _ | (x and y as minus(-)) + * _ | Deferred acquisition mode + * 0x07 | turn on the acquisition coil + * _ | set direction of the coil + * _ | (x and y as minus(-)) + * _ | Normal acquisition mode + * 0x11 | turn OFF the acquisition coil + * _ | set direction of the coil + * _ | (x and y as plus(+)) + * _ | Deferred acquisition mode + * 0x01 | turn OFF the acquisition coil + * _ | set direction of the coil + * _ | (x and y as plus(+)) + * _ | Normal acquisition mode + * + * @param xyz_data : the vector xyz output + * @param v_overflow_s8 : the value of overflow + * @param v_temp_correction_u8 : the value of temperate correction enable + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_measurement_xyz_data( +struct yas532_vector *xyz_data, u8 *v_overflow_s8, u8 v_temp_correction_u8, +u8 v_acquisition_command_u8) +{ + /* This variable used for provide the communication + results*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = BMI160_INIT_VALUE; + /* Array holding the linear calculation output*/ + s32 v_xy1y2_linear_s32[BMI160_YAS_XY1Y2_DATA_SIZE] = { + BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE}; + /* Array holding the temperature data */ + s32 v_xyz_tmp_s32[BMI160_YAS_TEMP_DATA_SIZE] = {BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE}; + s32 tmp = BMI160_INIT_VALUE; + s32 sx, sy1, sy2, sy, sz = BMI160_INIT_VALUE; + u8 i, v_busy_u8 = BMI160_INIT_VALUE; + u16 v_temp_u16 = BMI160_INIT_VALUE; + /* Array holding the xyy1 sensor raw data*/ + u16 v_xy1y2_u16[BMI160_YAS_XY1Y2_DATA_SIZE] = {BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE}; + #if YAS532_MAG_LOG < YAS532_MAG_TEMPERATURE_LOG + s32 sum = BMI160_INIT_VALUE; + #endif + *v_overflow_s8 = BMI160_INIT_VALUE; + switch (yas532_data.measure_state) { + case YAS532_MAG_STATE_INIT_COIL: + if (p_bmi160->mag_manual_enable != BMI160_MANUAL_ENABLE) + com_rslt = bmi160_set_mag_manual_enable( + BMI160_MANUAL_ENABLE); + /* write Rcoil*/ + com_rslt += bmi160_set_mag_write_data( + BMI160_YAS_DISABLE_RCOIL); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr(BMI160_YAS532_RCOIL); + p_bmi160->delay_msec(BMI160_YAS532_MEASUREMENT_DELAY); + if (!yas532_data.overflow && is_valid_offset( + yas532_data.v_hard_offset_s8)) + yas532_data.measure_state = 0; + break; + case YAS532_MAG_STATE_MEASURE_OFFSET: + com_rslt = bmi160_bst_yas532_magnetic_measure_set_offset(); + yas532_data.measure_state = 0; + break; + default: + break; + } + /* Read sensor data*/ + com_rslt += bmi160_bst_yas532_normal_measurement_data( + v_acquisition_command_u8, &v_busy_u8, &v_temp_u16, + v_xy1y2_u16, v_overflow_s8); + /* Calculate the linear data*/ + com_rslt += bmi160_bst_yas532_xy1y2_to_linear(v_xy1y2_u16, + v_xy1y2_linear_s32); + /* Calculate temperature correction */ + #if YAS532_MAG_LOG < YAS532_MAG_TEMPERATURE_LOG + yas532_data.temp_data.log[yas532_data.temp_data.idx++] = + v_temp_u16; + if (YAS532_MAG_TEMPERATURE_LOG <= yas532_data.temp_data.idx) + yas532_data.temp_data.idx = 0; + yas532_data.temp_data.num++; + if (YAS532_MAG_TEMPERATURE_LOG <= yas532_data.temp_data.num) + yas532_data.temp_data.num = YAS532_MAG_TEMPERATURE_LOG; + for (i = 0; i < yas532_data.temp_data.num; i++) + sum += yas532_data.temp_data.log[i]; + tmp = sum * 10 / yas532_data.temp_data.num + - YAS532_TEMP20DEGREE_TYPICAL * 10; + #else + tmp = (v_temp_u16 - YAS532_TEMP20DEGREE_TYPICAL) + * 10; + #endif + sx = v_xy1y2_linear_s32[0]; + sy1 = v_xy1y2_linear_s32[1]; + sy2 = v_xy1y2_linear_s32[2]; + /* Temperature correction */ + if (v_temp_correction_u8) { + sx -= (yas532_data.calib_yas532.cx * tmp) + / 1000; + sy1 -= (yas532_data.calib_yas532.cy1 * tmp) + / 1000; + sy2 -= (yas532_data.calib_yas532.cy2 * tmp) + / 1000; + } + sy = sy1 - sy2; + sz = -sy1 - sy2; + + xyz_data->yas532_vector_xyz[0] = yas532_data.calib_yas532.k * + ((100 * sx + yas532_data.calib_yas532.a2 * sy + + yas532_data.calib_yas532.a3 * sz) / 10); + xyz_data->yas532_vector_xyz[1] = yas532_data.calib_yas532.k * + ((yas532_data.calib_yas532.a4 * sx + yas532_data.calib_yas532.a5 * sy + + yas532_data.calib_yas532.a6 * sz) / 10); + xyz_data->yas532_vector_xyz[2] = yas532_data.calib_yas532.k * + ((yas532_data.calib_yas532.a7 * sx + yas532_data.calib_yas532.a8 * sy + + yas532_data.calib_yas532.a9 * sz) / 10); + if (yas532_data.transform != BMI160_NULL) { + for (i = 0; i < 3; i++) { + v_xyz_tmp_s32[i] = yas532_data.transform[i + * 3] * + xyz_data->yas532_vector_xyz[0] + + yas532_data.transform[i * 3 + 1] * + xyz_data->yas532_vector_xyz[1] + + yas532_data.transform[i * 3 + 2] * + xyz_data->yas532_vector_xyz[2]; + } + set_vector(xyz_data->yas532_vector_xyz, v_xyz_tmp_s32); + } + for (i = 0; i < 3; i++) { + xyz_data->yas532_vector_xyz[i] -= + xyz_data->yas532_vector_xyz[i] % 10; + if (*v_overflow_s8 & (1 + << (i * 2))) + xyz_data->yas532_vector_xyz[i] += + 1; /* set overflow */ + if (*v_overflow_s8 & (1 << + (i * 2 + 1))) + xyz_data->yas532_vector_xyz[i] += 2; /* set underflow */ + } + + +if (v_busy_u8) + return com_rslt; + if (0 < *v_overflow_s8) { + if (!yas532_data.overflow) + yas532_data.overflow = 1; + yas532_data.measure_state = YAS532_MAG_STATE_INIT_COIL; + } else + yas532_data.overflow = 0; + for (i = 0; i < 3; i++) + yas532_data.last_raw[i] = v_xy1y2_u16[i]; + yas532_data.last_raw[i] = v_temp_u16; + return com_rslt; +} +/*! + * @brief This function used for YAS532 write data acquisition + * command register write + * @param v_command_reg_data_u8 : the value of data acquisition + * acquisition_command | operation + * ---------------------|------------------------- + * 0x17 | turn on the acquisition coil + * - | set direction of the coil + * _ | (x and y as minus(-)) + * _ | Deferred acquisition mode + * 0x07 | turn on the acquisition coil + * _ | set direction of the coil + * _ | (x and y as minus(-)) + * _ | Normal acquisition mode + * 0x11 | turn OFF the acquisition coil + * _ | set direction of the coil + * _ | (x and y as plus(+)) + * _ | Deferred acquisition mode + * 0x01 | turn OFF the acquisition coil + * _ | set direction of the coil + * _ | (x and y as plus(+)) + * _ | Normal acquisition mode + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_acquisition_command_register( +u8 v_command_reg_data_u8) +{ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + + if (p_bmi160->mag_manual_enable != BMI160_MANUAL_ENABLE) + com_rslt = bmi160_set_mag_manual_enable( + BMI160_MANUAL_ENABLE); + + com_rslt = bmi160_set_mag_write_data(v_command_reg_data_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* YAMAHA YAS532-0x82*/ + com_rslt += bmi160_set_mag_write_addr( + BMI160_YAS532_COMMAND_REGISTER); + p_bmi160->delay_msec(BMI160_YAS_ACQ_COMMAND_DELAY); + com_rslt += bmi160_set_mag_read_addr( + BMI160_YAS532_DATA_REGISTER); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + + if (p_bmi160->mag_manual_enable == BMI160_MANUAL_ENABLE) + com_rslt += bmi160_set_mag_manual_enable(BMI160_MANUAL_DISABLE); + + return com_rslt; + +} +/*! + * @brief This function used write offset of YAS532 + * + * @param p_offset_s8 : The value of offset to write + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_set_offset( +const s8 *p_offset_s8) +{ + /* This variable used for provide the communication + results*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + + if (p_bmi160->mag_manual_enable != BMI160_MANUAL_ENABLE) + com_rslt = bmi160_set_mag_manual_enable(BMI160_MANUAL_ENABLE); + p_bmi160->delay_msec(BMI160_YAS532_OFFSET_DELAY); + + /* Write offset X data*/ + com_rslt = bmi160_set_mag_write_data(p_offset_s8[0]); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* YAS532 offset x write*/ + com_rslt += bmi160_set_mag_write_addr(BMI160_YAS532_OFFSET_X); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + + /* Write offset Y data*/ + com_rslt = bmi160_set_mag_write_data(p_offset_s8[1]); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* YAS532 offset y write*/ + com_rslt += bmi160_set_mag_write_addr(BMI160_YAS532_OFFSET_Y); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + + /* Write offset Z data*/ + com_rslt = bmi160_set_mag_write_data(p_offset_s8[2]); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* YAS532 offset z write*/ + com_rslt += bmi160_set_mag_write_addr(BMI160_YAS532_OFFSET_Z); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + set_vector(yas532_data.v_hard_offset_s8, p_offset_s8); + + if (p_bmi160->mag_manual_enable == BMI160_MANUAL_ENABLE) + com_rslt = bmi160_set_mag_manual_enable(BMI160_MANUAL_DISABLE); + return com_rslt; +} +/*! + * @brief This function used to init the YAMAH-YAS537 + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas537_mag_interface_init( +void) +{ +/* This variable used for provide the communication +results*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +u8 v_pull_value_u8 = BMI160_INIT_VALUE; +u8 v_data_u8 = BMI160_INIT_VALUE; +u8 i = BMI160_INIT_VALUE; +/* accel operation mode to normal*/ +com_rslt = bmi160_set_command_register(ACCEL_MODE_NORMAL); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* write mag power mode as NORMAL*/ +com_rslt += bmi160_set_mag_interface_normal(); +/* register 0x7E write the 0x37, 0x9A and 0x30*/ +com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_ONE); +p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); +com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_TWO); +p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); +com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_THREE); +p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); +/*switch the page1*/ +com_rslt += bmi160_set_target_page(BMI160_WRITE_TARGET_PAGE1); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +bmi160_get_target_page(&v_data_u8); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +com_rslt += bmi160_set_paging_enable(BMI160_WRITE_ENABLE_PAGE1); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +bmi160_get_paging_enable(&v_data_u8); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* enable the pullup configuration from +the register 0x05 bit 4 and 5 as 10*/ +bmi160_get_pullup_configuration(&v_pull_value_u8); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +v_pull_value_u8 = v_pull_value_u8 | BMI160_PULL_UP_DATA; +com_rslt += bmi160_set_pullup_configuration(v_pull_value_u8); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/*switch the page0*/ +com_rslt += bmi160_set_target_page(BMI160_WRITE_TARGET_PAGE0); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +bmi160_get_target_page(&v_data_u8); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* Write the YAS532 i2c address*/ +com_rslt += bmi160_set_i2c_device_addr(BMI160_YAS537_I2C_ADDRESS); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* enable the mag interface to manual mode*/ +com_rslt += bmi160_set_mag_manual_enable(BMI160_MANUAL_ENABLE); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +bmi160_get_mag_manual_enable(&v_data_u8); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/*Enable the MAG interface */ +com_rslt += bmi160_set_if_mode(BMI160_ENABLE_MAG_IF_MODE); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +bmi160_get_if_mode(&v_data_u8); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +v_data_u8 = BMI160_MANUAL_DISABLE; +/* Read the YAS537 device id*/ +com_rslt += bmi160_set_mag_read_addr(BMI160_YAS_DEVICE_ID_REG); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, +&v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH); +yas537_data.dev_id = v_data_u8; +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* Read the YAS532 calibration data*/ +com_rslt += +bmi160_bst_yamaha_yas537_calib_values( +BMI160_GEN_READ_WRITE_DATA_LENGTH); +p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); +/* set the mode to NORMAL*/ +yas537_data.measure_state = YAS537_MAG_STATE_NORMAL; +/* set the transform to zero */ +yas537_data.transform = BMI160_NULL; +yas537_data.average = 32; +for (i = 0; i < 3; i++) { + yas537_data.hard_offset[i] = -128; + yas537_data.last_after_rcoil[i] = 0; +} +for (i = 0; i < 4; i++) + yas537_data.last_raw[i] = 0; +/* write the mag bandwidth as 25Hz*/ +com_rslt += bmi160_set_mag_output_data_rate( +BMI160_MAG_OUTPUT_DATA_RATE_25HZ); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* Enable mag interface to auto mode*/ +com_rslt += bmi160_set_mag_manual_enable( +BMI160_MANUAL_DISABLE); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +bmi160_get_mag_manual_enable(&v_data_u8); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +return com_rslt; +} +/*! +* @brief This function used for read the +* YAMAHA YAS537 calibration data +* +* +* @param v_rcoil_u8 : The value of r coil +* +* +* @return results of bus communication function +* @retval 0 -> Success +* @retval -1 -> Error +* +* +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas537_calib_values( +u8 v_rcoil_u8) +{ +/* This variable used for provide the communication +results*/ +BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; +/* Array holding the YAS532 calibration values */ +u8 a_data_u8[BMI160_YAS537_CALIB_DATA_SIZE] = { +BMI160_INIT_VALUE, BMI160_INIT_VALUE, +BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE, +BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE, +BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE, +BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE, +BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE, +}; +static const u8 v_avrr_u8[] = {0x50, 0x60, 0x70}; +u8 v_cal_valid_u8 = BMI160_INIT_VALUE, i; +/* write soft reset as 0x02*/ +com_rslt = bmi160_set_mag_write_data( +YAS537_SRSTR_DATA); +p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); +com_rslt += bmi160_set_mag_write_addr(YAS537_REG_SRSTR); +p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); +/* Read the DX value */ +com_rslt = bmi160_set_mag_read_addr(YAS537_REG_CALR_C0); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* 0x04 is secondary read mag x lsb register */ +com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, +&a_data_u8[0], BMI160_GEN_READ_WRITE_DATA_LENGTH); +/* Read the DY1 value */ +com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_C1); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* 0x04 is secondary read mag x lsb register */ +com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, +&a_data_u8[1], BMI160_GEN_READ_WRITE_DATA_LENGTH); +/* Read the DY2 value */ +com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_C2); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* 0x04 is secondary read mag x lsb register */ +com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, +&a_data_u8[2], BMI160_GEN_READ_WRITE_DATA_LENGTH); +/* Read the D2 value */ +com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_C3); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* 0x04 is secondary read mag x lsb register */ +com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, +&a_data_u8[3], BMI160_GEN_READ_WRITE_DATA_LENGTH); +/* Read the D3 value */ +com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_C4); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* 0x04 is secondary read mag x lsb register */ +com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, +&a_data_u8[4], BMI160_GEN_READ_WRITE_DATA_LENGTH); +/* Read the D4 value */ +com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_C5); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* 0x04 is secondary read mag x lsb register */ +com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, +&a_data_u8[5], BMI160_GEN_READ_WRITE_DATA_LENGTH); +/* Read the D5 value */ +com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_C6); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* 0x04 is secondary read mag x lsb register */ +com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, +&a_data_u8[6], BMI160_GEN_READ_WRITE_DATA_LENGTH); +/* Read the D6 value */ +com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_C7); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* 0x04 is secondary read mag x lsb register */ +com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, +&a_data_u8[7], BMI160_GEN_READ_WRITE_DATA_LENGTH); +/* Read the D7 value */ +com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_C8); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* 0x04 is secondary read mag x lsb register */ +com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, +&a_data_u8[8], BMI160_GEN_READ_WRITE_DATA_LENGTH); +/* Read the D8 value */ +com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_C9); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* 0x04 is secondary read mag x lsb register */ +com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, +&a_data_u8[9], BMI160_GEN_READ_WRITE_DATA_LENGTH); +/* Read the D9 value */ +com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_CA); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* 0x04 is secondary read mag x lsb register */ +com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, +&a_data_u8[10], BMI160_GEN_READ_WRITE_DATA_LENGTH); +/* Read the RX value */ +com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_CB); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* 0x04 is secondary read mag x lsb register */ +com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, +&a_data_u8[11], BMI160_GEN_READ_WRITE_DATA_LENGTH); +/* Read the RY1 value */ +com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_CC); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* 0x04 is secondary read mag x lsb register */ +com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, +&a_data_u8[12], BMI160_GEN_READ_WRITE_DATA_LENGTH); +/* Read the RY2 value */ +com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_CD); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* 0x04 is secondary read mag x lsb register */ +com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, +&a_data_u8[13], BMI160_GEN_READ_WRITE_DATA_LENGTH); +/* Read the RY2 value */ +com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_CE); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* 0x04 is secondary read mag x lsb register */ +com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, +&a_data_u8[14], BMI160_GEN_READ_WRITE_DATA_LENGTH); +/* Read the CHF value */ +com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_CF); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* 0x04 is secondary read mag x lsb register */ +com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, +&a_data_u8[15], BMI160_GEN_READ_WRITE_DATA_LENGTH); +/* Read the VER value */ +com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_DO); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +/* 0x04 is secondary read mag x lsb register */ +com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG, +&a_data_u8[16], BMI160_GEN_READ_WRITE_DATA_LENGTH); +/* get the calib ver*/ +yas537_data.calib_yas537.ver = +(a_data_u8[16] >> BMI160_SHIFT_BIT_POSITION_BY_06_BITS); +for (i = 0; i < 17; i++) { + if (((i < 16 && a_data_u8[i]) != 0)) + v_cal_valid_u8 = 1; + if ((i < 16 && + (a_data_u8[i] & 0x3F)) != 0) + v_cal_valid_u8 = 1; +} +if (!v_cal_valid_u8) + return ERROR; +if (yas537_data.calib_yas537.ver == 0) { + for (i = 0; i < 17; i++) { + if (i < 12) { + /* write offset*/ + com_rslt += bmi160_set_mag_write_data( + a_data_u8[i]); + p_bmi160->delay_msec( + BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr( + YAS537_REG_MTCR + i); + p_bmi160->delay_msec( + BMI160_GEN_READ_WRITE_DELAY); + } else if (i < 15) { + /* write offset correction*/ + com_rslt += bmi160_set_mag_write_data( + a_data_u8[i]); + p_bmi160->delay_msec( + BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr(( + (YAS537_REG_OXR + i) - 12)); + p_bmi160->delay_msec( + BMI160_GEN_READ_WRITE_DELAY); + yas537_data.hard_offset[i - 12] + = a_data_u8[i]; + } else { + /* write offset correction*/ + com_rslt += bmi160_set_mag_write_data( + a_data_u8[i]); + p_bmi160->delay_msec( + BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr(( + (YAS537_REG_OXR + i) - 11)); + p_bmi160->delay_msec( + BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + } + +} +} else if (yas537_data.calib_yas537.ver == 1) { + for (i = 0; i < 3; i++) { + /* write offset*/ + com_rslt += bmi160_set_mag_write_data( + a_data_u8[i]); + p_bmi160->delay_msec( + BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr( + YAS537_REG_MTCR + i); + p_bmi160->delay_msec( + BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + if (com_rslt == SUCCESS) { + /* write offset*/ + com_rslt += bmi160_set_mag_write_data( + a_data_u8[i + 12]); + p_bmi160->delay_msec( + BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr( + YAS537_REG_OXR + i); + p_bmi160->delay_msec( + BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + yas537_data.hard_offset[i] = + a_data_u8[i + 12]; + } else { + com_rslt = ERROR; + } + } + /* write offset*/ + com_rslt += bmi160_set_mag_write_data( + ((a_data_u8[i] & 0xE0) | 0x10)); + p_bmi160->delay_msec( + BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr( + YAS537_REG_MTCR + i); + p_bmi160->delay_msec( + BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + /* write offset*/ + com_rslt += bmi160_set_mag_write_data( + ((a_data_u8[15] + >> BMI160_SHIFT_BIT_POSITION_BY_03_BITS) + & 0x1E)); + p_bmi160->delay_msec( + BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr(YAS537_REG_HCKR); + p_bmi160->delay_msec( + BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + /* write offset*/ + com_rslt += bmi160_set_mag_write_data( + ((a_data_u8[15] << 1) & 0x1E)); + p_bmi160->delay_msec( + BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr(YAS537_REG_LCKR); + p_bmi160->delay_msec( + BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + /* write offset*/ + com_rslt += bmi160_set_mag_write_data( + (a_data_u8[16] & 0x3F)); + p_bmi160->delay_msec( + BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr(YAS537_REG_OCR); + p_bmi160->delay_msec( + BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + + /* Assign the calibration values*/ + /* a2 */ + yas537_data.calib_yas537.a2 = + ((((a_data_u8[3] + << BMI160_SHIFT_BIT_POSITION_BY_02_BITS) + & 0x7C) + | (a_data_u8[4] + >> BMI160_SHIFT_BIT_POSITION_BY_06_BITS)) - 64); + /* a3 */ + yas537_data.calib_yas537.a3 = + ((((a_data_u8[4] << BMI160_SHIFT_BIT_POSITION_BY_01_BIT) + & 0x7E) + | (a_data_u8[5] + >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS)) - 64); + /* a4 */ + yas537_data.calib_yas537.a4 = + ((((a_data_u8[5] + << BMI160_SHIFT_BIT_POSITION_BY_01_BIT) + & 0xFE) + | (a_data_u8[6] + >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS)) + - 128); + /* a5 */ + yas537_data.calib_yas537.a5 = + ((((a_data_u8[6] + << BMI160_SHIFT_BIT_POSITION_BY_02_BITS) + & 0x1FC) + | (a_data_u8[7] + >> BMI160_SHIFT_BIT_POSITION_BY_06_BITS)) + - 112); + /* a6 */ + yas537_data.calib_yas537.a6 = + ((((a_data_u8[7] + << BMI160_SHIFT_BIT_POSITION_BY_01_BIT) + & 0x7E) + | (a_data_u8[8] + >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS)) - 64); + /* a7 */ + yas537_data.calib_yas537.a7 = + ((((a_data_u8[8] + << BMI160_SHIFT_BIT_POSITION_BY_01_BIT) + & 0xFE) + | (a_data_u8[9] + >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS)) + - 128); + /* a8 */ + yas537_data.calib_yas537.a8 = ((a_data_u8[9] & + 0x7F) - 64); + /* a9 */ + yas537_data.calib_yas537.a9 = ((((a_data_u8[10] + << BMI160_SHIFT_BIT_POSITION_BY_01_BIT) & 0x1FE) + | (a_data_u8[11] + >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS)) + - 112); + /* k */ + yas537_data.calib_yas537.k = ( + a_data_u8[11] & 0x7F); + } else { + return ERROR; + } +/* write A/D converter*/ +com_rslt += bmi160_set_mag_write_data( +YAS537_WRITE_A_D_CONVERTER); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +com_rslt += bmi160_set_mag_write_addr(YAS537_REG_ADCCALR); +p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); +/* write A/D converter second register*/ +com_rslt += bmi160_set_mag_write_data( +YAS537_WRITE_A_D_CONVERTER2); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +com_rslt += bmi160_set_mag_write_addr(YAS537_REG_ADCCALR_ONE); +p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); +/* write temperature calibration register*/ +com_rslt += bmi160_set_mag_write_data(YAS537_WRITE_TEMP_CALIB); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +com_rslt += bmi160_set_mag_write_addr(YAS537_REG_TRMR); +p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); +/* write average filter register*/ +com_rslt += bmi160_set_mag_write_data( +v_avrr_u8[yas537_data.average]); +p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); +com_rslt += bmi160_set_mag_write_addr(YAS537_REG_AVRR); +p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); +if (v_rcoil_u8) { + /* write average; filter register*/ + com_rslt += bmi160_set_mag_write_data( + YAS537_WRITE_FILTER); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr(YAS537_REG_CONFR); + p_bmi160->delay_msec( + BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); +} + +return com_rslt; + +} +/*! + * @brief This function used for YAS537 write data acquisition + * command register write + * @param v_command_reg_data_u8 : the value of data acquisition + * acquisition_command | operation + * ---------------------|------------------------- + * 0x17 | turn on the acquisition coil + * - | set direction of the coil + * _ | (x and y as minus(-)) + * _ | Deferred acquisition mode + * 0x07 | turn on the acquisition coil + * _ | set direction of the coil + * _ | (x and y as minus(-)) + * _ | Normal acquisition mode + * 0x11 | turn OFF the acquisition coil + * _ | set direction of the coil + * _ | (x and y as plus(+)) + * _ | Deferred acquisition mode + * 0x01 | turn OFF the acquisition coil + * _ | set direction of the coil + * _ | (x and y as plus(+)) + * _ | Normal acquisition mode + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas537_acquisition_command_register( +u8 v_command_reg_data_u8) +{ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + + if (p_bmi160->mag_manual_enable != BMI160_MANUAL_ENABLE) + com_rslt = bmi160_set_mag_manual_enable( + BMI160_MANUAL_ENABLE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + + com_rslt = bmi160_set_mag_write_data(v_command_reg_data_u8); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + /* YAMAHA YAS532-0x82*/ + com_rslt += bmi160_set_mag_write_addr( + BMI160_REG_YAS537_CMDR); + /* set the mode to RECORD*/ + yas537_data.measure_state = YAS537_MAG_STATE_RECORD_DATA; + p_bmi160->delay_msec(BMI160_YAS_ACQ_COMMAND_DELAY); + com_rslt += bmi160_set_mag_read_addr( + YAS537_REG_TEMPERATURE_0); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + + if (p_bmi160->mag_manual_enable == BMI160_MANUAL_ENABLE) + com_rslt += bmi160_set_mag_manual_enable( + BMI160_MANUAL_DISABLE); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + + return com_rslt; + +} +/*! + * @brief This function used for read the + * YAMAHA YAS537 xy1y2 data + * + * @param xy1y2: The value of raw xy1y2 data + * @param xyz: The value of xyz data + * + * + * @return None + * + * + */ +static void xy1y2_to_xyz(u16 *xy1y2, s32 *xyz) +{ + xyz[0] = ((xy1y2[0] - 8192) + * 300); + xyz[1] = (((xy1y2[1] - xy1y2[2]) + * 1732) / 10); + xyz[2] = (((-xy1y2[2] - xy1y2[2]) + + 16384) * 300); +} +/*! + * @brief This function used for read the + * YAMAHA YAS537 xy1y2 data + * + * @param v_coil_stat_u8: The value of R coil status + * @param v_busy_u8: The value of busy status + * @param v_temperature_u16: The value of temperature + * @param xy1y2: The value of raw xy1y2 data + * @param v_ouflow_u8: The value of overflow + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas537_read_xy1y2_data( +u8 *v_coil_stat_u8, u8 *v_busy_u8, +u16 *v_temperature_u16, u16 *xy1y2, u8 *v_ouflow_u8) +{ + /* This variable used for provide the communication + results*/ + BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES; + /* Array holding the YAS532 calibration values */ + u8 a_data_u8[BMI160_YAS_XY1Y2T_DATA_SIZE] = { + BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE, + BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE, + }; + u8 i = BMI160_INIT_VALUE; + s32 a_h_s32[BMI160_YAS_H_DATA_SIZE] = { + BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE}; + s32 a_s_s32[BMI160_YAS_S_DATA_SIZE] = { + BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE}; + /* set command register*/ + com_rslt = bmi160_bst_yas537_acquisition_command_register( + YAS537_SET_COMMAND_REGISTER); + /* read the yas537 sensor data of xy1y2*/ + com_rslt += + p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr, + BMI160_USER_DATA_MAG_X_LSB__REG, + a_data_u8, BMI160_MAG_YAS_DATA_LENGTH); + /* read the busy flag*/ + *v_busy_u8 = a_data_u8[2] + >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS; + /* read the coil status*/ + *v_coil_stat_u8 = + ((a_data_u8[2] >> + BMI160_SHIFT_BIT_POSITION_BY_06_BITS) & 0X01); + /* read temperature data*/ + *v_temperature_u16 = (u16)((a_data_u8[0] + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | a_data_u8[1]); + /* read x data*/ + xy1y2[0] = (u16)(((a_data_u8[2] & + 0x3F) + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) + | (a_data_u8[3])); + /* read y1 data*/ + xy1y2[1] = (u16)((a_data_u8[4] + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) + | a_data_u8[5]); + /* read y2 data*/ + xy1y2[2] = (u16)((a_data_u8[6] + << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) + | a_data_u8[7]); + for (i = 0; i < 3; i++) + yas537_data.last_raw[i] = xy1y2[i]; + yas537_data.last_raw[i] = *v_temperature_u16; + if (yas537_data.calib_yas537.ver == 1) { + for (i = 0; i < 3; i++) + a_s_s32[i] = xy1y2[i] - 8192; + /* read hx*/ + a_h_s32[0] = ((yas537_data.calib_yas537.k * ( + (128 * a_s_s32[0]) + + (yas537_data.calib_yas537.a2 * a_s_s32[1]) + + (yas537_data.calib_yas537.a3 * a_s_s32[2]))) + / (8192)); + /* read hy1*/ + a_h_s32[1] = ((yas537_data.calib_yas537.k * ( + (yas537_data.calib_yas537.a4 * a_s_s32[0]) + + (yas537_data.calib_yas537.a5 * a_s_s32[1]) + + (yas537_data.calib_yas537.a6 * a_s_s32[2]))) + / (8192)); + /* read hy2*/ + a_h_s32[2] = ((yas537_data.calib_yas537.k * ( + (yas537_data.calib_yas537.a7 * a_s_s32[0]) + + (yas537_data.calib_yas537.a8 * a_s_s32[1]) + + (yas537_data.calib_yas537.a9 * a_s_s32[2]))) + / (8192)); + + for (i = 0; i < 3; i++) { + if (a_h_s32[i] < -8192) + a_h_s32[i] = -8192; + + if (8192 < a_h_s32[i]) + a_h_s32[i] = 8192; + + xy1y2[i] = a_h_s32[i] + 8192; + + } + } + *v_ouflow_u8 = 0; + for (i = 0; i < 3; i++) { + if (YAS537_DATA_OVERFLOW <= xy1y2[i]) + *v_ouflow_u8 |= (1 << (i * 2)); + if (xy1y2[i] == YAS537_DATA_UNDERFLOW) + *v_ouflow_u8 |= (1 << (i * 2 + 1)); + } + + return com_rslt; + +} +/*! + * @brief This function used for read the + * YAMAHA YAS537 xy1y2 data + * + * @param v_ouflow_u8: The value of overflow + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +static BMI160_RETURN_FUNCTION_TYPE invalid_magnetic_field( +u16 *v_cur_u16, u16 *v_last_u16) +{ + s16 invalid_thresh[] = {1500, 1500, 1500}; + u8 i = BMI160_INIT_VALUE; + + for (i = 0; i < 3; i++) + if (invalid_thresh[i] < ABS(v_cur_u16[i] - v_last_u16[i])) + return 1; + return 0; +} +/*! + * @brief This function used for read the + * YAMAHA YAS537 xy1y2 data + * + * @param v_ouflow_u8: The value of overflow + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas537_measure_xyz_data( +u8 *v_ouflow_u8, struct yas_vector *vector_xyz) +{ + s32 a_xyz_tmp_s32[BMI160_YAS_TEMP_DATA_SIZE] = { + BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE}; + u8 i = BMI160_INIT_VALUE; + s8 com_rslt = BMI160_INIT_VALUE; + u8 v_busy_u8 = BMI160_INIT_VALUE; + u8 v_rcoil_u8 = BMI160_INIT_VALUE; + u16 v_temperature_u16 = BMI160_INIT_VALUE; + u16 a_xy1y2_u16[BMI160_YAS_XY1Y2_DATA_SIZE] = { + BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE}; + *v_ouflow_u8 = 0; + /* read the yas537 xy1y2 data*/ + com_rslt = bmi160_bst_yamaha_yas537_read_xy1y2_data( + &v_rcoil_u8, &v_busy_u8, + &v_temperature_u16, a_xy1y2_u16, v_ouflow_u8); + /* linear calculation*/ + xy1y2_to_xyz(a_xy1y2_u16, vector_xyz->yas537_vector_xyz); + if (yas537_data.transform != BMI160_NULL) { + for (i = 0; i < 3; i++) { + a_xyz_tmp_s32[i] = (( + yas537_data.transform[i + 3] + * vector_xyz->yas537_vector_xyz[0]) + + (yas537_data.transform[ + i * 3 + 1] + * vector_xyz->yas537_vector_xyz[1]) + + (yas537_data.transform[ + i * 3 + 2] + * vector_xyz->yas537_vector_xyz[2])); + } + yas537_set_vector( + vector_xyz->yas537_vector_xyz, a_xyz_tmp_s32); + } + for (i = 0; i < 3; i++) { + vector_xyz->yas537_vector_xyz[i] -= + vector_xyz->yas537_vector_xyz[i] % 10; + if (*v_ouflow_u8 & (1 << + (i * 2))) + vector_xyz->yas537_vector_xyz[i] += + 1; /* set overflow */ + if (*v_ouflow_u8 & (1 << (i * 2 + 1))) + /* set underflow */ + vector_xyz->yas537_vector_xyz[i] += 2; + } + if (v_busy_u8) + return ERROR; + switch (yas537_data.measure_state) { + case YAS537_MAG_STATE_INIT_COIL: + if (p_bmi160->mag_manual_enable != BMI160_MANUAL_ENABLE) + com_rslt = bmi160_set_mag_manual_enable( + BMI160_MANUAL_ENABLE); + com_rslt += bmi160_set_mag_write_data(YAS537_WRITE_CONFR); + p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY); + com_rslt += bmi160_set_mag_write_addr(YAS537_REG_CONFR); + p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + yas537_data.measure_state = YAS537_MAG_STATE_RECORD_DATA; + if (p_bmi160->mag_manual_enable == BMI160_MANUAL_ENABLE) + com_rslt = bmi160_set_mag_manual_enable( + BMI160_MANUAL_DISABLE); + break; + case YAS537_MAG_STATE_RECORD_DATA: + if (v_rcoil_u8) + break; + yas537_set_vector(yas537_data.last_after_rcoil, a_xy1y2_u16); + yas537_data.measure_state = YAS537_MAG_STATE_NORMAL; + break; + case YAS537_MAG_STATE_NORMAL: + if (BMI160_INIT_VALUE < v_ouflow_u8 + || invalid_magnetic_field(a_xy1y2_u16, + yas537_data.last_after_rcoil)) { + yas537_data.measure_state = YAS537_MAG_STATE_INIT_COIL; + for (i = 0; i < 3; i++) { + if (!*v_ouflow_u8) + vector_xyz->yas537_vector_xyz[i] += 3; + } + } + break; + } + + return com_rslt; +} +/*! + * @brief This function used for reading + * bmi160_t structure + * + * @return the reference and values of bmi160_t + * + * +*/ +struct bmi160_t *bmi160_get_ptr(void) +{ + return p_bmi160; +} diff --git a/drivers/input/misc/bmi160.h b/drivers/input/misc/bmi160.h new file mode 100755 index 0000000000000..1c1b4355cc2ed --- /dev/null +++ b/drivers/input/misc/bmi160.h @@ -0,0 +1,11814 @@ +/* +**************************************************************************** +* Copyright (C) 2014 Bosch Sensortec GmbH +* +* bmi160.h +* Date : 2015/04/02 +* @id "2e89046" +* Revision : 2.0.9 $ +* @brief +* The head file of BMI160API +* +**************************************************************************** +* +* \section Disclaimer +* +* Common: +* Bosch Sensortec products are developed for the consumer goods industry. +* They may only be used within the parameters of the respective valid +* product data sheet. Bosch Sensortec products are provided with the +* express understanding that there is no warranty of fitness for a +* particular purpose.They are not fit for use in life-sustaining, +* safety or security sensitive systems or any system or device +* that may lead to bodily harm or property damage if the system +* or device malfunctions. In addition,Bosch Sensortec products are +* not fit for use in products which interact with motor vehicle systems. +* The resale and or use of products are at the purchasers own risk and +* his own responsibility. The examination of fitness for the intended use +* is the sole responsibility of the Purchaser. +* +* The purchaser shall indemnify Bosch Sensortec from all third party +* claims, including any claims for incidental, or consequential damages, +* arising from any product use not covered by the parameters of +* the respective valid product data sheet or not approved by +* Bosch Sensortec and reimburse Bosch Sensortec for all costs in +* connection with such claims. +* +* The purchaser must monitor the market for the purchased products, +* particularly with regard to product safety and inform Bosch Sensortec +* without delay of all security relevant incidents. +* +* Engineering Samples are marked with an asterisk (*) or (e). +* Samples may vary from the valid technical specifications of the product +* series. They are therefore not intended or fit for resale to third +* parties or for use in end products. Their sole purpose is internal +* client testing. The testing of an engineering sample may in no way +* replace the testing of a product series. Bosch Sensortec assumes +* no liability for the use of engineering samples. +* By accepting the engineering samples, the Purchaser agrees to indemnify +* Bosch Sensortec from all claims arising from the use of engineering +* samples. +* +* Special: +* This software module (hereinafter called "Software") and any information +* on application-sheets (hereinafter called "Information") is provided +* free of charge for the sole purpose to support your application work. +* The Software and Information is subject to the following +* terms and conditions: +* +* The Software is specifically designed for the exclusive use for +* Bosch Sensortec products by personnel who have special experience +* and training. Do not use this Software if you do not have the +* proper experience or training. +* +* This Software package is provided `` as is `` and without any expressed +* or implied warranties,including without limitation, the implied warranties +* of merchantability and fitness for a particular purpose. +* +* Bosch Sensortec and their representatives and agents deny any liability +* for the functional impairment +* of this Software in terms of fitness, performance and safety. +* Bosch Sensortec and their representatives and agents shall not be liable +* for any direct or indirect damages or injury, except as +* otherwise stipulated in mandatory applicable law. +* +* The Information provided is believed to be accurate and reliable. +* Bosch Sensortec assumes no responsibility for the consequences of use +* of such Information nor for any infringement of patents or +* other rights of third parties which may result from its use. +* No license is granted by implication or otherwise under any patent or +* patent rights of Bosch. Specifications mentioned in the Information are +* subject to change without notice. +**************************************************************************/ +/*! \file bmi160.h + \brief BMI160 Sensor Driver Support Header File */ +/* user defined code to be added here ... */ +#ifndef __BMI160_H__ +#define __BMI160_H__ + +/*! +* @brief The following definition uses for define the data types +* +* @note While porting the API please consider the following +* @note Please check the version of C standard +* @note Are you using Linux platform +*/ + +/*! +* @brief For the Linux platform support +* Please use the types.h for your data types definitions +*/ +#ifdef __KERNEL__ + +#include + +#else /* ! __KERNEL__ */ +/********************************************************** +* These definition uses for define the C +* standard version data types +***********************************************************/ +# if !defined(__STDC_VERSION__) + +/************************************************ + * compiler is C11 C standard +************************************************/ +#if (__STDC_VERSION__ == 201112L) + +/************************************************/ +#include +/************************************************/ + +/*unsigned integer types*/ +#define u8 uint8_t +#define u16 uint16_t +#define u32 uint32_t +#define u64 uint64_t + +/*signed integer types*/ +#define s8 int8_t +#define s16 int16_t +#define s32 int32_t +#define s64 int64_t +/************************************************ + * compiler is C99 C standard +************************************************/ + +#elif (__STDC_VERSION__ == 199901L) + +/* stdint.h is a C99 supported c library. +which is used to fixed the integer size*/ +/************************************************/ +#include +/************************************************/ + +/*unsigned integer types*/ +#define u8 uint8_t +#define u16 uint16_t +#define u32 uint32_t +#define u64 uint64_t + +/*signed integer types*/ +#define s8 int8_t +#define s16 int16_t +#define s32 int32_t +#define s64 int64_t +/************************************************ + * compiler is C89 or other C standard +************************************************/ +#else /* !defined(__STDC_VERSION__) */ +/* By default it is defined as 32 bit machine configuration*/ +/* define the definition based on your machine configuration*/ +/* define the data types based on your + machine/compiler/controller configuration*/ +#define MACHINE_32_BIT + +/* If your machine support 16 bit +define the MACHINE_16_BIT*/ +#ifdef MACHINE_16_BIT +#include +/*signed integer types*/ +#define s8 signed char +#define s16 signed short int +#define s32 signed long int + +#if defined(LONG_MAX) && LONG_MAX == 0x7fffffffffffffffL +#define s64 long int +#define u64 unsigned long int +#elif defined(LLONG_MAX) && (LLONG_MAX == 0x7fffffffffffffffLL) +#define s64 long long int +#define u64 unsigned long long int +#else +#warning Either the correct data type for signed 64 bit integer \ +could not be found, or 64 bit integers are not supported in your environment. +#warning If 64 bit integers are supported on your platform, \ +please set s64 manually. +#endif + +/*unsigned integer types*/ +#define u8 unsigned char +#define u16 unsigned short int +#define u32 unsigned long int + +/* If your machine support 32 bit +define the MACHINE_32_BIT*/ +#elif defined MACHINE_32_BIT +/*signed integer types*/ +#define s8 signed char +#define s16 signed short int +#define s32 signed int +#define s64 signed long long int + +/*unsigned integer types*/ +#define u8 unsigned char +#define u16 unsigned short int +#define u32 unsigned int +#define u64 unsigned long long int + +/* If your machine support 64 bit +define the MACHINE_64_BIT*/ +#elif defined MACHINE_64_BIT +/*signed integer types*/ +#define s8 signed char +#define s16 signed short int +#define s32 signed int +#define s64 signed long int + +/*unsigned integer types*/ +#define u8 unsigned char +#define u16 unsigned short int +#define u32 unsigned int +#define u64 unsigned long int + +#else +#warning The data types defined above which not supported \ +define the data types manually +#endif +#endif + +/*** This else will execute for the compilers + * which are not supported the C standards + * Like C89/C99/C11***/ +#else +/* By default it is defined as 32 bit machine configuration*/ +/* define the definition based on your machine configuration*/ +/* define the data types based on your + machine/compiler/controller configuration*/ +#define MACHINE_32_BIT + +/* If your machine support 16 bit +define the MACHINE_16_BIT*/ +#ifdef MACHINE_16_BIT +#include +/*signed integer types*/ +#define s8 signed char +#define s16 signed short int +#define s32 signed long int + +#if defined(LONG_MAX) && LONG_MAX == 0x7fffffffffffffffL +#define s64 long int +#define u64 unsigned long int +#elif defined(LLONG_MAX) && (LLONG_MAX == 0x7fffffffffffffffLL) +#define s64 long long int +#define u64 unsigned long long int +#else +#warning Either the correct data type for signed 64 bit integer \ +could not be found, or 64 bit integers are not supported in your environment. +#warning If 64 bit integers are supported on your platform, \ +please set s64 manually. +#endif + +/*unsigned integer types*/ +#define u8 unsigned char +#define u16 unsigned short int +#define u32 unsigned long int + +/* If your machine support 32 bit +define the MACHINE_32_BIT*/ +#elif defined MACHINE_32_BIT +/*signed integer types*/ +#define s8 signed char +#define s16 signed short int +#define s32 signed int +#define s64 signed long long int + +/*unsigned integer types*/ +#define u8 unsigned char +#define u16 unsigned short int +#define u32 unsigned int +#define u64 unsigned long long int + +/* If your machine support 64 bit +define the MACHINE_64_BIT*/ +#elif defined MACHINE_64_BIT +/*signed integer types*/ +#define s8 signed char +#define s16 signed short int +#define s32 signed int +#define s64 signed long int + +/*unsigned integer types*/ +#define u8 unsigned char +#define u16 unsigned short int +#define u32 unsigned int +#define u64 unsigned long int + +#else +#warning The data types defined above which not supported \ +define the data types manually +#endif +#endif +#endif +/***************************************************************/ +/**\name BUS READ AND WRITE FUNCTION POINTERS */ +/***************************************************************/ +/*! + @brief Define the calling convention of YOUR bus communication routine. + @note This includes types of parameters. This example shows the + configuration for an SPI bus link. + + If your communication function looks like this: + + write_my_bus_xy(u8 device_addr, u8 register_addr, + u8 * data, u8 length); + + The BMI160_WR_FUNC_PTR would equal: + + BMI160_WR_FUNC_PTR s8 (* bus_write)(u8, + u8, u8 *, u8) + + Parameters can be mixed as needed refer to the + @ref BMI160_BUS_WRITE_FUNC macro. + + +*/ +#define BMI160_WR_FUNC_PTR s8 (*bus_write)(u8, u8,\ +u8 *, u8) +/**< link macro between API function calls and bus write function + @note The bus write function can change since this is a + system dependant issue. + + If the bus_write parameter calling order is like: reg_addr, + reg_data, wr_len it would be as it is here. + + If the parameters are differently ordered or your communication + function like I2C need to know the device address, + you can change this macro accordingly. + + + BMI160_BUS_WRITE_FUNC(dev_addr, reg_addr, reg_data, wr_len)\ + bus_write(dev_addr, reg_addr, reg_data, wr_len) + + This macro lets all API functions call YOUR communication routine in a + way that equals your definition in the + @ref BMI160_WR_FUNC_PTR definition. + +*/ +#define BMI160_BUS_WRITE_FUNC(dev_addr, reg_addr, reg_data, wr_len)\ + bus_write(dev_addr, reg_addr, reg_data, wr_len) + +/**< Define the calling convention of YOUR bus communication routine. + @note This includes types of parameters. This example shows the + configuration for an SPI bus link. + + If your communication function looks like this: + + read_my_bus_xy(u8 device_addr, u8 register_addr, + u8 * data, u8 length); + + The BMI160_RD_FUNC_PTR would equal: + + BMI160_RD_FUNC_PTR s8 (* bus_read)(u8, + u8, u8 *, u8) + + Parameters can be mixed as needed refer to the + refer BMI160_BUS_READ_FUNC macro. + +*/ +#define BMI160_SPI_RD_MASK (0x80) /* for spi read transactions on SPI the + MSB has to be set */ +#define BMI160_RD_FUNC_PTR s8 (*bus_read)(u8,\ + u8, u8 *, u8) + +#define BMI160_BRD_FUNC_PTR s8 \ +(*burst_read)(u8, u8, u8 *, u32) + +/**< link macro between API function calls and bus read function + @note The bus write function can change since this is a + system dependant issue. + + If the bus_read parameter calling order is like: reg_addr, + reg_data, wr_len it would be as it is here. + + If the parameters are differently ordered or your communication + function like I2C need to know the device address, + you can change this macro accordingly. + + + BMI160_BUS_READ_FUNC(dev_addr, reg_addr, reg_data, wr_len)\ + bus_read(dev_addr, reg_addr, reg_data, wr_len) + + This macro lets all API functions call YOUR communication routine in a + way that equals your definition in the + refer BMI160_WR_FUNC_PTR definition. + + @note: this macro also includes the "MSB='1' + for reading BMI160 addresses. + +*/ +#define BMI160_BUS_READ_FUNC(dev_addr, reg_addr, reg_data, r_len)\ + bus_read(dev_addr, reg_addr, reg_data, r_len) + +#define BMI160_BURST_READ_FUNC(device_addr, \ +register_addr, register_data, rd_len)\ +burst_read(device_addr, register_addr, register_data, rd_len) + + +#define BMI160_MDELAY_DATA_TYPE u32 + +/***************************************************************/ +/**\name BUS READ AND WRITE FUNCTION POINTERS */ +/***************************************************************/ +#define BMI160_I2C_ADDR1 0x68 /**< I2C Address needs to be changed */ +#define BMI160_I2C_ADDR2 0x69 /**< I2C Address needs to be changed */ +#define BMI160_AUX_BMM150_I2C_ADDRESS (0x10) +#define BMI160_AUX_YAS532_I2C_ADDRESS (0x2E) +/**< I2C address of YAS532*/ +#define BMI160_AKM09911_I2C_ADDRESS 0x0C/**< I2C address of AKM09911*/ +/**< I2C address of AKM09911*/ +#define BMI160_AUX_AKM09911_I2C_ADDR_2 (0x0D) +/**< I2C address of AKM09911*/ +#define BMI160_AUX_AKM09912_I2C_ADDR_1 (0x0C) +/**< I2C address of AKM09912*/ +#define BMI160_AUX_AKM09912_I2C_ADDR_2 (0x0D) +/**< I2C address of AKM09912*/ +#define BMI160_AUX_AKM09912_I2C_ADDR_3 (0x0E) +/**< I2C address of AKM09912*/ +#define BMI160_AKM09912_I2C_ADDRESS 0x0F/**< I2C address of akm09912*/ + +#define BMI160_YAS532_I2C_ADDRESS 0x2E/**< I2C address of YAS532*/ +/*******************************************/ +/**\name CONSTANTS */ +/******************************************/ +#define BMI160_INIT_VALUE (0) +#define BMI160_GEN_READ_WRITE_DATA_LENGTH (1) +#define BMI160_MAXIMUM_TIMEOUT (10) +/* output data rate condition check*/ +#define BMI160_OUTPUT_DATA_RATE0 (0) +#define BMI160_OUTPUT_DATA_RATE1 (1) +#define BMI160_OUTPUT_DATA_RATE2 (2) +#define BMI160_OUTPUT_DATA_RATE3 (3) +#define BMI160_OUTPUT_DATA_RATE4 (4) +#define BMI160_OUTPUT_DATA_RATE5 (5) +#define BMI160_OUTPUT_DATA_RATE6 (14) +#define BMI160_OUTPUT_DATA_RATE7 (15) +/* accel range check*/ +#define BMI160_ACCEL_RANGE0 (3) +#define BMI160_ACCEL_RANGE1 (5) +#define BMI160_ACCEL_RANGE3 (8) +#define BMI160_ACCEL_RANGE4 (12) +/* check the status of registers*/ +#define BMI160_FOC_STAT_HIGH (1) +#define BMI160_SIG_MOTION_STAT_HIGH (1) +#define BMI160_STEP_DET_STAT_HIGH (1) + +/*condition check for reading and writing data*/ +#define BMI160_MAX_VALUE_SIGNIFICANT_MOTION (1) +#define BMI160_MAX_VALUE_FIFO_FILTER (1) +#define BMI160_MAX_VALUE_FIFO_TIME (1) +#define BMI160_MAX_VALUE_FIFO_INTR (1) +#define BMI160_MAX_VALUE_FIFO_HEADER (1) +#define BMI160_MAX_VALUE_FIFO_MAG (1) +#define BMI160_MAX_VALUE_FIFO_ACCEL (1) +#define BMI160_MAX_VALUE_FIFO_GYRO (1) +#define BMI160_MAX_VALUE_SOURCE_INTR (1) +#define BMI160_MAX_VALUE_LOW_G_MODE (1) +#define BMI160_MAX_VALUE_NO_MOTION (1) +#define BMI160_MAX_VALUE_TAP_SHOCK (1) +#define BMI160_MAX_VALUE_TAP_QUIET (1) +#define BMI160_MAX_VALUE_ORIENT_UD (1) +#define BMI160_MAX_VALUE_ORIENT_AXES (1) +#define BMI160_MAX_VALUE_NVM_PROG (1) +#define BMI160_MAX_VALUE_SPI3 (1) +#define BMI160_MAX_VALUE_PAGE (1) +#define BMI160_MAX_VALUE_I2C_WDT (1) +#define BMI160_MAX_VALUE_SLEEP_STATE (1) +#define BMI160_MAX_VALUE_WAKEUP_INTR (1) +#define BMI160_MAX_VALUE_SELFTEST_SIGN (1) +#define BMI160_MAX_VALUE_SELFTEST_AMP (1) +#define BMI160_MAX_VALUE_SELFTEST_START (1) +#define BMI160_MAX_GYRO_WAKEUP_TRIGGER (3) +#define BMI160_MAX_ACCEL_SELFTEST_AXIS (3) +#define BMI160_MAX_GYRO_STEP_COUNTER (1) +#define BMI160_MAX_GYRO_BW (3) +#define BMI160_MAX_ACCEL_BW (7) +#define BMI160_MAX_ORIENT_MODE (3) +#define BMI160_MAX_ORIENT_BLOCKING (3) +#define BMI160_MAX_FLAT_HOLD (3) +#define BMI160_MAX_ACCEL_FOC (3) +#define BMI160_MAX_IF_MODE (3) +#define BMI160_MAX_TARGET_PAGE (3) +#define BMI160_MAX_GYRO_RANGE (4) +#define BMI160_MAX_GYRO_SLEEP_TIGGER (7) +#define BMI160_MAX_TAP_TURN (7) +#define BMI160_MAX_UNDER_SAMPLING (1) +#define BMI160_MAX_UNDER_SIG_MOTION (3) +#define BMI160_MAX_ACCEL_OUTPUT_DATA_RATE (12) +#define BMI160_MAX_LATCH_INTR (15) +#define BMI160_MAX_FLAT_HYST (15) +#define BMI160_MAX_ORIENT_THETA (63) +#define BMI160_MAX_FLAT_THETA (63) + +/* FIFO index definitions*/ +#define BMI160_FIFO_X_LSB_DATA (0) +#define BMI160_FIFO_X_MSB_DATA (1) +#define BMI160_FIFO_Y_LSB_DATA (2) +#define BMI160_FIFO_Y_MSB_DATA (3) +#define BMI160_FIFO_Z_LSB_DATA (4) +#define BMI160_FIFO_Z_MSB_DATA (5) +#define BMI160_FIFO_R_LSB_DATA (6) +#define BMI160_FIFO_R_MSB_DATA (7) +/* FIFO gyro definition*/ +#define BMI160_GA_FIFO_G_X_LSB (0) +#define BMI160_GA_FIFO_G_X_MSB (1) +#define BMI160_GA_FIFO_G_Y_LSB (2) +#define BMI160_GA_FIFO_G_Y_MSB (3) +#define BMI160_GA_FIFO_G_Z_LSB (4) +#define BMI160_GA_FIFO_G_Z_MSB (5) +#define BMI160_GA_FIFO_A_X_LSB (6) +#define BMI160_GA_FIFO_A_X_MSB (7) +#define BMI160_GA_FIFO_A_Y_LSB (8) +#define BMI160_GA_FIFO_A_Y_MSB (9) +#define BMI160_GA_FIFO_A_Z_LSB (10) +#define BMI160_GA_FIFO_A_Z_MSB (11) +/* FIFO mag/gyro/accel definition*/ +#define BMI160_MGA_FIFO_M_X_LSB (0) +#define BMI160_MGA_FIFO_M_X_MSB (1) +#define BMI160_MGA_FIFO_M_Y_LSB (2) +#define BMI160_MGA_FIFO_M_Y_MSB (3) +#define BMI160_MGA_FIFO_M_Z_LSB (4) +#define BMI160_MGA_FIFO_M_Z_MSB (5) +#define BMI160_MGA_FIFO_M_R_LSB (6) +#define BMI160_MGA_FIFO_M_R_MSB (7) +#define BMI160_MGA_FIFO_G_X_LSB (8) +#define BMI160_MGA_FIFO_G_X_MSB (9) +#define BMI160_MGA_FIFO_G_Y_LSB (10) +#define BMI160_MGA_FIFO_G_Y_MSB (11) +#define BMI160_MGA_FIFO_G_Z_LSB (12) +#define BMI160_MGA_FIFO_G_Z_MSB (13) +#define BMI160_MGA_FIFO_A_X_LSB (14) +#define BMI160_MGA_FIFO_A_X_MSB (15) +#define BMI160_MGA_FIFO_A_Y_LSB (16) +#define BMI160_MGA_FIFO_A_Y_MSB (17) +#define BMI160_MGA_FIFO_A_Z_LSB (18) +#define BMI160_MGA_FIFO_A_Z_MSB (19) +/* FIFO mag definition*/ +#define BMI160_MA_FIFO_M_X_LSB (0) +#define BMI160_MA_FIFO_M_X_MSB (1) +#define BMI160_MA_FIFO_M_Y_LSB (2) +#define BMI160_MA_FIFO_M_Y_MSB (3) +#define BMI160_MA_FIFO_M_Z_LSB (4) +#define BMI160_MA_FIFO_M_Z_MSB (5) +#define BMI160_MA_FIFO_M_R_LSB (6) +#define BMI160_MA_FIFO_M_R_MSB (7) +#define BMI160_MA_FIFO_A_X_LSB (8) +#define BMI160_MA_FIFO_A_X_MSB (9) +#define BMI160_MA_FIFO_A_Y_LSB (10) +#define BMI160_MA_FIFO_A_Y_MSB (11) +#define BMI160_MA_FIFO_A_Z_LSB (12) +#define BMI160_MA_FIFO_A_Z_MSB (13) +/* FIFO mag/gyro definition*/ +#define BMI160_MG_FIFO_M_X_LSB (0) +#define BMI160_MG_FIFO_M_X_MSB (1) +#define BMI160_MG_FIFO_M_Y_LSB (2) +#define BMI160_MG_FIFO_M_Y_MSB (3) +#define BMI160_MG_FIFO_M_Z_LSB (4) +#define BMI160_MG_FIFO_M_Z_MSB (5) +#define BMI160_MG_FIFO_M_R_LSB (6) +#define BMI160_MG_FIFO_M_R_MSB (7) +#define BMI160_MG_FIFO_G_X_LSB (8) +#define BMI160_MG_FIFO_G_X_MSB (9) +#define BMI160_MG_FIFO_G_Y_LSB (10) +#define BMI160_MG_FIFO_G_Y_MSB (11) +#define BMI160_MG_FIFO_G_Z_LSB (12) +#define BMI160_MG_FIFO_G_Z_MSB (13) +/* FIFO length definitions*/ +#define BMI160_FIFO_SENSOR_TIME_LSB (0) +#define BMI160_FIFO_SENSOR_TIME_XLSB (1) +#define BMI160_FIFO_SENSOR_TIME_MSB (2) +#define BMI160_FIFO_SENSOR_TIME_LENGTH (3) +#define BMI160_FIFO_A_LENGTH (6) +#define BMI160_FIFO_G_LENGTH (6) +#define BMI160_FIFO_M_LENGTH (8) +#define BMI160_FIFO_AG_LENGTH (12) +#define BMI160_FIFO_AMG_LENGTH (20) +#define BMI160_FIFO_MA_OR_MG_LENGTH (14) + +/* bus read and write length for mag, accel and gyro*/ +#define BMI160_MAG_X_DATA_LENGTH (2) +#define BMI160_MAG_Y_DATA_LENGTH (2) +#define BMI160_MAG_Z_DATA_LENGTH (2) +#define BMI160_MAG_R_DATA_LENGTH (2) +#define BMI160_MAG_XYZ_DATA_LENGTH (6) +#define BMI160_MAG_XYZR_DATA_LENGTH (8) +#define BMI160_MAG_YAS_DATA_LENGTH (8) +#define BMI160_GYRO_DATA_LENGTH (2) +#define BMI160_GYRO_XYZ_DATA_LENGTH (6) +#define BMI160_ACCEL_DATA_LENGTH (2) +#define BMI160_ACCEL_XYZ_DATA_LENGTH (6) +#define BMI160_TEMP_DATA_LENGTH (2) +#define BMI160_FIFO_DATA_LENGTH (2) +#define BMI160_STEP_COUNTER_LENGTH (2) +#define BMI160_SENSOR_TIME_LENGTH (3) + +/* Delay definitions*/ +#define BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY (5) +#define BMI160_BMM150_WAKEUP_DELAY1 (2) +#define BMI160_BMM150_WAKEUP_DELAY2 (3) +#define BMI160_BMM150_WAKEUP_DELAY3 (1) +#define BMI160_YAS532_OFFSET_DELAY (2) +#define BMI160_GEN_READ_WRITE_DELAY (1) +#define BMI160_YAS532_MEASUREMENT_DELAY (25) +#define BMI160_YAS_ACQ_COMMAND_DELAY (50) +#define BMI160_YAS532_SET_INITIAL_VALUE_DELAY (200) +#define BMI160_AKM_INIT_DELAY (60) +/****************************************************/ +/**\name ARRAY SIZE DEFINITIONS */ +/***************************************************/ +#define BMI160_ACCEL_X_DATA_SIZE (2) +#define BMI160_ACCEL_Y_DATA_SIZE (2) +#define BMI160_ACCEL_Z_DATA_SIZE (2) +#define BMI160_ACCEL_XYZ_DATA_SIZE (6) + +#define BMI160_GYRO_X_DATA_SIZE (2) +#define BMI160_GYRO_Y_DATA_SIZE (2) +#define BMI160_GYRO_Z_DATA_SIZE (2) +#define BMI160_GYRO_XYZ_DATA_SIZE (6) + +#define BMI160_MAG_X_DATA_SIZE (2) +#define BMI160_MAG_Y_DATA_SIZE (2) +#define BMI160_MAG_Z_DATA_SIZE (2) +#define BMI160_MAG_R_DATA_SIZE (2) +#define BMI160_MAG_XYZ_DATA_SIZE (6) +#define BMI160_MAG_XYZR_DATA_SIZE (8) +#define BMI160_MAG_TRIM_DATA_SIZE (16) + + +#define BMI160_TEMP_DATA_SIZE (2) +#define BMI160_FIFO_DATA_SIZE (2) +#define BMI160_STEP_COUNT_DATA_SIZE (2) + +#define BMI160_SENSOR_TIME_DATA_SIZE (3) +#define BMI160_AKM_SENSITIVITY_DATA_SIZE (3) +#define BMI160_HARD_OFFSET_DATA_SIZE (3) +#define BMI160_YAS_XY1Y2_DATA_SIZE (3) +#define BMI160_YAS_FLAG_DATA_SIZE (3) +#define BMI160_YAS_TEMP_DATA_SIZE (3) +#define BMI160_YAS_H_DATA_SIZE (3) +#define BMI160_YAS_S_DATA_SIZE (3) +#define BMI160_YAS_CORRECT_DATA_SIZE (5) +#define BMI160_YAS_XY1Y2T_DATA_SIZE (8) +#define BMI160_YAS537_CALIB_DATA_SIZE (17) +#define BMI160_YAS532_CALIB_DATA_SIZE (14) +/****************************************************/ +/**\name ARRAY PARAMETER DEFINITIONS */ +/***************************************************/ +#define BMI160_SENSOR_TIME_MSB_BYTE (2) +#define BMI160_SENSOR_TIME_XLSB_BYTE (1) +#define BMI160_SENSOR_TIME_LSB_BYTE (0) + +#define BMI160_MAG_X_LSB_BYTE (0) +#define BMI160_MAG_X_MSB_BYTE (1) +#define BMI160_MAG_Y_LSB_BYTE (0) +#define BMI160_MAG_Y_MSB_BYTE (1) +#define BMI160_MAG_Z_LSB_BYTE (0) +#define BMI160_MAG_Z_MSB_BYTE (1) +#define BMI160_MAG_R_LSB_BYTE (0) +#define BMI160_MAG_R_MSB_BYTE (1) +#define BMI160_DATA_FRAME_MAG_X_LSB_BYTE (0) +#define BMI160_DATA_FRAME_MAG_X_MSB_BYTE (1) +#define BMI160_DATA_FRAME_MAG_Y_LSB_BYTE (2) +#define BMI160_DATA_FRAME_MAG_Y_MSB_BYTE (3) +#define BMI160_DATA_FRAME_MAG_Z_LSB_BYTE (4) +#define BMI160_DATA_FRAME_MAG_Z_MSB_BYTE (5) +#define BMI160_DATA_FRAME_MAG_R_LSB_BYTE (6) +#define BMI160_DATA_FRAME_MAG_R_MSB_BYTE (7) + +#define BMI160_GYRO_X_LSB_BYTE (0) +#define BMI160_GYRO_X_MSB_BYTE (1) +#define BMI160_GYRO_Y_LSB_BYTE (0) +#define BMI160_GYRO_Y_MSB_BYTE (1) +#define BMI160_GYRO_Z_LSB_BYTE (0) +#define BMI160_GYRO_Z_MSB_BYTE (1) +#define BMI160_DATA_FRAME_GYRO_X_LSB_BYTE (0) +#define BMI160_DATA_FRAME_GYRO_X_MSB_BYTE (1) +#define BMI160_DATA_FRAME_GYRO_Y_LSB_BYTE (2) +#define BMI160_DATA_FRAME_GYRO_Y_MSB_BYTE (3) +#define BMI160_DATA_FRAME_GYRO_Z_LSB_BYTE (4) +#define BMI160_DATA_FRAME_GYRO_Z_MSB_BYTE (5) + +#define BMI160_ACCEL_X_LSB_BYTE (0) +#define BMI160_ACCEL_X_MSB_BYTE (1) +#define BMI160_ACCEL_Y_LSB_BYTE (0) +#define BMI160_ACCEL_Y_MSB_BYTE (1) +#define BMI160_ACCEL_Z_LSB_BYTE (0) +#define BMI160_ACCEL_Z_MSB_BYTE (1) +#define BMI160_DATA_FRAME_ACCEL_X_LSB_BYTE (0) +#define BMI160_DATA_FRAME_ACCEL_X_MSB_BYTE (1) +#define BMI160_DATA_FRAME_ACCEL_Y_LSB_BYTE (2) +#define BMI160_DATA_FRAME_ACCEL_Y_MSB_BYTE (3) +#define BMI160_DATA_FRAME_ACCEL_Z_LSB_BYTE (4) +#define BMI160_DATA_FRAME_ACCEL_Z_MSB_BYTE (5) + +#define BMI160_TEMP_LSB_BYTE (0) +#define BMI160_TEMP_MSB_BYTE (1) + +#define BMI160_FIFO_LENGTH_LSB_BYTE (0) +#define BMI160_FIFO_LENGTH_MSB_BYTE (1) + +#define BMI160_STEP_COUNT_LSB_BYTE (0) +#define BMI160_STEP_COUNT_MSB_BYTE (1) +/****************************************************/ +/**\name ERROR CODES */ +/***************************************************/ + +#define E_BMI160_NULL_PTR ((s8)-127) +#define E_BMI160_COMM_RES ((s8)-1) +#define E_BMI160_OUT_OF_RANGE ((s8)-2) +#define E_BMI160_BUSY ((s8)-3) +#define SUCCESS ((u8)0) +#define ERROR ((s8)-1) + +/* Constants */ +#define BMI160_NULL (0) +#define BMI160_DELAY_SETTLING_TIME (5) +/*This refers BMI160 return type as s8 */ +#define BMI160_RETURN_FUNCTION_TYPE s8 +/****************************************************/ +/**\name REGISTER DEFINITIONS */ +/***************************************************/ +/*******************/ +/**\name CHIP ID */ +/*******************/ +#define BMI160_USER_CHIP_ID_ADDR (0x00) +/*******************/ +/**\name ERROR STATUS */ +/*******************/ +#define BMI160_USER_ERROR_ADDR (0X02) +/*******************/ +/**\name POWER MODE STATUS */ +/*******************/ +#define BMI160_USER_PMU_STAT_ADDR (0X03) +/*******************/ +/**\name MAG DATA REGISTERS */ +/*******************/ +#define BMI160_USER_DATA_0_ADDR (0X04) +#define BMI160_USER_DATA_1_ADDR (0X05) +#define BMI160_USER_DATA_2_ADDR (0X06) +#define BMI160_USER_DATA_3_ADDR (0X07) +#define BMI160_USER_DATA_4_ADDR (0X08) +#define BMI160_USER_DATA_5_ADDR (0X09) +#define BMI160_USER_DATA_6_ADDR (0X0A) +#define BMI160_USER_DATA_7_ADDR (0X0B) +/*******************/ +/**\name GYRO DATA REGISTERS */ +/*******************/ +#define BMI160_USER_DATA_8_ADDR (0X0C) +#define BMI160_USER_DATA_9_ADDR (0X0D) +#define BMI160_USER_DATA_10_ADDR (0X0E) +#define BMI160_USER_DATA_11_ADDR (0X0F) +#define BMI160_USER_DATA_12_ADDR (0X10) +#define BMI160_USER_DATA_13_ADDR (0X11) +#define BMI160_USER_DATA_14_ADDR (0X12) +#define BMI160_USER_DATA_15_ADDR (0X13) +/*******************/ +/**\name ACCEL DATA REGISTERS */ +/*******************/ +#define BMI160_USER_DATA_16_ADDR (0X14) +#define BMI160_USER_DATA_17_ADDR (0X15) +#define BMI160_USER_DATA_18_ADDR (0X16) +#define BMI160_USER_DATA_19_ADDR (0X17) +/*******************/ +/**\name SENSOR TIME REGISTERS */ +/*******************/ +#define BMI160_USER_SENSORTIME_0_ADDR (0X18) +#define BMI160_USER_SENSORTIME_1_ADDR (0X19) +#define BMI160_USER_SENSORTIME_2_ADDR (0X1A) +/*******************/ +/**\name STATUS REGISTER FOR SENSOR STATUS FLAG */ +/*******************/ +#define BMI160_USER_STAT_ADDR (0X1B) +/*******************/ +/**\name INTERRUPY STATUS REGISTERS */ +/*******************/ +#define BMI160_USER_INTR_STAT_0_ADDR (0X1C) +#define BMI160_USER_INTR_STAT_1_ADDR (0X1D) +#define BMI160_USER_INTR_STAT_2_ADDR (0X1E) +#define BMI160_USER_INTR_STAT_3_ADDR (0X1F) +/*******************/ +/**\name TEMPERATURE REGISTERS */ +/*******************/ +#define BMI160_USER_TEMPERATURE_0_ADDR (0X20) +#define BMI160_USER_TEMPERATURE_1_ADDR (0X21) +/*******************/ +/**\name FIFO REGISTERS */ +/*******************/ +#define BMI160_USER_FIFO_LENGTH_0_ADDR (0X22) +#define BMI160_USER_FIFO_LENGTH_1_ADDR (0X23) +#define BMI160_USER_FIFO_DATA_ADDR (0X24) +/***************************************************/ +/**\name ACCEL CONFIG REGISTERS FOR ODR, BANDWIDTH AND UNDERSAMPLING*/ +/******************************************************/ +#define BMI160_USER_ACCEL_CONFIG_ADDR (0X40) +/*******************/ +/**\name ACCEL RANGE */ +/*******************/ +#define BMI160_USER_ACCEL_RANGE_ADDR (0X41) +/***************************************************/ +/**\name GYRO CONFIG REGISTERS FOR ODR AND BANDWIDTH */ +/******************************************************/ +#define BMI160_USER_GYRO_CONFIG_ADDR (0X42) +/*******************/ +/**\name GYRO RANGE */ +/*******************/ +#define BMI160_USER_GYRO_RANGE_ADDR (0X43) +/***************************************************/ +/**\name MAG CONFIG REGISTERS FOR ODR*/ +/******************************************************/ +#define BMI160_USER_MAG_CONFIG_ADDR (0X44) +/***************************************************/ +/**\name REGISTER FOR GYRO AND ACCEL DOWNSAMPLING RATES FOR FIFO*/ +/******************************************************/ +#define BMI160_USER_FIFO_DOWN_ADDR (0X45) +/***************************************************/ +/**\name FIFO CONFIG REGISTERS*/ +/******************************************************/ +#define BMI160_USER_FIFO_CONFIG_0_ADDR (0X46) +#define BMI160_USER_FIFO_CONFIG_1_ADDR (0X47) +/***************************************************/ +/**\name MAG INTERFACE REGISTERS*/ +/******************************************************/ +#define BMI160_USER_MAG_IF_0_ADDR (0X4B) +#define BMI160_USER_MAG_IF_1_ADDR (0X4C) +#define BMI160_USER_MAG_IF_2_ADDR (0X4D) +#define BMI160_USER_MAG_IF_3_ADDR (0X4E) +#define BMI160_USER_MAG_IF_4_ADDR (0X4F) +/***************************************************/ +/**\name INTERRUPT ENABLE REGISTERS*/ +/******************************************************/ +#define BMI160_USER_INTR_ENABLE_0_ADDR (0X50) +#define BMI160_USER_INTR_ENABLE_1_ADDR (0X51) +#define BMI160_USER_INTR_ENABLE_2_ADDR (0X52) +#define BMI160_USER_INTR_OUT_CTRL_ADDR (0X53) +/***************************************************/ +/**\name LATCH DURATION REGISTERS*/ +/******************************************************/ +#define BMI160_USER_INTR_LATCH_ADDR (0X54) +/***************************************************/ +/**\name MAP INTERRUPT 1 and 2 REGISTERS*/ +/******************************************************/ +#define BMI160_USER_INTR_MAP_0_ADDR (0X55) +#define BMI160_USER_INTR_MAP_1_ADDR (0X56) +#define BMI160_USER_INTR_MAP_2_ADDR (0X57) +/***************************************************/ +/**\name DATA SOURCE REGISTERS*/ +/******************************************************/ +#define BMI160_USER_INTR_DATA_0_ADDR (0X58) +#define BMI160_USER_INTR_DATA_1_ADDR (0X59) +/***************************************************/ +/**\name +INTERRUPT THRESHOLD, HYSTERESIS, DURATION, MODE CONFIGURATION REGISTERS*/ +/******************************************************/ +#define BMI160_USER_INTR_LOWHIGH_0_ADDR (0X5A) +#define BMI160_USER_INTR_LOWHIGH_1_ADDR (0X5B) +#define BMI160_USER_INTR_LOWHIGH_2_ADDR (0X5C) +#define BMI160_USER_INTR_LOWHIGH_3_ADDR (0X5D) +#define BMI160_USER_INTR_LOWHIGH_4_ADDR (0X5E) +#define BMI160_USER_INTR_MOTION_0_ADDR (0X5F) +#define BMI160_USER_INTR_MOTION_1_ADDR (0X60) +#define BMI160_USER_INTR_MOTION_2_ADDR (0X61) +#define BMI160_USER_INTR_MOTION_3_ADDR (0X62) +#define BMI160_USER_INTR_TAP_0_ADDR (0X63) +#define BMI160_USER_INTR_TAP_1_ADDR (0X64) +#define BMI160_USER_INTR_ORIENT_0_ADDR (0X65) +#define BMI160_USER_INTR_ORIENT_1_ADDR (0X66) +#define BMI160_USER_INTR_FLAT_0_ADDR (0X67) +#define BMI160_USER_INTR_FLAT_1_ADDR (0X68) +/***************************************************/ +/**\name FAST OFFSET CONFIGURATION REGISTER*/ +/******************************************************/ +#define BMI160_USER_FOC_CONFIG_ADDR (0X69) +/***************************************************/ +/**\name MISCELLANEOUS CONFIGURATION REGISTER*/ +/******************************************************/ +#define BMI160_USER_CONFIG_ADDR (0X6A) +/***************************************************/ +/**\name SERIAL INTERFACE SETTINGS REGISTER*/ +/******************************************************/ +#define BMI160_USER_IF_CONFIG_ADDR (0X6B) +/***************************************************/ +/**\name GYRO POWER MODE TRIGGER REGISTER */ +/******************************************************/ +#define BMI160_USER_PMU_TRIGGER_ADDR (0X6C) +/***************************************************/ +/**\name SELF_TEST REGISTER*/ +/******************************************************/ +#define BMI160_USER_SELF_TEST_ADDR (0X6D) +/***************************************************/ +/**\name SPI,I2C SELECTION REGISTER*/ +/******************************************************/ +#define BMI160_USER_NV_CONFIG_ADDR (0x70) +/***************************************************/ +/**\name ACCEL AND GYRO OFFSET REGISTERS*/ +/******************************************************/ +#define BMI160_USER_OFFSET_0_ADDR (0X71) +#define BMI160_USER_OFFSET_1_ADDR (0X72) +#define BMI160_USER_OFFSET_2_ADDR (0X73) +#define BMI160_USER_OFFSET_3_ADDR (0X74) +#define BMI160_USER_OFFSET_4_ADDR (0X75) +#define BMI160_USER_OFFSET_5_ADDR (0X76) +#define BMI160_USER_OFFSET_6_ADDR (0X77) +/***************************************************/ +/**\name STEP COUNTER INTERRUPT REGISTERS*/ +/******************************************************/ +#define BMI160_USER_STEP_COUNT_0_ADDR (0X78) +#define BMI160_USER_STEP_COUNT_1_ADDR (0X79) +/***************************************************/ +/**\name STEP COUNTER CONFIGURATION REGISTERS*/ +/******************************************************/ +#define BMI160_USER_STEP_CONFIG_0_ADDR (0X7A) +#define BMI160_USER_STEP_CONFIG_1_ADDR (0X7B) +/***************************************************/ +/**\name COMMAND REGISTER*/ +/******************************************************/ +#define BMI160_CMD_COMMANDS_ADDR (0X7E) +/***************************************************/ +/**\name PAGE REGISTERS*/ +/******************************************************/ +#define BMI160_CMD_EXT_MODE_ADDR (0X7F) +#define BMI160_COM_C_TRIM_FIVE_ADDR (0X05) + +/****************************************************/ +/**\name SHIFT VALUE DEFINITION */ +/***************************************************/ +#define BMI160_SHIFT_BIT_POSITION_BY_01_BIT (1) +#define BMI160_SHIFT_BIT_POSITION_BY_02_BITS (2) +#define BMI160_SHIFT_BIT_POSITION_BY_03_BITS (3) +#define BMI160_SHIFT_BIT_POSITION_BY_04_BITS (4) +#define BMI160_SHIFT_BIT_POSITION_BY_05_BITS (5) +#define BMI160_SHIFT_BIT_POSITION_BY_06_BITS (6) +#define BMI160_SHIFT_BIT_POSITION_BY_07_BITS (7) +#define BMI160_SHIFT_BIT_POSITION_BY_08_BITS (8) +#define BMI160_SHIFT_BIT_POSITION_BY_09_BITS (9) +#define BMI160_SHIFT_BIT_POSITION_BY_12_BITS (12) +#define BMI160_SHIFT_BIT_POSITION_BY_13_BITS (13) +#define BMI160_SHIFT_BIT_POSITION_BY_14_BITS (14) +#define BMI160_SHIFT_BIT_POSITION_BY_15_BITS (15) +#define BMI160_SHIFT_BIT_POSITION_BY_16_BITS (16) + +/****************************************************/ +/**\name DEFINITIONS USED FOR YAMAHA-YAS532 */ +/***************************************************/ +#define YAS532_MAG_STATE_NORMAL (0) +#define YAS532_MAG_STATE_INIT_COIL (1) +#define YAS532_MAG_STATE_MEASURE_OFFSET (2) +#define YAS532_MAG_INITCOIL_TIMEOUT (1000) +#define YAS532_MAG_NOTRANS_POSITION (3) +#define YAS532_DEFAULT_SENSOR_DELAY (50) +#define YAS532_DATA_OVERFLOW (8190) +#define YAS532_DATA_UNDERFLOW (0) +#define YAS532_MAG_LOG (20) +#define YAS532_MAG_TEMPERATURE_LOG (10) +#define YAS532_TEMP20DEGREE_TYPICAL (390) +#define YAS532_VERSION_AC_COEF_X (850) +#define YAS532_VERSION_AC_COEF_Y1 (750) +#define YAS532_VERSION_AC_COEF_Y2 (750) +#define YAS532_DATA_CENTER (4096) +/****************************************************/ +/**\name YAMAHA-YAS532 OFFSET DEFINITION */ +/***************************************************/ +static const s8 INVALID_OFFSET[] = {0x7f, 0x7f, 0x7f}; +#define set_vector(to, from) \ + {int _l; for (_l = 0; _l < 3; _l++) (to)[_l] = (from)[_l]; } +#define is_valid_offset(a) \ + (((a)[0] <= 31) && ((a)[1] <= 31) && ((a)[2] <= 31) \ + && (-31 <= (a)[0]) && (-31 <= (a)[1]) && (-31 <= (a)[2])) + +/**************************************************/ +/**\name YAS532 CALIB DATA DEFINITIONS */ +/*************************************************/ + + +/* register address of YAS532*/ +#define BMI160_YAS532_TESTR1 (0x88) +#define BMI160_YAS532_TESTR2 (0x89) +#define BMI160_YAS532_RCOIL (0x81) +#define BMI160_YAS532_COMMAND_REGISTER (0x82) +#define BMI160_YAS532_DATA_REGISTER (0xB0) +/* calib data register definition*/ +#define BMI160_YAS532_CALIB_CX (0x90) +#define BMI160_YAS532_CALIB_CY1 (0x91) +#define BMI160_YAS532_CALIB_CY2 (0x92) +#define BMI160_YAS532_CALIB1 (0x93) +#define BMI160_YAS532_CALIB2 (0x94) +#define BMI160_YAS532_CALIB3 (0x95) +#define BMI160_YAS532_CALIB4 (0x96) +#define BMI160_YAS532_CALIB5 (0x97) +#define BMI160_YAS532_CLAIB6 (0x98) +#define BMI160_YAS532_CALIB7 (0x99) +#define BMI160_YAS532_CALIB8 (0x9A) +#define BMI160_YAS532_CALIIB9 (0x9B) +#define BMI160_YAS532_CALIB10 (0x9C) +#define BMI160_YAS532_CALIB11 (0x9D) +/* offset definition */ +#define BMI160_YAS532_OFFSET_X (0x85) +#define BMI160_YAS532_OFFSET_Y (0x86) +#define BMI160_YAS532_OFFSET_Z (0x87) +/* data to write register for yas532*/ +#define BMI160_YAS532_WRITE_TESTR1 (0x00) +#define BMI160_YAS532_WRITE_TESTR2 (0x00) +#define BMI160_YAS532_WRITE_RCOIL (0x00) +/**************************************************/ +/**\name YAS537 DEFINITION */ +/*************************************************/ + +#define YAS537_SRSTR_DATA (0x02) +#define YAS537_WRITE_A_D_CONVERTER (0x03) +#define YAS537_WRITE_A_D_CONVERTER2 (0xF8) +#define YAS537_WRITE_FILTER (0x08) +#define YAS537_WRITE_CONFR (0x08) +#define YAS537_WRITE_TEMP_CALIB (0xFF) +#define YAS537_SET_COMMAND_REGISTER (0x01) + +/**************************************************/ +/**\name YAS537 REGISTER DEFINITION */ +/*************************************************/ +#define YAS537_REG_SRSTR (0x90) +#define YAS537_REG_CALR_C0 (0xC0) +#define YAS537_REG_CALR_C1 (0xC1) +#define YAS537_REG_CALR_C2 (0xC2) +#define YAS537_REG_CALR_C3 (0xC3) +#define YAS537_REG_CALR_C4 (0xC4) +#define YAS537_REG_CALR_C5 (0xC5) +#define YAS537_REG_CALR_C6 (0xC6) +#define YAS537_REG_CALR_C7 (0xC7) +#define YAS537_REG_CALR_C8 (0xC8) +#define YAS537_REG_CALR_C9 (0xC9) +#define YAS537_REG_CALR_CA (0xCA) +#define YAS537_REG_CALR_CB (0xCB) +#define YAS537_REG_CALR_CC (0xCC) +#define YAS537_REG_CALR_CD (0xCD) +#define YAS537_REG_CALR_CE (0xCE) +#define YAS537_REG_CALR_CF (0xCF) +#define YAS537_REG_CALR_DO (0xD0) +#define YAS537_REG_MTCR (0x93) +#define YAS537_REG_CONFR (0x82) +#define BMI160_REG_YAS537_CMDR (0x81) +#define YAS537_REG_OXR (0x84) +#define YAS537_REG_AVRR (0x87) +#define YAS537_REG_HCKR (0x88) +#define YAS537_REG_LCKR (0x89) +#define YAS537_REG_ADCCALR (0x91) +#define YAS537_REG_ADCCALR_ONE (0x92) +#define YAS537_REG_OCR (0x9E) +#define YAS537_REG_TRMR (0x9F) +#define YAS537_REG_TEMPERATURE_0 (0xB0) +#define YAS537_REG_TEMPERATURE_1 (0xB1) +#define YAS537_REG_DATA_X_0 (0xB2) +#define YAS537_REG_DATA_X_1 (0xB3) +#define YAS537_REG_DATA_Y1_0 (0xB4) +#define YAS537_REG_DATA_Y1_1 (0xB5) +#define YAS537_REG_DATA_Y2_0 (0xB6) +#define YAS537_REG_DATA_Y2_1 (0xB7) +#define YAS537_MAG_STATE_NORMAL (0) +#define YAS537_MAG_STATE_INIT_COIL (1) +#define YAS537_MAG_STATE_RECORD_DATA (2) +#define YAS537_DATA_UNDERFLOW (0) +#define YAS537_DATA_OVERFLOW (16383) +/****************************************************/ +/**\name YAS537_set vector */ +/***************************************************/ +#define yas537_set_vector(to, from) \ + {int _l; for (_l = 0; _l < 3; _l++) (to)[_l] = (from)[_l]; } + +#ifndef ABS +#define ABS(a) ((a) > 0 ? (a) : -(a)) /*!< Absolute value */ +#endif +/****************************************************/ +/**\name AKM09911 AND AKM09912 DEFINITION */ +/***************************************************/ +#define AKM09912_SENSITIVITY_DIV (256) +#define AKM09912_SENSITIVITY (128) +#define AKM09911_SENSITIVITY_DIV (128) +#define AKM_ASAX (0) +#define AKM_ASAY (1) +#define AKM_ASAZ (2) +#define AKM_POWER_DOWN_MODE_DATA (0x00) +#define AKM_FUSE_ROM_MODE (0x1F) +#define AKM_POWER_MODE_REG (0x31) +#define AKM_SINGLE_MEASUREMENT_MODE (0x01) +#define AKM_DATA_REGISTER (0x11) +/*! AKM09912 Register definition */ +#define AKM09912_CHIP_ID_REG (0x01) +/****************************************************/ +/**\name BMM150 DEFINITION */ +/***************************************************/ +#define BMI160_BMM150_SET_POWER_CONTROL (0x01) +#define BMI160_BMM150_MAX_RETRY_WAKEUP (5) +#define BMI160_BMM150_POWER_ON (0x01) +#define BMI160_BMM150_POWER_OFF (0x00) +#define BMI160_BMM150_FORCE_MODE (0x02) +#define BMI160_BMM150_POWER_ON_SUCCESS (0) +#define BMI160_BMM150_POWER_ON_FAIL ((s8)-1) + +#define BMI160_BMM150_DIG_X1 (0) +#define BMI160_BMM150_DIG_Y1 (1) +#define BMI160_BMM150_DIG_X2 (2) +#define BMI160_BMM150_DIG_Y3 (3) +#define BMI160_BMM150_DIG_XY1 (4) +#define BMI160_BMM150_DIG_XY2 (5) +#define BMI160_BMM150_DIG_Z1_LSB (6) +#define BMI160_BMM150_DIG_Z1_MSB (7) +#define BMI160_BMM150_DIG_Z2_LSB (8) +#define BMI160_BMM150_DIG_Z2_MSB (9) +#define BMI160_BMM150_DIG_DIG_Z3_LSB (10) +#define BMI160_BMM150_DIG_DIG_Z3_MSB (11) +#define BMI160_BMM150_DIG_DIG_Z4_LSB (12) +#define BMI160_BMM150_DIG_DIG_Z4_MSB (13) +#define BMI160_BMM150_DIG_DIG_XYZ1_LSB (14) +#define BMI160_BMM150_DIG_DIG_XYZ1_MSB (15) + +/**************************************************************/ +/**\name STRUCTURE DEFINITIONS */ +/**************************************************************/ +/*! +* @brief bmi160 structure +* This structure holds all relevant information about bmi160 +*/ +struct bmi160_t { +u8 chip_id;/**< chip id of BMI160 */ +u8 dev_addr;/**< device address of BMI160 */ +s8 mag_manual_enable;/**< used for check the mag manual/auto mode status */ +BMI160_WR_FUNC_PTR;/**< bus write function pointer */ +BMI160_RD_FUNC_PTR;/**< bus read function pointer */ +BMI160_BRD_FUNC_PTR;/**< burst write function pointer */ +void (*delay_msec)(BMI160_MDELAY_DATA_TYPE);/**< delay function pointer */ +}; +/*! + * @brief Structure containing bmm150 and akm09911 + * magnetometer values for x,y and + * z-axis in s16 + */ +struct bmi160_mag_t { +s16 x;/**< BMM150 and AKM09911 and AKM09912 X raw data*/ +s16 y;/**< BMM150 and AKM09911 and AKM09912 Y raw data*/ +s16 z;/**< BMM150 and AKM09911 and AKM09912 Z raw data*/ +}; +/*! + * @brief Structure containing bmm150 xyz data and temperature + */ +struct bmi160_mag_xyzr_t { +s16 x;/**< BMM150 X raw data*/ +s16 y;/**< BMM150 Y raw data*/ +s16 z;/** (0x00), Bit --> 0...7 */ +#define BMI160_USER_CHIP_ID__POS (0) +#define BMI160_USER_CHIP_ID__MSK (0xFF) +#define BMI160_USER_CHIP_ID__LEN (8) +#define BMI160_USER_CHIP_ID__REG (BMI160_USER_CHIP_ID_ADDR) +/**************************************************************/ +/**\name ERROR STATUS LENGTH, POSITION AND MASK */ +/**************************************************************/ +/* Error Description - Reg Addr --> (0x02), Bit --> 0 */ +#define BMI160_USER_ERR_STAT__POS (0) +#define BMI160_USER_ERR_STAT__LEN (8) +#define BMI160_USER_ERR_STAT__MSK (0xFF) +#define BMI160_USER_ERR_STAT__REG (BMI160_USER_ERROR_ADDR) + +#define BMI160_USER_FATAL_ERR__POS (0) +#define BMI160_USER_FATAL_ERR__LEN (1) +#define BMI160_USER_FATAL_ERR__MSK (0x01) +#define BMI160_USER_FATAL_ERR__REG (BMI160_USER_ERROR_ADDR) + +/* Error Description - Reg Addr --> (0x02), Bit --> 1...4 */ +#define BMI160_USER_ERR_CODE__POS (1) +#define BMI160_USER_ERR_CODE__LEN (4) +#define BMI160_USER_ERR_CODE__MSK (0x1E) +#define BMI160_USER_ERR_CODE__REG (BMI160_USER_ERROR_ADDR) + +/* Error Description - Reg Addr --> (0x02), Bit --> 5 */ +#define BMI160_USER_I2C_FAIL_ERR__POS (5) +#define BMI160_USER_I2C_FAIL_ERR__LEN (1) +#define BMI160_USER_I2C_FAIL_ERR__MSK (0x20) +#define BMI160_USER_I2C_FAIL_ERR__REG (BMI160_USER_ERROR_ADDR) + +/* Error Description - Reg Addr --> (0x02), Bit --> 6 */ +#define BMI160_USER_DROP_CMD_ERR__POS (6) +#define BMI160_USER_DROP_CMD_ERR__LEN (1) +#define BMI160_USER_DROP_CMD_ERR__MSK (0x40) +#define BMI160_USER_DROP_CMD_ERR__REG (BMI160_USER_ERROR_ADDR) +/**************************************************************/ +/**\name MAG DATA READY LENGTH, POSITION AND MASK */ +/**************************************************************/ +/* Error Description - Reg Addr --> (0x02), Bit --> 7 */ +#define BMI160_USER_MAG_DADA_RDY_ERR__POS (7) +#define BMI160_USER_MAG_DADA_RDY_ERR__LEN (1) +#define BMI160_USER_MAG_DADA_RDY_ERR__MSK (0x80) +#define BMI160_USER_MAG_DADA_RDY_ERR__REG (BMI160_USER_ERROR_ADDR) +/**************************************************************/ +/**\name MAG POWER MODE LENGTH, POSITION AND MASK */ +/**************************************************************/ +/* PMU_Status Description of MAG - Reg Addr --> (0x03), Bit --> 1..0 */ +#define BMI160_USER_MAG_POWER_MODE_STAT__POS (0) +#define BMI160_USER_MAG_POWER_MODE_STAT__LEN (2) +#define BMI160_USER_MAG_POWER_MODE_STAT__MSK (0x03) +#define BMI160_USER_MAG_POWER_MODE_STAT__REG \ +(BMI160_USER_PMU_STAT_ADDR) +/**************************************************************/ +/**\name GYRO POWER MODE LENGTH, POSITION AND MASK */ +/**************************************************************/ +/* PMU_Status Description of GYRO - Reg Addr --> (0x03), Bit --> 3...2 */ +#define BMI160_USER_GYRO_POWER_MODE_STAT__POS (2) +#define BMI160_USER_GYRO_POWER_MODE_STAT__LEN (2) +#define BMI160_USER_GYRO_POWER_MODE_STAT__MSK (0x0C) +#define BMI160_USER_GYRO_POWER_MODE_STAT__REG \ +(BMI160_USER_PMU_STAT_ADDR) +/**************************************************************/ +/**\name ACCEL POWER MODE LENGTH, POSITION AND MASK */ +/**************************************************************/ +/* PMU_Status Description of ACCEL - Reg Addr --> (0x03), Bit --> 5...4 */ +#define BMI160_USER_ACCEL_POWER_MODE_STAT__POS (4) +#define BMI160_USER_ACCEL_POWER_MODE_STAT__LEN (2) +#define BMI160_USER_ACCEL_POWER_MODE_STAT__MSK (0x30) +#define BMI160_USER_ACCEL_POWER_MODE_STAT__REG \ +(BMI160_USER_PMU_STAT_ADDR) +/**************************************************************/ +/**\name MAG DATA XYZ LENGTH, POSITION AND MASK */ +/**************************************************************/ +/* Mag_X(LSB) Description - Reg Addr --> (0x04), Bit --> 0...7 */ +#define BMI160_USER_DATA_0_MAG_X_LSB__POS (0) +#define BMI160_USER_DATA_0_MAG_X_LSB__LEN (8) +#define BMI160_USER_DATA_0_MAG_X_LSB__MSK (0xFF) +#define BMI160_USER_DATA_0_MAG_X_LSB__REG (BMI160_USER_DATA_0_ADDR) + +/* Mag_X(LSB) Description - Reg Addr --> (0x04), Bit --> 3...7 */ +#define BMI160_USER_DATA_MAG_X_LSB__POS (3) +#define BMI160_USER_DATA_MAG_X_LSB__LEN (5) +#define BMI160_USER_DATA_MAG_X_LSB__MSK (0xF8) +#define BMI160_USER_DATA_MAG_X_LSB__REG (BMI160_USER_DATA_0_ADDR) + +/* Mag_X(MSB) Description - Reg Addr --> (0x05), Bit --> 0...7 */ +#define BMI160_USER_DATA_1_MAG_X_MSB__POS (0) +#define BMI160_USER_DATA_1_MAG_X_MSB__LEN (8) +#define BMI160_USER_DATA_1_MAG_X_MSB__MSK (0xFF) +#define BMI160_USER_DATA_1_MAG_X_MSB__REG (BMI160_USER_DATA_1_ADDR) + +/* Mag_Y(LSB) Description - Reg Addr --> (0x06), Bit --> 0...7 */ +#define BMI160_USER_DATA_2_MAG_Y_LSB__POS (0) +#define BMI160_USER_DATA_2_MAG_Y_LSB__LEN (8) +#define BMI160_USER_DATA_2_MAG_Y_LSB__MSK (0xFF) +#define BMI160_USER_DATA_2_MAG_Y_LSB__REG (BMI160_USER_DATA_2_ADDR) + +/* Mag_Y(LSB) Description - Reg Addr --> (0x06), Bit --> 3...7 */ +#define BMI160_USER_DATA_MAG_Y_LSB__POS (3) +#define BMI160_USER_DATA_MAG_Y_LSB__LEN (5) +#define BMI160_USER_DATA_MAG_Y_LSB__MSK (0xF8) +#define BMI160_USER_DATA_MAG_Y_LSB__REG (BMI160_USER_DATA_2_ADDR) + +/* Mag_Y(MSB) Description - Reg Addr --> (0x07), Bit --> 0...7 */ +#define BMI160_USER_DATA_3_MAG_Y_MSB__POS (0) +#define BMI160_USER_DATA_3_MAG_Y_MSB__LEN (8) +#define BMI160_USER_DATA_3_MAG_Y_MSB__MSK (0xFF) +#define BMI160_USER_DATA_3_MAG_Y_MSB__REG (BMI160_USER_DATA_3_ADDR) + +/* Mag_Z(LSB) Description - Reg Addr --> (0x08), Bit --> 0...7 */ +#define BMI160_USER_DATA_4_MAG_Z_LSB__POS (0) +#define BMI160_USER_DATA_4_MAG_Z_LSB__LEN (8) +#define BMI160_USER_DATA_4_MAG_Z_LSB__MSK (0xFF) +#define BMI160_USER_DATA_4_MAG_Z_LSB__REG (BMI160_USER_DATA_4_ADDR) + +/* Mag_X(LSB) Description - Reg Addr --> (0x08), Bit --> 3...7 */ +#define BMI160_USER_DATA_MAG_Z_LSB__POS (1) +#define BMI160_USER_DATA_MAG_Z_LSB__LEN (7) +#define BMI160_USER_DATA_MAG_Z_LSB__MSK (0xFE) +#define BMI160_USER_DATA_MAG_Z_LSB__REG (BMI160_USER_DATA_4_ADDR) + +/* Mag_Z(MSB) Description - Reg Addr --> (0x09), Bit --> 0...7 */ +#define BMI160_USER_DATA_5_MAG_Z_MSB__POS (0) +#define BMI160_USER_DATA_5_MAG_Z_MSB__LEN (8) +#define BMI160_USER_DATA_5_MAG_Z_MSB__MSK (0xFF) +#define BMI160_USER_DATA_5_MAG_Z_MSB__REG (BMI160_USER_DATA_5_ADDR) + +/* RHALL(LSB) Description - Reg Addr --> (0x0A), Bit --> 0...7 */ +#define BMI160_USER_DATA_6_RHALL_LSB__POS (0) +#define BMI160_USER_DATA_6_RHALL_LSB__LEN (8) +#define BMI160_USER_DATA_6_RHALL_LSB__MSK (0xFF) +#define BMI160_USER_DATA_6_RHALL_LSB__REG (BMI160_USER_DATA_6_ADDR) + +/* Mag_R(LSB) Description - Reg Addr --> (0x0A), Bit --> 3...7 */ +#define BMI160_USER_DATA_MAG_R_LSB__POS (2) +#define BMI160_USER_DATA_MAG_R_LSB__LEN (6) +#define BMI160_USER_DATA_MAG_R_LSB__MSK (0xFC) +#define BMI160_USER_DATA_MAG_R_LSB__REG (BMI160_USER_DATA_6_ADDR) + +/* RHALL(MSB) Description - Reg Addr --> (0x0B), Bit --> 0...7 */ +#define BMI160_USER_DATA_7_RHALL_MSB__POS (0) +#define BMI160_USER_DATA_7_RHALL_MSB__LEN (8) +#define BMI160_USER_DATA_7_RHALL_MSB__MSK (0xFF) +#define BMI160_USER_DATA_7_RHALL_MSB__REG (BMI160_USER_DATA_7_ADDR) +/**************************************************************/ +/**\name GYRO DATA XYZ LENGTH, POSITION AND MASK */ +/**************************************************************/ +/* GYR_X (LSB) Description - Reg Addr --> (0x0C), Bit --> 0...7 */ +#define BMI160_USER_DATA_8_GYRO_X_LSB__POS (0) +#define BMI160_USER_DATA_8_GYRO_X_LSB__LEN (8) +#define BMI160_USER_DATA_8_GYRO_X_LSB__MSK (0xFF) +#define BMI160_USER_DATA_8_GYRO_X_LSB__REG (BMI160_USER_DATA_8_ADDR) + +/* GYR_X (MSB) Description - Reg Addr --> (0x0D), Bit --> 0...7 */ +#define BMI160_USER_DATA_9_GYRO_X_MSB__POS (0) +#define BMI160_USER_DATA_9_GYRO_X_MSB__LEN (8) +#define BMI160_USER_DATA_9_GYRO_X_MSB__MSK (0xFF) +#define BMI160_USER_DATA_9_GYRO_X_MSB__REG (BMI160_USER_DATA_9_ADDR) + +/* GYR_Y (LSB) Description - Reg Addr --> 0x0E, Bit --> 0...7 */ +#define BMI160_USER_DATA_10_GYRO_Y_LSB__POS (0) +#define BMI160_USER_DATA_10_GYRO_Y_LSB__LEN (8) +#define BMI160_USER_DATA_10_GYRO_Y_LSB__MSK (0xFF) +#define BMI160_USER_DATA_10_GYRO_Y_LSB__REG (BMI160_USER_DATA_10_ADDR) + +/* GYR_Y (MSB) Description - Reg Addr --> (0x0F), Bit --> 0...7 */ +#define BMI160_USER_DATA_11_GYRO_Y_MSB__POS (0) +#define BMI160_USER_DATA_11_GYRO_Y_MSB__LEN (8) +#define BMI160_USER_DATA_11_GYRO_Y_MSB__MSK (0xFF) +#define BMI160_USER_DATA_11_GYRO_Y_MSB__REG (BMI160_USER_DATA_11_ADDR) + +/* GYR_Z (LSB) Description - Reg Addr --> (0x10), Bit --> 0...7 */ +#define BMI160_USER_DATA_12_GYRO_Z_LSB__POS (0) +#define BMI160_USER_DATA_12_GYRO_Z_LSB__LEN (8) +#define BMI160_USER_DATA_12_GYRO_Z_LSB__MSK (0xFF) +#define BMI160_USER_DATA_12_GYRO_Z_LSB__REG (BMI160_USER_DATA_12_ADDR) + +/* GYR_Z (MSB) Description - Reg Addr --> (0x11), Bit --> 0...7 */ +#define BMI160_USER_DATA_13_GYRO_Z_MSB__POS (0) +#define BMI160_USER_DATA_13_GYRO_Z_MSB__LEN (8) +#define BMI160_USER_DATA_13_GYRO_Z_MSB__MSK (0xFF) +#define BMI160_USER_DATA_13_GYRO_Z_MSB__REG (BMI160_USER_DATA_13_ADDR) +/**************************************************************/ +/**\name ACCEL DATA XYZ LENGTH, POSITION AND MASK */ +/**************************************************************/ +/* ACC_X (LSB) Description - Reg Addr --> (0x12), Bit --> 0...7 */ +#define BMI160_USER_DATA_14_ACCEL_X_LSB__POS (0) +#define BMI160_USER_DATA_14_ACCEL_X_LSB__LEN (8) +#define BMI160_USER_DATA_14_ACCEL_X_LSB__MSK (0xFF) +#define BMI160_USER_DATA_14_ACCEL_X_LSB__REG (BMI160_USER_DATA_14_ADDR) + +/* ACC_X (MSB) Description - Reg Addr --> 0x13, Bit --> 0...7 */ +#define BMI160_USER_DATA_15_ACCEL_X_MSB__POS (0) +#define BMI160_USER_DATA_15_ACCEL_X_MSB__LEN (8) +#define BMI160_USER_DATA_15_ACCEL_X_MSB__MSK (0xFF) +#define BMI160_USER_DATA_15_ACCEL_X_MSB__REG (BMI160_USER_DATA_15_ADDR) + +/* ACC_Y (LSB) Description - Reg Addr --> (0x14), Bit --> 0...7 */ +#define BMI160_USER_DATA_16_ACCEL_Y_LSB__POS (0) +#define BMI160_USER_DATA_16_ACCEL_Y_LSB__LEN (8) +#define BMI160_USER_DATA_16_ACCEL_Y_LSB__MSK (0xFF) +#define BMI160_USER_DATA_16_ACCEL_Y_LSB__REG (BMI160_USER_DATA_16_ADDR) + +/* ACC_Y (MSB) Description - Reg Addr --> (0x15), Bit --> 0...7 */ +#define BMI160_USER_DATA_17_ACCEL_Y_MSB__POS (0) +#define BMI160_USER_DATA_17_ACCEL_Y_MSB__LEN (8) +#define BMI160_USER_DATA_17_ACCEL_Y_MSB__MSK (0xFF) +#define BMI160_USER_DATA_17_ACCEL_Y_MSB__REG (BMI160_USER_DATA_17_ADDR) + +/* ACC_Z (LSB) Description - Reg Addr --> 0x16, Bit --> 0...7 */ +#define BMI160_USER_DATA_18_ACCEL_Z_LSB__POS (0) +#define BMI160_USER_DATA_18_ACCEL_Z_LSB__LEN (8) +#define BMI160_USER_DATA_18_ACCEL_Z_LSB__MSK (0xFF) +#define BMI160_USER_DATA_18_ACCEL_Z_LSB__REG (BMI160_USER_DATA_18_ADDR) + +/* ACC_Z (MSB) Description - Reg Addr --> (0x17), Bit --> 0...7 */ +#define BMI160_USER_DATA_19_ACCEL_Z_MSB__POS (0) +#define BMI160_USER_DATA_19_ACCEL_Z_MSB__LEN (8) +#define BMI160_USER_DATA_19_ACCEL_Z_MSB__MSK (0xFF) +#define BMI160_USER_DATA_19_ACCEL_Z_MSB__REG (BMI160_USER_DATA_19_ADDR) +/**************************************************************/ +/**\name SENSOR TIME LENGTH, POSITION AND MASK */ +/**************************************************************/ +/* SENSORTIME_0 (LSB) Description - Reg Addr --> (0x18), Bit --> 0...7 */ +#define BMI160_USER_SENSORTIME_0_SENSOR_TIME_LSB__POS (0) +#define BMI160_USER_SENSORTIME_0_SENSOR_TIME_LSB__LEN (8) +#define BMI160_USER_SENSORTIME_0_SENSOR_TIME_LSB__MSK (0xFF) +#define BMI160_USER_SENSORTIME_0_SENSOR_TIME_LSB__REG \ + (BMI160_USER_SENSORTIME_0_ADDR) + +/* SENSORTIME_1 (MSB) Description - Reg Addr --> (0x19), Bit --> 0...7 */ +#define BMI160_USER_SENSORTIME_1_SENSOR_TIME_MSB__POS (0) +#define BMI160_USER_SENSORTIME_1_SENSOR_TIME_MSB__LEN (8) +#define BMI160_USER_SENSORTIME_1_SENSOR_TIME_MSB__MSK (0xFF) +#define BMI160_USER_SENSORTIME_1_SENSOR_TIME_MSB__REG \ + (BMI160_USER_SENSORTIME_1_ADDR) + +/* SENSORTIME_2 (MSB) Description - Reg Addr --> (0x1A), Bit --> 0...7 */ +#define BMI160_USER_SENSORTIME_2_SENSOR_TIME_MSB__POS (0) +#define BMI160_USER_SENSORTIME_2_SENSOR_TIME_MSB__LEN (8) +#define BMI160_USER_SENSORTIME_2_SENSOR_TIME_MSB__MSK (0xFF) +#define BMI160_USER_SENSORTIME_2_SENSOR_TIME_MSB__REG \ + (BMI160_USER_SENSORTIME_2_ADDR) +/**************************************************************/ +/**\name GYRO SELF TEST LENGTH, POSITION AND MASK */ +/**************************************************************/ +/* Status Description - Reg Addr --> 0x1B, Bit --> 1 */ +#define BMI160_USER_STAT_GYRO_SELFTEST_OK__POS (1) +#define BMI160_USER_STAT_GYRO_SELFTEST_OK__LEN (1) +#define BMI160_USER_STAT_GYRO_SELFTEST_OK__MSK (0x02) +#define BMI160_USER_STAT_GYRO_SELFTEST_OK__REG \ + (BMI160_USER_STAT_ADDR) +/**************************************************************/ +/**\name MAG MANUAL OPERATION LENGTH, POSITION AND MASK */ +/**************************************************************/ +/* Status Description - Reg Addr --> 0x1B, Bit --> 2 */ +#define BMI160_USER_STAT_MAG_MANUAL_OPERATION__POS (2) +#define BMI160_USER_STAT_MAG_MANUAL_OPERATION__LEN (1) +#define BMI160_USER_STAT_MAG_MANUAL_OPERATION__MSK (0x04) +#define BMI160_USER_STAT_MAG_MANUAL_OPERATION__REG \ + (BMI160_USER_STAT_ADDR) +/**************************************************************/ +/**\name FOC STATUS LENGTH, POSITION AND MASK */ +/**************************************************************/ +/* Status Description - Reg Addr --> 0x1B, Bit --> 3 */ +#define BMI160_USER_STAT_FOC_RDY__POS (3) +#define BMI160_USER_STAT_FOC_RDY__LEN (1) +#define BMI160_USER_STAT_FOC_RDY__MSK (0x08) +#define BMI160_USER_STAT_FOC_RDY__REG (BMI160_USER_STAT_ADDR) +/**************************************************************/ +/**\name NVM READY LENGTH, POSITION AND MASK */ +/**************************************************************/ +/* Status Description - Reg Addr --> 0x1B, Bit --> 4 */ +#define BMI160_USER_STAT_NVM_RDY__POS (4) +#define BMI160_USER_STAT_NVM_RDY__LEN (1) +#define BMI160_USER_STAT_NVM_RDY__MSK (0x10) +#define BMI160_USER_STAT_NVM_RDY__REG (BMI160_USER_STAT_ADDR) +/**************************************************************/ +/**\name DATA READY LENGTH, POSITION AND MASK FOR ACCEL, MAG AND GYRO*/ +/**************************************************************/ +/* Status Description - Reg Addr --> 0x1B, Bit --> 5 */ +#define BMI160_USER_STAT_DATA_RDY_MAG__POS (5) +#define BMI160_USER_STAT_DATA_RDY_MAG__LEN (1) +#define BMI160_USER_STAT_DATA_RDY_MAG__MSK (0x20) +#define BMI160_USER_STAT_DATA_RDY_MAG__REG (BMI160_USER_STAT_ADDR) + +/* Status Description - Reg Addr --> 0x1B, Bit --> 6 */ +#define BMI160_USER_STAT_DATA_RDY_GYRO__POS (6) +#define BMI160_USER_STAT_DATA_RDY_GYRO__LEN (1) +#define BMI160_USER_STAT_DATA_RDY_GYRO__MSK (0x40) +#define BMI160_USER_STAT_DATA_RDY_GYRO__REG (BMI160_USER_STAT_ADDR) + +/* Status Description - Reg Addr --> 0x1B, Bit --> 7 */ +#define BMI160_USER_STAT_DATA_RDY_ACCEL__POS (7) +#define BMI160_USER_STAT_DATA_RDY_ACCEL__LEN (1) +#define BMI160_USER_STAT_DATA_RDY_ACCEL__MSK (0x80) +#define BMI160_USER_STAT_DATA_RDY_ACCEL__REG (BMI160_USER_STAT_ADDR) +/**************************************************************/ +/**\name INTERRUPT STATUS LENGTH, POSITION AND MASK */ +/**************************************************************/ +/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 0 */ +#define BMI160_USER_INTR_STAT_0_STEP_INTR__POS (0) +#define BMI160_USER_INTR_STAT_0_STEP_INTR__LEN (1) +#define BMI160_USER_INTR_STAT_0_STEP_INTR__MSK (0x01) +#define BMI160_USER_INTR_STAT_0_STEP_INTR__REG \ + (BMI160_USER_INTR_STAT_0_ADDR) +/**************************************************************/ +/**\name SIGNIFICANT INTERRUPT STATUS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 1 */ +#define BMI160_USER_INTR_STAT_0_SIGNIFICANT_INTR__POS (1) +#define BMI160_USER_INTR_STAT_0_SIGNIFICANT_INTR__LEN (1) +#define BMI160_USER_INTR_STAT_0_SIGNIFICANT_INTR__MSK (0x02) +#define BMI160_USER_INTR_STAT_0_SIGNIFICANT_INTR__REG \ + (BMI160_USER_INTR_STAT_0_ADDR) +/**************************************************************/ +/**\name ANY_MOTION INTERRUPT STATUS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 2 */ +#define BMI160_USER_INTR_STAT_0_ANY_MOTION__POS (2) +#define BMI160_USER_INTR_STAT_0_ANY_MOTION__LEN (1) +#define BMI160_USER_INTR_STAT_0_ANY_MOTION__MSK (0x04) +#define BMI160_USER_INTR_STAT_0_ANY_MOTION__REG \ + (BMI160_USER_INTR_STAT_0_ADDR) +/**************************************************************/ +/**\name PMU TRIGGER INTERRUPT STATUS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 3 */ +#define BMI160_USER_INTR_STAT_0_PMU_TRIGGER__POS 3 +#define BMI160_USER_INTR_STAT_0_PMU_TRIGGER__LEN (1) +#define BMI160_USER_INTR_STAT_0_PMU_TRIGGER__MSK (0x08) +#define BMI160_USER_INTR_STAT_0_PMU_TRIGGER__REG \ + (BMI160_USER_INTR_STAT_0_ADDR) +/**************************************************************/ +/**\name DOUBLE TAP INTERRUPT STATUS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 4 */ +#define BMI160_USER_INTR_STAT_0_DOUBLE_TAP_INTR__POS 4 +#define BMI160_USER_INTR_STAT_0_DOUBLE_TAP_INTR__LEN (1) +#define BMI160_USER_INTR_STAT_0_DOUBLE_TAP_INTR__MSK (0x10) +#define BMI160_USER_INTR_STAT_0_DOUBLE_TAP_INTR__REG \ + (BMI160_USER_INTR_STAT_0_ADDR) +/**************************************************************/ +/**\name SINGLE TAP INTERRUPT STATUS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 5 */ +#define BMI160_USER_INTR_STAT_0_SINGLE_TAP_INTR__POS 5 +#define BMI160_USER_INTR_STAT_0_SINGLE_TAP_INTR__LEN (1) +#define BMI160_USER_INTR_STAT_0_SINGLE_TAP_INTR__MSK (0x20) +#define BMI160_USER_INTR_STAT_0_SINGLE_TAP_INTR__REG \ + (BMI160_USER_INTR_STAT_0_ADDR) +/**************************************************************/ +/**\name ORIENT INTERRUPT STATUS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 6 */ +#define BMI160_USER_INTR_STAT_0_ORIENT__POS (6) +#define BMI160_USER_INTR_STAT_0_ORIENT__LEN (1) +#define BMI160_USER_INTR_STAT_0_ORIENT__MSK (0x40) +#define BMI160_USER_INTR_STAT_0_ORIENT__REG \ + (BMI160_USER_INTR_STAT_0_ADDR) +/**************************************************************/ +/**\name FLAT INTERRUPT STATUS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 7 */ +#define BMI160_USER_INTR_STAT_0_FLAT__POS (7) +#define BMI160_USER_INTR_STAT_0_FLAT__LEN (1) +#define BMI160_USER_INTR_STAT_0_FLAT__MSK (0x80) +#define BMI160_USER_INTR_STAT_0_FLAT__REG \ + (BMI160_USER_INTR_STAT_0_ADDR) +/**************************************************************/ +/**\name HIGH_G INTERRUPT STATUS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 2 */ +#define BMI160_USER_INTR_STAT_1_HIGH_G_INTR__POS (2) +#define BMI160_USER_INTR_STAT_1_HIGH_G_INTR__LEN (1) +#define BMI160_USER_INTR_STAT_1_HIGH_G_INTR__MSK (0x04) +#define BMI160_USER_INTR_STAT_1_HIGH_G_INTR__REG \ + (BMI160_USER_INTR_STAT_1_ADDR) +/**************************************************************/ +/**\name LOW_G INTERRUPT STATUS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 3 */ +#define BMI160_USER_INTR_STAT_1_LOW_G_INTR__POS (3) +#define BMI160_USER_INTR_STAT_1_LOW_G_INTR__LEN (1) +#define BMI160_USER_INTR_STAT_1_LOW_G_INTR__MSK (0x08) +#define BMI160_USER_INTR_STAT_1_LOW_G_INTR__REG \ + (BMI160_USER_INTR_STAT_1_ADDR) +/**************************************************************/ +/**\name DATA READY INTERRUPT STATUS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 4 */ +#define BMI160_USER_INTR_STAT_1_DATA_RDY_INTR__POS (4) +#define BMI160_USER_INTR_STAT_1_DATA_RDY_INTR__LEN (1) +#define BMI160_USER_INTR_STAT_1_DATA_RDY_INTR__MSK (0x10) +#define BMI160_USER_INTR_STAT_1_DATA_RDY_INTR__REG \ + (BMI160_USER_INTR_STAT_1_ADDR) +/**************************************************************/ +/**\name FIFO FULL INTERRUPT STATUS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 5 */ +#define BMI160_USER_INTR_STAT_1_FIFO_FULL_INTR__POS (5) +#define BMI160_USER_INTR_STAT_1_FIFO_FULL_INTR__LEN (1) +#define BMI160_USER_INTR_STAT_1_FIFO_FULL_INTR__MSK (0x20) +#define BMI160_USER_INTR_STAT_1_FIFO_FULL_INTR__REG \ + (BMI160_USER_INTR_STAT_1_ADDR) +/**************************************************************/ +/**\name FIFO WATERMARK INTERRUPT STATUS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 6 */ +#define BMI160_USER_INTR_STAT_1_FIFO_WM_INTR__POS (6) +#define BMI160_USER_INTR_STAT_1_FIFO_WM_INTR__LEN (1) +#define BMI160_USER_INTR_STAT_1_FIFO_WM_INTR__MSK (0x40) +#define BMI160_USER_INTR_STAT_1_FIFO_WM_INTR__REG \ + (BMI160_USER_INTR_STAT_1_ADDR) +/**************************************************************/ +/**\name NO MOTION INTERRUPT STATUS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 7 */ +#define BMI160_USER_INTR_STAT_1_NOMOTION_INTR__POS (7) +#define BMI160_USER_INTR_STAT_1_NOMOTION_INTR__LEN (1) +#define BMI160_USER_INTR_STAT_1_NOMOTION_INTR__MSK (0x80) +#define BMI160_USER_INTR_STAT_1_NOMOTION_INTR__REG \ + (BMI160_USER_INTR_STAT_1_ADDR) +/**************************************************************/ +/**\name ANY MOTION-XYZ AXIS INTERRUPT STATUS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 0 */ +#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__POS (0) +#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__LEN (1) +#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__MSK (0x01) +#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__REG \ + (BMI160_USER_INTR_STAT_2_ADDR) + +/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 1 */ +#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__POS (1) +#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__LEN (1) +#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__MSK (0x02) +#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__REG \ + (BMI160_USER_INTR_STAT_2_ADDR) + +/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 2 */ +#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__POS (2) +#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__LEN (1) +#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__MSK (0x04) +#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__REG \ + (BMI160_USER_INTR_STAT_2_ADDR) +/**************************************************************/ +/**\name ANY MOTION SIGN LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 3 */ +#define BMI160_USER_INTR_STAT_2_ANY_MOTION_SIGN__POS (3) +#define BMI160_USER_INTR_STAT_2_ANY_MOTION_SIGN__LEN (1) +#define BMI160_USER_INTR_STAT_2_ANY_MOTION_SIGN__MSK (0x08) +#define BMI160_USER_INTR_STAT_2_ANY_MOTION_SIGN__REG \ + (BMI160_USER_INTR_STAT_2_ADDR) +/**************************************************************/ +/**\name TAP_XYZ AND SIGN LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 4 */ +#define BMI160_USER_INTR_STAT_2_TAP_FIRST_X__POS (4) +#define BMI160_USER_INTR_STAT_2_TAP_FIRST_X__LEN (1) +#define BMI160_USER_INTR_STAT_2_TAP_FIRST_X__MSK (0x10) +#define BMI160_USER_INTR_STAT_2_TAP_FIRST_X__REG \ + (BMI160_USER_INTR_STAT_2_ADDR) + +/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 5 */ +#define BMI160_USER_INTR_STAT_2_TAP_FIRST_Y__POS (5) +#define BMI160_USER_INTR_STAT_2_TAP_FIRST_Y__LEN (1) +#define BMI160_USER_INTR_STAT_2_TAP_FIRST_Y__MSK (0x20) +#define BMI160_USER_INTR_STAT_2_TAP_FIRST_Y__REG \ + (BMI160_USER_INTR_STAT_2_ADDR) + +/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 6 */ +#define BMI160_USER_INTR_STAT_2_TAP_FIRST_Z__POS (6) +#define BMI160_USER_INTR_STAT_2_TAP_FIRST_Z__LEN (1) +#define BMI160_USER_INTR_STAT_2_TAP_FIRST_Z__MSK (0x40) +#define BMI160_USER_INTR_STAT_2_TAP_FIRST_Z__REG \ + (BMI160_USER_INTR_STAT_2_ADDR) + +/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 7 */ +#define BMI160_USER_INTR_STAT_2_TAP_SIGN__POS (7) +#define BMI160_USER_INTR_STAT_2_TAP_SIGN__LEN (1) +#define BMI160_USER_INTR_STAT_2_TAP_SIGN__MSK (0x80) +#define BMI160_USER_INTR_STAT_2_TAP_SIGN__REG \ + (BMI160_USER_INTR_STAT_2_ADDR) +/**************************************************************/ +/**\name INTERRUPT SATAUS FOR WHOLE 0x1E LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 0...7 */ +#define BMI160_USER_INTR_STAT_2__POS (0) +#define BMI160_USER_INTR_STAT_2__LEN (8) +#define BMI160_USER_INTR_STAT_2__MSK (0xFF) +#define BMI160_USER_INTR_STAT_2__REG \ + (BMI160_USER_INTR_STAT_2_ADDR) +/**************************************************************/ +/**\name HIGH_G-XYZ AND SIGN LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 0 */ +#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_X__POS (0) +#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_X__LEN (1) +#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_X__MSK (0x01) +#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_X__REG \ + (BMI160_USER_INTR_STAT_3_ADDR) + +/* Int_Status_3 Description - Reg Addr --> 0x1E, Bit --> 1 */ +#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Y__POS (1) +#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Y__LEN (1) +#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Y__MSK (0x02) +#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Y__REG \ + (BMI160_USER_INTR_STAT_3_ADDR) + +/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 2 */ +#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Z__POS (2) +#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Z__LEN (1) +#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Z__MSK (0x04) +#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Z__REG \ + (BMI160_USER_INTR_STAT_3_ADDR) + +/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 3 */ +#define BMI160_USER_INTR_STAT_3_HIGH_G_SIGN__POS (3) +#define BMI160_USER_INTR_STAT_3_HIGH_G_SIGN__LEN (1) +#define BMI160_USER_INTR_STAT_3_HIGH_G_SIGN__MSK (0x08) +#define BMI160_USER_INTR_STAT_3_HIGH_G_SIGN__REG \ + (BMI160_USER_INTR_STAT_3_ADDR) +/**************************************************************/ +/**\name ORIENT XY and Z AXIS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 4...5 */ +#define BMI160_USER_INTR_STAT_3_ORIENT_XY__POS (4) +#define BMI160_USER_INTR_STAT_3_ORIENT_XY__LEN (2) +#define BMI160_USER_INTR_STAT_3_ORIENT_XY__MSK (0x30) +#define BMI160_USER_INTR_STAT_3_ORIENT_XY__REG \ + (BMI160_USER_INTR_STAT_3_ADDR) + +/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 6 */ +#define BMI160_USER_INTR_STAT_3_ORIENT_Z__POS (6) +#define BMI160_USER_INTR_STAT_3_ORIENT_Z__LEN (1) +#define BMI160_USER_INTR_STAT_3_ORIENT_Z__MSK (0x40) +#define BMI160_USER_INTR_STAT_3_ORIENT_Z__REG \ + (BMI160_USER_INTR_STAT_3_ADDR) +/**************************************************************/ +/**\name FLAT LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 7 */ +#define BMI160_USER_INTR_STAT_3_FLAT__POS (7) +#define BMI160_USER_INTR_STAT_3_FLAT__LEN (1) +#define BMI160_USER_INTR_STAT_3_FLAT__MSK (0x80) +#define BMI160_USER_INTR_STAT_3_FLAT__REG \ + (BMI160_USER_INTR_STAT_3_ADDR) +/**************************************************************/ +/**\name (0x1F) LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 0...7 */ +#define BMI160_USER_INTR_STAT_3__POS (0) +#define BMI160_USER_INTR_STAT_3__LEN (8) +#define BMI160_USER_INTR_STAT_3__MSK (0xFF) +#define BMI160_USER_INTR_STAT_3__REG \ + (BMI160_USER_INTR_STAT_3_ADDR) +/**************************************************************/ +/**\name TEMPERATURE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Temperature Description - LSB Reg Addr --> (0x20), Bit --> 0...7 */ +#define BMI160_USER_TEMP_LSB_VALUE__POS (0) +#define BMI160_USER_TEMP_LSB_VALUE__LEN (8) +#define BMI160_USER_TEMP_LSB_VALUE__MSK (0xFF) +#define BMI160_USER_TEMP_LSB_VALUE__REG \ + (BMI160_USER_TEMPERATURE_0_ADDR) + +/* Temperature Description - LSB Reg Addr --> 0x21, Bit --> 0...7 */ +#define BMI160_USER_TEMP_MSB_VALUE__POS (0) +#define BMI160_USER_TEMP_MSB_VALUE__LEN (8) +#define BMI160_USER_TEMP_MSB_VALUE__MSK (0xFF) +#define BMI160_USER_TEMP_MSB_VALUE__REG \ + (BMI160_USER_TEMPERATURE_1_ADDR) +/**************************************************************/ +/**\name FIFO BYTE COUNTER LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Fifo_Length0 Description - Reg Addr --> 0x22, Bit --> 0...7 */ +#define BMI160_USER_FIFO_BYTE_COUNTER_LSB__POS (0) +#define BMI160_USER_FIFO_BYTE_COUNTER_LSB__LEN (8) +#define BMI160_USER_FIFO_BYTE_COUNTER_LSB__MSK (0xFF) +#define BMI160_USER_FIFO_BYTE_COUNTER_LSB__REG \ + (BMI160_USER_FIFO_LENGTH_0_ADDR) + +/*Fifo_Length1 Description - Reg Addr --> 0x23, Bit --> 0...2 */ +#define BMI160_USER_FIFO_BYTE_COUNTER_MSB__POS (0) +#define BMI160_USER_FIFO_BYTE_COUNTER_MSB__LEN 3 +#define BMI160_USER_FIFO_BYTE_COUNTER_MSB__MSK (0x07) +#define BMI160_USER_FIFO_BYTE_COUNTER_MSB__REG \ + (BMI160_USER_FIFO_LENGTH_1_ADDR) + +/**************************************************************/ +/**\name FIFO DATA LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Fifo_Data Description - Reg Addr --> 0x24, Bit --> 0...7 */ +#define BMI160_USER_FIFO_DATA__POS (0) +#define BMI160_USER_FIFO_DATA__LEN (8) +#define BMI160_USER_FIFO_DATA__MSK (0xFF) +#define BMI160_USER_FIFO_DATA__REG (BMI160_USER_FIFO_DATA_ADDR) + +/**************************************************************/ +/**\name ACCEL CONFIGURATION LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Acc_Conf Description - Reg Addr --> (0x40), Bit --> 0...3 */ +#define BMI160_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__POS (0) +#define BMI160_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__LEN (4) +#define BMI160_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__MSK (0x0F) +#define BMI160_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__REG \ +(BMI160_USER_ACCEL_CONFIG_ADDR) + +/* Acc_Conf Description - Reg Addr --> (0x40), Bit --> 4...6 */ +#define BMI160_USER_ACCEL_CONFIG_ACCEL_BW__POS (4) +#define BMI160_USER_ACCEL_CONFIG_ACCEL_BW__LEN (3) +#define BMI160_USER_ACCEL_CONFIG_ACCEL_BW__MSK (0x70) +#define BMI160_USER_ACCEL_CONFIG_ACCEL_BW__REG (BMI160_USER_ACCEL_CONFIG_ADDR) + +/* Acc_Conf Description - Reg Addr --> (0x40), Bit --> 7 */ +#define BMI160_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__POS (7) +#define BMI160_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__LEN (1) +#define BMI160_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__MSK (0x80) +#define BMI160_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__REG \ +(BMI160_USER_ACCEL_CONFIG_ADDR) + +/* Acc_Range Description - Reg Addr --> 0x41, Bit --> 0...3 */ +#define BMI160_USER_ACCEL_RANGE__POS (0) +#define BMI160_USER_ACCEL_RANGE__LEN (4) +#define BMI160_USER_ACCEL_RANGE__MSK (0x0F) +#define BMI160_USER_ACCEL_RANGE__REG \ +(BMI160_USER_ACCEL_RANGE_ADDR) +/**************************************************************/ +/**\name GYRO CONFIGURATION LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Gyro_Conf Description - Reg Addr --> (0x42), Bit --> 0...3 */ +#define BMI160_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__POS (0) +#define BMI160_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__LEN (4) +#define BMI160_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__MSK (0x0F) +#define BMI160_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__REG \ +(BMI160_USER_GYRO_CONFIG_ADDR) + +/* Gyro_Conf Description - Reg Addr --> (0x42), Bit --> 4...5 */ +#define BMI160_USER_GYRO_CONFIG_BW__POS (4) +#define BMI160_USER_GYRO_CONFIG_BW__LEN (2) +#define BMI160_USER_GYRO_CONFIG_BW__MSK (0x30) +#define BMI160_USER_GYRO_CONFIG_BW__REG \ +(BMI160_USER_GYRO_CONFIG_ADDR) + +/* Gyr_Range Description - Reg Addr --> 0x43, Bit --> 0...2 */ +#define BMI160_USER_GYRO_RANGE__POS (0) +#define BMI160_USER_GYRO_RANGE__LEN (3) +#define BMI160_USER_GYRO_RANGE__MSK (0x07) +#define BMI160_USER_GYRO_RANGE__REG (BMI160_USER_GYRO_RANGE_ADDR) +/**************************************************************/ +/**\name MAG CONFIGURATION LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Mag_Conf Description - Reg Addr --> (0x44), Bit --> 0...3 */ +#define BMI160_USER_MAG_CONFIG_OUTPUT_DATA_RATE__POS (0) +#define BMI160_USER_MAG_CONFIG_OUTPUT_DATA_RATE__LEN (4) +#define BMI160_USER_MAG_CONFIG_OUTPUT_DATA_RATE__MSK (0x0F) +#define BMI160_USER_MAG_CONFIG_OUTPUT_DATA_RATE__REG \ +(BMI160_USER_MAG_CONFIG_ADDR) +/**************************************************************/ +/**\name FIFO DOWNS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Fifo_Downs Description - Reg Addr --> 0x45, Bit --> 0...2 */ +#define BMI160_USER_FIFO_DOWN_GYRO__POS (0) +#define BMI160_USER_FIFO_DOWN_GYRO__LEN (3) +#define BMI160_USER_FIFO_DOWN_GYRO__MSK (0x07) +#define BMI160_USER_FIFO_DOWN_GYRO__REG (BMI160_USER_FIFO_DOWN_ADDR) +/**************************************************************/ +/**\name FIFO FILTER FOR ACCEL AND GYRO LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Fifo_filt Description - Reg Addr --> 0x45, Bit --> 3 */ +#define BMI160_USER_FIFO_FILTER_GYRO__POS (3) +#define BMI160_USER_FIFO_FILTER_GYRO__LEN (1) +#define BMI160_USER_FIFO_FILTER_GYRO__MSK (0x08) +#define BMI160_USER_FIFO_FILTER_GYRO__REG (BMI160_USER_FIFO_DOWN_ADDR) + +/* Fifo_Downs Description - Reg Addr --> 0x45, Bit --> 4...6 */ +#define BMI160_USER_FIFO_DOWN_ACCEL__POS (4) +#define BMI160_USER_FIFO_DOWN_ACCEL__LEN (3) +#define BMI160_USER_FIFO_DOWN_ACCEL__MSK (0x70) +#define BMI160_USER_FIFO_DOWN_ACCEL__REG (BMI160_USER_FIFO_DOWN_ADDR) + +/* Fifo_FILT Description - Reg Addr --> 0x45, Bit --> 7 */ +#define BMI160_USER_FIFO_FILTER_ACCEL__POS (7) +#define BMI160_USER_FIFO_FILTER_ACCEL__LEN (1) +#define BMI160_USER_FIFO_FILTER_ACCEL__MSK (0x80) +#define BMI160_USER_FIFO_FILTER_ACCEL__REG (BMI160_USER_FIFO_DOWN_ADDR) +/**************************************************************/ +/**\name FIFO WATER MARK LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Fifo_Config_0 Description - Reg Addr --> 0x46, Bit --> 0...7 */ +#define BMI160_USER_FIFO_WM__POS (0) +#define BMI160_USER_FIFO_WM__LEN (8) +#define BMI160_USER_FIFO_WM__MSK (0xFF) +#define BMI160_USER_FIFO_WM__REG (BMI160_USER_FIFO_CONFIG_0_ADDR) +/**************************************************************/ +/**\name FIFO TIME LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 1 */ +#define BMI160_USER_FIFO_TIME_ENABLE__POS (1) +#define BMI160_USER_FIFO_TIME_ENABLE__LEN (1) +#define BMI160_USER_FIFO_TIME_ENABLE__MSK (0x02) +#define BMI160_USER_FIFO_TIME_ENABLE__REG (BMI160_USER_FIFO_CONFIG_1_ADDR) +/**************************************************************/ +/**\name FIFO TAG INTERRUPT LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 2 */ +#define BMI160_USER_FIFO_TAG_INTR2_ENABLE__POS (2) +#define BMI160_USER_FIFO_TAG_INTR2_ENABLE__LEN (1) +#define BMI160_USER_FIFO_TAG_INTR2_ENABLE__MSK (0x04) +#define BMI160_USER_FIFO_TAG_INTR2_ENABLE__REG (BMI160_USER_FIFO_CONFIG_1_ADDR) + +/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 3 */ +#define BMI160_USER_FIFO_TAG_INTR1_ENABLE__POS (3) +#define BMI160_USER_FIFO_TAG_INTR1_ENABLE__LEN (1) +#define BMI160_USER_FIFO_TAG_INTR1_ENABLE__MSK (0x08) +#define BMI160_USER_FIFO_TAG_INTR1_ENABLE__REG (BMI160_USER_FIFO_CONFIG_1_ADDR) +/**************************************************************/ +/**\name FIFO HEADER LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 4 */ +#define BMI160_USER_FIFO_HEADER_ENABLE__POS (4) +#define BMI160_USER_FIFO_HEADER_ENABLE__LEN (1) +#define BMI160_USER_FIFO_HEADER_ENABLE__MSK (0x10) +#define BMI160_USER_FIFO_HEADER_ENABLE__REG \ +(BMI160_USER_FIFO_CONFIG_1_ADDR) +/**************************************************************/ +/**\name FIFO MAG ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 5 */ +#define BMI160_USER_FIFO_MAG_ENABLE__POS (5) +#define BMI160_USER_FIFO_MAG_ENABLE__LEN (1) +#define BMI160_USER_FIFO_MAG_ENABLE__MSK (0x20) +#define BMI160_USER_FIFO_MAG_ENABLE__REG \ +(BMI160_USER_FIFO_CONFIG_1_ADDR) +/**************************************************************/ +/**\name FIFO ACCEL ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 6 */ +#define BMI160_USER_FIFO_ACCEL_ENABLE__POS (6) +#define BMI160_USER_FIFO_ACCEL_ENABLE__LEN (1) +#define BMI160_USER_FIFO_ACCEL_ENABLE__MSK (0x40) +#define BMI160_USER_FIFO_ACCEL_ENABLE__REG \ +(BMI160_USER_FIFO_CONFIG_1_ADDR) +/**************************************************************/ +/**\name FIFO GYRO ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 7 */ +#define BMI160_USER_FIFO_GYRO_ENABLE__POS (7) +#define BMI160_USER_FIFO_GYRO_ENABLE__LEN (1) +#define BMI160_USER_FIFO_GYRO_ENABLE__MSK (0x80) +#define BMI160_USER_FIFO_GYRO_ENABLE__REG \ +(BMI160_USER_FIFO_CONFIG_1_ADDR) + +/**************************************************************/ +/**\name MAG I2C ADDRESS SELECTION LENGTH, POSITION AND MASK*/ +/**************************************************************/ + +/* Mag_IF_0 Description - Reg Addr --> 0x4b, Bit --> 1...7 */ +#define BMI160_USER_I2C_DEVICE_ADDR__POS (1) +#define BMI160_USER_I2C_DEVICE_ADDR__LEN (7) +#define BMI160_USER_I2C_DEVICE_ADDR__MSK (0xFE) +#define BMI160_USER_I2C_DEVICE_ADDR__REG (BMI160_USER_MAG_IF_0_ADDR) +/**************************************************************/ +/**\name MAG CONFIGURATION FOR SECONDARY + INTERFACE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Mag_IF_1 Description - Reg Addr --> 0x4c, Bit --> 0...1 */ +#define BMI160_USER_MAG_BURST__POS (0) +#define BMI160_USER_MAG_BURST__LEN (2) +#define BMI160_USER_MAG_BURST__MSK (0x03) +#define BMI160_USER_MAG_BURST__REG (BMI160_USER_MAG_IF_1_ADDR) + +/* Mag_IF_1 Description - Reg Addr --> 0x4c, Bit --> 2...5 */ +#define BMI160_USER_MAG_OFFSET__POS (2) +#define BMI160_USER_MAG_OFFSET__LEN (4) +#define BMI160_USER_MAG_OFFSET__MSK (0x3C) +#define BMI160_USER_MAG_OFFSET__REG (BMI160_USER_MAG_IF_1_ADDR) + +/* Mag_IF_1 Description - Reg Addr --> 0x4c, Bit --> 7 */ +#define BMI160_USER_MAG_MANUAL_ENABLE__POS (7) +#define BMI160_USER_MAG_MANUAL_ENABLE__LEN (1) +#define BMI160_USER_MAG_MANUAL_ENABLE__MSK (0x80) +#define BMI160_USER_MAG_MANUAL_ENABLE__REG \ +(BMI160_USER_MAG_IF_1_ADDR) + +/* Mag_IF_2 Description - Reg Addr --> 0x4d, Bit -->0... 7 */ +#define BMI160_USER_READ_ADDR__POS (0) +#define BMI160_USER_READ_ADDR__LEN (8) +#define BMI160_USER_READ_ADDR__MSK (0xFF) +#define BMI160_USER_READ_ADDR__REG (BMI160_USER_MAG_IF_2_ADDR) + +/* Mag_IF_3 Description - Reg Addr --> 0x4e, Bit -->0... 7 */ +#define BMI160_USER_WRITE_ADDR__POS (0) +#define BMI160_USER_WRITE_ADDR__LEN (8) +#define BMI160_USER_WRITE_ADDR__MSK (0xFF) +#define BMI160_USER_WRITE_ADDR__REG (BMI160_USER_MAG_IF_3_ADDR) + +/* Mag_IF_4 Description - Reg Addr --> 0x4f, Bit -->0... 7 */ +#define BMI160_USER_WRITE_DATA__POS (0) +#define BMI160_USER_WRITE_DATA__LEN (8) +#define BMI160_USER_WRITE_DATA__MSK (0xFF) +#define BMI160_USER_WRITE_DATA__REG (BMI160_USER_MAG_IF_4_ADDR) +/**************************************************************/ +/**\name ANY MOTION XYZ AXIS ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->0 */ +#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__POS (0) +#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__LEN (1) +#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__MSK (0x01) +#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__REG \ +(BMI160_USER_INTR_ENABLE_0_ADDR) + +/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->1 */ +#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__POS (1) +#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__LEN (1) +#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__MSK (0x02) +#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__REG \ +(BMI160_USER_INTR_ENABLE_0_ADDR) + +/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->2 */ +#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__POS (2) +#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__LEN (1) +#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__MSK (0x04) +#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__REG \ +(BMI160_USER_INTR_ENABLE_0_ADDR) +/**************************************************************/ +/**\name DOUBLE TAP ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->4 */ +#define BMI160_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__POS (4) +#define BMI160_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__LEN (1) +#define BMI160_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__MSK (0x10) +#define BMI160_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__REG \ +(BMI160_USER_INTR_ENABLE_0_ADDR) +/**************************************************************/ +/**\name SINGLE TAP ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->5 */ +#define BMI160_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__POS (5) +#define BMI160_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__LEN (1) +#define BMI160_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__MSK (0x20) +#define BMI160_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__REG \ +(BMI160_USER_INTR_ENABLE_0_ADDR) +/**************************************************************/ +/**\name ORIENT ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->6 */ +#define BMI160_USER_INTR_ENABLE_0_ORIENT_ENABLE__POS (6) +#define BMI160_USER_INTR_ENABLE_0_ORIENT_ENABLE__LEN (1) +#define BMI160_USER_INTR_ENABLE_0_ORIENT_ENABLE__MSK (0x40) +#define BMI160_USER_INTR_ENABLE_0_ORIENT_ENABLE__REG \ +(BMI160_USER_INTR_ENABLE_0_ADDR) +/**************************************************************/ +/**\name FLAT ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->7 */ +#define BMI160_USER_INTR_ENABLE_0_FLAT_ENABLE__POS (7) +#define BMI160_USER_INTR_ENABLE_0_FLAT_ENABLE__LEN (1) +#define BMI160_USER_INTR_ENABLE_0_FLAT_ENABLE__MSK (0x80) +#define BMI160_USER_INTR_ENABLE_0_FLAT_ENABLE__REG \ +(BMI160_USER_INTR_ENABLE_0_ADDR) +/**************************************************************/ +/**\name HIGH_G XYZ ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->0 */ +#define BMI160_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__POS (0) +#define BMI160_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__LEN (1) +#define BMI160_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__MSK (0x01) +#define BMI160_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__REG \ +(BMI160_USER_INTR_ENABLE_1_ADDR) + +/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->1 */ +#define BMI160_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__POS (1) +#define BMI160_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__LEN (1) +#define BMI160_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__MSK (0x02) +#define BMI160_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__REG \ +(BMI160_USER_INTR_ENABLE_1_ADDR) + +/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->2 */ +#define BMI160_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__POS (2) +#define BMI160_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__LEN (1) +#define BMI160_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__MSK (0x04) +#define BMI160_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__REG \ +(BMI160_USER_INTR_ENABLE_1_ADDR) +/**************************************************************/ +/**\name LOW_G ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->3 */ +#define BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__POS (3) +#define BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__LEN (1) +#define BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__MSK (0x08) +#define BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG \ +(BMI160_USER_INTR_ENABLE_1_ADDR) +/**************************************************************/ +/**\name DATA READY ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->4 */ +#define BMI160_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__POS (4) +#define BMI160_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__LEN (1) +#define BMI160_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__MSK (0x10) +#define BMI160_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__REG \ +(BMI160_USER_INTR_ENABLE_1_ADDR) +/**************************************************************/ +/**\name FIFO FULL AND WATER MARK ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->5 */ +#define BMI160_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__POS (5) +#define BMI160_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__LEN (1) +#define BMI160_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__MSK (0x20) +#define BMI160_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__REG \ +(BMI160_USER_INTR_ENABLE_1_ADDR) + +/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->6 */ +#define BMI160_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__POS (6) +#define BMI160_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__LEN (1) +#define BMI160_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__MSK (0x40) +#define BMI160_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__REG \ +(BMI160_USER_INTR_ENABLE_1_ADDR) +/**************************************************************/ +/**\name NO MOTION XYZ ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_En_2 Description - Reg Addr --> (0x52), Bit -->0 */ +#define BMI160_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__POS (0) +#define BMI160_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__LEN (1) +#define BMI160_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__MSK (0x01) +#define BMI160_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__REG \ +(BMI160_USER_INTR_ENABLE_2_ADDR) + +/* Int_En_2 Description - Reg Addr --> (0x52), Bit -->1 */ +#define BMI160_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__POS (1) +#define BMI160_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__LEN (1) +#define BMI160_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__MSK (0x02) +#define BMI160_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__REG \ +(BMI160_USER_INTR_ENABLE_2_ADDR) + +/* Int_En_2 Description - Reg Addr --> (0x52), Bit -->2 */ +#define BMI160_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__POS (2) +#define BMI160_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__LEN (1) +#define BMI160_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__MSK (0x04) +#define BMI160_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__REG \ +(BMI160_USER_INTR_ENABLE_2_ADDR) +/**************************************************************/ +/**\name STEP DETECTOR ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_En_2 Description - Reg Addr --> (0x52), Bit -->3 */ +#define BMI160_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__POS (3) +#define BMI160_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__LEN (1) +#define BMI160_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__MSK (0x08) +#define BMI160_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__REG \ +(BMI160_USER_INTR_ENABLE_2_ADDR) +/**************************************************************/ +/**\name EDGE CONTROL ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->0 */ +#define BMI160_USER_INTR1_EDGE_CTRL__POS (0) +#define BMI160_USER_INTR1_EDGE_CTRL__LEN (1) +#define BMI160_USER_INTR1_EDGE_CTRL__MSK (0x01) +#define BMI160_USER_INTR1_EDGE_CTRL__REG \ +(BMI160_USER_INTR_OUT_CTRL_ADDR) +/**************************************************************/ +/**\name LEVEL CONTROL ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->1 */ +#define BMI160_USER_INTR1_LEVEL__POS (1) +#define BMI160_USER_INTR1_LEVEL__LEN (1) +#define BMI160_USER_INTR1_LEVEL__MSK (0x02) +#define BMI160_USER_INTR1_LEVEL__REG \ +(BMI160_USER_INTR_OUT_CTRL_ADDR) +/**************************************************************/ +/**\name OUTPUT TYPE ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->2 */ +#define BMI160_USER_INTR1_OUTPUT_TYPE__POS (2) +#define BMI160_USER_INTR1_OUTPUT_TYPE__LEN (1) +#define BMI160_USER_INTR1_OUTPUT_TYPE__MSK (0x04) +#define BMI160_USER_INTR1_OUTPUT_TYPE__REG \ +(BMI160_USER_INTR_OUT_CTRL_ADDR) +/**************************************************************/ +/**\name OUTPUT TYPE ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->3 */ +#define BMI160_USER_INTR1_OUTPUT_ENABLE__POS (3) +#define BMI160_USER_INTR1_OUTPUT_ENABLE__LEN (1) +#define BMI160_USER_INTR1_OUTPUT_ENABLE__MSK (0x08) +#define BMI160_USER_INTR1_OUTPUT_ENABLE__REG \ +(BMI160_USER_INTR_OUT_CTRL_ADDR) +/**************************************************************/ +/**\name EDGE CONTROL ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->4 */ +#define BMI160_USER_INTR2_EDGE_CTRL__POS (4) +#define BMI160_USER_INTR2_EDGE_CTRL__LEN (1) +#define BMI160_USER_INTR2_EDGE_CTRL__MSK (0x10) +#define BMI160_USER_INTR2_EDGE_CTRL__REG \ +(BMI160_USER_INTR_OUT_CTRL_ADDR) +/**************************************************************/ +/**\name LEVEL CONTROL ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->5 */ +#define BMI160_USER_INTR2_LEVEL__POS (5) +#define BMI160_USER_INTR2_LEVEL__LEN (1) +#define BMI160_USER_INTR2_LEVEL__MSK (0x20) +#define BMI160_USER_INTR2_LEVEL__REG \ +(BMI160_USER_INTR_OUT_CTRL_ADDR) +/**************************************************************/ +/**\name OUTPUT TYPE ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->6 */ +#define BMI160_USER_INTR2_OUTPUT_TYPE__POS (6) +#define BMI160_USER_INTR2_OUTPUT_TYPE__LEN (1) +#define BMI160_USER_INTR2_OUTPUT_TYPE__MSK (0x40) +#define BMI160_USER_INTR2_OUTPUT_TYPE__REG \ +(BMI160_USER_INTR_OUT_CTRL_ADDR) + +/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->7 */ +#define BMI160_USER_INTR2_OUTPUT_EN__POS (7) +#define BMI160_USER_INTR2_OUTPUT_EN__LEN (1) +#define BMI160_USER_INTR2_OUTPUT_EN__MSK (0x80) +#define BMI160_USER_INTR2_OUTPUT_EN__REG \ +(BMI160_USER_INTR_OUT_CTRL_ADDR) +/**************************************************************/ +/**\name LATCH INTERRUPT LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Latch Description - Reg Addr --> 0x54, Bit -->0...3 */ +#define BMI160_USER_INTR_LATCH__POS (0) +#define BMI160_USER_INTR_LATCH__LEN (4) +#define BMI160_USER_INTR_LATCH__MSK (0x0F) +#define BMI160_USER_INTR_LATCH__REG (BMI160_USER_INTR_LATCH_ADDR) +/**************************************************************/ +/**\name INPUT ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Latch Description - Reg Addr --> 0x54, Bit -->4 */ +#define BMI160_USER_INTR1_INPUT_ENABLE__POS (4) +#define BMI160_USER_INTR1_INPUT_ENABLE__LEN (1) +#define BMI160_USER_INTR1_INPUT_ENABLE__MSK (0x10) +#define BMI160_USER_INTR1_INPUT_ENABLE__REG \ +(BMI160_USER_INTR_LATCH_ADDR) + +/* Int_Latch Description - Reg Addr --> 0x54, Bit -->5*/ +#define BMI160_USER_INTR2_INPUT_ENABLE__POS (5) +#define BMI160_USER_INTR2_INPUT_ENABLE__LEN (1) +#define BMI160_USER_INTR2_INPUT_ENABLE__MSK (0x20) +#define BMI160_USER_INTR2_INPUT_ENABLE__REG \ +(BMI160_USER_INTR_LATCH_ADDR) +/**************************************************************/ +/**\name INTERRUPT1 MAPPIONG OF LOW_G LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->0 */ +#define BMI160_USER_INTR_MAP_0_INTR1_LOW_G__POS (0) +#define BMI160_USER_INTR_MAP_0_INTR1_LOW_G__LEN (1) +#define BMI160_USER_INTR_MAP_0_INTR1_LOW_G__MSK (0x01) +#define BMI160_USER_INTR_MAP_0_INTR1_LOW_G__REG (BMI160_USER_INTR_MAP_0_ADDR) +/**************************************************************/ +/**\name INTERRUPT1 MAPPIONG OF HIGH_G LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->1 */ +#define BMI160_USER_INTR_MAP_0_INTR1_HIGH_G__POS (1) +#define BMI160_USER_INTR_MAP_0_INTR1_HIGH_G__LEN (1) +#define BMI160_USER_INTR_MAP_0_INTR1_HIGH_G__MSK (0x02) +#define BMI160_USER_INTR_MAP_0_INTR1_HIGH_G__REG \ +(BMI160_USER_INTR_MAP_0_ADDR) +/**************************************************************/ +/**\name INTERRUPT MAPPIONG OF ANY MOTION_G LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->2 */ +#define BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION__POS (2) +#define BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION__LEN (1) +#define BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION__MSK (0x04) +#define BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG \ +(BMI160_USER_INTR_MAP_0_ADDR) +/**************************************************************/ +/**\name INTERRUPT1 MAPPIONG OF NO MOTION LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->3 */ +#define BMI160_USER_INTR_MAP_0_INTR1_NOMOTION__POS (3) +#define BMI160_USER_INTR_MAP_0_INTR1_NOMOTION__LEN (1) +#define BMI160_USER_INTR_MAP_0_INTR1_NOMOTION__MSK (0x08) +#define BMI160_USER_INTR_MAP_0_INTR1_NOMOTION__REG (BMI160_USER_INTR_MAP_0_ADDR) +/**************************************************************/ +/**\name INTERRUPT1 MAPPIONG OF DOUBLE TAP LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->4 */ +#define BMI160_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__POS (4) +#define BMI160_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__LEN (1) +#define BMI160_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__MSK (0x10) +#define BMI160_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__REG \ +(BMI160_USER_INTR_MAP_0_ADDR) +/**************************************************************/ +/**\name INTERRUPT1 MAPPIONG OF SINGLE TAP LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->5 */ +#define BMI160_USER_INTR_MAP_0_INTR1_SINGLE_TAP__POS (5) +#define BMI160_USER_INTR_MAP_0_INTR1_SINGLE_TAP__LEN (1) +#define BMI160_USER_INTR_MAP_0_INTR1_SINGLE_TAP__MSK (0x20) +#define BMI160_USER_INTR_MAP_0_INTR1_SINGLE_TAP__REG \ +(BMI160_USER_INTR_MAP_0_ADDR) +/**************************************************************/ +/**\name INTERRUPT1 MAPPIONG OF ORIENT LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->6 */ +#define BMI160_USER_INTR_MAP_0_INTR1_ORIENT__POS (6) +#define BMI160_USER_INTR_MAP_0_INTR1_ORIENT__LEN (1) +#define BMI160_USER_INTR_MAP_0_INTR1_ORIENT__MSK (0x40) +#define BMI160_USER_INTR_MAP_0_INTR1_ORIENT__REG \ +(BMI160_USER_INTR_MAP_0_ADDR) +/**************************************************************/ +/**\name INTERRUPT MAPPIONG OF FLAT LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_0 Description - Reg Addr --> 0x56, Bit -->7 */ +#define BMI160_USER_INTR_MAP_0_INTR1_FLAT__POS (7) +#define BMI160_USER_INTR_MAP_0_INTR1_FLAT__LEN (1) +#define BMI160_USER_INTR_MAP_0_INTR1_FLAT__MSK (0x80) +#define BMI160_USER_INTR_MAP_0_INTR1_FLAT__REG (BMI160_USER_INTR_MAP_0_ADDR) +/**************************************************************/ +/**\name INTERRUPT1 MAPPIONG OF PMU TRIGGER LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->0 */ +#define BMI160_USER_INTR_MAP_1_INTR2_PMU_TRIG__POS (0) +#define BMI160_USER_INTR_MAP_1_INTR2_PMU_TRIG__LEN (1) +#define BMI160_USER_INTR_MAP_1_INTR2_PMU_TRIG__MSK (0x01) +#define BMI160_USER_INTR_MAP_1_INTR2_PMU_TRIG__REG (BMI160_USER_INTR_MAP_1_ADDR) +/**************************************************************/ +/**\name INTERRUPT1 MAPPIONG OF FIFO FULL AND + WATER MARK LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->1 */ +#define BMI160_USER_INTR_MAP_1_INTR2_FIFO_FULL__POS (1) +#define BMI160_USER_INTR_MAP_1_INTR2_FIFO_FULL__LEN (1) +#define BMI160_USER_INTR_MAP_1_INTR2_FIFO_FULL__MSK (0x02) +#define BMI160_USER_INTR_MAP_1_INTR2_FIFO_FULL__REG \ +(BMI160_USER_INTR_MAP_1_ADDR) + +/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->2 */ +#define BMI160_USER_INTR_MAP_1_INTR2_FIFO_WM__POS (2) +#define BMI160_USER_INTR_MAP_1_INTR2_FIFO_WM__LEN (1) +#define BMI160_USER_INTR_MAP_1_INTR2_FIFO_WM__MSK (0x04) +#define BMI160_USER_INTR_MAP_1_INTR2_FIFO_WM__REG \ +(BMI160_USER_INTR_MAP_1_ADDR) +/**************************************************************/ +/**\name INTERRUPT1 MAPPIONG OF DATA READY LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->3 */ +#define BMI160_USER_INTR_MAP_1_INTR2_DATA_RDY__POS (3) +#define BMI160_USER_INTR_MAP_1_INTR2_DATA_RDY__LEN (1) +#define BMI160_USER_INTR_MAP_1_INTR2_DATA_RDY__MSK (0x08) +#define BMI160_USER_INTR_MAP_1_INTR2_DATA_RDY__REG \ +(BMI160_USER_INTR_MAP_1_ADDR) +/**************************************************************/ +/**\name INTERRUPT1 MAPPIONG OF PMU TRIGGER LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->4 */ +#define BMI160_USER_INTR_MAP_1_INTR1_PMU_TRIG__POS (4) +#define BMI160_USER_INTR_MAP_1_INTR1_PMU_TRIG__LEN (1) +#define BMI160_USER_INTR_MAP_1_INTR1_PMU_TRIG__MSK (0x10) +#define BMI160_USER_INTR_MAP_1_INTR1_PMU_TRIG__REG (BMI160_USER_INTR_MAP_1_ADDR) +/**************************************************************/ +/**\name INTERRUPT1 MAPPIONG OF FIFO FULL AND + WATER MARK LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->5 */ +#define BMI160_USER_INTR_MAP_1_INTR1_FIFO_FULL__POS (5) +#define BMI160_USER_INTR_MAP_1_INTR1_FIFO_FULL__LEN (1) +#define BMI160_USER_INTR_MAP_1_INTR1_FIFO_FULL__MSK (0x20) +#define BMI160_USER_INTR_MAP_1_INTR1_FIFO_FULL__REG \ +(BMI160_USER_INTR_MAP_1_ADDR) + +/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->6 */ +#define BMI160_USER_INTR_MAP_1_INTR1_FIFO_WM__POS (6) +#define BMI160_USER_INTR_MAP_1_INTR1_FIFO_WM__LEN (1) +#define BMI160_USER_INTR_MAP_1_INTR1_FIFO_WM__MSK (0x40) +#define BMI160_USER_INTR_MAP_1_INTR1_FIFO_WM__REG \ +(BMI160_USER_INTR_MAP_1_ADDR) +/**************************************************************/ +/**\name INTERRUPT1 MAPPIONG OF DATA READY LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->7 */ +#define BMI160_USER_INTR_MAP_1_INTR1_DATA_RDY__POS (7) +#define BMI160_USER_INTR_MAP_1_INTR1_DATA_RDY__LEN (1) +#define BMI160_USER_INTR_MAP_1_INTR1_DATA_RDY__MSK (0x80) +#define BMI160_USER_INTR_MAP_1_INTR1_DATA_RDY__REG \ +(BMI160_USER_INTR_MAP_1_ADDR) +/**************************************************************/ +/**\name INTERRUPT2 MAPPIONG OF LOW_G LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->0 */ +#define BMI160_USER_INTR_MAP_2_INTR2_LOW_G__POS (0) +#define BMI160_USER_INTR_MAP_2_INTR2_LOW_G__LEN (1) +#define BMI160_USER_INTR_MAP_2_INTR2_LOW_G__MSK (0x01) +#define BMI160_USER_INTR_MAP_2_INTR2_LOW_G__REG (BMI160_USER_INTR_MAP_2_ADDR) +/**************************************************************/ +/**\name INTERRUPT2 MAPPIONG OF HIGH_G LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->1 */ +#define BMI160_USER_INTR_MAP_2_INTR2_HIGH_G__POS (1) +#define BMI160_USER_INTR_MAP_2_INTR2_HIGH_G__LEN (1) +#define BMI160_USER_INTR_MAP_2_INTR2_HIGH_G__MSK (0x02) +#define BMI160_USER_INTR_MAP_2_INTR2_HIGH_G__REG \ +(BMI160_USER_INTR_MAP_2_ADDR) +/**************************************************************/ +/**\name INTERRUPT2 MAPPIONG OF ANY MOTION LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->2 */ +#define BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION__POS (2) +#define BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION__LEN (1) +#define BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION__MSK (0x04) +#define BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG \ +(BMI160_USER_INTR_MAP_2_ADDR) +/**************************************************************/ +/**\name INTERRUPT2 MAPPIONG OF NO MOTION LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->3 */ +#define BMI160_USER_INTR_MAP_2_INTR2_NOMOTION__POS (3) +#define BMI160_USER_INTR_MAP_2_INTR2_NOMOTION__LEN (1) +#define BMI160_USER_INTR_MAP_2_INTR2_NOMOTION__MSK (0x08) +#define BMI160_USER_INTR_MAP_2_INTR2_NOMOTION__REG (BMI160_USER_INTR_MAP_2_ADDR) +/**************************************************************/ +/**\name INTERRUPT2 MAPPIONG OF DOUBLE TAP LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->4 */ +#define BMI160_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__POS (4) +#define BMI160_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__LEN (1) +#define BMI160_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__MSK (0x10) +#define BMI160_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__REG \ +(BMI160_USER_INTR_MAP_2_ADDR) +/**************************************************************/ +/**\name INTERRUPT2 MAPPIONG OF SINGLE TAP LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->5 */ +#define BMI160_USER_INTR_MAP_2_INTR2_SINGLE_TAP__POS (5) +#define BMI160_USER_INTR_MAP_2_INTR2_SINGLE_TAP__LEN (1) +#define BMI160_USER_INTR_MAP_2_INTR2_SINGLE_TAP__MSK (0x20) +#define BMI160_USER_INTR_MAP_2_INTR2_SINGLE_TAP__REG \ +(BMI160_USER_INTR_MAP_2_ADDR) +/**************************************************************/ +/**\name INTERRUPT2 MAPPIONG OF ORIENT LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->6 */ +#define BMI160_USER_INTR_MAP_2_INTR2_ORIENT__POS (6) +#define BMI160_USER_INTR_MAP_2_INTR2_ORIENT__LEN (1) +#define BMI160_USER_INTR_MAP_2_INTR2_ORIENT__MSK (0x40) +#define BMI160_USER_INTR_MAP_2_INTR2_ORIENT__REG \ +(BMI160_USER_INTR_MAP_2_ADDR) +/**************************************************************/ +/**\name INTERRUPT2 MAPPIONG OF FLAT LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->7 */ +#define BMI160_USER_INTR_MAP_2_INTR2_FLAT__POS (7) +#define BMI160_USER_INTR_MAP_2_INTR2_FLAT__LEN (1) +#define BMI160_USER_INTR_MAP_2_INTR2_FLAT__MSK (0x80) +#define BMI160_USER_INTR_MAP_2_INTR2_FLAT__REG (BMI160_USER_INTR_MAP_2_ADDR) + +/**************************************************************/ +/**\name TAP SOURCE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Data_0 Description - Reg Addr --> 0x58, Bit --> 3 */ +#define BMI160_USER_INTR_DATA_0_INTR_TAP_SOURCE__POS (3) +#define BMI160_USER_INTR_DATA_0_INTR_TAP_SOURCE__LEN (1) +#define BMI160_USER_INTR_DATA_0_INTR_TAP_SOURCE__MSK (0x08) +#define BMI160_USER_INTR_DATA_0_INTR_TAP_SOURCE__REG \ +(BMI160_USER_INTR_DATA_0_ADDR) + +/**************************************************************/ +/**\name HIGH SOURCE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Data_0 Description - Reg Addr --> 0x58, Bit --> 7 */ +#define BMI160_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__POS (7) +#define BMI160_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__LEN (1) +#define BMI160_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__MSK (0x80) +#define BMI160_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__REG \ +(BMI160_USER_INTR_DATA_0_ADDR) + +/**************************************************************/ +/**\name MOTION SOURCE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Data_1 Description - Reg Addr --> 0x59, Bit --> 7 */ +#define BMI160_USER_INTR_DATA_1_INTR_MOTION_SOURCE__POS (7) +#define BMI160_USER_INTR_DATA_1_INTR_MOTION_SOURCE__LEN (1) +#define BMI160_USER_INTR_DATA_1_INTR_MOTION_SOURCE__MSK (0x80) +#define BMI160_USER_INTR_DATA_1_INTR_MOTION_SOURCE__REG \ + (BMI160_USER_INTR_DATA_1_ADDR) +/**************************************************************/ +/**\name LOW HIGH DURATION LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_LowHigh_0 Description - Reg Addr --> 0x5a, Bit --> 0...7 */ +#define BMI160_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__POS (0) +#define BMI160_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__LEN (8) +#define BMI160_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__MSK (0xFF) +#define BMI160_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__REG \ + (BMI160_USER_INTR_LOWHIGH_0_ADDR) +/**************************************************************/ +/**\name LOW THRESHOLD LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_LowHigh_1 Description - Reg Addr --> 0x5b, Bit --> 0...7 */ +#define BMI160_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__POS (0) +#define BMI160_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__LEN (8) +#define BMI160_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__MSK (0xFF) +#define BMI160_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__REG \ + (BMI160_USER_INTR_LOWHIGH_1_ADDR) +/**************************************************************/ +/**\name LOW HYSTERESIS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_LowHigh_2 Description - Reg Addr --> 0x5c, Bit --> 0...1 */ +#define BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__POS (0) +#define BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__LEN (2) +#define BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__MSK (0x03) +#define BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__REG \ + (BMI160_USER_INTR_LOWHIGH_2_ADDR) +/**************************************************************/ +/**\name LOW MODE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_LowHigh_2 Description - Reg Addr --> 0x5c, Bit --> 2 */ +#define BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__POS (2) +#define BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__LEN (1) +#define BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__MSK (0x04) +#define BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__REG \ + (BMI160_USER_INTR_LOWHIGH_2_ADDR) +/**************************************************************/ +/**\name HIGH_G HYSTERESIS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_LowHigh_2 Description - Reg Addr --> 0x5c, Bit --> 6...7 */ +#define BMI160_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__POS (6) +#define BMI160_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__LEN (2) +#define BMI160_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__MSK (0xC0) +#define BMI160_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__REG \ + (BMI160_USER_INTR_LOWHIGH_2_ADDR) +/**************************************************************/ +/**\name HIGH_G DURATION LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_LowHigh_3 Description - Reg Addr --> 0x5d, Bit --> 0...7 */ +#define BMI160_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__POS (0) +#define BMI160_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__LEN (8) +#define BMI160_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__MSK (0xFF) +#define BMI160_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__REG \ + (BMI160_USER_INTR_LOWHIGH_3_ADDR) +/**************************************************************/ +/**\name HIGH_G THRESHOLD LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_LowHigh_4 Description - Reg Addr --> 0x5e, Bit --> 0...7 */ +#define BMI160_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__POS (0) +#define BMI160_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__LEN (8) +#define BMI160_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__MSK (0xFF) +#define BMI160_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__REG \ + (BMI160_USER_INTR_LOWHIGH_4_ADDR) +/**************************************************************/ +/**\name ANY MOTION DURATION LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Motion_0 Description - Reg Addr --> 0x5f, Bit --> 0...1 */ +#define BMI160_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__POS (0) +#define BMI160_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__LEN (2) +#define BMI160_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__MSK (0x03) +#define BMI160_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__REG \ + (BMI160_USER_INTR_MOTION_0_ADDR) +/**************************************************************/ +/**\name SLOW/NO MOTION DURATION LENGTH, POSITION AND MASK*/ +/**************************************************************/ + /* Int_Motion_0 Description - Reg Addr --> 0x5f, Bit --> 2...7 */ +#define BMI160_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__POS (2) +#define BMI160_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__LEN (6) +#define BMI160_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__MSK (0xFC) +#define BMI160_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__REG \ + (BMI160_USER_INTR_MOTION_0_ADDR) +/**************************************************************/ +/**\name ANY MOTION THRESHOLD LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Motion_1 Description - Reg Addr --> (0x60), Bit --> 0...7 */ +#define BMI160_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__POS (0) +#define BMI160_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__LEN (8) +#define BMI160_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__MSK (0xFF) +#define BMI160_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__REG \ + (BMI160_USER_INTR_MOTION_1_ADDR) +/**************************************************************/ +/**\name SLOW/NO MOTION THRESHOLD LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Motion_2 Description - Reg Addr --> 0x61, Bit --> 0...7 */ +#define BMI160_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__POS (0) +#define BMI160_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__LEN (8) +#define BMI160_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__MSK (0xFF) +#define BMI160_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__REG \ + (BMI160_USER_INTR_MOTION_2_ADDR) +/**************************************************************/ +/**\name SLOW/NO MOTION SELECT LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Motion_3 Description - Reg Addr --> (0x62), Bit --> 0 */ +#define BMI160_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__POS (0) +#define BMI160_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__LEN (1) +#define BMI160_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__MSK (0x01) +#define BMI160_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__REG \ +(BMI160_USER_INTR_MOTION_3_ADDR) +/**************************************************************/ +/**\name SIGNIFICANT MOTION SELECT LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Motion_3 Description - Reg Addr --> (0x62), Bit --> 1 */ +#define BMI160_USER_INTR_SIGNIFICATION_MOTION_SELECT__POS (1) +#define BMI160_USER_INTR_SIGNIFICATION_MOTION_SELECT__LEN (1) +#define BMI160_USER_INTR_SIGNIFICATION_MOTION_SELECT__MSK (0x02) +#define BMI160_USER_INTR_SIGNIFICATION_MOTION_SELECT__REG \ + (BMI160_USER_INTR_MOTION_3_ADDR) + +/* Int_Motion_3 Description - Reg Addr --> (0x62), Bit --> 3..2 */ +#define BMI160_USER_INTR_SIGNIFICANT_MOTION_SKIP__POS (2) +#define BMI160_USER_INTR_SIGNIFICANT_MOTION_SKIP__LEN (2) +#define BMI160_USER_INTR_SIGNIFICANT_MOTION_SKIP__MSK (0x0C) +#define BMI160_USER_INTR_SIGNIFICANT_MOTION_SKIP__REG \ + (BMI160_USER_INTR_MOTION_3_ADDR) + +/* Int_Motion_3 Description - Reg Addr --> (0x62), Bit --> 5..4 */ +#define BMI160_USER_INTR_SIGNIFICANT_MOTION_PROOF__POS (4) +#define BMI160_USER_INTR_SIGNIFICANT_MOTION_PROOF__LEN (2) +#define BMI160_USER_INTR_SIGNIFICANT_MOTION_PROOF__MSK (0x30) +#define BMI160_USER_INTR_SIGNIFICANT_MOTION_PROOF__REG \ + (BMI160_USER_INTR_MOTION_3_ADDR) +/**************************************************************/ +/**\name TAP DURATION LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* INT_TAP_0 Description - Reg Addr --> (0x63), Bit --> 0..2*/ +#define BMI160_USER_INTR_TAP_0_INTR_TAP_DURN__POS (0) +#define BMI160_USER_INTR_TAP_0_INTR_TAP_DURN__LEN (3) +#define BMI160_USER_INTR_TAP_0_INTR_TAP_DURN__MSK (0x07) +#define BMI160_USER_INTR_TAP_0_INTR_TAP_DURN__REG \ +(BMI160_USER_INTR_TAP_0_ADDR) +/**************************************************************/ +/**\name TAP SHOCK LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Tap_0 Description - Reg Addr --> (0x63), Bit --> 6 */ +#define BMI160_USER_INTR_TAP_0_INTR_TAP_SHOCK__POS (6) +#define BMI160_USER_INTR_TAP_0_INTR_TAP_SHOCK__LEN (1) +#define BMI160_USER_INTR_TAP_0_INTR_TAP_SHOCK__MSK (0x40) +#define BMI160_USER_INTR_TAP_0_INTR_TAP_SHOCK__REG (BMI160_USER_INTR_TAP_0_ADDR) +/**************************************************************/ +/**\name TAP QUIET LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Tap_0 Description - Reg Addr --> (0x63), Bit --> 7 */ +#define BMI160_USER_INTR_TAP_0_INTR_TAP_QUIET__POS (7) +#define BMI160_USER_INTR_TAP_0_INTR_TAP_QUIET__LEN (1) +#define BMI160_USER_INTR_TAP_0_INTR_TAP_QUIET__MSK (0x80) +#define BMI160_USER_INTR_TAP_0_INTR_TAP_QUIET__REG (BMI160_USER_INTR_TAP_0_ADDR) +/**************************************************************/ +/**\name TAP THRESHOLD LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Tap_1 Description - Reg Addr --> (0x64), Bit --> 0...4 */ +#define BMI160_USER_INTR_TAP_1_INTR_TAP_THRES__POS (0) +#define BMI160_USER_INTR_TAP_1_INTR_TAP_THRES__LEN (5) +#define BMI160_USER_INTR_TAP_1_INTR_TAP_THRES__MSK (0x1F) +#define BMI160_USER_INTR_TAP_1_INTR_TAP_THRES__REG (BMI160_USER_INTR_TAP_1_ADDR) +/**************************************************************/ +/**\name ORIENT MODE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Orient_0 Description - Reg Addr --> (0x65), Bit --> 0...1 */ +#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__POS (0) +#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__LEN (2) +#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__MSK (0x03) +#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__REG \ + (BMI160_USER_INTR_ORIENT_0_ADDR) +/**************************************************************/ +/**\name ORIENT BLOCKING LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Orient_0 Description - Reg Addr --> (0x65), Bit --> 2...3 */ +#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__POS (2) +#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__LEN (2) +#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__MSK (0x0C) +#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__REG \ + (BMI160_USER_INTR_ORIENT_0_ADDR) +/**************************************************************/ +/**\name ORIENT HYSTERESIS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Orient_0 Description - Reg Addr --> (0x65), Bit --> 4...7 */ +#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__POS (4) +#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__LEN (4) +#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__MSK (0xF0) +#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__REG \ + (BMI160_USER_INTR_ORIENT_0_ADDR) +/**************************************************************/ +/**\name ORIENT THETA LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Orient_1 Description - Reg Addr --> 0x66, Bit --> 0...5 */ +#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__POS (0) +#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__LEN (6) +#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__MSK (0x3F) +#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__REG \ + (BMI160_USER_INTR_ORIENT_1_ADDR) +/**************************************************************/ +/**\name ORIENT UD LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Orient_1 Description - Reg Addr --> 0x66, Bit --> 6 */ +#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__POS (6) +#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__LEN (1) +#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__MSK (0x40) +#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__REG \ + (BMI160_USER_INTR_ORIENT_1_ADDR) +/**************************************************************/ +/**\name ORIENT AXIS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Orient_1 Description - Reg Addr --> 0x66, Bit --> 7 */ +#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__POS (7) +#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__LEN (1) +#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__MSK (0x80) +#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__REG \ + (BMI160_USER_INTR_ORIENT_1_ADDR) +/**************************************************************/ +/**\name FLAT THETA LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Flat_0 Description - Reg Addr --> 0x67, Bit --> 0...5 */ +#define BMI160_USER_INTR_FLAT_0_INTR_FLAT_THETA__POS (0) +#define BMI160_USER_INTR_FLAT_0_INTR_FLAT_THETA__LEN (6) +#define BMI160_USER_INTR_FLAT_0_INTR_FLAT_THETA__MSK (0x3F) +#define BMI160_USER_INTR_FLAT_0_INTR_FLAT_THETA__REG \ + (BMI160_USER_INTR_FLAT_0_ADDR) +/**************************************************************/ +/**\name FLAT HYSTERESIS LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Flat_1 Description - Reg Addr --> (0x68), Bit --> 0...3 */ +#define BMI160_USER_INTR_FLAT_1_INTR_FLAT_HYST__POS (0) +#define BMI160_USER_INTR_FLAT_1_INTR_FLAT_HYST__LEN (4) +#define BMI160_USER_INTR_FLAT_1_INTR_FLAT_HYST__MSK (0x0F) +#define BMI160_USER_INTR_FLAT_1_INTR_FLAT_HYST__REG \ +(BMI160_USER_INTR_FLAT_1_ADDR) +/**************************************************************/ +/**\name FLAT HOLD LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Int_Flat_1 Description - Reg Addr --> (0x68), Bit --> 4...5 */ +#define BMI160_USER_INTR_FLAT_1_INTR_FLAT_HOLD__POS (4) +#define BMI160_USER_INTR_FLAT_1_INTR_FLAT_HOLD__LEN (2) +#define BMI160_USER_INTR_FLAT_1_INTR_FLAT_HOLD__MSK (0x30) +#define BMI160_USER_INTR_FLAT_1_INTR_FLAT_HOLD__REG \ +(BMI160_USER_INTR_FLAT_1_ADDR) +/**************************************************************/ +/**\name FOC ACCEL XYZ LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Foc_Conf Description - Reg Addr --> (0x69), Bit --> 0...1 */ +#define BMI160_USER_FOC_ACCEL_Z__POS (0) +#define BMI160_USER_FOC_ACCEL_Z__LEN (2) +#define BMI160_USER_FOC_ACCEL_Z__MSK (0x03) +#define BMI160_USER_FOC_ACCEL_Z__REG (BMI160_USER_FOC_CONFIG_ADDR) + +/* Foc_Conf Description - Reg Addr --> (0x69), Bit --> 2...3 */ +#define BMI160_USER_FOC_ACCEL_Y__POS (2) +#define BMI160_USER_FOC_ACCEL_Y__LEN (2) +#define BMI160_USER_FOC_ACCEL_Y__MSK (0x0C) +#define BMI160_USER_FOC_ACCEL_Y__REG (BMI160_USER_FOC_CONFIG_ADDR) + +/* Foc_Conf Description - Reg Addr --> (0x69), Bit --> 4...5 */ +#define BMI160_USER_FOC_ACCEL_X__POS (4) +#define BMI160_USER_FOC_ACCEL_X__LEN (2) +#define BMI160_USER_FOC_ACCEL_X__MSK (0x30) +#define BMI160_USER_FOC_ACCEL_X__REG (BMI160_USER_FOC_CONFIG_ADDR) +/**************************************************************/ +/**\name FOC GYRO LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Foc_Conf Description - Reg Addr --> (0x69), Bit --> 6 */ +#define BMI160_USER_FOC_GYRO_ENABLE__POS (6) +#define BMI160_USER_FOC_GYRO_ENABLE__LEN (1) +#define BMI160_USER_FOC_GYRO_ENABLE__MSK (0x40) +#define BMI160_USER_FOC_GYRO_ENABLE__REG \ +(BMI160_USER_FOC_CONFIG_ADDR) +/**************************************************************/ +/**\name NVM PROGRAM LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* CONF Description - Reg Addr --> (0x6A), Bit --> 1 */ +#define BMI160_USER_CONFIG_NVM_PROG_ENABLE__POS (1) +#define BMI160_USER_CONFIG_NVM_PROG_ENABLE__LEN (1) +#define BMI160_USER_CONFIG_NVM_PROG_ENABLE__MSK (0x02) +#define BMI160_USER_CONFIG_NVM_PROG_ENABLE__REG \ +(BMI160_USER_CONFIG_ADDR) + +/*IF_CONF Description - Reg Addr --> (0x6B), Bit --> 0 */ + +#define BMI160_USER_IF_CONFIG_SPI3__POS (0) +#define BMI160_USER_IF_CONFIG_SPI3__LEN (1) +#define BMI160_USER_IF_CONFIG_SPI3__MSK (0x01) +#define BMI160_USER_IF_CONFIG_SPI3__REG \ +(BMI160_USER_IF_CONFIG_ADDR) + +/*IF_CONF Description - Reg Addr --> (0x6B), Bit --> 5..4 */ +#define BMI160_USER_IF_CONFIG_IF_MODE__POS (4) +#define BMI160_USER_IF_CONFIG_IF_MODE__LEN (2) +#define BMI160_USER_IF_CONFIG_IF_MODE__MSK (0x30) +#define BMI160_USER_IF_CONFIG_IF_MODE__REG \ +(BMI160_USER_IF_CONFIG_ADDR) +/**************************************************************/ +/**\name GYRO SLEEP CONFIGURATION LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Pmu_Trigger Description - Reg Addr --> 0x6c, Bit --> 0...2 */ +#define BMI160_USER_GYRO_SLEEP_TRIGGER__POS (0) +#define BMI160_USER_GYRO_SLEEP_TRIGGER__LEN (3) +#define BMI160_USER_GYRO_SLEEP_TRIGGER__MSK (0x07) +#define BMI160_USER_GYRO_SLEEP_TRIGGER__REG (BMI160_USER_PMU_TRIGGER_ADDR) + +/* Pmu_Trigger Description - Reg Addr --> 0x6c, Bit --> 3...4 */ +#define BMI160_USER_GYRO_WAKEUP_TRIGGER__POS (3) +#define BMI160_USER_GYRO_WAKEUP_TRIGGER__LEN (2) +#define BMI160_USER_GYRO_WAKEUP_TRIGGER__MSK (0x18) +#define BMI160_USER_GYRO_WAKEUP_TRIGGER__REG (BMI160_USER_PMU_TRIGGER_ADDR) + +/* Pmu_Trigger Description - Reg Addr --> 0x6c, Bit --> 5 */ +#define BMI160_USER_GYRO_SLEEP_STATE__POS (5) +#define BMI160_USER_GYRO_SLEEP_STATE__LEN (1) +#define BMI160_USER_GYRO_SLEEP_STATE__MSK (0x20) +#define BMI160_USER_GYRO_SLEEP_STATE__REG (BMI160_USER_PMU_TRIGGER_ADDR) + +/* Pmu_Trigger Description - Reg Addr --> 0x6c, Bit --> 6 */ +#define BMI160_USER_GYRO_WAKEUP_INTR__POS (6) +#define BMI160_USER_GYRO_WAKEUP_INTR__LEN (1) +#define BMI160_USER_GYRO_WAKEUP_INTR__MSK (0x40) +#define BMI160_USER_GYRO_WAKEUP_INTR__REG (BMI160_USER_PMU_TRIGGER_ADDR) +/**************************************************************/ +/**\name ACCEL SELF TEST LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Self_Test Description - Reg Addr --> 0x6d, Bit --> 0...1 */ +#define BMI160_USER_ACCEL_SELFTEST_AXIS__POS (0) +#define BMI160_USER_ACCEL_SELFTEST_AXIS__LEN (2) +#define BMI160_USER_ACCEL_SELFTEST_AXIS__MSK (0x03) +#define BMI160_USER_ACCEL_SELFTEST_AXIS__REG (BMI160_USER_SELF_TEST_ADDR) + +/* Self_Test Description - Reg Addr --> 0x6d, Bit --> 2 */ +#define BMI160_USER_ACCEL_SELFTEST_SIGN__POS (2) +#define BMI160_USER_ACCEL_SELFTEST_SIGN__LEN (1) +#define BMI160_USER_ACCEL_SELFTEST_SIGN__MSK (0x04) +#define BMI160_USER_ACCEL_SELFTEST_SIGN__REG (BMI160_USER_SELF_TEST_ADDR) + +/* Self_Test Description - Reg Addr --> 0x6d, Bit --> 3 */ +#define BMI160_USER_SELFTEST_AMP__POS (3) +#define BMI160_USER_SELFTEST_AMP__LEN (1) +#define BMI160_USER_SELFTEST_AMP__MSK (0x08) +#define BMI160_USER_SELFTEST_AMP__REG (BMI160_USER_SELF_TEST_ADDR) +/**************************************************************/ +/**\name GYRO SELF TEST LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Self_Test Description - Reg Addr --> 0x6d, Bit --> 4 */ +#define BMI160_USER_GYRO_SELFTEST_START__POS (4) +#define BMI160_USER_GYRO_SELFTEST_START__LEN (1) +#define BMI160_USER_GYRO_SELFTEST_START__MSK (0x10) +#define BMI160_USER_GYRO_SELFTEST_START__REG \ +(BMI160_USER_SELF_TEST_ADDR) +/**************************************************************/ +/**\name NV_CONFIG LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* NV_CONF Description - Reg Addr --> (0x70), Bit --> 0 */ +#define BMI160_USER_NV_CONFIG_SPI_ENABLE__POS (0) +#define BMI160_USER_NV_CONFIG_SPI_ENABLE__LEN (1) +#define BMI160_USER_NV_CONFIG_SPI_ENABLE__MSK (0x01) +#define BMI160_USER_NV_CONFIG_SPI_ENABLE__REG (BMI160_USER_NV_CONFIG_ADDR) + +/*IF_CONF Description - Reg Addr --> (0x70), Bit --> 1 */ +#define BMI160_USER_IF_CONFIG_I2C_WDT_SELECT__POS (1) +#define BMI160_USER_IF_CONFIG_I2C_WDT_SELECT__LEN (1) +#define BMI160_USER_IF_CONFIG_I2C_WDT_SELECT__MSK (0x02) +#define BMI160_USER_IF_CONFIG_I2C_WDT_SELECT__REG \ +(BMI160_USER_NV_CONFIG_ADDR) + +/*IF_CONF Description - Reg Addr --> (0x70), Bit --> 2 */ +#define BMI160_USER_IF_CONFIG_I2C_WDT_ENABLE__POS (2) +#define BMI160_USER_IF_CONFIG_I2C_WDT_ENABLE__LEN (1) +#define BMI160_USER_IF_CONFIG_I2C_WDT_ENABLE__MSK (0x04) +#define BMI160_USER_IF_CONFIG_I2C_WDT_ENABLE__REG \ +(BMI160_USER_NV_CONFIG_ADDR) + +/* NV_CONF Description - Reg Addr --> (0x70), Bit --> 3 */ +#define BMI160_USER_NV_CONFIG_SPARE0__POS (3) +#define BMI160_USER_NV_CONFIG_SPARE0__LEN (1) +#define BMI160_USER_NV_CONFIG_SPARE0__MSK (0x08) +#define BMI160_USER_NV_CONFIG_SPARE0__REG (BMI160_USER_NV_CONFIG_ADDR) + +/* NV_CONF Description - Reg Addr --> (0x70), Bit --> 4...7 */ +#define BMI160_USER_NV_CONFIG_NVM_COUNTER__POS (4) +#define BMI160_USER_NV_CONFIG_NVM_COUNTER__LEN (4) +#define BMI160_USER_NV_CONFIG_NVM_COUNTER__MSK (0xF0) +#define BMI160_USER_NV_CONFIG_NVM_COUNTER__REG (BMI160_USER_NV_CONFIG_ADDR) +/**************************************************************/ +/**\name ACCEL MANUAL OFFSET LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Offset_0 Description - Reg Addr --> (0x71), Bit --> 0...7 */ +#define BMI160_USER_OFFSET_0_ACCEL_OFF_X__POS (0) +#define BMI160_USER_OFFSET_0_ACCEL_OFF_X__LEN (8) +#define BMI160_USER_OFFSET_0_ACCEL_OFF_X__MSK (0xFF) +#define BMI160_USER_OFFSET_0_ACCEL_OFF_X__REG (BMI160_USER_OFFSET_0_ADDR) + +/* Offset_1 Description - Reg Addr --> 0x72, Bit --> 0...7 */ +#define BMI160_USER_OFFSET_1_ACCEL_OFF_Y__POS (0) +#define BMI160_USER_OFFSET_1_ACCEL_OFF_Y__LEN (8) +#define BMI160_USER_OFFSET_1_ACCEL_OFF_Y__MSK (0xFF) +#define BMI160_USER_OFFSET_1_ACCEL_OFF_Y__REG (BMI160_USER_OFFSET_1_ADDR) + +/* Offset_2 Description - Reg Addr --> 0x73, Bit --> 0...7 */ +#define BMI160_USER_OFFSET_2_ACCEL_OFF_Z__POS (0) +#define BMI160_USER_OFFSET_2_ACCEL_OFF_Z__LEN (8) +#define BMI160_USER_OFFSET_2_ACCEL_OFF_Z__MSK (0xFF) +#define BMI160_USER_OFFSET_2_ACCEL_OFF_Z__REG (BMI160_USER_OFFSET_2_ADDR) +/**************************************************************/ +/**\name GYRO MANUAL OFFSET LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Offset_3 Description - Reg Addr --> 0x74, Bit --> 0...7 */ +#define BMI160_USER_OFFSET_3_GYRO_OFF_X__POS (0) +#define BMI160_USER_OFFSET_3_GYRO_OFF_X__LEN (8) +#define BMI160_USER_OFFSET_3_GYRO_OFF_X__MSK (0xFF) +#define BMI160_USER_OFFSET_3_GYRO_OFF_X__REG (BMI160_USER_OFFSET_3_ADDR) + +/* Offset_4 Description - Reg Addr --> 0x75, Bit --> 0...7 */ +#define BMI160_USER_OFFSET_4_GYRO_OFF_Y__POS (0) +#define BMI160_USER_OFFSET_4_GYRO_OFF_Y__LEN (8) +#define BMI160_USER_OFFSET_4_GYRO_OFF_Y__MSK (0xFF) +#define BMI160_USER_OFFSET_4_GYRO_OFF_Y__REG (BMI160_USER_OFFSET_4_ADDR) + +/* Offset_5 Description - Reg Addr --> 0x76, Bit --> 0...7 */ +#define BMI160_USER_OFFSET_5_GYRO_OFF_Z__POS (0) +#define BMI160_USER_OFFSET_5_GYRO_OFF_Z__LEN (8) +#define BMI160_USER_OFFSET_5_GYRO_OFF_Z__MSK (0xFF) +#define BMI160_USER_OFFSET_5_GYRO_OFF_Z__REG (BMI160_USER_OFFSET_5_ADDR) + + +/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 0..1 */ +#define BMI160_USER_OFFSET_6_GYRO_OFF_X__POS (0) +#define BMI160_USER_OFFSET_6_GYRO_OFF_X__LEN (2) +#define BMI160_USER_OFFSET_6_GYRO_OFF_X__MSK (0x03) +#define BMI160_USER_OFFSET_6_GYRO_OFF_X__REG (BMI160_USER_OFFSET_6_ADDR) + +/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 2...3 */ +#define BMI160_USER_OFFSET_6_GYRO_OFF_Y__POS (2) +#define BMI160_USER_OFFSET_6_GYRO_OFF_Y__LEN (2) +#define BMI160_USER_OFFSET_6_GYRO_OFF_Y__MSK (0x0C) +#define BMI160_USER_OFFSET_6_GYRO_OFF_Y__REG (BMI160_USER_OFFSET_6_ADDR) + +/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 4...5 */ +#define BMI160_USER_OFFSET_6_GYRO_OFF_Z__POS (4) +#define BMI160_USER_OFFSET_6_GYRO_OFF_Z__LEN (2) +#define BMI160_USER_OFFSET_6_GYRO_OFF_Z__MSK (0x30) +#define BMI160_USER_OFFSET_6_GYRO_OFF_Z__REG (BMI160_USER_OFFSET_6_ADDR) +/**************************************************************/ +/**\name ACCEL OFFSET ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 6 */ +#define BMI160_USER_OFFSET_6_ACCEL_OFF_ENABLE__POS (6) +#define BMI160_USER_OFFSET_6_ACCEL_OFF_ENABLE__LEN (1) +#define BMI160_USER_OFFSET_6_ACCEL_OFF_ENABLE__MSK (0x40) +#define BMI160_USER_OFFSET_6_ACCEL_OFF_ENABLE__REG \ +(BMI160_USER_OFFSET_6_ADDR) +/**************************************************************/ +/**\name GYRO OFFSET ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 7 */ +#define BMI160_USER_OFFSET_6_GYRO_OFF_EN__POS (7) +#define BMI160_USER_OFFSET_6_GYRO_OFF_EN__LEN (1) +#define BMI160_USER_OFFSET_6_GYRO_OFF_EN__MSK (0x80) +#define BMI160_USER_OFFSET_6_GYRO_OFF_EN__REG (BMI160_USER_OFFSET_6_ADDR) +/**************************************************************/ +/**\name STEP COUNTER LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* STEP_CNT_0 Description - Reg Addr --> 0x78, Bit --> 0 to 7 */ +#define BMI160_USER_STEP_COUNT_LSB__POS (0) +#define BMI160_USER_STEP_COUNT_LSB__LEN (7) +#define BMI160_USER_STEP_COUNT_LSB__MSK (0xFF) +#define BMI160_USER_STEP_COUNT_LSB__REG (BMI160_USER_STEP_COUNT_0_ADDR) + +/* STEP_CNT_1 Description - Reg Addr --> 0x79, Bit --> 0 to 7 */ +#define BMI160_USER_STEP_COUNT_MSB__POS (0) +#define BMI160_USER_STEP_COUNT_MSB__LEN (7) +#define BMI160_USER_STEP_COUNT_MSB__MSK (0xFF) +#define BMI160_USER_STEP_COUNT_MSB__REG (BMI160_USER_STEP_COUNT_1_ADDR) +/**************************************************************/ +/**\name STEP COUNTER CONFIGURATION LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* STEP_CONFIG_0 Description - Reg Addr --> 0x7A, Bit --> 0 to 7 */ +#define BMI160_USER_STEP_CONFIG_ZERO__POS (0) +#define BMI160_USER_STEP_CONFIG_ZERO__LEN (7) +#define BMI160_USER_STEP_CONFIG_ZERO__MSK (0xFF) +#define BMI160_USER_STEP_CONFIG_ZERO__REG \ +(BMI160_USER_STEP_CONFIG_0_ADDR) + + +/* STEP_CONFIG_1 Description - Reg Addr --> 0x7B, Bit --> 0 to 2 and +4 to 7 */ +#define BMI160_USER_STEP_CONFIG_ONE_CNF1__POS (0) +#define BMI160_USER_STEP_CONFIG_ONE_CNF1__LEN (3) +#define BMI160_USER_STEP_CONFIG_ONE_CNF1__MSK (0x07) +#define BMI160_USER_STEP_CONFIG_ONE_CNF1__REG \ +(BMI160_USER_STEP_CONFIG_1_ADDR) + +#define BMI160_USER_STEP_CONFIG_ONE_CNF2__POS (4) +#define BMI160_USER_STEP_CONFIG_ONE_CNF2__LEN (4) +#define BMI160_USER_STEP_CONFIG_ONE_CNF2__MSK (0xF0) +#define BMI160_USER_STEP_CONFIG_ONE_CNF2__REG \ +(BMI160_USER_STEP_CONFIG_1_ADDR) +/**************************************************************/ +/**\name STEP COUNTER ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* STEP_CONFIG_1 Description - Reg Addr --> 0x7B, Bit --> 0 to 2 */ +#define BMI160_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__POS (3) +#define BMI160_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__LEN (1) +#define BMI160_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__MSK (0x08) +#define BMI160_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__REG \ +(BMI160_USER_STEP_CONFIG_1_ADDR) + +/* USER REGISTERS DEFINITION END */ +/**************************************************************************/ +/* CMD REGISTERS DEFINITION START */ +/**************************************************************/ +/**\name COMMAND REGISTER LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Command description address - Reg Addr --> 0x7E, Bit --> 0....7 */ +#define BMI160_CMD_COMMANDS__POS (0) +#define BMI160_CMD_COMMANDS__LEN (8) +#define BMI160_CMD_COMMANDS__MSK (0xFF) +#define BMI160_CMD_COMMANDS__REG (BMI160_CMD_COMMANDS_ADDR) +/**************************************************************/ +/**\name PAGE ENABLE LENGTH, POSITION AND MASK*/ +/**************************************************************/ +/* Target page address - Reg Addr --> 0x7F, Bit --> 4....5 */ +#define BMI160_CMD_TARGET_PAGE__POS (4) +#define BMI160_CMD_TARGET_PAGE__LEN (2) +#define BMI160_CMD_TARGET_PAGE__MSK (0x30) +#define BMI160_CMD_TARGET_PAGE__REG (BMI160_CMD_EXT_MODE_ADDR) + +/* Target page address - Reg Addr --> 0x7F, Bit --> 4....5 */ +#define BMI160_CMD_PAGING_EN__POS (7) +#define BMI160_CMD_PAGING_EN__LEN (1) +#define BMI160_CMD_PAGING_EN__MSK (0x80) +#define BMI160_CMD_PAGING_EN__REG (BMI160_CMD_EXT_MODE_ADDR) + +/* Target page address - Reg Addr --> 0x7F, Bit --> 4....5 */ +#define BMI160_COM_C_TRIM_FIVE__POS (0) +#define BMI160_COM_C_TRIM_FIVE__LEN (8) +#define BMI160_COM_C_TRIM_FIVE__MSK (0xFF) +#define BMI160_COM_C_TRIM_FIVE__REG (BMI160_COM_C_TRIM_FIVE_ADDR) + +/**************************************************************************/ +/* CMD REGISTERS DEFINITION END */ + +/**************************************************/ +/**\name FIFO FRAME COUNT DEFINITION */ +/*************************************************/ +#define FIFO_FRAME (1024) +#define FIFO_CONFIG_CHECK1 (0x00) +#define FIFO_CONFIG_CHECK2 (0x80) +/**************************************************/ +/**\name MAG SENSOR SELECT */ +/*************************************************/ +#define BST_BMM (0) +#define BST_AKM (1) +#define BMI160_YAS537_I2C_ADDRESS (0x2E) +/**************************************************/ +/**\name ACCEL RANGE */ +/*************************************************/ +#define BMI160_ACCEL_RANGE_2G (0X03) +#define BMI160_ACCEL_RANGE_4G (0X05) +#define BMI160_ACCEL_RANGE_8G (0X08) +#define BMI160_ACCEL_RANGE_16G (0X0C) +/**************************************************/ +/**\name ACCEL ODR */ +/*************************************************/ +#define BMI160_ACCEL_OUTPUT_DATA_RATE_RESERVED (0x00) +#define BMI160_ACCEL_OUTPUT_DATA_RATE_0_78HZ (0x01) +#define BMI160_ACCEL_OUTPUT_DATA_RATE_1_56HZ (0x02) +#define BMI160_ACCEL_OUTPUT_DATA_RATE_3_12HZ (0x03) +#define BMI160_ACCEL_OUTPUT_DATA_RATE_6_25HZ (0x04) +#define BMI160_ACCEL_OUTPUT_DATA_RATE_12_5HZ (0x05) +#define BMI160_ACCEL_OUTPUT_DATA_RATE_25HZ (0x06) +#define BMI160_ACCEL_OUTPUT_DATA_RATE_50HZ (0x07) +#define BMI160_ACCEL_OUTPUT_DATA_RATE_100HZ (0x08) +#define BMI160_ACCEL_OUTPUT_DATA_RATE_200HZ (0x09) +#define BMI160_ACCEL_OUTPUT_DATA_RATE_400HZ (0x0A) +#define BMI160_ACCEL_OUTPUT_DATA_RATE_800HZ (0x0B) +#define BMI160_ACCEL_OUTPUT_DATA_RATE_1600HZ (0x0C) +#define BMI160_ACCEL_OUTPUT_DATA_RATE_RESERVED0 (0x0D) +#define BMI160_ACCEL_OUTPUT_DATA_RATE_RESERVED1 (0x0E) +#define BMI160_ACCEL_OUTPUT_DATA_RATE_RESERVED2 (0x0F) +/**************************************************/ +/**\name ACCEL BANDWIDTH PARAMETER */ +/*************************************************/ +#define BMI160_ACCEL_OSR4_AVG1 (0x00) +#define BMI160_ACCEL_OSR2_AVG2 (0x01) +#define BMI160_ACCEL_NORMAL_AVG4 (0x02) +#define BMI160_ACCEL_CIC_AVG8 (0x03) +#define BMI160_ACCEL_RES_AVG16 (0x04) +#define BMI160_ACCEL_RES_AVG32 (0x05) +#define BMI160_ACCEL_RES_AVG64 (0x06) +#define BMI160_ACCEL_RES_AVG128 (0x07) +/**************************************************/ +/**\name GYRO ODR */ +/*************************************************/ +#define BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED (0x00) +#define BMI160_GYRO_OUTPUT_DATA_RATE_25HZ (0x06) +#define BMI160_GYRO_OUTPUT_DATA_RATE_50HZ (0x07) +#define BMI160_GYRO_OUTPUT_DATA_RATE_100HZ (0x08) +#define BMI160_GYRO_OUTPUT_DATA_RATE_200HZ (0x09) +#define BMI160_GYRO_OUTPUT_DATA_RATE_400HZ (0x0A) +#define BMI160_GYRO_OUTPUT_DATA_RATE_800HZ (0x0B) +#define BMI160_GYRO_OUTPUT_DATA_RATE_1600HZ (0x0C) +#define BMI160_GYRO_OUTPUT_DATA_RATE_3200HZ (0x0D) +/**************************************************/ +/**\name GYRO BANDWIDTH PARAMETER */ +/*************************************************/ +#define BMI160_GYRO_OSR4_MODE (0x00) +#define BMI160_GYRO_OSR2_MODE (0x01) +#define BMI160_GYRO_NORMAL_MODE (0x02) +#define BMI160_GYRO_CIC_MODE (0x03) +/**************************************************/ +/**\name GYROSCOPE RANGE PARAMETER */ +/*************************************************/ +#define BMI160_GYRO_RANGE_2000_DEG_SEC (0x00) +#define BMI160_GYRO_RANGE_1000_DEG_SEC (0x01) +#define BMI160_GYRO_RANGE_500_DEG_SEC (0x02) +#define BMI160_GYRO_RANGE_250_DEG_SEC (0x03) +#define BMI160_GYRO_RANGE_125_DEG_SEC (0x04) +/**************************************************/ +/**\name MAG ODR */ +/*************************************************/ +#define BMI160_MAG_OUTPUT_DATA_RATE_RESERVED (0x00) +#define BMI160_MAG_OUTPUT_DATA_RATE_0_78HZ (0x01) +#define BMI160_MAG_OUTPUT_DATA_RATE_1_56HZ (0x02) +#define BMI160_MAG_OUTPUT_DATA_RATE_3_12HZ (0x03) +#define BMI160_MAG_OUTPUT_DATA_RATE_6_25HZ (0x04) +#define BMI160_MAG_OUTPUT_DATA_RATE_12_5HZ (0x05) +#define BMI160_MAG_OUTPUT_DATA_RATE_25HZ (0x06) +#define BMI160_MAG_OUTPUT_DATA_RATE_50HZ (0x07) +#define BMI160_MAG_OUTPUT_DATA_RATE_100HZ (0x08) +#define BMI160_MAG_OUTPUT_DATA_RATE_200HZ (0x09) +#define BMI160_MAG_OUTPUT_DATA_RATE_400HZ (0x0A) +#define BMI160_MAG_OUTPUT_DATA_RATE_800HZ (0x0B) +#define BMI160_MAG_OUTPUT_DATA_RATE_1600HZ (0x0C) +#define BMI160_MAG_OUTPUT_DATA_RATE_RESERVED0 (0x0D) +#define BMI160_MAG_OUTPUT_DATA_RATE_RESERVED1 (0x0E) +#define BMI160_MAG_OUTPUT_DATA_RATE_RESERVED2 (0x0F) + +/**************************************************/ +/**\name ENABLE/DISABLE SELECTIONS */ +/*************************************************/ + +/* Enable accel and gyro offset */ +#define ACCEL_OFFSET_ENABLE (0x01) +#define GYRO_OFFSET_ENABLE (0x01) + +/* command register definition */ +#define START_FOC_ACCEL_GYRO (0X03) + + /* INT ENABLE 1 */ +#define BMI160_ANY_MOTION_X_ENABLE (0) +#define BMI160_ANY_MOTION_Y_ENABLE (1) +#define BMI160_ANY_MOTION_Z_ENABLE (2) +#define BMI160_DOUBLE_TAP_ENABLE (4) +#define BMI160_SINGLE_TAP_ENABLE (5) +#define BMI160_ORIENT_ENABLE (6) +#define BMI160_FLAT_ENABLE (7) + +/* INT ENABLE 1 */ +#define BMI160_HIGH_G_X_ENABLE (0) +#define BMI160_HIGH_G_Y_ENABLE (1) +#define BMI160_HIGH_G_Z_ENABLE (2) +#define BMI160_LOW_G_ENABLE (3) +#define BMI160_DATA_RDY_ENABLE (4) +#define BMI160_FIFO_FULL_ENABLE (5) +#define BMI160_FIFO_WM_ENABLE (6) + +/* INT ENABLE 2 */ +#define BMI160_NOMOTION_X_ENABLE (0) +#define BMI160_NOMOTION_Y_ENABLE (1) +#define BMI160_NOMOTION_Z_ENABLE (2) +#define BMI160_STEP_DETECTOR_EN (3) + +/* FOC axis selection for accel*/ +#define FOC_X_AXIS (0) +#define FOC_Y_AXIS (1) +#define FOC_Z_AXIS (2) + +/* IN OUT CONTROL */ +#define BMI160_INTR1_EDGE_CTRL (0) +#define BMI160_INTR2_EDGE_CTRL (1) +#define BMI160_INTR1_LEVEL (0) +#define BMI160_INTR2_LEVEL (1) +#define BMI160_INTR1_OUTPUT_TYPE (0) +#define BMI160_INTR2_OUTPUT_TYPE (1) +#define BMI160_INTR1_OUTPUT_ENABLE (0) +#define BMI160_INTR2_OUTPUT_ENABLE (1) + +#define BMI160_INTR1_INPUT_ENABLE (0) +#define BMI160_INTR2_INPUT_ENABLE (1) + +/* INTERRUPT MAPS */ +#define BMI160_INTR1_MAP_LOW_G (0) +#define BMI160_INTR2_MAP_LOW_G (1) +#define BMI160_INTR1_MAP_HIGH_G (0) +#define BMI160_INTR2_MAP_HIGH_G (1) +#define BMI160_INTR1_MAP_ANY_MOTION (0) +#define BMI160_INTR2_MAP_ANY_MOTION (1) +#define BMI160_INTR1_MAP_NOMO (0) +#define BMI160_INTR2_MAP_NOMO (1) +#define BMI160_INTR1_MAP_DOUBLE_TAP (0) +#define BMI160_INTR2_MAP_DOUBLE_TAP (1) +#define BMI160_INTR1_MAP_SINGLE_TAP (0) +#define BMI160_INTR2_MAP_SINGLE_TAP (1) +#define BMI160_INTR1_MAP_ORIENT (0) +#define BMI160_INTR2_MAP_ORIENT (1) +#define BMI160_INTR1_MAP_FLAT (0) +#define BMI160_INTR2_MAP_FLAT (1) +#define BMI160_INTR1_MAP_DATA_RDY (0) +#define BMI160_INTR2_MAP_DATA_RDY (1) +#define BMI160_INTR1_MAP_FIFO_WM (0) +#define BMI160_INTR2_MAP_FIFO_WM (1) +#define BMI160_INTR1_MAP_FIFO_FULL (0) +#define BMI160_INTR2_MAP_FIFO_FULL (1) +#define BMI160_INTR1_MAP_PMUTRIG (0) +#define BMI160_INTR2_MAP_PMUTRIG (1) + +/* Interrupt mapping*/ +#define BMI160_MAP_INTR1 (0) +#define BMI160_MAP_INTR2 (1) +/**************************************************/ +/**\name TAP DURATION */ +/*************************************************/ +#define BMI160_TAP_DURN_50MS (0x00) +#define BMI160_TAP_DURN_100MS (0x01) +#define BMI160_TAP_DURN_150MS (0x02) +#define BMI160_TAP_DURN_200MS (0x03) +#define BMI160_TAP_DURN_250MS (0x04) +#define BMI160_TAP_DURN_375MS (0x05) +#define BMI160_TAP_DURN_500MS (0x06) +#define BMI160_TAP_DURN_700MS (0x07) +/**************************************************/ +/**\name TAP SHOCK */ +/*************************************************/ +#define BMI160_TAP_SHOCK_50MS (0x00) +#define BMI160_TAP_SHOCK_75MS (0x01) +/**************************************************/ +/**\name TAP QUIET */ +/*************************************************/ +#define BMI160_TAP_QUIET_30MS (0x00) +#define BMI160_TAP_QUIET_20MS (0x01) +/**************************************************/ +/**\name STEP DETECTION SELECTION MODES */ +/*************************************************/ +#define BMI160_STEP_NORMAL_MODE (0) +#define BMI160_STEP_SENSITIVE_MODE (1) +#define BMI160_STEP_ROBUST_MODE (2) +/**************************************************/ +/**\name STEP CONFIGURATION SELECT MODE */ +/*************************************************/ +#define STEP_CONFIG_NORMAL (0X315) +#define STEP_CONFIG_SENSITIVE (0X2D) +#define STEP_CONFIG_ROBUST (0X71D) +/**************************************************/ +/**\name BMM150 TRIM DATA DEFINITIONS */ +/*************************************************/ +#define BMI160_MAG_DIG_X1 (0x5D) +#define BMI160_MAG_DIG_Y1 (0x5E) +#define BMI160_MAG_DIG_Z4_LSB (0x62) +#define BMI160_MAG_DIG_Z4_MSB (0x63) +#define BMI160_MAG_DIG_X2 (0x64) +#define BMI160_MAG_DIG_Y2 (0x65) +#define BMI160_MAG_DIG_Z2_LSB (0x68) +#define BMI160_MAG_DIG_Z2_MSB (0x69) +#define BMI160_MAG_DIG_Z1_LSB (0x6A) +#define BMI160_MAG_DIG_Z1_MSB (0x6B) +#define BMI160_MAG_DIG_XYZ1_LSB (0x6C) +#define BMI160_MAG_DIG_XYZ1_MSB (0x6D) +#define BMI160_MAG_DIG_Z3_LSB (0x6E) +#define BMI160_MAG_DIG_Z3_MSB (0x6F) +#define BMI160_MAG_DIG_XY2 (0x70) +#define BMI160_MAG_DIG_XY1 (0x71) +/**************************************************/ +/**\name BMM150 PRE-SET MODE DEFINITIONS */ +/*************************************************/ +#define BMI160_MAG_PRESETMODE_LOWPOWER (1) +#define BMI160_MAG_PRESETMODE_REGULAR (2) +#define BMI160_MAG_PRESETMODE_HIGHACCURACY (3) +#define BMI160_MAG_PRESETMODE_ENHANCED (4) +/**************************************************/ +/**\name BMM150 PRESET MODES - DATA RATES */ +/*************************************************/ +#define BMI160_MAG_LOWPOWER_DR (0x02) +#define BMI160_MAG_REGULAR_DR (0x02) +#define BMI160_MAG_HIGHACCURACY_DR (0x2A) +#define BMI160_MAG_ENHANCED_DR (0x02) +/**************************************************/ +/**\name BMM150 PRESET MODES - REPETITIONS-XY RATES */ +/*************************************************/ +#define BMI160_MAG_LOWPOWER_REPXY (1) +#define BMI160_MAG_REGULAR_REPXY (4) +#define BMI160_MAG_HIGHACCURACY_REPXY (23) +#define BMI160_MAG_ENHANCED_REPXY (7) +/**************************************************/ +/**\name BMM150 PRESET MODES - REPETITIONS-Z RATES */ +/*************************************************/ +#define BMI160_MAG_LOWPOWER_REPZ (2) +#define BMI160_MAG_REGULAR_REPZ (14) +#define BMI160_MAG_HIGHACCURACY_REPZ (82) +#define BMI160_MAG_ENHANCED_REPZ (26) +#define BMI160_MAG_NOAMRL_SWITCH_TIMES (5) +#define MAG_INTERFACE_PMU_ENABLE (1) +#define MAG_INTERFACE_PMU_DISABLE (0) +/**************************************************/ +/**\name USED FOR MAG OVERFLOW CHECK FOR BMM150 */ +/*************************************************/ +#define BMI160_MAG_OVERFLOW_OUTPUT ((s16)-32768) +#define BMI160_MAG_OVERFLOW_OUTPUT_S32 ((s32)(-2147483647-1)) +#define BMI160_MAG_NEGATIVE_SATURATION_Z ((s16)-32767) +#define BMI160_MAG_POSITIVE_SATURATION_Z ((u16)32767) +#define BMI160_MAG_FLIP_OVERFLOW_ADCVAL ((s16)-4096) +#define BMI160_MAG_HALL_OVERFLOW_ADCVAL ((s16)-16384) +/**************************************************/ +/**\name BMM150 REGISTER DEFINITION */ +/*************************************************/ +#define BMI160_BMM150_CHIP_ID (0x40) +#define BMI160_BMM150_POWE_CONTROL_REG (0x4B) +#define BMI160_BMM150_POWE_MODE_REG (0x4C) +#define BMI160_BMM150_DATA_REG (0x42) +#define BMI160_BMM150_XY_REP (0x51) +#define BMI160_BMM150_Z_REP (0x52) +/**************************************************/ +/**\name AKM COMPENSATING DATA REGISTERS */ +/*************************************************/ +#define BMI160_BST_AKM_ASAX (0x60) +#define BMI160_BST_AKM_ASAY (0x61) +#define BMI160_BST_AKM_ASAZ (0x62) +/**************************************************/ +/**\name AKM POWER MODE SELECTION */ +/*************************************************/ +#define AKM_POWER_DOWN_MODE (0) +#define AKM_SINGLE_MEAS_MODE (1) +#define FUSE_ROM_MODE (2) +/**************************************************/ +/**\name SECONDARY_MAG POWER MODE SELECTION */ +/*************************************************/ +#define BMI160_MAG_FORCE_MODE (0) +#define BMI160_MAG_SUSPEND_MODE (1) +/**************************************************/ +/**\name MAG POWER MODE SELECTION */ +/*************************************************/ +#define FORCE_MODE (0) +#define SUSPEND_MODE (1) +#define NORMAL_MODE (2) +#define MAG_SUSPEND_MODE (1) +/**************************************************/ +/**\name FIFO CONFIGURATIONS */ +/*************************************************/ +#define FIFO_HEADER_ENABLE (0x01) +#define FIFO_MAG_ENABLE (0x01) +#define FIFO_ACCEL_ENABLE (0x01) +#define FIFO_GYRO_ENABLE (0x01) +#define FIFO_TIME_ENABLE (0x01) +#define FIFO_STOPONFULL_ENABLE (0x01) +#define FIFO_WM_INTERRUPT_ENABLE (0x01) +#define BMI160_FIFO_INDEX_LENGTH (1) +#define BMI160_FIFO_TAG_INTR_MASK (0xFC) + +/**************************************************/ +/**\name ACCEL POWER MODE */ +/*************************************************/ +#define ACCEL_MODE_NORMAL (0x11) +#define ACCEL_LOWPOWER (0X12) +#define ACCEL_SUSPEND (0X10) +/**************************************************/ +/**\name GYRO POWER MODE */ +/*************************************************/ +#define GYRO_MODE_SUSPEND (0x14) +#define GYRO_MODE_NORMAL (0x15) +#define GYRO_MODE_FASTSTARTUP (0x17) +/**************************************************/ +/**\name MAG POWER MODE */ +/*************************************************/ +#define MAG_MODE_SUSPEND (0x18) +#define MAG_MODE_NORMAL (0x19) +#define MAG_MODE_LOWPOWER (0x1A) +/**************************************************/ +/**\name ENABLE/DISABLE BIT VALUES */ +/*************************************************/ +#define BMI160_ENABLE (0x01) +#define BMI160_DISABLE (0x00) +/**************************************************/ +/**\name INTERRUPT EDGE TRIGGER ENABLE */ +/*************************************************/ +#define BMI160_EDGE (0x01) +#define BMI160_LEVEL (0x00) +/**************************************************/ +/**\name INTERRUPT LEVEL ENABLE */ +/*************************************************/ +#define BMI160_LEVEL_LOW (0x00) +#define BMI160_LEVEL_HIGH (0x01) +/**************************************************/ +/**\name INTERRUPT OUTPUT ENABLE */ +/*************************************************/ +#define BMI160_OPEN_DRAIN (0x01) +#define BMI160_PUSH_PULL (0x00) + +/* interrupt output enable*/ +#define BMI160_INPUT (0x01) +#define BMI160_OUTPUT (0x00) + +/**************************************************/ +/**\name INTERRUPT TAP SOURCE ENABLE */ +/*************************************************/ +#define FILTER_DATA (0x00) +#define UNFILTER_DATA (0x01) +/**************************************************/ +/**\name SLOW MOTION/ NO MOTION SELECT */ +/*************************************************/ +#define SLOW_MOTION (0x00) +#define NO_MOTION (0x01) +/**************************************************/ +/**\name SIGNIFICANT MOTION SELECTION */ +/*************************************************/ +#define ANY_MOTION (0x00) +#define SIGNIFICANT_MOTION (0x01) +/**************************************************/ +/**\name LATCH DURATION */ +/*************************************************/ +#define BMI160_LATCH_DUR_NONE (0x00) +#define BMI160_LATCH_DUR_312_5_MICRO_SEC (0x01) +#define BMI160_LATCH_DUR_625_MICRO_SEC (0x02) +#define BMI160_LATCH_DUR_1_25_MILLI_SEC (0x03) +#define BMI160_LATCH_DUR_2_5_MILLI_SEC (0x04) +#define BMI160_LATCH_DUR_5_MILLI_SEC (0x05) +#define BMI160_LATCH_DUR_10_MILLI_SEC (0x06) +#define BMI160_LATCH_DUR_20_MILLI_SEC (0x07) +#define BMI160_LATCH_DUR_40_MILLI_SEC (0x08) +#define BMI160_LATCH_DUR_80_MILLI_SEC (0x09) +#define BMI160_LATCH_DUR_160_MILLI_SEC (0x0A) +#define BMI160_LATCH_DUR_320_MILLI_SEC (0x0B) +#define BMI160_LATCH_DUR_640_MILLI_SEC (0x0C) +#define BMI160_LATCH_DUR_1_28_SEC (0x0D) +#define BMI160_LATCH_DUR_2_56_SEC (0x0E) +#define BMI160_LATCHED (0x0F) +/**************************************************/ +/**\name GYRO OFFSET MASK DEFINITION */ +/*************************************************/ +#define BMI160_GYRO_MANUAL_OFFSET_0_7 (0x00FF) +#define BMI160_GYRO_MANUAL_OFFSET_8_9 (0x0300) +/**************************************************/ +/**\name STEP CONFIGURATION MASK DEFINITION */ +/*************************************************/ +#define BMI160_STEP_CONFIG_0_7 (0x00FF) +#define BMI160_STEP_CONFIG_8_10 (0x0700) +#define BMI160_STEP_CONFIG_11_14 (0xF000) +/**************************************************/ +/**\name DEFINITION USED FOR DIFFERENT WRITE */ +/*************************************************/ +#define BMI160_WRITE_TARGET_PAGE0 (0x00) +#define BMI160_WRITE_TARGET_PAGE1 (0x01) +#define BMI160_WRITE_ENABLE_PAGE1 (0x01) +#define BMI160_MANUAL_DISABLE (0x00) +#define BMI160_MANUAL_ENABLE (0x01) +#define BMI160_YAS_DISABLE_RCOIL (0x00) +#define BMI160_ENABLE_MAG_IF_MODE (0x02) +#define BMI160_ENABLE_ANY_MOTION_INTR1 (0x04) +#define BMI160_ENABLE_ANY_MOTION_INTR2 (0x04) +#define BMI160_MAG_DATA_READ_REG (0x04) +#define BMI160_BMM_POWER_MODE_REG (0x06) +#define BMI160_ENABLE_ANY_MOTION_AXIS (0x07) +#define BMI160_ENABLE_LOW_G (0x08) +#define BMI160_YAS532_ACQ_START (0x11) +#define BMI160_YAS_DEVICE_ID_REG (0x80) +#define BMI160_FIFO_GYRO_ENABLE (0x80) +#define BMI160_SIG_MOTION_INTR_ENABLE (0x01) +#define BMI160_STEP_DETECT_INTR_ENABLE (0x01) +#define BMI160_LOW_G_INTR_STAT (0x01) +#define BMI160_PULL_UP_DATA (0x30) +#define BMI160_FIFO_M_G_A_ENABLE (0xE0) +#define BMI160_FIFO_M_G_ENABLE (0xA0) +#define BMI160_FIFO_M_A_ENABLE (0x60) +#define BMI160_FIFO_G_A_ENABLE (0xC0) +#define BMI160_FIFO_A_ENABLE (0x40) +#define BMI160_FIFO_M_ENABLE (0x20) +/**************************************************/ +/**\name MAG INIT DEFINITION */ +/*************************************************/ +#define BMI160_COMMAND_REG_ONE (0x37) +#define BMI160_COMMAND_REG_TWO (0x9A) +#define BMI160_COMMAND_REG_THREE (0xC0) +#define RESET_STEP_COUNTER (0xB2) +/**************************************************/ +/**\name BIT SLICE GET AND SET FUNCTIONS */ +/*************************************************/ +#define BMI160_GET_BITSLICE(regvar, bitname)\ + ((regvar & bitname##__MSK) >> bitname##__POS) + + +#define BMI160_SET_BITSLICE(regvar, bitname, val)\ + ((regvar & ~bitname##__MSK) | \ + ((val< Success + * @retval -1 -> Error + * + * @note + * While changing the parameter of the bmi160_t + * consider the following point: + * Changing the reference value of the parameter + * will changes the local copy or local reference + * make sure your changes will not + * affect the reference value of the parameter + * (Better case don't change the reference value of the parameter) + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_init(struct bmi160_t *bmi160); +/**************************************************/ +/**\name FUNCTION FOR READ AND WRITE REGISTERS */ +/*************************************************/ +/*! + * @brief + * This API write the data to + * the given register + * + * + * @param v_addr_u8 -> Address of the register + * @param v_data_u8 -> The data from the register + * @param v_len_u8 -> no of bytes to read + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_write_reg(u8 v_addr_u8, +u8 *v_data_u8, u8 v_len_u8); +/*! + * @brief + * This API reads the data from + * the given register + * + * + * @param v_addr_u8 -> Address of the register + * @param v_data_u8 -> The data from the register + * @param v_len_u8 -> no of bytes to read + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_reg(u8 v_addr_u8, +u8 *v_data_u8, u8 v_len_u8); +/**************************************************/ +/**\name FUNCTION FOR ERROR CODES */ +/*************************************************/ +/*! + * @brief This API used to reads the fatal error + * from the Register 0x02 bit 0 + * This flag will be reset only by power-on-reset and soft reset + * + * + * @param v_fatal_err_u8 : The status of fatal error + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fatal_err(u8 +*v_fatal_err_u8); +/*! + * @brief This API used to read the error code + * from register 0x02 bit 1 to 4 + * + * + * @param v_err_code_u8 : The status of error codes + * error_code | description + * ------------|--------------- + * 0x00 |no error + * 0x01 |ACC_CONF error (accel ODR and bandwidth not compatible) + * 0x02 |GYR_CONF error (Gyroscope ODR and bandwidth not compatible) + * 0x03 |Under sampling mode and interrupt uses pre filtered data + * 0x04 |reserved + * 0x05 |Selected trigger-readout offset in + * - |MAG_IF greater than selected ODR + * 0x06 |FIFO configuration error for header less mode + * 0x07 |Under sampling mode and pre filtered data as FIFO source + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_err_code(u8 +*v_error_code_u8); +/*! + * @brief This API Reads the i2c error code from the + * Register 0x02 bit 5. + * This error occurred in I2C master detected + * + * @param v_i2c_err_code_u8 : The status of i2c fail error + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_i2c_fail_err(u8 +*v_i2c_error_code_u8); + /*! + * @brief This API Reads the dropped command error + * from the register 0x02 bit 6 + * + * + * @param v_drop_cmd_err_u8 : The status of drop command error + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_drop_cmd_err(u8 +*v_drop_cmd_err_u8); +/*! + * @brief This API reads the magnetometer data ready + * interrupt not active. + * It reads from the error register 0x0x2 bit 7 + * + * + * + * + * @param v_mag_data_rdy_err_u8 : The status of mag data ready interrupt + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_dada_rdy_err(u8 +*v_mag_data_rdy_err_u8); +/*! + * @brief This API reads the error status + * from the error register 0x02 bit 0 to 7 + * + * @param v_mag_data_rdy_err_u8 : The status of mag data ready interrupt + * @param v_fatal_er_u8r : The status of fatal error + * @param v_err_code_u8 : The status of error code + * @param v_i2c_fail_err_u8 : The status of I2C fail error + * @param v_drop_cmd_err_u8 : The status of drop command error + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_error_status(u8 *v_fatal_er_u8r, +u8 *v_err_code_u8, u8 *v_i2c_fail_err_u8, +u8 *v_drop_cmd_err_u8, u8 *v_mag_data_rdy_err_u8); +/******************************************************************/ +/**\name FUNCTIONS FOR MAG,ACCEL AND GYRO POWER MODE STATUS */ +/*****************************************************************/ +/*! + * @brief This API reads the magnetometer power mode from + * PMU status register 0x03 bit 0 and 1 + * + * @param v_mag_power_mode_stat_u8 : The value of mag power mode + * mag_powermode | value + * ------------------|---------- + * SUSPEND | 0x00 + * NORMAL | 0x01 + * LOW POWER | 0x02 + * + * + * @note The power mode of mag set by the 0x7E command register + * @note using the function "bmi160_set_command_register()" + * value | mode + * ---------|---------------- + * 0x18 | MAG_MODE_SUSPEND + * 0x19 | MAG_MODE_NORMAL + * 0x1A | MAG_MODE_LOWPOWER + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_power_mode_stat(u8 +*v_mag_power_mode_stat_u8); +/*! + * @brief This API reads the gyroscope power mode from + * PMU status register 0x03 bit 2 and 3 + * + * @param v_gyro_power_mode_stat_u8 : The value of gyro power mode + * gyro_powermode | value + * ------------------|---------- + * SUSPEND | 0x00 + * NORMAL | 0x01 + * FAST POWER UP | 0x03 + * + * @note The power mode of gyro set by the 0x7E command register + * @note using the function "bmi160_set_command_register()" + * value | mode + * ---------|---------------- + * 0x14 | GYRO_MODE_SUSPEND + * 0x15 | GYRO_MODE_NORMAL + * 0x17 | GYRO_MODE_FASTSTARTUP + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_power_mode_stat(u8 +*v_gyro_power_mode_stat_u8); +/*! + * @brief This API reads the accelerometer power mode from + * PMU status register 0x03 bit 4 and 5 + * + * + * @param v_accel_power_mode_stat_u8 : The value of accel power mode + * accel_powermode | value + * ------------------|---------- + * SUSPEND | 0x00 + * NORMAL | 0x01 + * LOW POWER | 0x03 + * + * @note The power mode of accel set by the 0x7E command register + * @note using the function "bmi160_set_command_register()" + * value | mode + * ---------|---------------- + * 0x11 | ACCEL_MODE_NORMAL + * 0x12 | ACCEL_LOWPOWER + * 0x10 | ACCEL_SUSPEND + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_power_mode_stat(u8 +*v_accel_power_mode_stat_u8); +/*! + * @brief This API switch mag interface to normal mode + * and confirm whether the mode switching done successfully or not +* + * @return results of bus communication function and current MAG_PMU result + * @retval 0 -> Success + * @retval -1 -> Error + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_interface_normal(void); +/**************************************************/ +/**\name FUNCTION FOR Mag XYZ data read */ +/*************************************************/ +/*! + * @brief This API reads magnetometer data X values + * from the register 0x04 and 0x05 + * @brief The mag sensor data read form auxiliary mag + * + * @param v_mag_x_s16 : The value of mag x + * @param v_sensor_select_u8 : Mag selection value + * value | sensor + * ---------|---------------- + * 0 | BMM150 + * 1 | AKM09911 or AKM09912 + * + * @note For mag data output rate configuration use the following function + * @note bmi160_set_mag_output_data_rate() + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_x(s16 *v_mag_x_s16, +u8 v_sensor_select_u8); +/*! + * @brief This API reads magnetometer data Y values + * from the register 0x06 and 0x07 + * @brief The mag sensor data read form auxiliary mag + * + * @param v_mag_y_s16 : The value of mag y + * @param v_sensor_select_u8 : Mag selection value + * value | sensor + * ---------|---------------- + * 0 | BMM150 + * 1 | AKM09911 or AKM09912 + * + * @note For mag data output rate configuration use the following function + * @note bmi160_set_mag_output_data_rate() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_y(s16 *v_mag_y_s16, +u8 v_sensor_select_u8); +/*! + * @brief This API reads magnetometer data Z values + * from the register 0x08 and 0x09 + * @brief The mag sensor data read form auxiliary mag + * + * @param v_mag_z_s16 : The value of mag z + * @param v_sensor_select_u8 : Mag selection value + * value | sensor + * ---------|---------------- + * 0 | BMM150 + * 1 | AKM09911 or AKM09912 + * + * @note For mag data output rate configuration use the following function + * @note bmi160_set_mag_output_data_rate() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_z(s16 *v_mag_z_s16, +u8 v_sensor_select_u8); +/*! + * @brief This API reads magnetometer data RHALL values + * from the register 0x0A and 0x0B + * + * + * @param v_mag_r_s16 : The value of BMM150 r data + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_r( +s16 *v_mag_r_s16); +/*! + * @brief This API reads magnetometer data X,Y,Z values + * from the register 0x04 to 0x09 + * + * @brief The mag sensor data read form auxiliary mag + * + * @param mag : The value of mag xyz data + * @param v_sensor_select_u8 : Mag selection value + * value | sensor + * ---------|---------------- + * 0 | BMM150 + * 1 | AKM09911 or AKM09912 + * + * @note For mag data output rate configuration use the following function + * @note bmi160_set_mag_output_data_rate() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_xyz( +struct bmi160_mag_t *mag, u8 v_sensor_select_u8); + /*!* + * @brief This API reads magnetometer data X,Y,Z,r + * values from the register 0x04 to 0x0B + * + * @brief The mag sensor data read form auxiliary mag + * + * @param mag : The value of mag-BMM150 xyzr data + * + * @note For mag data output rate configuration use the following function + * @note bmi160_set_mag_output_data_rate() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_xyzr( +struct bmi160_mag_xyzr_t *mag); +/**************************************************/ +/**\name FUNCTION FOR GYRO XYZ DATA READ */ +/*************************************************/ +/*! + * @brief This API reads gyro data X values + * form the register 0x0C and 0x0D + * + * + * + * + * @param v_gyro_x_s16 : The value of gyro x data + * + * @note Gyro Configuration use the following function + * @note bmi160_set_gyro_output_data_rate() + * @note bmi160_set_gyro_bw() + * @note bmi160_set_gyro_range() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_gyro_x( +s16 *v_gyro_x_s16); +/*! + * @brief This API reads gyro data Y values + * form the register 0x0E and 0x0F + * + * + * + * + * @param v_gyro_y_s16 : The value of gyro y data + * + * @note Gyro Configuration use the following function + * @note bmi160_set_gyro_output_data_rate() + * @note bmi160_set_gyro_bw() + * @note bmi160_set_gyro_range() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error result of communication routines + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_gyro_y( +s16 *v_gyro_y_s16); +/*! + * @brief This API reads gyro data Z values + * form the register 0x10 and 0x11 + * + * + * + * + * @param v_gyro_z_s16 : The value of gyro z data + * + * @note Gyro Configuration use the following function + * @note bmi160_set_gyro_output_data_rate() + * @note bmi160_set_gyro_bw() + * @note bmi160_set_gyro_range() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_gyro_z( +s16 *v_gyro_z_s16); +/*! + * @brief This API reads gyro data X,Y,Z values + * from the register 0x0C to 0x11 + * + * + * + * + * @param gyro : The value of gyro xyz + * + * @note Gyro Configuration use the following function + * @note bmi160_set_gyro_output_data_rate() + * @note bmi160_set_gyro_bw() + * @note bmi160_set_gyro_range() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_gyro_xyz( +struct bmi160_gyro_t *gyro); +/**************************************************/ +/**\name FUNCTION FOR ACCEL XYZ DATA READ */ +/*************************************************/ +/*! + * @brief This API reads accelerometer data X values + * form the register 0x12 and 0x13 + * + * + * + * + * @param v_accel_x_s16 : The value of accel x + * + * @note For accel configuration use the following functions + * @note bmi160_set_accel_output_data_rate() + * @note bmi160_set_accel_bw() + * @note bmi160_set_accel_under_sampling_parameter() + * @note bmi160_set_accel_range() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_accel_x( +s16 *v_accel_x_s16); +/*! + * @brief This API reads accelerometer data Y values + * form the register 0x14 and 0x15 + * + * + * + * + * @param v_accel_y_s16 : The value of accel y + * + * @note For accel configuration use the following functions + * @note bmi160_set_accel_output_data_rate() + * @note bmi160_set_accel_bw() + * @note bmi160_set_accel_under_sampling_parameter() + * @note bmi160_set_accel_range() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_accel_y( +s16 *v_accel_y_s16); +/*! + * @brief This API reads accelerometer data Z values + * form the register 0x16 and 0x17 + * + * + * + * + * @param v_accel_z_s16 : The value of accel z + * + * @note For accel configuration use the following functions + * @note bmi160_set_accel_output_data_rate() + * @note bmi160_set_accel_bw() + * @note bmi160_set_accel_under_sampling_parameter() + * @note bmi160_set_accel_range() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_accel_z( +s16 *v_accel_z_s16); +/*! + * @brief This API reads accelerometer data X,Y,Z values + * from the register 0x12 to 0x17 + * + * + * + * + * @param accel :The value of accel xyz + * + * @note For accel configuration use the following functions + * @note bmi160_set_accel_output_data_rate() + * @note bmi160_set_accel_bw() + * @note bmi160_set_accel_under_sampling_parameter() + * @note bmi160_set_accel_range() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_accel_xyz( +struct bmi160_accel_t *accel); +/**************************************************/ +/**\name FUNCTION FOR SENSOR TIME */ +/*************************************************/ +/*! + * @brief This API reads sensor_time from the register + * 0x18 to 0x1A + * + * + * @param v_sensor_time_u32 : The value of sensor time + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_sensor_time( +u32 *v_sensor_time_u32); +/**************************************************/ +/**\name FUNCTION FOR GYRO SLEF TEST */ +/*************************************************/ +/*! + * @brief This API reads the Gyroscope self test + * status from the register 0x1B bit 1 + * + * + * @param v_gyro_selftest_u8 : The value of gyro self test status + * value | status + * ---------|---------------- + * 0 | Gyroscope self test is running or failed + * 1 | Gyroscope self test completed successfully + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_selftest(u8 +*v_gyro_selftest_u8); +/**************************************************/ +/**\name FUNCTION FOR MANUAL INTERFACE */ +/*************************************************/ +/*! + * @brief This API reads the status of + * mag manual interface operation form the register 0x1B bit 2 + * + * + * + * @param v_mag_manual_stat_u8 : The value of mag manual operation status + * value | status + * ---------|---------------- + * 0 | Indicates no manual magnetometer + * - | interface operation is ongoing + * 1 | Indicates manual magnetometer + * - | interface operation is ongoing + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_manual_operation_stat(u8 +*v_mag_manual_stat_u8); +/**************************************************/ +/**\name FUNCTION FOR FAST OFFSET READY */ +/*************************************************/ +/*! + * @brief This API reads the fast offset compensation + * status form the register 0x1B bit 3 + * + * + * @param v_foc_rdy_u8 : The status of fast compensation + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_rdy(u8 +*v_foc_rdy_u8); +/**************************************************/ +/**\name FUNCTION FOR NVM READY */ +/*************************************************/ +/*! + * @brief This API Reads the nvm_rdy status from the + * resister 0x1B bit 4 + * + * + * @param v_nvm_rdy_u8 : The value of NVM ready status + * value | status + * ---------|---------------- + * 0 | NVM write operation in progress + * 1 | NVM is ready to accept a new write trigger + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_nvm_rdy(u8 +*v_nvm_rdy_u8); +/**************************************************/ +/**\name FUNCTION FOR DATA READY FOR MAG, GYRO, AND ACCEL */ +/*************************************************/ +/*! + * @brief This API reads the status of mag data ready + * from the register 0x1B bit 5 + * The status get reset when one mag data register is read out + * + * @param v_data_rdy_u8 : The value of mag data ready status + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_data_rdy_mag(u8 +*v_data_rdy_u8); +/*! + * @brief This API reads the status of gyro data ready form the + * register 0x1B bit 6 + * The status get reset when gyro data register read out + * + * + * @param v_data_rdy_u8 : The value of gyro data ready + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_data_rdy(u8 +*v_data_rdy_u8); +/*! + * @brief This API reads the status of accel data ready form the + * register 0x1B bit 7 + * The status get reset when accel data register read out + * + * + * @param v_data_rdy_u8 : The value of accel data ready status + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_data_rdy(u8 +*drdy_acc); +/**************************************************/ +/**\name FUNCTION FOR STEP INTERRUPT STATUS */ +/*************************************************/ +/*! + * @brief This API reads the step detector interrupt status + * from the register 0x1C bit 0 + * flag is associated with a specific interrupt function. + * It is set when the single tab interrupt triggers. The + * setting of INT_LATCH controls if the interrupt + * signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_step_intr_u8 : The status of step detector interrupt + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_step_intr(u8 +*v_step_intr_u8); +/**************************************************/ +/**\name FUNCTION FOR SIGNIFICANT INTERRUPT STATUS */ +/*************************************************/ +/*! + * @brief This API reads the + * significant motion interrupt status + * from the register 0x1C bit 1 + * flag is associated with a specific interrupt function. + * It is set when the single tab interrupt triggers. The + * setting of INT_LATCH controls if the interrupt + * signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * + * @param v_significant_intr_u8 : The status of step + * motion interrupt + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_significant_intr(u8 +*sigmot_intr); +/**************************************************/ +/**\name FUNCTION FOR ANY MOTION INTERRUPT STATUS */ +/*************************************************/ + /*! + * @brief This API reads the any motion interrupt status + * from the register 0x1C bit 2 + * flag is associated with a specific interrupt function. + * It is set when the single tab interrupt triggers. The + * setting of INT_LATCH controls if the interrupt + * signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * @param v_any_motion_intr_u8 : The status of any-motion interrupt + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_any_motion_intr(u8 +*v_any_motion_intr_u8); +/**************************************************/ +/**\name FUNCTION FOR PMU TRIGGER INTERRUPT STATUS */ +/*************************************************/ +/*! + * @brief This API reads the power mode trigger interrupt status + * from the register 0x1C bit 3 + * flag is associated with a specific interrupt function. + * It is set when the single tab interrupt triggers. The + * setting of INT_LATCH controls if the interrupt + * signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * + * @param v_pmu_trigger_intr_u8 : The status of power mode trigger interrupt + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_pmu_trigger_intr(u8 +*v_pmu_trigger_intr_u8); +/**************************************************/ +/**\name FUNCTION FOR DOUBLE TAB STATUS */ +/*************************************************/ +/*! + * @brief This API reads the double tab status + * from the register 0x1C bit 4 + * flag is associated with a specific interrupt function. + * It is set when the single tab interrupt triggers. The + * setting of INT_LATCH controls if the interrupt + * signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_double_tap_intr_u8 :The status of double tab interrupt + * + * @note Double tap interrupt can be configured by the following functions + * @note INTERRUPT MAPPING + * @note bmi160_set_intr_double_tap() + * @note AXIS MAPPING + * @note bmi160_get_stat2_tap_first_x() + * @note bmi160_get_stat2_tap_first_y() + * @note bmi160_get_stat2_tap_first_z() + * @note DURATION + * @note bmi160_set_intr_tap_durn() + * @note THRESHOLD + * @note bmi160_set_intr_tap_thres() + * @note TAP QUIET + * @note bmi160_set_intr_tap_quiet() + * @note TAP SHOCK + * @note bmi160_set_intr_tap_shock() + * @note TAP SOURCE + * @note bmi160_set_intr_tap_source() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_double_tap_intr(u8 +*v_double_tap_intr_u8); +/**************************************************/ +/**\name FUNCTION FOR SINGLE TAB STATUS */ +/*************************************************/ +/*! + * @brief This API reads the single tab status + * from the register 0x1C bit 5 + * flag is associated with a specific interrupt function. + * It is set when the single tab interrupt triggers. The + * setting of INT_LATCH controls if the interrupt + * signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_single_tap_intr_u8 :The status of single tap interrupt + * + * @note Single tap interrupt can be configured by the following functions + * @note INTERRUPT MAPPING + * @note bmi160_set_intr_single_tap() + * @note AXIS MAPPING + * @note bmi160_get_stat2_tap_first_x() + * @note bmi160_get_stat2_tap_first_y() + * @note bmi160_get_stat2_tap_first_z() + * @note DURATION + * @note bmi160_set_intr_tap_durn() + * @note THRESHOLD + * @note bmi160_set_intr_tap_thres() + * @note TAP QUIET + * @note bmi160_set_intr_tap_quiet() + * @note TAP SHOCK + * @note bmi160_set_intr_tap_shock() + * @note TAP SOURCE + * @note bmi160_set_intr_tap_source() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_single_tap_intr(u8 +*v_single_tap_intr_u8); +/**************************************************/ +/**\name FUNCTION FOR ORIENT INTERRUPT STATUS */ +/*************************************************/ +/*! + * @brief This API reads the orient status + * from the register 0x1C bit 6 + * flag is associated with a specific interrupt function. + * It is set when the orient interrupt triggers. The + * setting of INT_LATCH controls if the + * interrupt signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_orient_intr_u8 : The status of orient interrupt + * + * @note For orient interrupt configuration use the following functions + * @note STATUS + * @note bmi160_get_stat0_orient_intr() + * @note AXIS MAPPING + * @note bmi160_get_stat3_orient_xy() + * @note bmi160_get_stat3_orient_z() + * @note bmi160_set_intr_orient_axes_enable() + * @note INTERRUPT MAPPING + * @note bmi160_set_intr_orient() + * @note INTERRUPT OUTPUT + * @note bmi160_set_intr_orient_ud_enable() + * @note THETA + * @note bmi160_set_intr_orient_theta() + * @note HYSTERESIS + * @note bmi160_set_intr_orient_hyst() + * @note BLOCKING + * @note bmi160_set_intr_orient_blocking() + * @note MODE + * @note bmi160_set_intr_orient_mode() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_orient_intr(u8 +*v_orient_intr_u8); +/**************************************************/ +/**\name FUNCTION FOR FLAT INTERRUPT STATUS */ +/*************************************************/ +/*! + * @brief This API reads the flat interrupt status + * from the register 0x1C bit 7 + * flag is associated with a specific interrupt function. + * It is set when the flat interrupt triggers. The + * setting of INT_LATCH controls if the + * interrupt signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_flat_intr_u8 : The status of flat interrupt + * + * @note For flat configuration use the following functions + * @note STATS + * @note bmi160_get_stat0_flat_intr() + * @note bmi160_get_stat3_flat() + * @note INTERRUPT MAPPING + * @note bmi160_set_intr_flat() + * @note THETA + * @note bmi160_set_intr_flat_theta() + * @note HOLD TIME + * @note bmi160_set_intr_flat_hold() + * @note HYSTERESIS + * @note bmi160_set_intr_flat_hyst() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_flat_intr(u8 +*v_flat_intr_u8); +/**************************************************/ +/**\name FUNCTION FOR HIGH_G INTERRUPT STATUS */ +/*************************************************/ +/*! + * @brief This API reads the high_g interrupt status + * from the register 0x1D bit 2 + * flag is associated with a specific interrupt function. + * It is set when the high g interrupt triggers. The + * setting of INT_LATCH controls if the interrupt signal and hence the + * respective interrupt flag will be permanently + * latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_high_g_intr_u8 : The status of high_g interrupt + * + * @note High_g interrupt configured by following functions + * @note STATUS + * @note bmi160_get_stat1_high_g_intr() + * @note AXIS MAPPING + * @note bmi160_get_stat3_high_g_first_x() + * @note bmi160_get_stat3_high_g_first_y() + * @note bmi160_get_stat3_high_g_first_z() + * @note SIGN MAPPING + * @note bmi160_get_stat3_high_g_first_sign() + * @note INTERRUPT MAPPING + * @note bmi160_set_intr_high_g() + * @note HYSTERESIS + * @note bmi160_set_intr_high_g_hyst() + * @note DURATION + * @note bmi160_set_intr_high_g_durn() + * @note THRESHOLD + * @note bmi160_set_intr_high_g_thres() + * @note SOURCE + * @note bmi160_set_intr_low_high_source() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_high_g_intr(u8 +*v_high_g_intr_u8); +/**************************************************/ +/**\name FUNCTION FOR LOW_G INTERRUPT STATUS */ +/*************************************************/ +/*! + * @brief This API reads the low g interrupt status + * from the register 0x1D bit 3 + * flag is associated with a specific interrupt function. + * It is set when the low g interrupt triggers. The + * setting of INT_LATCH controls if the interrupt signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_low_g_intr_u8 : The status of low_g interrupt + * + * @note Low_g interrupt configured by following functions + * @note STATUS + * @note bmi160_get_stat1_low_g_intr() + * @note INTERRUPT MAPPING + * @note bmi160_set_intr_low_g() + * @note SOURCE + * @note bmi160_set_intr_low_high_source() + * @note DURATION + * @note bmi160_set_intr_low_g_durn() + * @note THRESHOLD + * @note bmi160_set_intr_low_g_thres() + * @note HYSTERESIS + * @note bmi160_set_intr_low_g_hyst() + * @note MODE + * @note bmi160_set_intr_low_g_mode() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_low_g_intr(u8 +*v_low_g_intr_u8); +/**************************************************/ +/**\name FUNCTION FOR DATA READY INTERRUPT STATUS */ +/*************************************************/ +/*! + * @brief This API reads data ready interrupt status + * from the register 0x1D bit 4 + * flag is associated with a specific interrupt function. + * It is set when the data ready interrupt triggers. The + * setting of INT_LATCH controls if the interrupt signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_data_rdy_intr_u8 : The status of data ready interrupt + * + * @note Data ready interrupt configured by following functions + * @note STATUS + * @note bmi160_get_stat1_data_rdy_intr() + * @note INTERRUPT MAPPING + * @note bmi160_set_intr_data_rdy() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_data_rdy_intr(u8 +*v_data_rdy_intr_u8); +/**************************************************/ +/**\name FUNCTIONS FOR FIFO FULL AND WATER MARK INTERRUPT STATUS*/ +/*************************************************/ +/*! + * @brief This API reads data ready FIFO full interrupt status + * from the register 0x1D bit 5 + * flag is associated with a specific interrupt function. + * It is set when the FIFO full interrupt triggers. The + * setting of INT_LATCH controls if the + * interrupt signal and hence the + * respective interrupt flag will + * be permanently latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_fifo_full_intr_u8 : The status of fifo full interrupt + * + * @note FIFO full interrupt can be configured by following functions + * @note bmi160_set_intr_fifo_full() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_fifo_full_intr(u8 +*v_fifo_full_intr_u8); +/*! + * @brief This API reads data + * ready FIFO watermark interrupt status + * from the register 0x1D bit 6 + * flag is associated with a specific interrupt function. + * It is set when the FIFO watermark interrupt triggers. The + * setting of INT_LATCH controls if the + * interrupt signal and hence the + * respective interrupt flag will be + * permanently latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_fifo_wm_intr_u8 : The status of fifo water mark interrupt + * + * @note FIFO full interrupt can be configured by following functions + * @note bmi160_set_intr_fifo_wm() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_fifo_wm_intr(u8 +*v_fifo_wm_intr_u8); +/**************************************************/ +/**\name FUNCTIONS FOR NO MOTION INTERRUPT STATUS*/ +/*************************************************/ +/*! + * @brief This API reads data ready no motion interrupt status + * from the register 0x1D bit 7 + * flag is associated with a specific interrupt function. + * It is set when the no motion interrupt triggers. The + * setting of INT_LATCH controls if the interrupt signal and hence the + * respective interrupt flag will be permanently + * latched, temporarily latched + * or not latched. + * + * + * + * + * @param v_nomotion_intr_u8 : The status of no motion interrupt + * + * @note No motion interrupt can be configured by following function + * @note STATUS + * @note bmi160_get_stat1_nomotion_intr() + * @note INTERRUPT MAPPING + * @note bmi160_set_intr_nomotion() + * @note DURATION + * @note bmi160_set_intr_slow_no_motion_durn() + * @note THRESHOLD + * @note bmi160_set_intr_slow_no_motion_thres() + * @note SLOW/NO MOTION SELECT + * @note bmi160_set_intr_slow_no_motion_select() + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_nomotion_intr(u8 +*nomo_intr); +/**************************************************/ +/**\name FUNCTIONS FOR ANY MOTION FIRST XYZ AND SIGN INTERRUPT STATUS*/ +/*************************************************/ +/*! + * @brief This API reads the status of any motion first x + * from the register 0x1E bit 0 + * + * + * @param v_anymotion_first_x_u8 : The status of any motion first x interrupt + * value | status + * -----------|------------- + * 0 | not triggered + * 1 | triggered by x axis + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_any_motion_first_x(u8 +*v_anymotion_first_x_u8); +/*! + * @brief This API reads the status of any motion first y interrupt + * from the register 0x1E bit 1 + * + * + * + *@param v_any_motion_first_y_u8 : The status of any motion first y interrupt + * value | status + * -----------|------------- + * 0 | not triggered + * 1 | triggered by y axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_any_motion_first_y(u8 +*v_any_motion_first_y_u8); +/*! + * @brief This API reads the status of any motion first z interrupt + * from the register 0x1E bit 2 + * + * + * + * + *@param v_any_motion_first_z_u8 : The status of any motion first z interrupt + * value | status + * -----------|------------- + * 0 | not triggered + * 1 | triggered by y axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_any_motion_first_z(u8 +*v_any_motion_first_z_u8); +/*! + * @brief This API reads the any motion sign status from the + * register 0x1E bit 3 + * + * + * + * + * @param v_anymotion_sign_u8 : The status of any motion sign + * value | sign + * -----------|------------- + * 0 | positive + * 1 | negative + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_any_motion_sign(u8 +*v_anymotion_sign_u8); +/**************************************************/ +/**\name FUNCTIONS FOR TAP FIRST XYZ AND SIGN INTERRUPT STATUS*/ +/*************************************************/ +/*! + * @brief This API reads the any motion tap first x status from the + * register 0x1E bit 4 + * + * + * + * + * @param v_tap_first_x_u8 :The status of any motion tap first x + * value | status + * -----------|------------- + * 0 | not triggered + * 1 | triggered by x axis + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_tap_first_x(u8 +*v_tap_first_x_u8); +/*! + * @brief This API reads the tap first y interrupt status from the + * register 0x1E bit 5 + * + * + * + * + * @param v_tap_first_y_u8 :The status of tap first y interrupt + * value | status + * -----------|------------- + * 0 | not triggered + * 1 | triggered by y axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_tap_first_y(u8 +*v_tap_first_y_u8); +/*! + * @brief This API reads the tap first z interrupt status from the + * register 0x1E bit 6 + * + * + * + * + * @param v_tap_first_z_u8 :The status of tap first z interrupt + * value | status + * -----------|------------- + * 0 | not triggered + * 1 | triggered by z axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_tap_first_z(u8 +*v_tap_first_z_u8); +/*! + * @brief This API reads the tap sign status from the + * register 0x1E bit 7 + * + * + * + * + * @param v_tap_sign_u8 : The status of tap sign + * value | sign + * -----------|------------- + * 0 | positive + * 1 | negative + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_tap_sign(u8 +*tap_sign); +/**************************************************/ +/**\name FUNCTIONS FOR HIGH_G FIRST XYZ AND SIGN INTERRUPT STATUS*/ +/*************************************************/ +/*! + * @brief This API reads the high_g first x status from the + * register 0x1F bit 0 + * + * + * + * + * @param v_high_g_first_x_u8 :The status of high_g first x + * value | status + * -----------|------------- + * 0 | not triggered + * 1 | triggered by x axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_high_g_first_x(u8 +*v_high_g_first_x_u8); +/*! + * @brief This API reads the high_g first y status from the + * register 0x1F bit 1 + * + * + * + * + * @param v_high_g_first_y_u8 : The status of high_g first y + * value | status + * -----------|------------- + * 0 | not triggered + * 1 | triggered by y axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_high_g_first_y(u8 +*v_high_g_first_y_u8); +/*! + * @brief This API reads the high_g first z status from the + * register 0x1F bit 3 + * + * + * + * + * @param v_high_g_first_z_u8 : The status of high_g first z + * value | status + * -----------|------------- + * 0 | not triggered + * 1 | triggered by z axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_high_g_first_z(u8 +*v_high_g_first_z_u8); +/*! + * @brief This API reads the high sign status from the + * register 0x1F bit 3 + * + * + * + * + * @param v_high_g_sign_u8 :The status of high sign + * value | sign + * -----------|------------- + * 0 | positive + * 1 | negative + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_high_g_sign(u8 +*v_high_g_sign_u8); +/**************************************************/ +/**\name FUNCTIONS FOR ORIENT XY AND Z INTERRUPT STATUS*/ +/*************************************************/ +/*! + * @brief This API reads the status of orient_xy plane + * from the register 0x1F bit 4 and 5 + * + * + * @param v_orient_xy_u8 :The status of orient_xy plane + * value | status + * -----------|------------- + * 0x00 | portrait upright + * 0x01 | portrait upside down + * 0x02 | landscape left + * 0x03 | landscape right + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_orient_xy(u8 +*v_orient_xy_u8); +/*! + * @brief This API reads the status of orient z plane + * from the register 0x1F bit 6 + * + * + * @param v_orient_z_u8 :The status of orient z + * value | status + * -----------|------------- + * 0x00 | upward looking + * 0x01 | downward looking + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_orient_z(u8 +*v_orient_z_u8); +/**************************************************/ +/**\name FUNCTIONS FOR FLAT INTERRUPT STATUS*/ +/*************************************************/ +/*! + * @brief This API reads the flat status from the register + * 0x1F bit 7 + * + * + * @param v_flat_u8 : The status of flat interrupt + * value | status + * -----------|------------- + * 0x00 | non flat + * 0x01 | flat position + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_flat(u8 +*flat); +/**************************************************/ +/**\name FUNCTION FOR TEMPERATUE READ */ +/*************************************************/ +/*! + * @brief This API reads the temperature of the sensor + * from the register 0x21 bit 0 to 7 + * + * + * + * @param v_temp_s16 : The value of temperature + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_temp(s16 +*v_temp_s16); +/**************************************************/ +/**\name FUNCTION FOR FIFO LENGTH AND FIFO DATA READ */ +/*************************************************/ +/*! + * @brief This API reads the of the sensor + * form the register 0x23 and 0x24 bit 0 to 7 and 0 to 2 + * @brief this byte counter is updated each time a complete frame + * was read or writtern + * + * + * @param v_fifo_length_u32 : The value of fifo byte counter + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_fifo_length( +u32 *v_fifo_length_u32); +/*! + * @brief This API reads the fifo data of the sensor + * from the register 0x24 + * @brief Data format depends on the setting of register FIFO_CONFIG + * + * + * + * @param v_fifodata_u8 : Pointer holding the fifo data + * + * @note For reading FIFO data use the following functions + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_fifo_data( +u8 *v_fifodata_u8, u16 v_fifo_length_u16); +/**************************************************/ +/**\name FUNCTION FOR ACCEL CONFIGURATIONS */ +/*************************************************/ +/*! + * @brief This API is used to get the + * accel output date rate form the register 0x40 bit 0 to 3 + * + * + * @param v_output_data_rate_u8 :The value of accel output date rate + * value | output data rate + * -------|-------------------------- + * 0 | BMI160_ACCEL_OUTPUT_DATA_RATE_RESERVED + * 1 | BMI160_ACCEL_OUTPUT_DATA_RATE_0_78HZ + * 2 | BMI160_ACCEL_OUTPUT_DATA_RATE_1_56HZ + * 3 | BMI160_ACCEL_OUTPUT_DATA_RATE_3_12HZ + * 4 | BMI160_ACCEL_OUTPUT_DATA_RATE_6_25HZ + * 5 | BMI160_ACCEL_OUTPUT_DATA_RATE_12_5HZ + * 6 | BMI160_ACCEL_OUTPUT_DATA_RATE_25HZ + * 7 | BMI160_ACCEL_OUTPUT_DATA_RATE_50HZ + * 8 | BMI160_ACCEL_OUTPUT_DATA_RATE_100HZ + * 9 | BMI160_ACCEL_OUTPUT_DATA_RATE_200HZ + * 10 | BMI160_ACCEL_OUTPUT_DATA_RATE_400HZ + * 11 | BMI160_ACCEL_OUTPUT_DATA_RATE_800HZ + * 12 | BMI160_ACCEL_OUTPUT_DATA_RATE_1600HZ + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_output_data_rate( +u8 *v_output_data_rate_u8); +/*! + * @brief This API is used to set the + * accel output date rate form the register 0x40 bit 0 to 3 + * + * + * @param v_output_data_rate_u8 :The value of accel output date rate + * value | output data rate + * -------|-------------------------- + * 0 | BMI160_ACCEL_OUTPUT_DATA_RATE_RESERVED + * 1 | BMI160_ACCEL_OUTPUT_DATA_RATE_0_78HZ + * 2 | BMI160_ACCEL_OUTPUT_DATA_RATE_1_56HZ + * 3 | BMI160_ACCEL_OUTPUT_DATA_RATE_3_12HZ + * 4 | BMI160_ACCEL_OUTPUT_DATA_RATE_6_25HZ + * 5 | BMI160_ACCEL_OUTPUT_DATA_RATE_12_5HZ + * 6 | BMI160_ACCEL_OUTPUT_DATA_RATE_25HZ + * 7 | BMI160_ACCEL_OUTPUT_DATA_RATE_50HZ + * 8 | BMI160_ACCEL_OUTPUT_DATA_RATE_100HZ + * 9 | BMI160_ACCEL_OUTPUT_DATA_RATE_200HZ + * 10 | BMI160_ACCEL_OUTPUT_DATA_RATE_400HZ + * 11 | BMI160_ACCEL_OUTPUT_DATA_RATE_800HZ + * 12 | BMI160_ACCEL_OUTPUT_DATA_RATE_1600HZ + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_output_data_rate(u8 odr); +/*! + * @brief This API is used to get the + * accel bandwidth from the register 0x40 bit 4 to 6 + * @brief bandwidth parameter determines filter configuration(acc_us=0) + * and averaging for under sampling mode(acc_us=1) + * + * + * @param v_bw_u8 : The value of accel bandwidth + * + * @note accel bandwidth depends on under sampling parameter + * @note under sampling parameter cab be set by the function + * "BMI160_SET_ACCEL_UNDER_SAMPLING_PARAMETER" + * + * @note Filter configuration + * accel_us | Filter configuration + * -----------|--------------------- + * 0x00 | OSR4 mode + * 0x01 | OSR2 mode + * 0x02 | normal mode + * 0x03 | CIC mode + * 0x04 | Reserved + * 0x05 | Reserved + * 0x06 | Reserved + * 0x07 | Reserved + * + * @note accel under sampling mode + * accel_us | Under sampling mode + * -----------|--------------------- + * 0x00 | no averaging + * 0x01 | average 2 samples + * 0x02 | average 4 samples + * 0x03 | average 8 samples + * 0x04 | average 16 samples + * 0x05 | average 32 samples + * 0x06 | average 64 samples + * 0x07 | average 128 samples + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_bw(u8 *v_bw_u8); +/*! + * @brief This API is used to set the + * accel bandwidth from the register 0x40 bit 4 to 6 + * @brief bandwidth parameter determines filter configuration(acc_us=0) + * and averaging for under sampling mode(acc_us=1) + * + * + * @param v_bw_u8 : The value of accel bandwidth + * + * @note accel bandwidth depends on under sampling parameter + * @note under sampling parameter cab be set by the function + * "BMI160_SET_ACCEL_UNDER_SAMPLING_PARAMETER" + * + * @note Filter configuration + * accel_us | Filter configuration + * -----------|--------------------- + * 0x00 | OSR4 mode + * 0x01 | OSR2 mode + * 0x02 | normal mode + * 0x03 | CIC mode + * 0x04 | Reserved + * 0x05 | Reserved + * 0x06 | Reserved + * 0x07 | Reserved + * + * @note accel under sampling mode + * accel_us | Under sampling mode + * -----------|--------------------- + * 0x00 | no averaging + * 0x01 | average 2 samples + * 0x02 | average 4 samples + * 0x03 | average 8 samples + * 0x04 | average 16 samples + * 0x05 | average 32 samples + * 0x06 | average 64 samples + * 0x07 | average 128 samples + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_bw(u8 v_bw_u8); +/*! + * @brief This API is used to get the accel + * under sampling parameter form the register 0x40 bit 7 + * + * + * + * + * @param v_accel_under_sampling_u8 : The value of accel under sampling + * value | under_sampling + * ----------|--------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_under_sampling_parameter( +u8 *v_accel_under_sampling_u8); +/*! + * @brief This API is used to set the accel + * under sampling parameter form the register 0x40 bit 7 + * + * + * + * + * @param v_accel_under_sampling_u8 : The value of accel under sampling + * value | under_sampling + * ----------|--------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_under_sampling_parameter( +u8 v_accel_under_sampling_u8); +/*! + * @brief This API is used to get the ranges + * (g values) of the accel from the register 0x41 bit 0 to 3 + * + * + * + * + * @param v_range_u8 : The value of accel g range + * value | g_range + * ----------|----------- + * 0x03 | BMI160_ACCEL_RANGE_2G + * 0x05 | BMI160_ACCEL_RANGE_4G + * 0x08 | BMI160_ACCEL_RANGE_8G + * 0x0C | BMI160_ACCEL_RANGE_16G + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_range( +u8 *v_range_u8); +/*! + * @brief This API is used to set the ranges + * (g values) of the accel from the register 0x41 bit 0 to 3 + * + * + * + * + * @param v_range_u8 : The value of accel g range + * value | g_range + * ----------|----------- + * 0x03 | BMI160_ACCEL_RANGE_2G + * 0x05 | BMI160_ACCEL_RANGE_4G + * 0x08 | BMI160_ACCEL_RANGE_8G + * 0x0C | BMI160_ACCEL_RANGE_16G + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_range( +u8 v_range_u8); +/**************************************************/ +/**\name FUNCTION FOR GYRO CONFIGURATIONS */ +/*************************************************/ +/*! + * @brief This API is used to get the + * gyroscope output data rate from the register 0x42 bit 0 to 3 + * + * + * + * + * @param v_output_data_rate_u8 :The value of gyro output data rate + * value | gyro output data rate + * -----------|----------------------------- + * 0x00 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x01 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x02 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x03 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x04 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x05 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x06 | BMI160_GYRO_OUTPUT_DATA_RATE_25HZ + * 0x07 | BMI160_GYRO_OUTPUT_DATA_RATE_50HZ + * 0x08 | BMI160_GYRO_OUTPUT_DATA_RATE_100HZ + * 0x09 | BMI160_GYRO_OUTPUT_DATA_RATE_200HZ + * 0x0A | BMI160_GYRO_OUTPUT_DATA_RATE_400HZ + * 0x0B | BMI160_GYRO_OUTPUT_DATA_RATE_800HZ + * 0x0C | BMI160_GYRO_OUTPUT_DATA_RATE_1600HZ + * 0x0D | BMI160_GYRO_OUTPUT_DATA_RATE_3200HZ + * 0x0E | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x0F | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_output_data_rate( +u8 *gyro_output_typer); +/*! + * @brief This API is used to set the + * gyroscope output data rate from the register 0x42 bit 0 to 3 + * + * + * + * + * @param v_output_data_rate_u8 :The value of gyro output data rate + * value | gyro output data rate + * -----------|----------------------------- + * 0x00 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x01 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x02 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x03 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x04 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x05 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x06 | BMI160_GYRO_OUTPUT_DATA_RATE_25HZ + * 0x07 | BMI160_GYRO_OUTPUT_DATA_RATE_50HZ + * 0x08 | BMI160_GYRO_OUTPUT_DATA_RATE_100HZ + * 0x09 | BMI160_GYRO_OUTPUT_DATA_RATE_200HZ + * 0x0A | BMI160_GYRO_OUTPUT_DATA_RATE_400HZ + * 0x0B | BMI160_GYRO_OUTPUT_DATA_RATE_800HZ + * 0x0C | BMI160_GYRO_OUTPUT_DATA_RATE_1600HZ + * 0x0D | BMI160_GYRO_OUTPUT_DATA_RATE_3200HZ + * 0x0E | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * 0x0F | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_output_data_rate( +u8 gyro_output_typer); +/*! + * @brief This API is used to get the + * data of gyro from the register 0x42 bit 4 to 5 + * + * + * + * + * @param v_bw_u8 : The value of gyro bandwidth + * value | gyro bandwidth + * ----------|---------------- + * 0x00 | BMI160_GYRO_OSR4_MODE + * 0x01 | BMI160_GYRO_OSR2_MODE + * 0x02 | BMI160_GYRO_NORMAL_MODE + * 0x03 | BMI160_GYRO_CIC_MODE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_bw(u8 *v_bw_u8); +/*! + * @brief This API is used to set the + * data of gyro from the register 0x42 bit 4 to 5 + * + * + * + * + * @param v_bw_u8 : The value of gyro bandwidth + * value | gyro bandwidth + * ----------|---------------- + * 0x00 | BMI160_GYRO_OSR4_MODE + * 0x01 | BMI160_GYRO_OSR2_MODE + * 0x02 | BMI160_GYRO_NORMAL_MODE + * 0x03 | BMI160_GYRO_CIC_MODE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_bw(u8 v_bw_u8); +/*! + * @brief This API reads the range + * of gyro from the register 0x43 bit 0 to 2 + * + * @param v_range_u8 : The value of gyro range + * value | range + * ----------|------------------------------- + * 0x00 | BMI160_GYRO_RANGE_2000_DEG_SEC + * 0x01 | BMI160_GYRO_RANGE_1000_DEG_SEC + * 0x02 | BMI160_GYRO_RANGE_500_DEG_SEC + * 0x03 | BMI160_GYRO_RANGE_250_DEG_SEC + * 0x04 | BMI160_GYRO_RANGE_125_DEG_SEC + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_range( +u8 *v_range_u8); +/*! + * @brief This API set the range + * of gyro from the register 0x43 bit 0 to 2 + * + * @param v_range_u8 : The value of gyro range + * value | range + * ----------|------------------------------- + * 0x00 | BMI160_GYRO_RANGE_2000_DEG_SEC + * 0x01 | BMI160_GYRO_RANGE_1000_DEG_SEC + * 0x02 | BMI160_GYRO_RANGE_500_DEG_SEC + * 0x03 | BMI160_GYRO_RANGE_250_DEG_SEC + * 0x04 | BMI160_GYRO_RANGE_125_DEG_SEC + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_range( +u8 v_range_u8); +/**************************************************/ +/**\name FUNCTION FOR MAG CONFIGURATIONS */ +/*************************************************/ +/*! + * @brief This API is used to get the + * output data rate of magnetometer from the register 0x44 bit 0 to 3 + * + * + * + * + * @param v_output_data_rat_u8e : The value of mag output data rate + * value | mag output data rate + * ---------|--------------------------- + * 0x00 |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED + * 0x01 |BMI160_MAG_OUTPUT_DATA_RATE_0_78HZ + * 0x02 |BMI160_MAG_OUTPUT_DATA_RATE_1_56HZ + * 0x03 |BMI160_MAG_OUTPUT_DATA_RATE_3_12HZ + * 0x04 |BMI160_MAG_OUTPUT_DATA_RATE_6_25HZ + * 0x05 |BMI160_MAG_OUTPUT_DATA_RATE_12_5HZ + * 0x06 |BMI160_MAG_OUTPUT_DATA_RATE_25HZ + * 0x07 |BMI160_MAG_OUTPUT_DATA_RATE_50HZ + * 0x08 |BMI160_MAG_OUTPUT_DATA_RATE_100HZ + * 0x09 |BMI160_MAG_OUTPUT_DATA_RATE_200HZ + * 0x0A |BMI160_MAG_OUTPUT_DATA_RATE_400HZ + * 0x0B |BMI160_MAG_OUTPUT_DATA_RATE_800HZ + * 0x0C |BMI160_MAG_OUTPUT_DATA_RATE_1600HZ + * 0x0D |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED0 + * 0x0E |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED1 + * 0x0F |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED2 + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_output_data_rate(u8 *odr); +/*! + * @brief This API is used to set the + * output data rate of magnetometer from the register 0x44 bit 0 to 3 + * + * + * + * + * @param v_output_data_rat_u8e : The value of mag output data rate + * value | mag output data rate + * ---------|--------------------------- + * 0x00 |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED + * 0x01 |BMI160_MAG_OUTPUT_DATA_RATE_0_78HZ + * 0x02 |BMI160_MAG_OUTPUT_DATA_RATE_1_56HZ + * 0x03 |BMI160_MAG_OUTPUT_DATA_RATE_3_12HZ + * 0x04 |BMI160_MAG_OUTPUT_DATA_RATE_6_25HZ + * 0x05 |BMI160_MAG_OUTPUT_DATA_RATE_12_5HZ + * 0x06 |BMI160_MAG_OUTPUT_DATA_RATE_25HZ + * 0x07 |BMI160_MAG_OUTPUT_DATA_RATE_50HZ + * 0x08 |BMI160_MAG_OUTPUT_DATA_RATE_100HZ + * 0x09 |BMI160_MAG_OUTPUT_DATA_RATE_200HZ + * 0x0A |BMI160_MAG_OUTPUT_DATA_RATE_400HZ + * 0x0B |BMI160_MAG_OUTPUT_DATA_RATE_800HZ + * 0x0C |BMI160_MAG_OUTPUT_DATA_RATE_1600HZ + * 0x0D |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED0 + * 0x0E |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED1 + * 0x0F |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED2 + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_output_data_rate(u8 odr); +/**************************************************/ +/**\name FUNCTION FOR FIFO CONFIGURATIONS */ +/*************************************************/ + /*! + * @brief This API is used to read Down sampling + * for gyro (2**downs_gyro) in the register 0x45 bit 0 to 2 + * + * + * + * + * @param v_fifo_down_gyro_u8 :The value of gyro fifo down + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_down_gyro( +u8 *v_fifo_down_gyro_u8); + /*! + * @brief This API is used to set Down sampling + * for gyro (2**downs_gyro) in the register 0x45 bit 0 to 2 + * + * + * + * + * @param v_fifo_down_gyro_u8 :The value of gyro fifo down + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_down_gyro( +u8 v_fifo_down_gyro_u8); +/*! + * @brief This API is used to read gyro fifo filter data + * from the register 0x45 bit 3 + * + * + * + * @param v_gyro_fifo_filter_data_u8 :The value of gyro filter data + * value | gyro_fifo_filter_data + * ------------|------------------------- + * 0x00 | Unfiltered data + * 0x01 | Filtered data + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_fifo_filter_data( +u8 *v_gyro_fifo_filter_data_u8); +/*! + * @brief This API is used to set gyro fifo filter data + * from the register 0x45 bit 3 + * + * + * + * @param v_gyro_fifo_filter_data_u8 :The value of gyro filter data + * value | gyro_fifo_filter_data + * ------------|------------------------- + * 0x00 | Unfiltered data + * 0x01 | Filtered data + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_fifo_filter_data( +u8 v_gyro_fifo_filter_data_u8); +/*! + * @brief This API is used to read Down sampling + * for accel (2*downs_accel) from the register 0x45 bit 4 to 6 + * + * + * + * + * @param v_fifo_down_u8 :The value of accel fifo down + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_down_accel( +u8 *v_fifo_down_u8); + /*! + * @brief This API is used to set Down sampling + * for accel (2*downs_accel) from the register 0x45 bit 4 to 6 + * + * + * + * + * @param v_fifo_down_u8 :The value of accel fifo down + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_down_accel( +u8 v_fifo_down_u8); +/*! + * @brief This API is used to read accel fifo filter data + * from the register 0x45 bit 7 + * + * + * + * @param v_accel_fifo_filter_u8 :The value of accel filter data + * value | accel_fifo_filter_data + * ------------|------------------------- + * 0x00 | Unfiltered data + * 0x01 | Filtered data + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_fifo_filter_data( +u8 *v_accel_fifo_filter_u8); +/*! + * @brief This API is used to set accel fifo filter data + * from the register 0x45 bit 7 + * + * + * + * @param v_accel_fifo_filter_u8 :The value of accel filter data + * value | accel_fifo_filter_data + * ------------|------------------------- + * 0x00 | Unfiltered data + * 0x01 | Filtered data + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_fifo_filter_data( +u8 v_accel_fifo_filter_u8); +/**************************************************/ +/**\name FUNCTION FOR FIFO WATER MARK ENABLE */ +/*************************************************/ +/*! + * @brief This API is used to Trigger an interrupt + * when FIFO contains water mark level from the register 0x46 bit 0 to 7 + * + * + * + * @param v_fifo_wm_u8 : The value of fifo water mark level + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_wm( +u8 *v_fifo_wm_u8); +/*! + * @brief This API is used to Trigger an interrupt + * when FIFO contains water mark level from the register 0x46 bit 0 to 7 + * + * + * + * @param v_fifo_wm_u8 : The value of fifo water mark level + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_wm( +u8 v_fifo_wm_u8); +/**************************************************/ +/**\name FUNCTION FOR FIFO CONFIGURATIONS */ +/*************************************************/ +/*! + * @brief This API reads fifo sensor time + * frame after the last valid data frame form the register 0x47 bit 1 + * + * + * + * + * @param v_fifo_time_enable_u8 : The value of sensor time + * value | fifo sensor time + * ------------|------------------------- + * 0x00 | do not return sensortime frame + * 0x01 | return sensortime frame + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_time_enable( +u8 *v_fifo_time_enable_u8); +/*! + * @brief This API set fifo sensor time + * frame after the last valid data frame form the register 0x47 bit 1 + * + * + * + * + * @param v_fifo_time_enable_u8 : The value of sensor time + * value | fifo sensor time + * ------------|------------------------- + * 0x00 | do not return sensortime frame + * 0x01 | return sensortime frame + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_time_enable( +u8 v_fifo_time_enable_u8); +/*! + * @brief This API reads FIFO tag interrupt2 enable status + * from the resister 0x47 bit 2 + * + * @param v_fifo_tag_intr2_u8 : The value of fifo tag interrupt + * value | fifo tag interrupt + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_tag_intr2_enable( +u8 *v_fifo_tag_intr2_u8); +/*! + * @brief This API set FIFO tag interrupt2 enable status + * from the resister 0x47 bit 2 + * + * @param v_fifo_tag_intr2_u8 : The value of fifo tag interrupt + * value | fifo tag interrupt + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_tag_intr2_enable( +u8 v_fifo_tag_intr2_u8); +/*! + * @brief This API get FIFO tag interrupt1 enable status + * from the resister 0x47 bit 3 + * + * @param v_fifo_tag_intr1_u8 :The value of fifo tag interrupt1 + * value | fifo tag interrupt + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_tag_intr1_enable( +u8 *v_fifo_tag_intr1_u8); +/*! + * @brief This API set FIFO tag interrupt1 enable status + * from the resister 0x47 bit 3 + * + * @param v_fifo_tag_intr1_u8 :The value of fifo tag interrupt1 + * value | fifo tag interrupt + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_tag_intr1_enable( +u8 v_fifo_tag_intr1_u8); +/*! + * @brief This API reads FIFO frame + * header enable from the register 0x47 bit 4 + * + * @param v_fifo_header_u8 :The value of fifo header + * value | fifo header + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_header_enable( +u8 *v_fifo_header_u8); +/*! + * @brief This API set FIFO frame + * header enable from the register 0x47 bit 4 + * + * @param v_fifo_header_u8 :The value of fifo header + * value | fifo header + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_header_enable( +u8 v_fifo_header_u8); +/*! + * @brief This API is used to read stored + * magnetometer data in FIFO (all 3 axes) from the register 0x47 bit 5 + * + * @param v_fifo_mag_u8 : The value of fifo mag enble + * value | fifo mag + * ----------|------------------- + * 0x00 | no magnetometer data is stored + * 0x01 | magnetometer data is stored + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_mag_enable( +u8 *v_fifo_mag_u8); +/*! + * @brief This API is used to set stored + * magnetometer data in FIFO (all 3 axes) from the register 0x47 bit 5 + * + * @param v_fifo_mag_u8 : The value of fifo mag enble + * value | fifo mag + * ----------|------------------- + * 0x00 | no magnetometer data is stored + * 0x01 | magnetometer data is stored + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_mag_enable( +u8 v_fifo_mag_u8); +/*! + * @brief This API is used to read stored + * accel data in FIFO (all 3 axes) from the register 0x47 bit 6 + * + * @param v_fifo_accel_u8 : The value of fifo accel enble + * value | fifo accel + * ----------|------------------- + * 0x00 | no accel data is stored + * 0x01 | accel data is stored + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_accel_enable( +u8 *v_fifo_accel_u8); +/*! + * @brief This API is used to set stored + * accel data in FIFO (all 3 axes) from the register 0x47 bit 6 + * + * @param v_fifo_accel_u8 : The value of fifo accel enble + * value | fifo accel + * ----------|------------------- + * 0x00 | no accel data is stored + * 0x01 | accel data is stored + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_accel_enable( +u8 v_fifo_accel_u8); +/*! + * @brief This API is used to read stored + * gyro data in FIFO (all 3 axes) from the resister 0x47 bit 7 + * + * + * @param v_fifo_gyro_u8 : The value of fifo gyro enble + * value | fifo gyro + * ----------|------------------- + * 0x00 | no gyro data is stored + * 0x01 | gyro data is stored + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_gyro_enable( +u8 *v_fifo_gyro_u8); +/*! + * @brief This API is used to set stored + * gyro data in FIFO (all 3 axes) from the resister 0x47 bit 7 + * + * + * @param v_fifo_gyro_u8 : The value of fifo gyro enble + * value | fifo gyro + * ----------|------------------- + * 0x00 | no gyro data is stored + * 0x01 | gyro data is stored + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_gyro_enable( +u8 v_fifo_gyro_u8); +/***************************************************************/ +/**\name FUNCTION FOR MAG I2C ADDRESS SELECTION */ +/***************************************************************/ +/*! + * @brief This API is used to read + * I2C device address of auxiliary mag from the register 0x4B bit 1 to 7 + * + * + * + * + * @param v_i2c_device_addr_u8 : The value of mag I2C device address + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_i2c_device_addr( +u8 *v_i2c_device_addr_u8); +/*! + * @brief This API is used to set + * I2C device address of auxiliary mag from the register 0x4B bit 1 to 7 + * + * + * + * + * @param v_i2c_device_addr_u8 : The value of mag I2C device address + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_i2c_device_addr( +u8 v_i2c_device_addr_u8); +/*! + * @brief This API is used to read + * Burst data length (1,2,6,8 byte) from the register 0x4C bit 0 to 1 + * + * + * + * + * @param v_mag_burst_u8 : The data of mag burst read lenth + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_burst( +u8 *v_mag_burst_u8); +/*! + * @brief This API is used to set + * Burst data length (1,2,6,8 byte) from the register 0x4C bit 0 to 1 + * + * + * + * + * @param v_mag_burst_u8 : The data of mag burst read lenth + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_burst( +u8 v_mag_burst_u8); +/***************************************************************/ +/**\name FUNCTION FOR MAG OFFSET */ +/***************************************************************/ +/*! + * @brief This API is used to read + * trigger-readout offset in units of 2.5 ms. If set to zero, + * the offset is maximum, i.e. after readout a trigger + * is issued immediately. from the register 0x4C bit 2 to 5 + * + * + * + * + * @param v_mag_offset_u8 : The value of mag offset + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_offset( +u8 *v_mag_offset_u8); +/*! + * @brief This API is used to set + * trigger-readout offset in units of 2.5 ms. If set to zero, + * the offset is maximum, i.e. after readout a trigger + * is issued immediately. from the register 0x4C bit 2 to 5 + * + * + * + * + * @param v_mag_offset_u8 : The value of mag offset + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_offset( +u8 v_mag_offset_u8); +/***************************************************************/ +/**\name FUNCTION FOR MAG MANUAL/AUTO MODE SELECTION */ +/***************************************************************/ +/*! + * @brief This API is used to read + * Enable register access on MAG_IF[2] or MAG_IF[3] writes. + * This implies that the DATA registers are not updated with + * magnetometer values. Accessing magnetometer requires + * the magnetometer in normal mode in PMU_STATUS. + * from the register 0x4C bit 7 + * + * + * + * @param v_mag_manual_u8 : The value of mag manual enable + * value | mag manual + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_manual_enable( +u8 *v_mag_manual_u8); +/*! + * @brief This API is used to set + * Enable register access on MAG_IF[2] or MAG_IF[3] writes. + * This implies that the DATA registers are not updated with + * magnetometer values. Accessing magnetometer requires + * the magnetometer in normal mode in PMU_STATUS. + * from the register 0x4C bit 7 + * + * + * + * @param v_mag_manual_u8 : The value of mag manual enable + * value | mag manual + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_manual_enable( +u8 v_mag_manual_u8); +/***************************************************************/ +/**\name FUNCTIONS FOR MAG READ, WRITE AND WRITE DATA ADDRESS */ +/***************************************************************/ +/*! + * @brief This API is used to read data + * magnetometer address to read from the register 0x4D bit 0 to 7 + * @brief It used to provide mag read address of auxiliary mag + * + * + * + * + * @param v_mag_read_addr_u8 : The value of address need to be read + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_read_addr( +u8 *v_mag_read_addr_u8); +/*! + * @brief This API is used to set + * magnetometer write address from the register 0x4D bit 0 to 7 + * @brief mag write address writes the address of auxiliary mag to write + * + * + * + * @param v_mag_read_addr_u8: + * The data of auxiliary mag address to write data + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_read_addr( +u8 v_mag_read_addr_u8); +/*! + * @brief This API is used to read + * magnetometer write address from the register 0x4E bit 0 to 7 + * @brief mag write address writes the address of auxiliary mag to write + * + * + * + * @param v_mag_write_addr_u8: + * The data of auxiliary mag address to write data + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_write_addr( +u8 *v_mag_write_addr_u8); +/*! + * @brief This API is used to set + * magnetometer write address from the register 0x4E bit 0 to 7 + * @brief mag write address writes the address of auxiliary mag to write + * + * + * + * @param v_mag_write_addr_u8: + * The data of auxiliary mag address to write data + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_write_addr( +u8 v_mag_write_addr_u8); +/*! + * @brief This API is used to read magnetometer write data + * form the resister 0x4F bit 0 to 7 + * @brief This writes the data will be wrote to mag + * + * + * + * @param v_mag_write_data_u8: The value of mag data + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_write_data( +u8 *v_mag_write_data_u8); +/*! + * @brief This API is used to set magnetometer write data + * form the resister 0x4F bit 0 to 7 + * @brief This writes the data will be wrote to mag + * + * + * + * @param v_mag_write_data_u8: The value of mag data + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_write_data( +u8 v_mag_write_data_u8); +/***************************************************************/ +/**\name FUNCTION FOR INTERRUPT ENABLE OF +ANY-MOTION XYZ, DOUBLE AND SINGLE TAP, ORIENT AND FLAT */ +/***************************************************************/ +/*! + * @brief This API is used to read + * interrupt enable from the register 0x50 bit 0 to 7 + * + * + * + * + * @param v_enable_u8 : Value to decided to select interrupt + * v_enable_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_ANY_MOTION_X_ENABLE + * 1 | BMI160_ANY_MOTION_Y_ENABLE + * 2 | BMI160_ANY_MOTION_Z_ENABLE + * 3 | BMI160_DOUBLE_TAP_ENABLE + * 4 | BMI160_SINGLE_TAP_ENABLE + * 5 | BMI160_ORIENT_ENABLE + * 6 | BMI160_FLAT_ENABLE + * + * @param v_intr_enable_zero_u8 : The interrupt enable value + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_enable_0( +u8 enable, u8 *v_intr_enable_zero_u8); +/*! + * @brief This API is used to set + * interrupt enable from the register 0x50 bit 0 to 7 + * + * + * + * + * @param v_enable_u8 : Value to decided to select interrupt + * v_enable_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_ANY_MOTION_X_ENABLE + * 1 | BMI160_ANY_MOTION_Y_ENABLE + * 2 | BMI160_ANY_MOTION_Z_ENABLE + * 3 | BMI160_DOUBLE_TAP_ENABLE + * 4 | BMI160_SINGLE_TAP_ENABLE + * 5 | BMI160_ORIENT_ENABLE + * 6 | BMI160_FLAT_ENABLE + * + * @param v_intr_enable_zero_u8 : The interrupt enable value + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_enable_0( +u8 enable, u8 v_intr_enable_zero_u8); +/***************************************************************/ +/**\name FUNCTION FOR INTERRUPT ENABLE OF +HIGH_G XYZ, LOW_G, DATA READY, FIFO FULL AND FIFO WATER MARK */ +/***************************************************************/ +/*! + * @brief This API is used to read + * interrupt enable byte1 from the register 0x51 bit 0 to 6 + * @brief It read the high_g_x,high_g_y,high_g_z,low_g_enable + * data ready, fifo full and fifo water mark. + * + * + * + * @param v_enable_u8 : The value of interrupt enable + * @param v_enable_u8 : Value to decided to select interrupt + * v_enable_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_HIGH_G_X_ENABLE + * 1 | BMI160_HIGH_G_Y_ENABLE + * 2 | BMI160_HIGH_G_Z_ENABLE + * 3 | BMI160_LOW_G_ENABLE + * 4 | BMI160_DATA_RDY_ENABLE + * 5 | BMI160_FIFO_FULL_ENABLE + * 6 | BMI160_FIFO_WM_ENABLE + * + * @param v_intr_enable_1_u8 : The interrupt enable value + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_enable_1( +u8 enable, u8 *v_intr_enable_1_u8); +/*! + * @brief This API is used to set + * interrupt enable byte1 from the register 0x51 bit 0 to 6 + * @brief It read the high_g_x,high_g_y,high_g_z,low_g_enable + * data ready, fifo full and fifo water mark. + * + * + * + * @param v_enable_u8 : The value of interrupt enable + * @param v_enable_u8 : Value to decided to select interrupt + * v_enable_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_HIGH_G_X_ENABLE + * 1 | BMI160_HIGH_G_Y_ENABLE + * 2 | BMI160_HIGH_G_Z_ENABLE + * 3 | BMI160_LOW_G_ENABLE + * 4 | BMI160_DATA_RDY_ENABLE + * 5 | BMI160_FIFO_FULL_ENABLE + * 6 | BMI160_FIFO_WM_ENABLE + * + * @param v_intr_enable_1_u8 : The interrupt enable value + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_enable_1( +u8 enable, u8 v_intr_enable_1_u8); +/***************************************************************/ +/**\name FUNCTION FOR INTERRUPT ENABLE OF +NO MOTION XYZ */ +/***************************************************************/ +/*! + * @brief This API is used to read + * interrupt enable byte2 from the register bit 0x52 bit 0 to 3 + * @brief It reads no motion x,y and z + * + * + * + * @param v_enable_u8: The value of interrupt enable + * v_enable_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_NOMOTION_X_ENABLE + * 1 | BMI160_NOMOTION_Y_ENABLE + * 2 | BMI160_NOMOTION_Z_ENABLE + * + * @param v_intr_enable_2_u8 : The interrupt enable value + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_enable_2( +u8 enable, u8 *v_intr_enable_2_u8); +/*! + * @brief This API is used to set + * interrupt enable byte2 from the register bit 0x52 bit 0 to 3 + * @brief It reads no motion x,y and z + * + * + * + * @param v_enable_u8: The value of interrupt enable + * v_enable_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_NOMOTION_X_ENABLE + * 1 | BMI160_NOMOTION_Y_ENABLE + * 2 | BMI160_NOMOTION_Z_ENABLE + * + * @param v_intr_enable_2_u8 : The interrupt enable value + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_enable_2( +u8 enable, u8 v_intr_enable_2_u8); +/***************************************************************/ +/**\name FUNCTION FOR INTERRUPT ENABLE OF + STEP DETECTOR */ +/***************************************************************/ + /*! + * @brief This API is used to read + * interrupt enable step detector interrupt from + * the register bit 0x52 bit 3 + * + * + * + * + * @param v_step_intr_u8 : The value of step detector interrupt enable + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_step_detector_enable( +u8 *v_step_intr_u8); + /*! + * @brief This API is used to set + * interrupt enable step detector interrupt from + * the register bit 0x52 bit 3 + * + * + * + * + * @param v_step_intr_u8 : The value of step detector interrupt enable + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_step_detector_enable( +u8 v_step_intr_u8); +/***************************************************************/ +/**\name FUNCTION FOR INTERRUPT CONTROL */ +/***************************************************************/ +/*! + * @brief Configure trigger condition of interrupt1 + * and interrupt2 pin from the register 0x53 + * @brief interrupt1 - bit 0 + * @brief interrupt2 - bit 4 + * + * @param v_channel_u8: The value of edge trigger selection + * v_channel_u8 | Edge trigger + * ---------------|--------------- + * 0 | BMI160_INTR1_EDGE_CTRL + * 1 | BMI160_INTR2_EDGE_CTRL + * + * @param v_intr_edge_ctrl_u8 : The value of edge trigger enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_EDGE + * 0x00 | BMI160_LEVEL + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_edge_ctrl( +u8 v_channel_u8, u8 *v_intr_edge_ctrl_u8); +/*! + * @brief Configure trigger condition of interrupt1 + * and interrupt2 pin from the register 0x53 + * @brief interrupt1 - bit 0 + * @brief interrupt2 - bit 4 + * + * @param v_channel_u8: The value of edge trigger selection + * v_channel_u8 | Edge trigger + * ---------------|--------------- + * 0 | BMI160_INTR1_EDGE_CTRL + * 1 | BMI160_INTR2_EDGE_CTRL + * + * @param v_intr_edge_ctrl_u8 : The value of edge trigger enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_EDGE + * 0x00 | BMI160_LEVEL + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_edge_ctrl( +u8 v_channel_u8, u8 v_intr_edge_ctrl_u8); +/*! + * @brief API used for get the Configure level condition of interrupt1 + * and interrupt2 pin form the register 0x53 + * @brief interrupt1 - bit 1 + * @brief interrupt2 - bit 5 + * + * @param v_channel_u8: The value of level condition selection + * v_channel_u8 | level selection + * ---------------|--------------- + * 0 | BMI160_INTR1_LEVEL + * 1 | BMI160_INTR2_LEVEL + * + * @param v_intr_level_u8 : The value of level of interrupt enable + * value | Behaviour + * ----------|------------------- + * 0x01 | BMI160_LEVEL_HIGH + * 0x00 | BMI160_LEVEL_LOW + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_level( +u8 v_channel_u8, u8 *v_intr_level_u8); +/*! + * @brief API used for set the Configure level condition of interrupt1 + * and interrupt2 pin form the register 0x53 + * @brief interrupt1 - bit 1 + * @brief interrupt2 - bit 5 + * + * @param v_channel_u8: The value of level condition selection + * v_channel_u8 | level selection + * ---------------|--------------- + * 0 | BMI160_INTR1_LEVEL + * 1 | BMI160_INTR2_LEVEL + * + * @param v_intr_level_u8 : The value of level of interrupt enable + * value | Behaviour + * ----------|------------------- + * 0x01 | BMI160_LEVEL_HIGH + * 0x00 | BMI160_LEVEL_LOW + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_level( +u8 v_channel_u8, u8 v_intr_level_u8); +/*! + * @brief API used to get configured output enable of interrupt1 + * and interrupt2 from the register 0x53 + * @brief interrupt1 - bit 2 + * @brief interrupt2 - bit 6 + * + * + * @param v_channel_u8: The value of output type enable selection + * v_channel_u8 | level selection + * ---------------|--------------- + * 0 | BMI160_INTR1_OUTPUT_TYPE + * 1 | BMI160_INTR2_OUTPUT_TYPE + * + * @param v_intr_output_type_u8 : + * The value of output type of interrupt enable + * value | Behaviour + * ----------|------------------- + * 0x01 | BMI160_OPEN_DRAIN + * 0x00 | BMI160_PUSH_PULL + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_output_type( +u8 v_channel_u8, u8 *v_intr_output_type_u8); +/*! + * @brief API used to set output enable of interrupt1 + * and interrupt2 from the register 0x53 + * @brief interrupt1 - bit 2 + * @brief interrupt2 - bit 6 + * + * + * @param v_channel_u8: The value of output type enable selection + * v_channel_u8 | level selection + * ---------------|--------------- + * 0 | BMI160_INTR1_OUTPUT_TYPE + * 1 | BMI160_INTR2_OUTPUT_TYPE + * + * @param v_intr_output_type_u8 : + * The value of output type of interrupt enable + * value | Behaviour + * ----------|------------------- + * 0x01 | BMI160_OPEN_DRAIN + * 0x00 | BMI160_PUSH_PULL + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_output_type( +u8 v_channel_u8, u8 v_intr_output_type_u8); + /*! + * @brief API used to get the Output enable for interrupt1 + * and interrupt1 pin from the register 0x53 + * @brief interrupt1 - bit 3 + * @brief interrupt2 - bit 7 + * + * @param v_channel_u8: The value of output enable selection + * v_channel_u8 | level selection + * ---------------|--------------- + * 0 | BMI160_INTR1_OUTPUT_TYPE + * 1 | BMI160_INTR2_OUTPUT_TYPE + * + * @param v_output_enable_u8 : + * The value of output enable of interrupt enable + * value | Behaviour + * ----------|------------------- + * 0x01 | BMI160_INPUT + * 0x00 | BMI160_OUTPUT + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_output_enable( +u8 v_channel_u8, u8 *v_output_enable_u8); + /*! + * @brief API used to set the Output enable for interrupt1 + * and interrupt1 pin from the register 0x53 + * @brief interrupt1 - bit 3 + * @brief interrupt2 - bit 7 + * + * @param v_channel_u8: The value of output enable selection + * v_channel_u8 | level selection + * ---------------|--------------- + * 0 | BMI160_INTR1_OUTPUT_TYPE + * 1 | BMI160_INTR2_OUTPUT_TYPE + * + * @param v_output_enable_u8 : + * The value of output enable of interrupt enable + * value | Behaviour + * ----------|------------------- + * 0x01 | BMI160_INPUT + * 0x00 | BMI160_OUTPUT + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_output_enable( +u8 v_channel_u8, u8 v_output_enable_u8); +/***************************************************************/ +/**\name FUNCTION FOR INTERRUPT LATCH INTERRUPT */ +/***************************************************************/ +/*! +* @brief This API is used to get the latch duration +* from the register 0x54 bit 0 to 3 +* @brief This latch selection is not applicable for data ready, +* orientation and flat interrupts. +* +* +* +* @param v_latch_intr_u8 : The value of latch duration +* Latch Duration | value +* --------------------------------------|------------------ +* BMI160_LATCH_DUR_NONE | 0x00 +* BMI160_LATCH_DUR_312_5_MICRO_SEC | 0x01 +* BMI160_LATCH_DUR_625_MICRO_SEC | 0x02 +* BMI160_LATCH_DUR_1_25_MILLI_SEC | 0x03 +* BMI160_LATCH_DUR_2_5_MILLI_SEC | 0x04 +* BMI160_LATCH_DUR_5_MILLI_SEC | 0x05 +* BMI160_LATCH_DUR_10_MILLI_SEC | 0x06 +* BMI160_LATCH_DUR_20_MILLI_SEC | 0x07 +* BMI160_LATCH_DUR_40_MILLI_SEC | 0x08 +* BMI160_LATCH_DUR_80_MILLI_SEC | 0x09 +* BMI160_LATCH_DUR_160_MILLI_SEC | 0x0A +* BMI160_LATCH_DUR_320_MILLI_SEC | 0x0B +* BMI160_LATCH_DUR_640_MILLI_SEC | 0x0C +* BMI160_LATCH_DUR_1_28_SEC | 0x0D +* BMI160_LATCH_DUR_2_56_SEC | 0x0E +* BMI160_LATCHED | 0x0F +* +* +* +* @return results of bus communication function +* @retval 0 -> Success +* @retval -1 -> Error +* +* +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_latch_intr( +u8 *v_latch_intr_u8); +/*! +* @brief This API is used to set the latch duration +* from the register 0x54 bit 0 to 3 +* @brief This latch selection is not applicable for data ready, +* orientation and flat interrupts. +* +* +* +* @param v_latch_intr_u8 : The value of latch duration +* Latch Duration | value +* --------------------------------------|------------------ +* BMI160_LATCH_DUR_NONE | 0x00 +* BMI160_LATCH_DUR_312_5_MICRO_SEC | 0x01 +* BMI160_LATCH_DUR_625_MICRO_SEC | 0x02 +* BMI160_LATCH_DUR_1_25_MILLI_SEC | 0x03 +* BMI160_LATCH_DUR_2_5_MILLI_SEC | 0x04 +* BMI160_LATCH_DUR_5_MILLI_SEC | 0x05 +* BMI160_LATCH_DUR_10_MILLI_SEC | 0x06 +* BMI160_LATCH_DUR_20_MILLI_SEC | 0x07 +* BMI160_LATCH_DUR_40_MILLI_SEC | 0x08 +* BMI160_LATCH_DUR_80_MILLI_SEC | 0x09 +* BMI160_LATCH_DUR_160_MILLI_SEC | 0x0A +* BMI160_LATCH_DUR_320_MILLI_SEC | 0x0B +* BMI160_LATCH_DUR_640_MILLI_SEC | 0x0C +* BMI160_LATCH_DUR_1_28_SEC | 0x0D +* BMI160_LATCH_DUR_2_56_SEC | 0x0E +* BMI160_LATCHED | 0x0F +* +* +* +* @return results of bus communication function +* @retval 0 -> Success +* @retval -1 -> Error +* +* +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_latch_intr( +u8 v_latch_intr_u8); +/*! + * @brief API used to get input enable for interrupt1 + * and interrupt2 pin from the register 0x54 + * @brief interrupt1 - bit 4 + * @brief interrupt2 - bit 5 + * + * @param v_channel_u8: The value of input enable selection + * v_channel_u8 | input selection + * ---------------|--------------- + * 0 | BMI160_INTR1_INPUT_ENABLE + * 1 | BMI160_INTR2_INPUT_ENABLE + * + * @param v_input_en_u8 : + * The value of input enable of interrupt enable + * value | Behaviour + * ----------|------------------- + * 0x01 | BMI160_INPUT + * 0x00 | BMI160_OUTPUT + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_input_enable( +u8 v_channel_u8, u8 *v_input_en_u8); +/*! + * @brief API used to set input enable for interrupt1 + * and interrupt2 pin from the register 0x54 + * @brief interrupt1 - bit 4 + * @brief interrupt2 - bit 5 + * + * @param v_channel_u8: The value of input enable selection + * v_channel_u8 | input selection + * ---------------|--------------- + * 0 | BMI160_INTR1_INPUT_ENABLE + * 1 | BMI160_INTR2_INPUT_ENABLE + * + * @param v_input_en_u8 : + * The value of input enable of interrupt enable + * value | Behaviour + * ----------|------------------- + * 0x01 | BMI160_INPUT + * 0x00 | BMI160_OUTPUT + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_input_enable( +u8 v_channel_u8, u8 v_input_en_u8); +/***************************************************************/ +/**\name FUNCTION FOR INTERRUPT1 AND INTERRUPT2 MAPPING */ +/***************************************************************/ + /*! + * @brief reads the Low g interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 0 in the register 0x55 + * @brief interrupt2 bit 0 in the register 0x57 + * + * + * @param v_channel_u8: The value of low_g selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_LOW_G + * 1 | BMI160_INTR2_MAP_LOW_G + * + * @param v_intr_low_g_u8 : The value of low_g enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g( +u8 v_channel_u8, u8 *v_intr_low_g_u8); + /*! + * @brief set the Low g interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 0 in the register 0x55 + * @brief interrupt2 bit 0 in the register 0x57 + * + * + * @param v_channel_u8: The value of low_g selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_LOW_G + * 1 | BMI160_INTR2_MAP_LOW_G + * + * @param v_intr_low_g_u8 : The value of low_g enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g( +u8 v_channel_u8, u8 v_intr_low_g_u8); +/*! + * @brief Reads the HIGH g interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 1 in the register 0x55 + * @brief interrupt2 bit 1 in the register 0x57 + * + * + * @param v_channel_u8: The value of high_g selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_HIGH_G + * 1 | BMI160_INTR2_MAP_HIGH_G + * + * @param v_intr_high_g_u8 : The value of high_g enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_high_g( +u8 v_channel_u8, u8 *v_intr_high_g_u8); +/*! + * @brief Write the HIGH g interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 1 in the register 0x55 + * @brief interrupt2 bit 1 in the register 0x57 + * + * + * @param v_channel_u8: The value of high_g selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_HIGH_G + * 1 | BMI160_INTR2_MAP_HIGH_G + * + * @param v_intr_high_g_u8 : The value of high_g enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_high_g( +u8 v_channel_u8, u8 v_intr_high_g_u8); +/*! + * @brief Reads the Any motion interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 2 in the register 0x55 + * @brief interrupt2 bit 2 in the register 0x57 + * + * + * @param v_channel_u8: The value of any motion selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_ANY_MOTION + * 1 | BMI160_INTR2_MAP_ANY_MOTION + * + * @param v_intr_any_motion_u8 : The value of any motion enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_any_motion( +u8 v_channel_u8, u8 *v_intr_any_motion_u8); +/*! + * @brief Write the Any motion interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 2 in the register 0x55 + * @brief interrupt2 bit 2 in the register 0x57 + * + * + * @param v_channel_u8: The value of any motion selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_ANY_MOTION + * 1 | BMI160_INTR2_MAP_ANY_MOTION + * + * @param v_intr_any_motion_u8 : The value of any motion enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_any_motion( +u8 v_channel_u8, u8 v_intr_any_motion_u8); +/*! + * @brief Reads the No motion interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 3 in the register 0x55 + * @brief interrupt2 bit 3 in the register 0x57 + * + * + * @param v_channel_u8: The value of no motion selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_NOMO + * 1 | BMI160_INTR2_MAP_NOMO + * + * @param v_intr_nomotion_u8 : The value of no motion enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_nomotion( +u8 v_channel_u8, u8 *v_intr_nomotion_u8); +/*! + * @brief Write the No motion interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 3 in the register 0x55 + * @brief interrupt2 bit 3 in the register 0x57 + * + * + * @param v_channel_u8: The value of no motion selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_NOMO + * 1 | BMI160_INTR2_MAP_NOMO + * + * @param v_intr_nomotion_u8 : The value of no motion enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_nomotion( +u8 v_channel_u8, u8 v_intr_nomotion_u8); +/*! + * @brief Reads the Double Tap interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 4 in the register 0x55 + * @brief interrupt2 bit 4 in the register 0x57 + * + * + * @param v_channel_u8: The value of double tap interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_DOUBLE_TAP + * 1 | BMI160_INTR2_MAP_DOUBLE_TAP + * + * @param v_intr_double_tap_u8 : The value of double tap enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_double_tap( +u8 v_channel_u8, u8 *v_intr_double_tap_u8); +/*! + * @brief Write the Double Tap interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 4 in the register 0x55 + * @brief interrupt2 bit 4 in the register 0x57 + * + * + * @param v_channel_u8: The value of double tap interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_DOUBLE_TAP + * 1 | BMI160_INTR2_MAP_DOUBLE_TAP + * + * @param v_intr_double_tap_u8 : The value of double tap enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_double_tap( +u8 v_channel_u8, u8 v_intr_double_tap_u8); +/*! + * @brief Reads the Single Tap interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 5 in the register 0x55 + * @brief interrupt2 bit 5 in the register 0x57 + * + * + * @param v_channel_u8: The value of single tap interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_SINGLE_TAP + * 1 | BMI160_INTR2_MAP_SINGLE_TAP + * + * @param v_intr_single_tap_u8 : The value of single tap enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_single_tap( +u8 v_channel_u8, u8 *v_intr_single_tap_u8); +/*! + * @brief Write the Single Tap interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 5 in the register 0x55 + * @brief interrupt2 bit 5 in the register 0x57 + * + * + * @param v_channel_u8: The value of single tap interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_SINGLE_TAP + * 1 | BMI160_INTR2_MAP_SINGLE_TAP + * + * @param v_intr_single_tap_u8 : The value of single tap enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_single_tap( +u8 v_channel_u8, u8 v_intr_single_tap_u8); +/*! + * @brief Reads the Orient interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 6 in the register 0x55 + * @brief interrupt2 bit 6 in the register 0x57 + * + * + * @param v_channel_u8: The value of orient interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_ORIENT + * 1 | BMI160_INTR2_MAP_ORIENT + * + * @param v_intr_orient_u8 : The value of orient enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient( +u8 v_channel_u8, u8 *v_intr_orient_u8); +/*! + * @brief Write the Orient interrupt + * interrupt mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 6 in the register 0x55 + * @brief interrupt2 bit 6 in the register 0x57 + * + * + * @param v_channel_u8: The value of orient interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_ORIENT + * 1 | BMI160_INTR2_MAP_ORIENT + * + * @param v_intr_orient_u8 : The value of orient enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient( +u8 v_channel_u8, u8 v_intr_orient_u8); + /*! + * @brief Reads the Flat interrupt + * mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 7 in the register 0x55 + * @brief interrupt2 bit 7 in the register 0x57 + * + * + * @param v_channel_u8: The value of flat interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_FLAT + * 1 | BMI160_INTR2_MAP_FLAT + * + * @param v_intr_flat_u8 : The value of flat enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_flat( +u8 v_channel_u8, u8 *v_intr_flat_u8); + /*! + * @brief Write the Flat interrupt + * mapped to interrupt1 + * and interrupt2 from the register 0x55 and 0x57 + * @brief interrupt1 bit 7 in the register 0x55 + * @brief interrupt2 bit 7 in the register 0x57 + * + * + * @param v_channel_u8: The value of flat interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_FLAT + * 1 | BMI160_INTR2_MAP_FLAT + * + * @param v_intr_flat_u8 : The value of flat enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_flat( +u8 v_channel_u8, u8 v_intr_flat_u8); +/*! + * @brief Reads PMU trigger interrupt mapped to interrupt1 + * and interrupt2 form the register 0x56 bit 0 and 4 + * @brief interrupt1 bit 0 in the register 0x56 + * @brief interrupt2 bit 4 in the register 0x56 + * + * + * @param v_channel_u8: The value of pmu trigger selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_PMUTRIG + * 1 | BMI160_INTR2_MAP_PMUTRIG + * + * @param v_intr_pmu_trig_u8 : The value of pmu trigger enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_pmu_trig( +u8 v_channel_u8, u8 *v_intr_pmu_trig_u8); +/*! + * @brief Write PMU trigger interrupt mapped to interrupt1 + * and interrupt2 form the register 0x56 bit 0 and 4 + * @brief interrupt1 bit 0 in the register 0x56 + * @brief interrupt2 bit 4 in the register 0x56 + * + * + * @param v_channel_u8: The value of pmu trigger selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_PMUTRIG + * 1 | BMI160_INTR2_MAP_PMUTRIG + * + * @param v_intr_pmu_trig_u8 : The value of pmu trigger enable + * value | trigger enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_pmu_trig( +u8 v_channel_u8, u8 v_intr_pmu_trig_u8); +/*! + * @brief Reads FIFO Full interrupt mapped to interrupt1 + * and interrupt2 form the register 0x56 bit 5 and 1 + * @brief interrupt1 bit 5 in the register 0x56 + * @brief interrupt2 bit 1 in the register 0x56 + * + * + * @param v_channel_u8: The value of fifo full interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_FIFO_FULL + * 1 | BMI160_INTR2_MAP_FIFO_FULL + * + * @param v_intr_fifo_full_u8 : The value of fifo full interrupt enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_fifo_full( +u8 v_channel_u8, u8 *v_intr_fifo_full_u8); +/*! + * @brief Write FIFO Full interrupt mapped to interrupt1 + * and interrupt2 form the register 0x56 bit 5 and 1 + * @brief interrupt1 bit 5 in the register 0x56 + * @brief interrupt2 bit 1 in the register 0x56 + * + * + * @param v_channel_u8: The value of fifo full interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_FIFO_FULL + * 1 | BMI160_INTR2_MAP_FIFO_FULL + * + * @param v_intr_fifo_full_u8 : The value of fifo full interrupt enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_fifo_full( +u8 v_channel_u8, u8 v_intr_fifo_full_u8); +/*! + * @brief Reads FIFO Watermark interrupt mapped to interrupt1 + * and interrupt2 form the register 0x56 bit 6 and 2 + * @brief interrupt1 bit 6 in the register 0x56 + * @brief interrupt2 bit 2 in the register 0x56 + * + * + * @param v_channel_u8: The value of fifo Watermark interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_FIFO_WM + * 1 | BMI160_INTR2_MAP_FIFO_WM + * + * @param v_intr_fifo_wm_u8 : The value of fifo Watermark interrupt enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_fifo_wm( +u8 v_channel_u8, u8 *v_intr_fifo_wm_u8); +/*! + * @brief Write FIFO Watermark interrupt mapped to interrupt1 + * and interrupt2 form the register 0x56 bit 6 and 2 + * @brief interrupt1 bit 6 in the register 0x56 + * @brief interrupt2 bit 2 in the register 0x56 + * + * + * @param v_channel_u8: The value of fifo Watermark interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_FIFO_WM + * 1 | BMI160_INTR2_MAP_FIFO_WM + * + * @param v_intr_fifo_wm_u8 : The value of fifo Watermark interrupt enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_fifo_wm( +u8 v_channel_u8, u8 v_intr_fifo_wm_u8); +/*! + * @brief Reads Data Ready interrupt mapped to interrupt1 + * and interrupt2 form the register 0x56 + * @brief interrupt1 bit 7 in the register 0x56 + * @brief interrupt2 bit 3 in the register 0x56 + * + * + * @param v_channel_u8: The value of data ready interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_DATA_RDY + * 1 | BMI160_INTR2_MAP_DATA_RDY + * + * @param v_intr_data_rdy_u8 : The value of data ready interrupt enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_data_rdy( +u8 v_channel_u8, u8 *v_intr_data_rdy_u8); +/*! + * @brief Write Data Ready interrupt mapped to interrupt1 + * and interrupt2 form the register 0x56 + * @brief interrupt1 bit 7 in the register 0x56 + * @brief interrupt2 bit 3 in the register 0x56 + * + * + * @param v_channel_u8: The value of data ready interrupt selection + * v_channel_u8 | interrupt + * ---------------|--------------- + * 0 | BMI160_INTR1_MAP_DATA_RDY + * 1 | BMI160_INTR2_MAP_DATA_RDY + * + * @param v_intr_data_rdy_u8 : The value of data ready interrupt enable + * value | interrupt enable + * ----------|------------------- + * 0x01 | BMI160_ENABLE + * 0x00 | BMI160_DISABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_data_rdy( +u8 v_channel_u8, u8 v_intr_data_rdy_u8); +/***************************************************************/ +/**\name FUNCTION FOR TAP SOURCE CONFIGURATION */ +/***************************************************************/ + /*! + * @brief This API reads data source for the interrupt + * engine for the single and double tap interrupts from the register + * 0x58 bit 3 + * + * + * @param v_tap_source_u8 : The value of the tap source + * value | Description + * ----------|------------------- + * 0x01 | UNFILTER_DATA + * 0x00 | FILTER_DATA + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_source( +u8 *v_tap_source_u8); + /*! + * @brief This API write data source for the interrupt + * engine for the single and double tap interrupts from the register + * 0x58 bit 3 + * + * + * @param v_tap_source_u8 : The value of the tap source + * value | Description + * ----------|------------------- + * 0x01 | UNFILTER_DATA + * 0x00 | FILTER_DATA + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_source( +u8 v_tap_source_u8); +/***************************************************************/ +/**\name FUNCTION FOR LOW_G AND HIGH_G SOURCE CONFIGURATION */ +/***************************************************************/ + /*! + * @brief This API Reads Data source for the + * interrupt engine for the low and high g interrupts + * from the register 0x58 bit 7 + * + * @param v_low_high_source_u8 : The value of the tap source + * value | Description + * ----------|------------------- + * 0x01 | UNFILTER_DATA + * 0x00 | FILTER_DATA + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_high_source( +u8 *v_low_high_source_u8); + /*! + * @brief This API write Data source for the + * interrupt engine for the low and high g interrupts + * from the register 0x58 bit 7 + * + * @param v_low_high_source_u8 : The value of the tap source + * value | Description + * ----------|------------------- + * 0x01 | UNFILTER_DATA + * 0x00 | FILTER_DATA + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_high_source( +u8 v_low_high_source_u8); +/***************************************************************/ +/**\name FUNCTION FOR MOTION SOURCE CONFIGURATION */ +/***************************************************************/ + /*! + * @brief This API reads Data source for the + * interrupt engine for the nomotion and anymotion interrupts + * from the register 0x59 bit 7 + * + * @param v_motion_source_u8 : + * The value of the any/no motion interrupt source + * value | Description + * ----------|------------------- + * 0x01 | UNFILTER_DATA + * 0x00 | FILTER_DATA + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_motion_source( +u8 *v_motion_source_u8); + /*! + * @brief This API write Data source for the + * interrupt engine for the nomotion and anymotion interrupts + * from the register 0x59 bit 7 + * + * @param v_motion_source_u8 : + * The value of the any/no motion interrupt source + * value | Description + * ----------|------------------- + * 0x01 | UNFILTER_DATA + * 0x00 | FILTER_DATA + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_motion_source( +u8 v_motion_source_u8); +/***************************************************************/ +/**\name FUNCTION FOR LOW_G DURATION CONFIGURATION */ +/***************************************************************/ +/*! + * @brief This API is used to read the low_g duration from register + * 0x5A bit 0 to 7 + * + * + * + * + * @param v_low_g_durn_u8 : The value of low_g duration + * + * @note Low_g duration trigger trigger delay according to + * "(v_low_g_durn_u8 * 2.5)ms" in a range from 2.5ms to 640ms. + * the default corresponds delay is 20ms + * @note When low_g data source of interrupt is unfiltered + * the sensor must not be in low power mode + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g_durn( +u8 *v_low_durn_u8); + /*! + * @brief This API is used to write the low_g duration from register + * 0x5A bit 0 to 7 + * + * + * + * + * @param v_low_g_durn_u8 : The value of low_g duration + * + * @note Low_g duration trigger trigger delay according to + * "(v_low_g_durn_u8 * 2.5)ms" in a range from 2.5ms to 640ms. + * the default corresponds delay is 20ms + * @note When low_g data source of interrupt is unfiltered + * the sensor must not be in low power mode + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g_durn( +u8 v_low_durn_u8); +/***************************************************************/ +/**\name FUNCTION FOR LOW_G THRESH CONFIGURATION */ +/***************************************************************/ +/*! + * @brief This API is used to read Threshold + * definition for the low-g interrupt from the register 0x5B bit 0 to 7 + * + * + * + * + * @param v_low_g_thres_u8 : The value of low_g threshold + * + * @note Low_g interrupt trigger threshold according to + * (v_low_g_thres_u8 * 7.81)mg for v_low_g_thres_u8 > 0 + * 3.91 mg for v_low_g_thres_u8 = 0 + * The threshold range is form 3.91mg to 2.000mg + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g_thres( +u8 *v_low_g_thres_u8); +/*! + * @brief This API is used to write Threshold + * definition for the low-g interrupt from the register 0x5B bit 0 to 7 + * + * + * + * + * @param v_low_g_thres_u8 : The value of low_g threshold + * + * @note Low_g interrupt trigger threshold according to + * (v_low_g_thres_u8 * 7.81)mg for v_low_g_thres_u8 > 0 + * 3.91 mg for v_low_g_thres_u8 = 0 + * The threshold range is form 3.91mg to 2.000mg + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g_thres( +u8 v_low_g_thres_u8); +/***************************************************************/ +/**\name FUNCTION FOR LOW_G HYSTERESIS CONFIGURATION */ +/***************************************************************/ + /*! + * @brief This API Reads Low-g interrupt hysteresis + * from the register 0x5C bit 0 to 1 + * + * @param v_low_hyst_u8 :The value of low_g hysteresis + * + * @note Low_g hysteresis calculated by v_low_hyst_u8*125 mg + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g_hyst( +u8 *v_low_hyst_u8); + /*! + * @brief This API write Low-g interrupt hysteresis + * from the register 0x5C bit 0 to 1 + * + * @param v_low_hyst_u8 :The value of low_g hysteresis + * + * @note Low_g hysteresis calculated by v_low_hyst_u8*125 mg + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g_hyst( +u8 v_low_hyst_u8); +/***************************************************************/ +/**\name FUNCTION FOR LOW_G MODE CONFIGURATION */ +/***************************************************************/ +/*! + * @brief This API reads Low-g interrupt mode + * from the register 0x5C bit 2 + * + * @param v_low_g_mode_u8 : The value of low_g mode + * Value | Description + * ----------|----------------- + * 0 | single-axis + * 1 | axis-summing + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g_mode( +u8 *v_low_g_mode_u8); +/*! + * @brief This API write Low-g interrupt mode + * from the register 0x5C bit 2 + * + * @param v_low_g_mode_u8 : The value of low_g mode + * Value | Description + * ----------|----------------- + * 0 | single-axis + * 1 | axis-summing + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g_mode( +u8 v_low_g_mode_u8); +/***************************************************************/ +/**\name FUNCTION FOR HIGH_G HYST CONFIGURATION */ +/***************************************************************/ +/*! + * @brief This API reads High-g interrupt hysteresis + * from the register 0x5C bit 6 and 7 + * + * @param v_high_g_hyst_u8 : The value of high hysteresis + * + * @note High_g hysteresis changes according to accel g range + * accel g range can be set by the function "" + * accel_range | high_g hysteresis + * ----------------|--------------------- + * 2g | high_hy*125 mg + * 4g | high_hy*250 mg + * 8g | high_hy*500 mg + * 16g | high_hy*1000 mg + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_high_g_hyst( +u8 *v_high_g_hyst_u8); +/*! + * @brief This API write High-g interrupt hysteresis + * from the register 0x5C bit 6 and 7 + * + * @param v_high_g_hyst_u8 : The value of high hysteresis + * + * @note High_g hysteresis changes according to accel g range + * accel g range can be set by the function "" + * accel_range | high_g hysteresis + * ----------------|--------------------- + * 2g | high_hy*125 mg + * 4g | high_hy*250 mg + * 8g | high_hy*500 mg + * 16g | high_hy*1000 mg + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_high_g_hyst( +u8 v_high_g_hyst_u8); +/***************************************************************/ +/**\name FUNCTION FOR HIGH_G DURATION CONFIGURATION */ +/***************************************************************/ +/*! + * @brief This API is used to read Delay + * time definition for the high-g interrupt from the register + * 0x5D bit 0 to 7 + * + * + * + * @param v_high_g_durn_u8 : The value of high duration + * + * @note High_g interrupt delay triggered according to + * v_high_g_durn_u8 * 2.5ms in a range from 2.5ms to 640ms + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_high_g_durn( +u8 *v_high_g_durn_u8); +/*! + * @brief This API is used to write Delay + * time definition for the high-g interrupt from the register + * 0x5D bit 0 to 7 + * + * + * + * @param v_high_g_durn_u8 : The value of high duration + * + * @note High_g interrupt delay triggered according to + * v_high_g_durn_u8 * 2.5ms in a range from 2.5ms to 640ms + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_high_g_durn( +u8 v_high_g_durn_u8); +/***************************************************************/ +/**\name FUNCTION FOR HIGH_G THRESHOLD CONFIGURATION */ +/***************************************************************/ +/*! + * @brief This API is used to read Threshold + * definition for the high-g interrupt from the register 0x5E 0 to 7 + * + * + * + * + * @param v_high_g_thres_u8 : Pointer holding the value of Threshold + * @note High_g threshold changes according to accel g range + * accel g range can be set by the function "" + * accel_range | high_g threshold + * ----------------|--------------------- + * 2g | v_high_g_thres_u8*7.81 mg + * 4g | v_high_g_thres_u8*15.63 mg + * 8g | v_high_g_thres_u8*31.25 mg + * 16g | v_high_g_thres_u8*62.5 mg + * @note when v_high_g_thres_u8 = 0 + * accel_range | high_g threshold + * ----------------|--------------------- + * 2g | 3.91 mg + * 4g | 7.81 mg + * 8g | 15.63 mg + * 16g | 31.25 mg + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_high_g_thres( +u8 *v_high_g_thres_u8); +/*! + * @brief This API is used to write Threshold + * definition for the high-g interrupt from the register 0x5E 0 to 7 + * + * + * + * + * @param v_high_g_thres_u8 : Pointer holding the value of Threshold + * @note High_g threshold changes according to accel g range + * accel g range can be set by the function "" + * accel_range | high_g threshold + * ----------------|--------------------- + * 2g | v_high_g_thres_u8*7.81 mg + * 4g | v_high_g_thres_u8*15.63 mg + * 8g | v_high_g_thres_u8*31.25 mg + * 16g | v_high_g_thres_u8*62.5 mg + * @note when v_high_g_thres_u8 = 0 + * accel_range | high_g threshold + * ----------------|--------------------- + * 2g | 3.91 mg + * 4g | 7.81 mg + * 8g | 15.63 mg + * 16g | 31.25 mg + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_high_g_thres( +u8 v_high_g_thres_u8); +/***************************************************************/ +/**\name FUNCTION FOR ANY MOTION DURATION CONFIGURATION */ +/***************************************************************/ +/*! + * @brief This API reads any motion duration + * from the register 0x5F bit 0 and 1 + * + * @param v_any_motion_durn_u8 : The value of any motion duration + * + * @note Any motion duration can be calculated by "v_any_motion_durn_u8 + 1" + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_any_motion_durn( +u8 *v_any_motion_durn_u8); +/*! + * @brief This API write any motion duration + * from the register 0x5F bit 0 and 1 + * + * @param v_any_motion_durn_u8 : The value of any motion duration + * + * @note Any motion duration can be calculated by "v_any_motion_durn_u8 + 1" + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_any_motion_durn( +u8 nomotion); +/***************************************************************/ +/**\name FUNCTION FOR SLOW NO MOTION DURATION CONFIGURATION */ +/***************************************************************/ + /*! + * @brief This API read Slow/no-motion + * interrupt trigger delay duration from the register 0x5F bit 2 to 7 + * + * @param v_slow_no_motion_u8 :The value of slow no motion duration + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * @note + * @note v_slow_no_motion_u8(5:4)=0b00 -> + * [v_slow_no_motion_u8(3:0) + 1] * 1.28s (1.28s-20.48s) + * @note v_slow_no_motion_u8(5:4)=1 -> + * [v_slow_no_motion_u8(3:0)+5] * 5.12s (25.6s-102.4s) + * @note v_slow_no_motion_u8(5)='1' -> + * [(v_slow_no_motion_u8:0)+11] * 10.24s (112.64s-430.08s); + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_slow_no_motion_durn( +u8 *v_slow_no_motion_u8); + /*! + * @brief This API write Slow/no-motion + * interrupt trigger delay duration from the register 0x5F bit 2 to 7 + * + * @param v_slow_no_motion_u8 :The value of slow no motion duration + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * @note + * @note v_slow_no_motion_u8(5:4)=0b00 -> + * [v_slow_no_motion_u8(3:0) + 1] * 1.28s (1.28s-20.48s) + * @note v_slow_no_motion_u8(5:4)=1 -> + * [v_slow_no_motion_u8(3:0)+5] * 5.12s (25.6s-102.4s) + * @note v_slow_no_motion_u8(5)='1' -> + * [(v_slow_no_motion_u8:0)+11] * 10.24s (112.64s-430.08s); + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_slow_no_motion_durn( +u8 v_slow_no_motion_u8); +/***************************************************************/ +/**\name FUNCTION FOR ANY MOTION THRESHOLD CONFIGURATION */ +/***************************************************************/ +/*! + * @brief This API is used to read threshold + * definition for the any-motion interrupt + * from the register 0x60 bit 0 to 7 + * + * + * @param v_any_motion_thres_u8 : The value of any motion threshold + * + * @note any motion threshold changes according to accel g range + * accel g range can be set by the function "" + * accel_range | any motion threshold + * ----------------|--------------------- + * 2g | v_any_motion_thres_u8*3.91 mg + * 4g | v_any_motion_thres_u8*7.81 mg + * 8g | v_any_motion_thres_u8*15.63 mg + * 16g | v_any_motion_thres_u8*31.25 mg + * @note when v_any_motion_thres_u8 = 0 + * accel_range | any motion threshold + * ----------------|--------------------- + * 2g | 1.95 mg + * 4g | 3.91 mg + * 8g | 7.81 mg + * 16g | 15.63 mg + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_any_motion_thres( +u8 *v_any_motion_thres_u8); +/*! + * @brief This API is used to write threshold + * definition for the any-motion interrupt + * from the register 0x60 bit 0 to 7 + * + * + * @param v_any_motion_thres_u8 : The value of any motion threshold + * + * @note any motion threshold changes according to accel g range + * accel g range can be set by the function "" + * accel_range | any motion threshold + * ----------------|--------------------- + * 2g | v_any_motion_thres_u8*3.91 mg + * 4g | v_any_motion_thres_u8*7.81 mg + * 8g | v_any_motion_thres_u8*15.63 mg + * 16g | v_any_motion_thres_u8*31.25 mg + * @note when v_any_motion_thres_u8 = 0 + * accel_range | any motion threshold + * ----------------|--------------------- + * 2g | 1.95 mg + * 4g | 3.91 mg + * 8g | 7.81 mg + * 16g | 15.63 mg + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_any_motion_thres( +u8 v_any_motion_thres_u8); +/***************************************************************/ +/**\name FUNCTION FOR SLO/NO MOTION THRESHOLD CONFIGURATION */ +/***************************************************************/ + /*! + * @brief This API is used to read threshold + * for the slow/no-motion interrupt + * from the register 0x61 bit 0 to 7 + * + * + * + * + * @param v_slow_no_motion_thres_u8 : The value of slow no motion threshold + * @note slow no motion threshold changes according to accel g range + * accel g range can be set by the function "" + * accel_range | slow no motion threshold + * ----------------|--------------------- + * 2g | v_slow_no_motion_thres_u8*3.91 mg + * 4g | v_slow_no_motion_thres_u8*7.81 mg + * 8g | v_slow_no_motion_thres_u8*15.63 mg + * 16g | v_slow_no_motion_thres_u8*31.25 mg + * @note when v_slow_no_motion_thres_u8 = 0 + * accel_range | slow no motion threshold + * ----------------|--------------------- + * 2g | 1.95 mg + * 4g | 3.91 mg + * 8g | 7.81 mg + * 16g | 15.63 mg + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_slow_no_motion_thres( +u8 *v_slow_no_motion_thres_u8); + /*! + * @brief This API is used to write threshold + * for the slow/no-motion interrupt + * from the register 0x61 bit 0 to 7 + * + * + * + * + * @param v_slow_no_motion_thres_u8 : The value of slow no motion threshold + * @note slow no motion threshold changes according to accel g range + * accel g range can be set by the function "" + * accel_range | slow no motion threshold + * ----------------|--------------------- + * 2g | v_slow_no_motion_thres_u8*3.91 mg + * 4g | v_slow_no_motion_thres_u8*7.81 mg + * 8g | v_slow_no_motion_thres_u8*15.63 mg + * 16g | v_slow_no_motion_thres_u8*31.25 mg + * @note when v_slow_no_motion_thres_u8 = 0 + * accel_range | slow no motion threshold + * ----------------|--------------------- + * 2g | 1.95 mg + * 4g | 3.91 mg + * 8g | 7.81 mg + * 16g | 15.63 mg + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_slow_no_motion_thres( +u8 v_slow_no_motion_thres_u8); +/***************************************************************/ +/**\name FUNCTION FOR SLO/NO MOTION SELECT CONFIGURATION */ +/***************************************************************/ + /*! + * @brief This API is used to read + * the slow/no-motion selection from the register 0x62 bit 0 + * + * + * + * + * @param v_intr_slow_no_motion_select_u8 : + * The value of slow/no-motion select + * value | Behaviour + * ----------|------------------- + * 0x00 | SLOW_MOTION + * 0x01 | NO_MOTION + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_slow_no_motion_select( +u8 *v_intr_slow_no_motion_select_u8); + /*! + * @brief This API is used to write + * the slow/no-motion selection from the register 0x62 bit 0 + * + * + * + * + * @param v_intr_slow_no_motion_select_u8 : + * The value of slow/no-motion select + * value | Behaviour + * ----------|------------------- + * 0x00 | SLOW_MOTION + * 0x01 | NO_MOTION + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_slow_no_motion_select( +u8 v_intr_slow_no_motion_select_u8); +/***************************************************************/ +/**\name FUNCTION FOR SIGNIFICANT MOTION SELECT CONFIGURATION*/ +/***************************************************************/ + /*! + * @brief This API is used to select + * the significant or any motion interrupt from the register 0x62 bit 1 + * + * + * + * + * @param v_intr_significant_motion_select_u8 : + * the value of significant or any motion interrupt selection + * value | Behaviour + * ----------|------------------- + * 0x00 | ANY_MOTION + * 0x01 | SIGNIFICANT_MOTION + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_significant_motion_select( +u8 *int_sig_mot_sel); + /*! + * @brief This API is used to write, select + * the significant or any motion interrupt from the register 0x62 bit 1 + * + * + * + * + * @param v_intr_significant_motion_select_u8 : + * the value of significant or any motion interrupt selection + * value | Behaviour + * ----------|------------------- + * 0x00 | ANY_MOTION + * 0x01 | SIGNIFICANT_MOTION + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_significant_motion_select( +u8 int_sig_mot_sel); + /*! + * @brief This API is used to read + * the significant skip time from the register 0x62 bit 2 and 3 + * + * + * + * + * @param v_int_sig_mot_skip_u8 : the value of significant skip time + * value | Behaviour + * ----------|------------------- + * 0x00 | skip time 1.5 seconds + * 0x01 | skip time 3 seconds + * 0x02 | skip time 6 seconds + * 0x03 | skip time 12 seconds + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_significant_motion_skip( +u8 *v_int_sig_mot_skip_u8); + /*! + * @brief This API is used to write + * the significant skip time from the register 0x62 bit 2 and 3 + * + * + * + * + * @param v_int_sig_mot_skip_u8 : the value of significant skip time + * value | Behaviour + * ----------|------------------- + * 0x00 | skip time 1.5 seconds + * 0x01 | skip time 3 seconds + * 0x02 | skip time 6 seconds + * 0x03 | skip time 12 seconds + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_significant_motion_skip( +u8 v_int_sig_mot_skip_u8); + /*! + * @brief This API is used to read + * the significant proof time from the register 0x62 bit 4 and 5 + * + * + * + * + * @param v_significant_motion_proof_u8 : + * the value of significant proof time + * value | Behaviour + * ----------|------------------- + * 0x00 | proof time 0.25 seconds + * 0x01 | proof time 0.5 seconds + * 0x02 | proof time 1 seconds + * 0x03 | proof time 2 seconds + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_significant_motion_proof( +u8 *int_sig_mot_proof); + /*! + * @brief This API is used to write + * the significant proof time from the register 0x62 bit 4 and 5 + * + * + * + * + * @param v_significant_motion_proof_u8 : + * the value of significant proof time + * value | Behaviour + * ----------|------------------- + * 0x00 | proof time 0.25 seconds + * 0x01 | proof time 0.5 seconds + * 0x02 | proof time 1 seconds + * 0x03 | proof time 2 seconds + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_significant_motion_proof( +u8 int_sig_mot_proof); +/***************************************************************/ +/**\name FUNCTION FOR TAP DURATION CONFIGURATION*/ +/***************************************************************/ +/*! + * @brief This API is used to get the tap duration + * from the register 0x63 bit 0 to 2 + * + * + * + * @param v_tap_durn_u8 : The value of tap duration + * value | Behaviour + * ----------|------------------- + * 0x00 | BMI160_TAP_DURN_50MS + * 0x01 | BMI160_TAP_DURN_100MS + * 0x03 | BMI160_TAP_DURN_150MS + * 0x04 | BMI160_TAP_DURN_200MS + * 0x05 | BMI160_TAP_DURN_250MS + * 0x06 | BMI160_TAP_DURN_375MS + * 0x07 | BMI160_TAP_DURN_700MS + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_durn( +u8 *v_tap_durn_u8); +/*! + * @brief This API is used to write the tap duration + * from the register 0x63 bit 0 to 2 + * + * + * + * @param v_tap_durn_u8 : The value of tap duration + * value | Behaviour + * ----------|------------------- + * 0x00 | BMI160_TAP_DURN_50MS + * 0x01 | BMI160_TAP_DURN_100MS + * 0x03 | BMI160_TAP_DURN_150MS + * 0x04 | BMI160_TAP_DURN_200MS + * 0x05 | BMI160_TAP_DURN_250MS + * 0x06 | BMI160_TAP_DURN_375MS + * 0x07 | BMI160_TAP_DURN_700MS + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_durn( +u8 v_tap_durn_u8); +/***************************************************************/ +/**\name FUNCTION FOR TAP SHOCK CONFIGURATION*/ +/***************************************************************/ + /*! + * @brief This API read the + * tap shock duration from the register 0x63 bit 2 + * + * @param v_tap_shock_u8 :The value of tap shock + * value | Behaviour + * ----------|------------------- + * 0x00 | BMI160_TAP_SHOCK_50MS + * 0x01 | BMI160_TAP_SHOCK_75MS + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_shock( +u8 *v_tap_shock_u8); + /*! + * @brief This API write the + * tap shock duration from the register 0x63 bit 2 + * + * @param v_tap_shock_u8 :The value of tap shock + * value | Behaviour + * ----------|------------------- + * 0x00 | BMI160_TAP_SHOCK_50MS + * 0x01 | BMI160_TAP_SHOCK_75MS + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_shock( +u8 v_tap_shock_u8); +/***************************************************************/ +/**\name FUNCTION FOR TAP QUIET CONFIGURATION*/ +/***************************************************************/ +/*! + * @brief This API read + * tap quiet duration from the register 0x63 bit 7 + * + * + * @param v_tap_quiet_u8 : The value of tap quiet + * value | Behaviour + * ----------|------------------- + * 0x00 | BMI160_TAP_QUIET_30MS + * 0x01 | BMI160_TAP_QUIET_20MS + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_quiet( +u8 *v_tap_quiet_u8); +/*! + * @brief This API write + * tap quiet duration from the register 0x63 bit 7 + * + * + * @param v_tap_quiet_u8 : The value of tap quiet + * value | Behaviour + * ----------|------------------- + * 0x00 | BMI160_TAP_QUIET_30MS + * 0x01 | BMI160_TAP_QUIET_20MS + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_quiet( +u8 v_tap_quiet_u8); +/***************************************************************/ +/**\name FUNCTION FOR TAP THRESHOLD CONFIGURATION*/ +/***************************************************************/ + /*! + * @brief This API read Threshold of the + * single/double tap interrupt from the register 0x64 bit 0 to 4 + * + * + * @param v_tap_thres_u8 : The value of single/double tap threshold + * + * @note single/double tap threshold changes according to accel g range + * accel g range can be set by the function "" + * accel_range | single/double tap threshold + * ----------------|--------------------- + * 2g | ((v_tap_thres_u8 + 1) * 62.5)mg + * 4g | ((v_tap_thres_u8 + 1) * 125)mg + * 8g | ((v_tap_thres_u8 + 1) * 250)mg + * 16g | ((v_tap_thres_u8 + 1) * 500)mg + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_thres( +u8 *v_tap_thres_u8); + /*! + * @brief This API write Threshold of the + * single/double tap interrupt from the register 0x64 bit 0 to 4 + * + * + * @param v_tap_thres_u8 : The value of single/double tap threshold + * + * @note single/double tap threshold changes according to accel g range + * accel g range can be set by the function "" + * accel_range | single/double tap threshold + * ----------------|--------------------- + * 2g | ((v_tap_thres_u8 + 1) * 62.5)mg + * 4g | ((v_tap_thres_u8 + 1) * 125)mg + * 8g | ((v_tap_thres_u8 + 1) * 250)mg + * 16g | ((v_tap_thres_u8 + 1) * 500)mg + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_thres( +u8 v_tap_thres_u8); +/***************************************************************/ +/**\name FUNCTION FOR ORIENT MODE CONFIGURATION*/ +/***************************************************************/ + /*! + * @brief This API read the threshold for orientation interrupt + * from the register 0x65 bit 0 and 1 + * + * @param v_orient_mode_u8 : The value of threshold for orientation + * value | Behaviour + * ----------|------------------- + * 0x00 | symmetrical + * 0x01 | high-asymmetrical + * 0x02 | low-asymmetrical + * 0x03 | symmetrical + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_mode( +u8 *v_orient_mode_u8); + /*! + * @brief This API write the threshold for orientation interrupt + * from the register 0x65 bit 0 and 1 + * + * @param v_orient_mode_u8 : The value of threshold for orientation + * value | Behaviour + * ----------|------------------- + * 0x00 | symmetrical + * 0x01 | high-asymmetrical + * 0x02 | low-asymmetrical + * 0x03 | symmetrical + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_mode( +u8 v_orient_mode_u8); +/***************************************************************/ +/**\name FUNCTION FOR ORIENT BLOCKING CONFIGURATION*/ +/***************************************************************/ +/*! + * @brief This API read the orient blocking mode + * that is used for the generation of the orientation interrupt. + * from the register 0x65 bit 2 and 3 + * + * @param v_orient_blocking_u8 : The value of orient blocking mode + * value | Behaviour + * ----------|------------------- + * 0x00 | No blocking + * 0x01 | Theta blocking or acceleration in any axis > 1.5g + * 0x02 | Theta blocking or acceleration slope in any axis > + * - | 0.2g or acceleration in any axis > 1.5g + * 0x03 | Theta blocking or acceleration slope in any axis > + * - | 0.4g or acceleration in any axis > + * - | 1.5g and value of orient is not stable + * - | for at least 100 ms + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_blocking( +u8 *v_orient_blocking_u8); +/*! + * @brief This API write the orient blocking mode + * that is used for the generation of the orientation interrupt. + * from the register 0x65 bit 2 and 3 + * + * @param v_orient_blocking_u8 : The value of orient blocking mode + * value | Behaviour + * ----------|------------------- + * 0x00 | No blocking + * 0x01 | Theta blocking or acceleration in any axis > 1.5g + * 0x02 | Theta blocking or acceleration slope in any axis > + * - | 0.2g or acceleration in any axis > 1.5g + * 0x03 | Theta blocking or acceleration slope in any axis > + * - | 0.4g or acceleration in any axis > + * - | 1.5g and value of orient is not stable + * - | for at least 100 ms + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_blocking( +u8 v_orient_blocking_u8); +/***************************************************************/ +/**\name FUNCTION FOR ORIENT HYSTERESIS CONFIGURATION*/ +/***************************************************************/ +/*! + * @brief This API read Orient interrupt + * hysteresis, from the register 0x64 bit 4 to 7 + * + * + * + * @param v_orient_hyst_u8 : The value of orient hysteresis + * + * @note 1 LSB corresponds to 62.5 mg, + * irrespective of the selected accel range + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_hyst( +u8 *v_orient_hyst_u8); +/*! + * @brief This API write Orient interrupt + * hysteresis, from the register 0x64 bit 4 to 7 + * + * + * + * @param v_orient_hyst_u8 : The value of orient hysteresis + * + * @note 1 LSB corresponds to 62.5 mg, + * irrespective of the selected accel range + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_hyst( +u8 v_orient_hyst_u8); +/***************************************************************/ +/**\name FUNCTION FOR ORIENT THETA CONFIGURATION*/ +/***************************************************************/ + /*! + * @brief This API read Orient + * blocking angle (0 to 44.8) from the register 0x66 bit 0 to 5 + * + * @param v_orient_theta_u8 : The value of Orient blocking angle + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_theta( +u8 *v_orient_theta_u8); + /*! + * @brief This API write Orient + * blocking angle (0 to 44.8) from the register 0x66 bit 0 to 5 + * + * @param v_orient_theta_u8 : The value of Orient blocking angle + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_theta( +u8 v_orient_theta_u8); +/***************************************************************/ +/**\name FUNCTION FOR ORIENT OUTPUT ENABLE CONFIGURATION*/ +/***************************************************************/ +/*! + * @brief This API read orient change + * of up/down bit from the register 0x66 bit 6 + * + * @param v_orient_ud_u8 : The value of orient change of up/down + * value | Behaviour + * ----------|------------------- + * 0x00 | Is ignored + * 0x01 | Generates orientation interrupt + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_ud_enable( +u8 *v_orient_ud_u8); +/*! + * @brief This API write orient change + * of up/down bit from the register 0x66 bit 6 + * + * @param v_orient_ud_u8 : The value of orient change of up/down + * value | Behaviour + * ----------|------------------- + * 0x00 | Is ignored + * 0x01 | Generates orientation interrupt + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_ud_enable( +u8 v_orient_ud_u8); +/***************************************************************/ +/**\name FUNCTION FOR ORIENT AXIS ENABLE CONFIGURATION*/ +/***************************************************************/ + /*! + * @brief This API read orientation axes changes + * from the register 0x66 bit 7 + * + * @param v_orient_axes_u8 : The value of orient axes assignment + * value | Behaviour | Name + * ----------|--------------------|------ + * 0x00 | x = x, y = y, z = z|orient_ax_noex + * 0x01 | x = y, y = z, z = x|orient_ax_ex + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_axes_enable( +u8 *v_orient_axes_u8); + /*! + * @brief This API write orientation axes changes + * from the register 0x66 bit 7 + * + * @param v_orient_axes_u8 : The value of orient axes assignment + * value | Behaviour | Name + * ----------|--------------------|------ + * 0x00 | x = x, y = y, z = z|orient_ax_noex + * 0x01 | x = y, y = z, z = x|orient_ax_ex + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_axes_enable( +u8 v_orient_axes_u8); +/***************************************************************/ +/**\name FUNCTION FOR FLAT THETA CONFIGURATION*/ +/***************************************************************/ + /*! + * @brief This API read Flat angle (0 to 44.8) for flat interrupt + * from the register 0x67 bit 0 to 5 + * + * @param v_flat_theta_u8 : The value of flat angle + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_flat_theta( +u8 *v_flat_theta_u8); + /*! + * @brief This API write Flat angle (0 to 44.8) for flat interrupt + * from the register 0x67 bit 0 to 5 + * + * @param v_flat_theta_u8 : The value of flat angle + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_flat_theta( +u8 v_flat_theta_u8); +/***************************************************************/ +/**\name FUNCTION FOR FLAT HOLD CONFIGURATION*/ +/***************************************************************/ +/*! + * @brief This API read Flat interrupt hold time; + * from the register 0x68 bit 4 and 5 + * + * @param v_flat_hold_u8 : The value of flat hold time + * value | Behaviour + * ----------|------------------- + * 0x00 | 0ms + * 0x01 | 512ms + * 0x01 | 1024ms + * 0x01 | 2048ms + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_flat_hold( +u8 *v_flat_hold_u8); +/*! + * @brief This API write Flat interrupt hold time; + * from the register 0x68 bit 4 and 5 + * + * @param v_flat_hold_u8 : The value of flat hold time + * value | Behaviour + * ----------|------------------- + * 0x00 | 0ms + * 0x01 | 512ms + * 0x01 | 1024ms + * 0x01 | 2048ms + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_flat_hold( +u8 v_flat_hold_u8); +/***************************************************************/ +/**\name FUNCTION FOR FLAT HYSTERESIS CONFIGURATION*/ +/***************************************************************/ +/*! + * @brief This API read flat interrupt hysteresis + * from the register 0x68 bit 0 to 3 + * + * @param v_flat_hyst_u8 : The value of flat hysteresis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_flat_hyst( +u8 *v_flat_hyst_u8); +/*! + * @brief This API write flat interrupt hysteresis + * from the register 0x68 bit 0 to 3 + * + * @param v_flat_hyst_u8 : The value of flat hysteresis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_flat_hyst( +u8 v_flat_hyst_u8); +/***************************************************************/ +/**\name FUNCTION FAST OFFSET COMPENSATION FOR ACCEL */ +/***************************************************************/ + /*! + * @brief This API read accel offset compensation + * target value for z-axis from the register 0x69 bit 0 and 1 + * + * @param v_foc_accel_z_u8 : the value of accel offset compensation z axis + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x01 | -1g + * 0x01 | 0g + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_accel_z( +u8 *v_foc_accel_z_u8); + /*! + * @brief This API write accel offset compensation + * target value for z-axis from the register 0x69 bit 0 and 1 + * + * @param v_foc_accel_z_u8 : the value of accel offset compensation z axis + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x01 | -1g + * 0x01 | 0g + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_foc_accel_z( +u8 v_foc_accel_z_u8); +/*! + * @brief This API read accel offset compensation + * target value for y-axis + * from the register 0x69 bit 2 and 3 + * + * @param v_foc_accel_y_u8 : the value of accel offset compensation y axis + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x01 | -1g + * 0x01 | 0g + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_accel_y( +u8 *v_foc_accel_y_u8); +/*! + * @brief This API write accel offset compensation + * target value for y-axis + * from the register 0x69 bit 2 and 3 + * + * @param v_foc_accel_y_u8 : the value of accel offset compensation y axis + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x01 | -1g + * 0x01 | 0g + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_foc_accel_y( +u8 v_foc_accel_y_u8); +/*! + * @brief This API read accel offset compensation + * target value for x-axis is + * from the register 0x69 bit 4 and 5 + * + * @param v_foc_accel_x_u8 : the value of accel offset compensation x axis + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x01 | -1g + * 0x01 | 0g + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_accel_x( +u8 *v_foc_accel_x_u8); +/*! + * @brief This API write accel offset compensation + * target value for x-axis is + * from the register 0x69 bit 4 and 5 + * + * @param v_foc_accel_x_u8 : the value of accel offset compensation x axis + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x01 | -1g + * 0x01 | 0g + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_foc_accel_x( +u8 v_foc_accel_x_u8); +/***************************************************************/ +/**\name FUNCTION FAST OFFSET COMPENSATION FOR GYRO */ +/***************************************************************/ +/*! + * @brief This API write gyro fast offset enable + * from the register 0x69 bit 6 + * + * @param v_foc_gyro_u8 : The value of gyro fast offset enable + * value | Description + * ----------|------------- + * 0 | fast offset compensation disabled + * 1 | fast offset compensation enabled + * + * @param v_gyro_off_x_s16 : The value of gyro fast offset x axis data + * @param v_gyro_off_y_s16 : The value of gyro fast offset y axis data + * @param v_gyro_off_z_s16 : The value of gyro fast offset z axis data + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_foc_gyro_enable( +u8 v_foc_gyro_u8, s16 *v_gyro_off_x_s16, +s16 *v_gyro_off_y_s16, s16 *v_gyro_off_z_s16); +/***************************************************/ +/**\name FUNCTION FOR NVM*/ +/***************************************************/ + /*! + * @brief This API read NVM program enable + * from the register 0x6A bit 1 + * + * @param v_nvm_prog_u8 : The value of NVM program enable + * Value | Description + * --------|------------- + * 0 | DISABLE + * 1 | ENABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_nvm_prog_enable( +u8 *v_nvm_prog_u8); + /*! + * @brief This API write NVM program enable + * from the register 0x6A bit 1 + * + * @param v_nvm_prog_u8 : The value of NVM program enable + * Value | Description + * --------|------------- + * 0 | DISABLE + * 1 | ENABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_nvm_prog_enable( +u8 v_nvm_prog_u8); +/***************************************************/ +/**\name FUNCTION FOR SPI MODE*/ +/***************************************************/ +/*! + * @brief This API read to configure SPI + * Interface Mode for primary and OIS interface + * from the register 0x6B bit 0 + * + * @param v_spi3_u8 : The value of SPI mode selection + * Value | Description + * --------|------------- + * 0 | SPI 4-wire mode + * 1 | SPI 3-wire mode + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_spi3( +u8 *v_spi3_u8); +/*! + * @brief This API write to configure SPI + * Interface Mode for primary and OIS interface + * from the register 0x6B bit 0 + * + * @param v_spi3_u8 : The value of SPI mode selection + * Value | Description + * --------|------------- + * 0 | SPI 4-wire mode + * 1 | SPI 3-wire mode + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_spi3( +u8 v_spi3_u8); +/***************************************************/ +/**\name FUNCTION FOR FOC GYRO */ +/***************************************************/ +/*! + * @brief This API read gyro fast offset enable + * from the register 0x69 bit 6 + * + * @param v_foc_gyro_u8 : The value of gyro fast offset enable + * value | Description + * ----------|------------- + * 0 | fast offset compensation disabled + * 1 | fast offset compensation enabled + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_gyro_enable( +u8 *v_foc_gyro_u8); +/***************************************************/ +/**\name FUNCTION FOR I2C WATCHDOG TIMBER */ +/***************************************************/ +/*! + * @brief This API read I2C Watchdog timer + * from the register 0x70 bit 1 + * + * @param v_i2c_wdt_u8 : The value of I2C watch dog timer + * Value | Description + * --------|------------- + * 0 | I2C watchdog v_timeout_u8 after 1 ms + * 1 | I2C watchdog v_timeout_u8 after 50 ms + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_i2c_wdt_select( +u8 *v_i2c_wdt_u8); +/*! + * @brief This API write I2C Watchdog timer + * from the register 0x70 bit 1 + * + * @param v_i2c_wdt_u8 : The value of I2C watch dog timer + * Value | Description + * --------|------------- + * 0 | I2C watchdog v_timeout_u8 after 1 ms + * 1 | I2C watchdog v_timeout_u8 after 50 ms + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE +bmi160_set_i2c_wdt_select(u8 v_i2c_wdt_u8); +/*! + * @brief This API read I2C watchdog enable + * from the register 0x70 bit 2 + * + * @param v_i2c_wdt_u8 : The value of I2C watchdog enable + * Value | Description + * --------|------------- + * 0 | DISABLE + * 1 | ENABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_i2c_wdt_enable( +u8 *v_i2c_wdt_u8); +/*! + * @brief This API write I2C watchdog enable + * from the register 0x70 bit 2 + * + * @param v_i2c_wdt_u8 : The value of I2C watchdog enable + * Value | Description + * --------|------------- + * 0 | DISABLE + * 1 | ENABLE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_i2c_wdt_enable( +u8 v_i2c_wdt_u8); +/***************************************************/ +/**\name FUNCTION FOR IF MODE*/ +/***************************************************/ +/*! + * @brief This API read I2C interface configuration(if) moe + * from the register 0x6B bit 4 and 5 + * + * @param v_if_mode_u8 : The value of interface configuration mode + * Value | Description + * --------|------------- + * 0x00 | Primary interface:autoconfig / secondary interface:off + * 0x01 | Primary interface:I2C / secondary interface:OIS + * 0x02 | Primary interface:autoconfig/secondary interface:Magnetometer + * 0x03 | Reserved + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_if_mode( +u8 *v_if_mode_u8); +/*! + * @brief This API write I2C interface configuration(if) moe + * from the register 0x6B bit 4 and 5 + * + * @param v_if_mode_u8 : The value of interface configuration mode + * Value | Description + * --------|------------- + * 0x00 | Primary interface:autoconfig / secondary interface:off + * 0x01 | Primary interface:I2C / secondary interface:OIS + * 0x02 | Primary interface:autoconfig/secondary interface:Magnetometer + * 0x03 | Reserved + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_if_mode( +u8 v_if_mode_u8); +/***************************************************/ +/**\name FUNCTION FOR GYRO SLEEP TRIGGER INTERRUPT CONFIGURATION*/ +/***************************************************/ +/*! + * @brief This API read gyro sleep trigger + * from the register 0x6C bit 0 to 2 + * + * @param v_gyro_sleep_trigger_u8 : The value of gyro sleep trigger + * Value | Description + * --------|------------- + * 0x00 | nomotion: no / Not INT1 pin: no / INT2 pin: no + * 0x01 | nomotion: no / Not INT1 pin: no / INT2 pin: yes + * 0x02 | nomotion: no / Not INT1 pin: yes / INT2 pin: no + * 0x03 | nomotion: no / Not INT1 pin: yes / INT2 pin: yes + * 0x04 | nomotion: yes / Not INT1 pin: no / INT2 pin: no + * 0x05 | anymotion: yes / Not INT1 pin: no / INT2 pin: yes + * 0x06 | anymotion: yes / Not INT1 pin: yes / INT2 pin: no + * 0x07 | anymotion: yes / Not INT1 pin: yes / INT2 pin: yes + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_sleep_trigger( +u8 *v_gyro_sleep_trigger_u8); +/*! + * @brief This API write gyro sleep trigger + * from the register 0x6C bit 0 to 2 + * + * @param v_gyro_sleep_trigger_u8 : The value of gyro sleep trigger + * Value | Description + * --------|------------- + * 0x00 | nomotion: no / Not INT1 pin: no / INT2 pin: no + * 0x01 | nomotion: no / Not INT1 pin: no / INT2 pin: yes + * 0x02 | nomotion: no / Not INT1 pin: yes / INT2 pin: no + * 0x03 | nomotion: no / Not INT1 pin: yes / INT2 pin: yes + * 0x04 | nomotion: yes / Not INT1 pin: no / INT2 pin: no + * 0x05 | anymotion: yes / Not INT1 pin: no / INT2 pin: yes + * 0x06 | anymotion: yes / Not INT1 pin: yes / INT2 pin: no + * 0x07 | anymotion: yes / Not INT1 pin: yes / INT2 pin: yes + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_sleep_trigger( +u8 v_gyro_sleep_trigger_u8); +/*! + * @brief This API read gyro wakeup trigger + * from the register 0x6C bit 3 and 4 + * + * @param v_gyro_wakeup_trigger_u8 : The value of gyro wakeup trigger + * Value | Description + * --------|------------- + * 0x00 | anymotion: no / INT1 pin: no + * 0x01 | anymotion: no / INT1 pin: yes + * 0x02 | anymotion: yes / INT1 pin: no + * 0x03 | anymotion: yes / INT1 pin: yes + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_wakeup_trigger( +u8 *v_gyro_wakeup_trigger_u8); +/*! + * @brief This API write gyro wakeup trigger + * from the register 0x6C bit 3 and 4 + * + * @param v_gyro_wakeup_trigger_u8 : The value of gyro wakeup trigger + * Value | Description + * --------|------------- + * 0x00 | anymotion: no / INT1 pin: no + * 0x01 | anymotion: no / INT1 pin: yes + * 0x02 | anymotion: yes / INT1 pin: no + * 0x03 | anymotion: yes / INT1 pin: yes + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_wakeup_trigger( +u8 v_gyro_wakeup_trigger_u8); +/*! + * @brief This API read Target state for gyro sleep mode + * from the register 0x6C bit 5 + * + * @param v_gyro_sleep_state_u8 : The value of gyro sleep mode + * Value | Description + * --------|------------- + * 0x00 | Sleep transition to fast wake up state + * 0x01 | Sleep transition to suspend state + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_sleep_state( +u8 *v_gyro_sleep_state_u8); +/*! + * @brief This API write Target state for gyro sleep mode + * from the register 0x6C bit 5 + * + * @param v_gyro_sleep_state_u8 : The value of gyro sleep mode + * Value | Description + * --------|------------- + * 0x00 | Sleep transition to fast wake up state + * 0x01 | Sleep transition to suspend state + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_sleep_state( +u8 v_gyro_sleep_state_u8); +/*! + * @brief This API read gyro wakeup interrupt + * from the register 0x6C bit 6 + * + * @param v_gyro_wakeup_intr_u8 : The valeu of gyro wakeup interrupt + * Value | Description + * --------|------------- + * 0x00 | DISABLE + * 0x01 | ENABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_wakeup_intr( +u8 *v_gyro_wakeup_intr_u8); +/*! + * @brief This API write gyro wakeup interrupt + * from the register 0x6C bit 6 + * + * @param v_gyro_wakeup_intr_u8 : The valeu of gyro wakeup interrupt + * Value | Description + * --------|------------- + * 0x00 | DISABLE + * 0x01 | ENABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_wakeup_intr( +u8 v_gyro_wakeup_intr_u8); +/***************************************************/ +/**\name FUNCTION FOR ACCEL SELF TEST */ +/***************************************************/ +/*! + * @brief This API read accel select axis to be self-test + * + * @param v_accel_selftest_axis_u8 : + * The value of accel self test axis selection + * Value | Description + * --------|------------- + * 0x00 | disabled + * 0x01 | x-axis + * 0x02 | y-axis + * 0x03 | z-axis + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_selftest_axis( +u8 *acc_selftest_axis); +/*! + * @brief This API write accel select axis to be self-test + * + * @param v_accel_selftest_axis_u8 : + * The value of accel self test axis selection + * Value | Description + * --------|------------- + * 0x00 | disabled + * 0x01 | x-axis + * 0x02 | y-axis + * 0x03 | z-axis + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_selftest_axis( +u8 acc_selftest_axis); +/*! + * @brief This API read accel self test axis sign + * from the register 0x6D bit 2 + * + * @param v_accel_selftest_sign_u8: The value of accel self test axis sign + * Value | Description + * --------|------------- + * 0x00 | negative + * 0x01 | positive + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_selftest_sign( +u8 *acc_selftest_sign); +/*! + * @brief This API write accel self test axis sign + * from the register 0x6D bit 2 + * + * @param v_accel_selftest_sign_u8: The value of accel self test axis sign + * Value | Description + * --------|------------- + * 0x00 | negative + * 0x01 | positive + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_selftest_sign( +u8 acc_selftest_sign); +/*! + * @brief This API read accel self test amplitude + * from the register 0x6D bit 3 + * select amplitude of the selftest deflection: + * + * @param v_accel_selftest_amp_u8 : The value of accel self test amplitude + * Value | Description + * --------|------------- + * 0x00 | LOW + * 0x01 | HIGH + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_selftest_amp( +u8 *acc_selftest_amp); +/*! + * @brief This API write accel self test amplitude + * from the register 0x6D bit 3 + * select amplitude of the selftest deflection: + * + * @param v_accel_selftest_amp_u8 : The value of accel self test amplitude + * Value | Description + * --------|------------- + * 0x00 | LOW + * 0x01 | HIGH + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_selftest_amp( +u8 acc_selftest_amp); +/***************************************************/ +/**\name FUNCTION FOR GYRO SELF TEST */ +/***************************************************/ +/*! + * @brief This API read gyro self test trigger + * + * @param v_gyro_selftest_start_u8: The value of gyro self test start + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_selftest_start( +u8 *v_gyro_selftest_start_u8); +/*! + * @brief This API write gyro self test trigger + * + * @param v_gyro_selftest_start_u8: The value of gyro self test start + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_selftest_start( +u8 v_gyro_selftest_start_u8); +/***************************************************/ +/**\name FUNCTION FOR SPI/I2C ENABLE */ +/***************************************************/ + /*! + * @brief This API read primary interface selection I2C or SPI + * from the register 0x70 bit 0 + * + * @param v_spi_enable_u8: The value of Interface selection + * Value | Description + * --------|------------- + * 0x00 | I2C Enable + * 0x01 | I2C DISBALE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_spi_enable( +u8 *v_spi_enable_u8); + /*! + * @brief This API write primary interface selection I2C or SPI + * from the register 0x70 bit 0 + * + * @param v_spi_enable_u8: The value of Interface selection + * Value | Description + * --------|------------- + * 0x00 | I2C Enable + * 0x01 | I2C DISBALE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_spi_enable( +u8 v_spi_enable_u8); + /*! + * @brief This API read the spare zero + * form register 0x70 bit 3 + * + * + * @param v_spare0_trim_u8: The value of spare zero + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_spare0_trim +(u8 *v_spare0_trim_u8); + /*! + * @brief This API write the spare zero + * form register 0x70 bit 3 + * + * + * @param v_spare0_trim_u8: The value of spare zero + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_spare0_trim +(u8 v_spare0_trim_u8); +/***************************************************/ +/**\name FUNCTION FOR NVM COUNTER */ +/***************************************************/ + /*! + * @brief This API read the NVM counter + * form register 0x70 bit 4 to 7 + * + * + * @param v_nvm_counter_u8: The value of NVM counter + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_nvm_counter( +u8 *v_nvm_counter_u8); + /*! + * @brief This API write the NVM counter + * form register 0x70 bit 4 to 7 + * + * + * @param v_nvm_counter_u8: The value of NVM counter + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_nvm_counter( +u8 v_nvm_counter_u8); +/***************************************************/ +/**\name FUNCTION FOR ACCEL MANUAL OFFSET COMPENSATION */ +/***************************************************/ +/*! + * @brief This API read accel manual offset compensation of x axis + * from the register 0x71 bit 0 to 7 + * + * + * + * @param v_accel_off_x_s8: + * The value of accel manual offset compensation of x axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_offset_compensation_xaxis( +s8 *v_accel_off_x_s8); +/*! + * @brief This API write accel manual offset compensation of x axis + * from the register 0x71 bit 0 to 7 + * + * + * + * @param v_accel_off_x_s8: + * The value of accel manual offset compensation of x axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_offset_compensation_xaxis( +s8 v_accel_off_x_s8); +/*! + * @brief This API read accel manual offset compensation of y axis + * from the register 0x72 bit 0 to 7 + * + * + * + * @param v_accel_off_y_s8: + * The value of accel manual offset compensation of y axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_offset_compensation_yaxis( +s8 *v_accel_off_y_s8); +/*! + * @brief This API write accel manual offset compensation of y axis + * from the register 0x72 bit 0 to 7 + * + * + * + * @param v_accel_off_y_s8: + * The value of accel manual offset compensation of y axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_offset_compensation_yaxis( +s8 v_accel_off_y_s8); +/*! + * @brief This API read accel manual offset compensation of z axis + * from the register 0x73 bit 0 to 7 + * + * + * + * @param v_accel_off_z_s8: + * The value of accel manual offset compensation of z axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_offset_compensation_zaxis( +s8 *v_accel_off_z_s8); +/*! + * @brief This API write accel manual offset compensation of z axis + * from the register 0x73 bit 0 to 7 + * + * + * + * @param v_accel_off_z_s8: + * The value of accel manual offset compensation of z axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_offset_compensation_zaxis( +s8 v_accel_off_z_s8); +/***************************************************/ +/**\name FUNCTION FOR GYRO MANUAL OFFSET COMPENSATION */ +/***************************************************/ +/*! + * @brief This API read gyro manual offset compensation of x axis + * from the register 0x74 bit 0 to 7 and 0x77 bit 0 and 1 + * + * + * + * @param v_gyro_off_x_s16: + * The value of gyro manual offset compensation of x axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_offset_compensation_xaxis( +s16 *v_gyro_off_x_s16); +/*! + * @brief This API write gyro manual offset compensation of x axis + * from the register 0x74 bit 0 to 7 and 0x77 bit 0 and 1 + * + * + * + * @param v_gyro_off_x_s16: + * The value of gyro manual offset compensation of x axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_offset_compensation_xaxis( +s16 v_gyro_off_x_s16); +/*! + * @brief This API read gyro manual offset compensation of y axis + * from the register 0x75 bit 0 to 7 and 0x77 bit 2 and 3 + * + * + * + * @param v_gyro_off_y_s16: + * The value of gyro manual offset compensation of y axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_offset_compensation_yaxis( +s16 *v_gyro_off_y_s16); +/*! + * @brief This API write gyro manual offset compensation of y axis + * from the register 0x75 bit 0 to 7 and 0x77 bit 2 and 3 + * + * + * + * @param v_gyro_off_y_s16: + * The value of gyro manual offset compensation of y axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_offset_compensation_yaxis( +s16 v_gyro_off_y_s16); +/*! + * @brief This API read gyro manual offset compensation of z axis + * from the register 0x76 bit 0 to 7 and 0x77 bit 4 and 5 + * + * + * + * @param v_gyro_off_z_s16: + * The value of gyro manual offset compensation of z axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_offset_compensation_zaxis( +s16 *v_gyro_off_z_s16); +/*! + * @brief This API write gyro manual offset compensation of z axis + * from the register 0x76 bit 0 to 7 and 0x77 bit 4 and 5 + * + * + * + * @param v_gyro_off_z_s16: + * The value of gyro manual offset compensation of z axis + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_offset_compensation_zaxis( +s16 v_gyro_off_z_s16); +/*! + * @brief This API writes accel fast offset compensation + * from the register 0x69 bit 0 to 5 + * @brief This API writes each axis individually + * FOC_X_AXIS - bit 4 and 5 + * FOC_Y_AXIS - bit 2 and 3 + * FOC_Z_AXIS - bit 0 and 1 + * + * @param v_foc_accel_u8: The value of accel offset compensation + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x01 | -1g + * 0x01 | 0g + * + * @param v_axis_u8: The value of accel offset axis selection + * value | axis + * ----------|------------------- + * 0 | FOC_X_AXIS + * 1 | FOC_Y_AXIS + * 2 | FOC_Z_AXIS + * + * @param v_accel_offset_s8: The accel offset value + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_foc_trigger(u8 axis, +u8 foc_acc, s8 *accel_offset); +/*! + * @brief This API write fast accel offset compensation + * it writes all axis together.To the register 0x69 bit 0 to 5 + * FOC_X_AXIS - bit 4 and 5 + * FOC_Y_AXIS - bit 2 and 3 + * FOC_Z_AXIS - bit 0 and 1 + * + * @param v_foc_accel_x_u8: The value of accel offset x compensation + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x01 | -1g + * 0x01 | 0g + * + * @param v_foc_accel_y_u8: The value of accel offset y compensation + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x01 | -1g + * 0x01 | 0g + * + * @param v_foc_accel_z_u8: The value of accel offset z compensation + * value | Behaviour + * ----------|------------------- + * 0x00 | disable + * 0x01 | +1g + * 0x01 | -1g + * 0x01 | 0g + * + * @param v_accel_off_x_s8: The value of accel offset x axis + * @param v_accel_off_y_s8: The value of accel offset y axis + * @param v_accel_off_z_s8: The value of accel offset z axis + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_accel_foc_trigger_xyz(u8 v_foc_accel_x_u8, +u8 v_foc_accel_y_u8, u8 v_foc_accel_z_u8, +s8 *acc_off_x, s8 *acc_off_y, s8 *acc_off_z); +/***************************************************/ +/**\name FUNCTION FOR ACEL AND GYRO OFFSET ENABLE */ +/***************************************************/ +/*! + * @brief This API read the accel offset enable bit + * from the register 0x77 bit 6 + * + * + * + * @param v_accel_off_enable_u8: The value of accel offset enable + * value | Description + * ----------|-------------- + * 0x01 | ENABLE + * 0x00 | DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_offset_enable( +u8 *acc_off_en); +/*! + * @brief This API write the accel offset enable bit + * from the register 0x77 bit 6 + * + * + * + * @param v_accel_off_enable_u8: The value of accel offset enable + * value | Description + * ----------|-------------- + * 0x01 | ENABLE + * 0x00 | DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_offset_enable( +u8 acc_off_en); +/*! + * @brief This API read the accel offset enable bit + * from the register 0x77 bit 7 + * + * + * + * @param v_gyro_off_enable_u8: The value of gyro offset enable + * value | Description + * ----------|-------------- + * 0x01 | ENABLE + * 0x00 | DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_offset_enable( +u8 *v_gyro_off_enable_u8); +/*! + * @brief This API write the accel offset enable bit + * from the register 0x77 bit 7 + * + * + * + * @param v_gyro_off_enable_u8: The value of gyro offset enable + * value | Description + * ----------|-------------- + * 0x01 | ENABLE + * 0x00 | DISABLE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_offset_enable( +u8 v_gyro_off_enable_u8); +/***************************************************/ +/**\name FUNCTION FOR STEP COUNTER INTERRUPT */ +/***************************************************/ +/*! + * @brief This API reads step counter value + * form the register 0x78 and 0x79 + * + * + * + * + * @param v_step_cnt_s16 : The value of step counter + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_step_count(s16 *v_step_cnt_s16); + /*! + * @brief This API Reads + * step counter configuration + * from the register 0x7A bit 0 to 7 + * and from the register 0x7B bit 0 to 2 and 4 to 7 + * + * + * @param v_step_config_u16 : The value of step configuration + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_step_config( +u16 *v_step_config_u16); + /*! + * @brief This API write + * step counter configuration + * from the register 0x7A bit 0 to 7 + * and from the register 0x7B bit 0 to 2 and 4 to 7 + * + * + * @param v_step_config_u16 : + * the value of Enable step configuration + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_step_config( +u16 v_step_config_u16); + /*! + * @brief This API read enable step counter + * from the register 0x7B bit 3 + * + * + * @param v_step_counter_u8 : The value of step counter enable + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_step_counter_enable( +u8 *v_step_counter_u8); + /*! + * @brief This API write enable step counter + * from the register 0x7B bit 3 + * + * + * @param v_step_counter_u8 : The value of step counter enable + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_step_counter_enable( +u8 v_step_counter_u8); + /*! + * @brief This API set Step counter modes + * + * + * @param v_step_mode_u8 : The value of step counter mode + * value | mode + * ----------|----------- + * 0 | BMI160_STEP_NORMAL_MODE + * 1 | BMI160_STEP_SENSITIVE_MODE + * 2 | BMI160_STEP_ROBUST_MODE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_step_mode(u8 v_step_mode_u8); +/*! + * @brief This API used to trigger the signification motion + * interrupt + * + * + * @param v_significant_u8 : The value of interrupt selection + * value | interrupt + * ----------|----------- + * 0 | BMI160_MAP_INTR1 + * 1 | BMI160_MAP_INTR2 + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_map_significant_motion_intr( +u8 v_significant_u8); +/*! + * @brief This API used to trigger the step detector + * interrupt + * + * + * @param v_step_detector_u8 : The value of interrupt selection + * value | interrupt + * ----------|----------- + * 0 | BMI160_MAP_INTR1 + * 1 | BMI160_MAP_INTR2 + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_map_step_detector_intr( +u8 v_step_detector_u8); + /*! + * @brief This API used to clear the step counter interrupt + * interrupt + * + * + * @param : None + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_clear_step_counter(void); +/***************************************************/ +/**\name FUNCTION FOR STEP COMMAND REGISTER WRITE */ +/***************************************************/ + /*! + * @brief This API writes value to the register 0x7E bit 0 to 7 + * + * + * @param v_command_reg_u8 : The value to write command register + * value | Description + * ---------|-------------------------------------------------------- + * 0x00 | Reserved + * 0x03 | Starts fast offset calibration for the accel and gyro + * 0x10 | Sets the PMU mode for the Accelerometer to suspend + * 0x11 | Sets the PMU mode for the Accelerometer to normal + * 0x12 | Sets the PMU mode for the Accelerometer Lowpower + * 0x14 | Sets the PMU mode for the Gyroscope to suspend + * 0x15 | Sets the PMU mode for the Gyroscope to normal + * 0x16 | Reserved + * 0x17 | Sets the PMU mode for the Gyroscope to fast start-up + * 0x18 | Sets the PMU mode for the Magnetometer to suspend + * 0x19 | Sets the PMU mode for the Magnetometer to normal + * 0x1A | Sets the PMU mode for the Magnetometer to Lowpower + * 0xB0 | Clears all data in the FIFO + * 0xB1 | Resets the interrupt engine + * 0xB2 | step_cnt_clr Clears the step counter + * 0xB6 | Triggers a reset + * 0x37 | See extmode_en_last + * 0x9A | See extmode_en_last + * 0xC0 | Enable the extended mode + * 0xC4 | Erase NVM cell + * 0xC8 | Load NVM cell + * 0xF0 | Reset acceleration data path + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_command_register( +u8 v_command_reg_u8); +/***************************************************/ +/**\name FUNCTION FOR PAGE ENABLE */ +/***************************************************/ + /*! + * @brief This API read target page from the register 0x7F bit 4 and 5 + * + * @param v_target_page_u8: The value of target page + * value | page + * ---------|----------- + * 0 | User data/configure page + * 1 | Chip level trim/test page + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_target_page( +u8 *v_target_page_u8); + /*! + * @brief This API write target page from the register 0x7F bit 4 and 5 + * + * @param v_target_page_u8: The value of target page + * value | page + * ---------|----------- + * 0 | User data/configure page + * 1 | Chip level trim/test page + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_target_page( +u8 v_target_page_u8); + /*! + * @brief This API read page enable from the register 0x7F bit 7 + * + * + * + * @param v_page_enable_u8: The value of page enable + * value | page + * ---------|----------- + * 0 | DISABLE + * 1 | ENABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_paging_enable( +u8 *v_page_enable_u8); + /*! + * @brief This API write page enable from the register 0x7F bit 7 + * + * + * + * @param v_page_enable_u8: The value of page enable + * value | page + * ---------|----------- + * 0 | DISABLE + * 1 | ENABLE + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_paging_enable( +u8 v_page_enable_u8); + /*! + * @brief This API read + * pull up configuration from the register 0X85 bit 4 an 5 + * + * + * + * @param v_control_pullup_u8: The value of pull up register + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_get_pullup_configuration( +u8 *v_control_pullup_u8); + /*! + * @brief This API write + * pull up configuration from the register 0X85 bit 4 an 5 + * + * + * + * @param v_control_pullup_u8: The value of pull up register + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_pullup_configuration( +u8 v_control_pullup_u8); +/***************************************************/ +/**\name FUNCTION FOR BMM150 */ +/***************************************************/ + /*! + * @brief This function used for initialize the bmm150 sensor + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_interface_init(void); + /*! + * @brief This function used for set the mag power control + * bit enable + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_wakeup(void); + /*! + * @brief This function used for read the trim values of magnetometer + * + * @note + * Before reading the mag trimming values + * make sure the following two points are addressed + * @note + * 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note + * 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_bmm150_mag_trim(void); + /*! + * @brief This function used for read the compensated value of mag + * Before start reading the mag compensated data's + * make sure the following two points are addressed + * @note + * 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note + * 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_compensate_xyz( +struct bmi160_mag_xyz_s32_t *mag_comp_xyz); +BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_compensate_xyz_raw( +struct bmi160_mag_xyz_s32_t *mag_comp_xyz, struct bmi160_mag_xyzr_t mag_xyzr); + +/*! + * @brief This API used to get the compensated BMM150-X data + * the out put of X as s32 + * Before start reading the mag compensated X data + * make sure the following two points are addressed + * @note + * 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note + * 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * + * @param v_mag_data_x_s16 : The value of mag raw X data + * @param v_data_r_u16 : The value of mag R data + * + * @return results of compensated X data value output as s32 + * + */ +s32 bmi160_bmm150_mag_compensate_X(s16 v_mag_data_x_s16, u16 v_data_r_u16); +/*! + * @brief This API used to get the compensated BMM150-Y data + * the out put of Y as s32 + * Before start reading the mag compensated Y data + * make sure the following two points are addressed + * @note + * 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note + * 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * + * @param v_mag_data_y_s16 : The value of mag raw Y data + * @param v_data_r_u16 : The value of mag R data + * + * @return results of compensated Y data value output as s32 + */ +s32 bmi160_bmm150_mag_compensate_Y(s16 v_mag_data_y_s16, u16 v_data_r_u16); +/*! + * @brief This API used to get the compensated BMM150-Z data + * the out put of Z as s32 + * Before start reading the mag compensated Z data + * make sure the following two points are addressed + * @note + * 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note + * 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * + * @param v_mag_data_z_s16 : The value of mag raw Z data + * @param v_data_r_u16 : The value of mag R data + * + * @return results of compensated Z data value output as s32 + */ +s32 bmi160_bmm150_mag_compensate_Z(s16 v_mag_data_z_s16, u16 v_data_r_u16); +/*! + * @brief This API used to set the pre-set modes of bmm150 + * The pre-set mode setting is depend on data rate and xy and z repetitions + * + * @note + * Before set the mag preset mode + * make sure the following two points are addressed + * @note + * 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note + * 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * @param v_mode_u8: The value of pre-set mode selection value + * value | pre_set mode + * ----------|------------ + * 1 | BMI160_MAG_PRESETMODE_LOWPOWER + * 2 | BMI160_MAG_PRESETMODE_REGULAR + * 3 | BMI160_MAG_PRESETMODE_HIGHACCURACY + * 4 | BMI160_MAG_PRESETMODE_ENHANCED + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_bmm150_mag_presetmode(u8 mode); +/*! + * @brief This function used for set the magnetometer + * power mode. + * @note + * Before set the mag power mode + * make sure the following two points are addressed + * @note + * 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note + * 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * @param v_mag_pow_mode_u8 : The value of mag power mode + * value | mode + * ----------|------------ + * 0 | FORCE_MODE + * 1 | SUSPEND_MODE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_set_power_mode(u8 mag_pow_mode); + /*! + * @brief This function used for set the magnetometer + * power mode. + * @note + * Before set the mag power mode + * make sure the following two point is addressed + * Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * + * @param v_mag_sec_if_pow_mode_u8 : The value of mag power mode + * value | mode + * ----------|------------ + * 0 | BMI160_MAG_FORCE_MODE + * 1 | BMI160_MAG_SUSPEND_MODE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_bmm150_mag_and_secondary_if_power_mode( +u8 v_mag_sec_if_pow_mode_u8); +/***************************************************/ +/**\name FUNCTIONS FOR AKM09911 AND AKM09912*/ +/***************************************************/ + /*! + * @brief This function used for initialize + * the AKM09911 and AKM09912 sensor + * + * + * @param v_akm_i2c_address_u8: The value of device address + * AKM sensor | Slave address + * --------------|--------------------- + * AKM09911 | AKM09911_I2C_ADDR_1 + * - | and AKM09911_I2C_ADDR_2 + * AKM09912 | AKM09912_I2C_ADDR_1 + * - | AKM09912_I2C_ADDR_2 + * - | AKM09912_I2C_ADDR_3 + * - | AKM09912_I2C_ADDR_4 + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm_mag_interface_init( +u8 v_akm_i2c_address_u8); + /*! + * @brief This function used for read the sensitivity data of + * AKM09911 and AKM09912 + * + * @note Before reading the mag sensitivity values + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_bst_akm_sensitivity_data(void); +/*! + * @brief This API used to get the compensated X data + * of AKM09911 the out put of X as s32 + * @note Before start reading the mag compensated X data + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * @param v_bst_akm_x_s16 : The value of X data + * + * @return results of compensated X data value output as s32 + * + */ +s32 bmi160_bst_akm09911_compensate_X(s16 v_bst_akm_x_s16); +/*! + * @brief This API used to get the compensated Y data + * of AKM09911 the out put of Y as s32 + * @note Before start reading the mag compensated Y data + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * @param v_bst_akm_y_s16 : The value of Y data + * + * @return results of compensated Y data value output as s32 + * + */ +s32 bmi160_bst_akm09911_compensate_Y(s16 v_bst_akm_y_s16); +/*! + * @brief This API used to get the compensated Z data + * of AKM09911 the out put of Z as s32 + * @note Before start reading the mag compensated Z data + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * @param v_bst_akm_z_s16 : The value of Z data + * + * @return results of compensated Z data value output as s32 + * + */ +s32 bmi160_bst_akm09911_compensate_Z(s16 v_bst_akm_z_s16); +/*! + * @brief This API used to get the compensated X data + * of AKM09912 the out put of X as s32 + * @note Before start reading the mag compensated X data + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * @param v_bst_akm_x_s16 : The value of X data + * + * @return results of compensated X data value output as s32 + * + */ +s32 bmi160_bst_akm09912_compensate_X(s16 v_bst_akm_x_s16); +/*! + * @brief This API used to get the compensated Y data + * of AKM09912 the out put of Y as s32 + * @note Before start reading the mag compensated Y data + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * @param v_bst_akm_y_s16 : The value of Y data + * + * @return results of compensated Y data value output as s32 + * + */ +s32 bmi160_bst_akm09912_compensate_Y(s16 v_bst_akm_y_s16); +/*! + * @brief This API used to get the compensated Z data + * of AKM09912 the out put of Z as s32 + * @note Before start reading the mag compensated Z data + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * + * @param v_bst_akm_z_s16 : The value of Z data + * + * @return results of compensated Z data value output as s32 + * + */ +s32 bmi160_bst_akm09912_compensate_Z(s16 v_bst_akm_z_s16); + /*! + * @brief This function used for read the compensated value of + * AKM09911 + * @note Before start reading the mag compensated data's + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm09911_compensate_xyz( +struct bmi160_mag_xyz_s32_t *bst_akm_xyz); + /*! + * @brief This function used for read the compensated value of + * AKM09912 + * @note Before start reading the mag compensated data's + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm09912_compensate_xyz( +struct bmi160_mag_xyz_s32_t *bst_akm_xyz); +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm09912_compensate_xyz_raw( +struct bmi160_mag_xyz_s32_t *bst_akm_xyz); +/*! + * @brief This function used for set the AKM09911 and AKM09912 + * power mode. + * @note Before set the AKM power mode + * make sure the following two points are addressed + * @note 1. Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * @note 2. And also confirm the secondary-interface power mode + * is not in the SUSPEND mode. + * by using the function bmi160_get_mag_pmu_status(). + * If the secondary-interface power mode is in SUSPEND mode + * set the value of 0x19(NORMAL mode)by using the + * bmi160_set_command_register(0x19) function. + * + * @param v_akm_pow_mode_u8 : The value of akm power mode + * value | Description + * ---------|-------------------- + * 0 | AKM_POWER_DOWN_MODE + * 1 | AKM_SINGLE_MEAS_MODE + * 2 | FUSE_ROM_MODE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm_set_powermode(u8 v_akm_pow_mode_u8); + /*! + * @brief This function used for set the magnetometer + * power mode of AKM09911 and AKM09912 + * @note Before set the mag power mode + * make sure the following two point is addressed + * Make sure the mag interface is enabled or not, + * by using the bmi160_get_if_mode() function. + * If mag interface is not enabled set the value of 0x02 + * to the function bmi160_get_if_mode(0x02) + * + * @param v_mag_sec_if_pow_mode_u8 : The value of secondary if power mode + * value | Description + * ---------|-------------------- + * 0 | BMI160_MAG_FORCE_MODE + * 1 | BMI160_MAG_SUSPEND_MODE + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_set_bst_akm_and_secondary_if_powermode( +u8 v_mag_sec_if_pow_mode_u8); +/***************************************************/ +/**\name FUNCTIONS FOR YAMAH-YAS532 */ +/***************************************************/ +/*! + * @brief This function used for read the YAMAH-YAS532 init + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas532_mag_interface_init( +void); +/*! + * @brief This function used to set the YAS532 initial values + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_set_initial_values(void); +/*! + * @brief This function used for YAS532 offset correction + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_magnetic_measure_set_offset( +void); +/*! + * @brief This function used for read the + * YAMAHA YAS532 calibration data + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas532_calib_values(void); +/*! + * @brief This function used for calculate the + * YAS532 read the linear data + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_xy1y2_to_linear( +u16 *v_xy1y2_u16, s32 *xy1y2_linear); +/*! + * @brief This function used for read the YAS532 sensor data + * @param v_acquisition_command_u8: used to set the data acquisition + * acquisition_command | operation + * ---------------------|------------------------- + * 0x17 | turn on the acquisition coil + * - | set direction of the coil + * _ | (x and y as minus(-)) + * _ | Deferred acquisition mode + * 0x07 | turn on the acquisition coil + * _ | set direction of the coil + * _ | (x and y as minus(-)) + * _ | Normal acquisition mode + * 0x11 | turn OFF the acquisition coil + * _ | set direction of the coil + * _ | (x and y as plus(+)) + * _ | Deferred acquisition mode + * 0x01 | turn OFF the acquisition coil + * _ | set direction of the coil + * _ | (x and y as plus(+)) + * _ | Normal acquisition mode + * + * @param v_busy_u8 : used to get the busy flay for sensor data read + * @param v_temp_u16 : used to get the temperature data + * @param v_xy1y2_u16 : used to get the sensor xy1y2 data + * @param v_overflow_u8 : used to get the overflow data + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_normal_measurement_data( +u8 v_acquisition_command_u8, u8 *v_busy_u8, +u16 *v_temp_u16, u16 *v_xy1y2_u16, u8 *v_overflow_u8); +/*! + * @brief This function used for YAS532 sensor data + * @param v_acquisition_command_u8 : the value of CMDR + * acquisition_command | operation + * ---------------------|------------------------- + * 0x17 | turn on the acquisition coil + * - | set direction of the coil + * _ | (x and y as minus(-)) + * _ | Deferred acquisition mode + * 0x07 | turn on the acquisition coil + * _ | set direction of the coil + * _ | (x and y as minus(-)) + * _ | Normal acquisition mode + * 0x11 | turn OFF the acquisition coil + * _ | set direction of the coil + * _ | (x and y as plus(+)) + * _ | Deferred acquisition mode + * 0x01 | turn OFF the acquisition coil + * _ | set direction of the coil + * _ | (x and y as plus(+)) + * _ | Normal acquisition mode + * + * @param xyz_data : the vector xyz output + * @param v_overflow_s8 : the value of overflow + * @param v_temp_correction_u8 : the value of temperate correction enable + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_measurement_xyz_data( +struct yas532_vector *xyz_data, u8 *v_overflow_s8, u8 v_temp_correction_u8, +u8 v_acquisition_command_u8); +/*! + * @brief This function used for YAS532 write data acquisition + * command register write + * @param v_command_reg_data_u8 : the value of data acquisition + * acquisition_command | operation + * ---------------------|------------------------- + * 0x17 | turn on the acquisition coil + * - | set direction of the coil + * _ | (x and y as minus(-)) + * _ | Deferred acquisition mode + * 0x07 | turn on the acquisition coil + * _ | set direction of the coil + * _ | (x and y as minus(-)) + * _ | Normal acquisition mode + * 0x11 | turn OFF the acquisition coil + * _ | set direction of the coil + * _ | (x and y as plus(+)) + * _ | Deferred acquisition mode + * 0x01 | turn OFF the acquisition coil + * _ | set direction of the coil + * _ | (x and y as plus(+)) + * _ | Normal acquisition mode + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_acquisition_command_register( +u8 v_command_reg_data_u8); +/*! + * @brief This function used write offset of YAS532 + * + * @param p_offset_s8 : The value of offset to write + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_set_offset( +const s8 *p_offset_s8); +/*! + * @brief This function used to init the YAMAH-YAS537 + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas537_mag_interface_init( +void); +/*! + * @brief This function used for read the + * YAMAHA YAS537 calibration data + * + * + * @param v_rcoil_u8 : The value of r coil + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas537_calib_values( +u8 v_rcoil_u8); +/*! + * @brief This function used for YAS537 write data acquisition + * command register write + * @param v_command_reg_data_u8 : the value of data acquisition + * acquisition_command | operation + * ---------------------|------------------------- + * 0x17 | turn on the acquisition coil + * - | set direction of the coil + * _ | (x and y as minus(-)) + * _ | Deferred acquisition mode + * 0x07 | turn on the acquisition coil + * _ | set direction of the coil + * _ | (x and y as minus(-)) + * _ | Normal acquisition mode + * 0x11 | turn OFF the acquisition coil + * _ | set direction of the coil + * _ | (x and y as plus(+)) + * _ | Deferred acquisition mode + * 0x01 | turn OFF the acquisition coil + * _ | set direction of the coil + * _ | (x and y as plus(+)) + * _ | Normal acquisition mode + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas537_acquisition_command_register( +u8 v_command_reg_data_u8); + +/*! + * @brief This function used for read the + * YAMAHA YAS537 xy1y2 data + * + * @param v_coil_stat_u8: The value of R coil status + * @param v_busy_u8: The value of busy status + * @param v_temperature_u16: The value of temperature + * @param xy1y2: The value of raw xy1y2 data + * @param v_ouflow_u8: The value of overflow + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas537_read_xy1y2_data( +u8 *v_coil_stat_u8, u8 *v_busy_u8, +u16 *v_temperature_u16, u16 *xy1y2, u8 *v_ouflow_u8); +/*! + * @brief This function used for read the + * YAMAHA YAS537 xy1y2 data + * + * @param v_ouflow_u8: The value of overflow + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas537_measure_xyz_data( +u8 *v_ouflow_u8, struct yas_vector *vector_xyz); + +/***************************************************/ +/**\name FUNCTIONS FOR FIFO DATA READ */ +/***************************************************/ +/*! + * @brief This function used for reading the + * fifo data of header less mode + * + * + * + * @note Configure the below functions for FIFO header less mode + * @note 1. bmi160_set_fifo_down_gyro + * @note 2. bmi160_set_gyro_fifo_filter_data + * @note 3. bmi160_set_fifo_down_accel + * @note 4. bmi160_set_accel_fifo_filter_dat + * @note 5. bmi160_set_fifo_mag_enable + * @note 6. bmi160_set_fifo_accel_enable + * @note 7. bmi160_set_fifo_gyro_enable + * @note For interrupt configuration + * @note 1. bmi160_set_intr_fifo_full + * @note 2. bmi160_set_intr_fifo_wm + * @note 3. bmi160_set_fifo_tag_intr2_enable + * @note 4. bmi160_set_fifo_tag_intr1_enable + * + * @note The fifo reads the whole 1024 bytes + * and processing the data + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_fifo_headerless_mode( +void); +/*! + * @brief This function used for reading the + * fifo data of header less mode for using user defined length + * + * + * @param v_fifo_user_length_u16: The value of length of fifo read data + * + * @note Configure the below functions for FIFO header less mode + * @note 1. bmi160_set_fifo_down_gyro + * @note 2. bmi160_set_gyro_fifo_filter_data + * @note 3. bmi160_set_fifo_down_accel + * @note 4. bmi160_set_accel_fifo_filter_dat + * @note 5. bmi160_set_fifo_mag_enable + * @note 6. bmi160_set_fifo_accel_enable + * @note 7. bmi160_set_fifo_gyro_enable + * @note For interrupt configuration + * @note 1. bmi160_set_intr_fifo_full + * @note 2. bmi160_set_intr_fifo_wm + * @note 3. bmi160_set_fifo_tag_intr2_enable + * @note 4. bmi160_set_fifo_tag_intr1_enable + * + * @note The fifo reads the whole 1024 bytes + * and processing the data + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE +bmi160_read_fifo_headerless_mode_user_defined_length( +u16 v_fifo_user_length_u16); +/*! + * @brief This function used for reading the + * fifo data of header mode + * + * + * @note Configure the below functions for FIFO header mode + * @note 1. bmi160_set_fifo_down_gyro() + * @note 2. bmi160_set_gyro_fifo_filter_data() + * @note 3. bmi160_set_fifo_down_accel() + * @note 4. bmi160_set_accel_fifo_filter_dat() + * @note 5. bmi160_set_fifo_mag_enable() + * @note 6. bmi160_set_fifo_accel_enable() + * @note 7. bmi160_set_fifo_gyro_enable() + * @note 8. bmi160_set_fifo_header_enable() + * @note For interrupt configuration + * @note 1. bmi160_set_intr_fifo_full() + * @note 2. bmi160_set_intr_fifo_wm() + * @note 3. bmi160_set_fifo_tag_intr2_enable() + * @note 4. bmi160_set_fifo_tag_intr1_enable() + * + * @note The fifo reads the whole 1024 bytes + * and processing the data + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_fifo_header_data( +void); +/*! + * @brief This function used for reading the + * fifo data of header mode for using user defined length + * + * + * @note Configure the below functions for FIFO header mode + * @note 1. bmi160_set_fifo_down_gyro() + * @note 2. bmi160_set_gyro_fifo_filter_data() + * @note 3. bmi160_set_fifo_down_accel() + * @note 4. bmi160_set_accel_fifo_filter_dat() + * @note 5. bmi160_set_fifo_mag_enable() + * @note 6. bmi160_set_fifo_accel_enable() + * @note 7. bmi160_set_fifo_gyro_enable() + * @note 8. bmi160_set_fifo_header_enable() + * @note For interrupt configuration + * @note 1. bmi160_set_intr_fifo_full() + * @note 2. bmi160_set_intr_fifo_wm() + * @note 3. bmi160_set_fifo_tag_intr2_enable() + * @note 4. bmi160_set_fifo_tag_intr1_enable() + * + * @note The fifo reads the whole 1024 bytes + * and processing the data + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BMI160_RETURN_FUNCTION_TYPE bmi160_read_fifo_header_data_user_defined_length( +u16 v_fifo_user_length_u16); +/*! + * @brief This function used for reading + * bmi160_t structure + * + * @return the reference and values of bmi160_t + * + * +*/ +struct bmi160_t *bmi160_get_ptr(void); + +#endif + diff --git a/drivers/input/misc/bmi160_driver.c b/drivers/input/misc/bmi160_driver.c new file mode 100755 index 0000000000000..9152399cdc5b8 --- /dev/null +++ b/drivers/input/misc/bmi160_driver.c @@ -0,0 +1,4843 @@ +/*! + * @section LICENSE + * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved + * + * This software program is licensed subject to the GNU General + * Public License (GPL).Version 2,June 1991, + * available at http://www.fsf.org/copyleft/gpl.html + * + * @filename bmi160_driver.c + * @date 2015/08/17 14:40 + * @id "09afbe6" + * @version 1.4 + * + * @brief + * The core code of BMI160 device driver + * + * @detail + * This file implements the core code of BMI160 device driver, + * which includes hardware related functions, input device register, + * device attribute files, etc. +*/ + +#include "bmi160.h" +#include "bmi160_driver.h" +#include +#include +#include +#include + + +#define I2C_BURST_READ_MAX_LEN (256) +#define BMI160_STORE_COUNT (6000) +#define LMADA (1) +uint64_t g_current_apts_us; +static unsigned char g_fifo_data_arr[2048];/*1024 + 12*4*/ + +enum BMI_SENSOR_INT_T { + /* Interrupt enable0*/ + BMI_ANYMO_X_INT = 0, + BMI_ANYMO_Y_INT, + BMI_ANYMO_Z_INT, + BMI_D_TAP_INT, + BMI_S_TAP_INT, + BMI_ORIENT_INT, + BMI_FLAT_INT, + /* Interrupt enable1*/ + BMI_HIGH_X_INT, + BMI_HIGH_Y_INT, + BMI_HIGH_Z_INT, + BMI_LOW_INT, + BMI_DRDY_INT, + BMI_FFULL_INT, + BMI_FWM_INT, + /* Interrupt enable2 */ + BMI_NOMOTION_X_INT, + BMI_NOMOTION_Y_INT, + BMI_NOMOTION_Z_INT, + BMI_STEP_DETECTOR_INT, + INT_TYPE_MAX +}; + +/*bmi fifo sensor type combination*/ +enum BMI_SENSOR_FIFO_COMBINATION { + BMI_FIFO_A = 0, + BMI_FIFO_G, + BMI_FIFO_M, + BMI_FIFO_G_A, + BMI_FIFO_M_A, + BMI_FIFO_M_G, + BMI_FIFO_M_G_A, + BMI_FIFO_COM_MAX +}; + +/*bmi fifo analyse return err status*/ +enum BMI_FIFO_ANALYSE_RETURN_T { + FIFO_OVER_READ_RETURN = -10, + FIFO_SENSORTIME_RETURN = -9, + FIFO_SKIP_OVER_LEN = -8, + FIFO_M_G_A_OVER_LEN = -7, + FIFO_M_G_OVER_LEN = -6, + FIFO_M_A_OVER_LEN = -5, + FIFO_G_A_OVER_LEN = -4, + FIFO_M_OVER_LEN = -3, + FIFO_G_OVER_LEN = -2, + FIFO_A_OVER_LEN = -1 +}; + +/*!bmi sensor generic power mode enum */ +enum BMI_DEV_OP_MODE { + SENSOR_PM_NORMAL = 0, + SENSOR_PM_LP1, + SENSOR_PM_SUSPEND, + SENSOR_PM_LP2 +}; + +/*! bmi acc sensor power mode enum */ +enum BMI_ACC_PM_TYPE { + BMI_ACC_PM_NORMAL = 0, + BMI_ACC_PM_LP1, + BMI_ACC_PM_SUSPEND, + BMI_ACC_PM_LP2, + BMI_ACC_PM_MAX +}; + +/*! bmi gyro sensor power mode enum */ +enum BMI_GYRO_PM_TYPE { + BMI_GYRO_PM_NORMAL = 0, + BMI_GYRO_PM_FAST_START, + BMI_GYRO_PM_SUSPEND, + BMI_GYRO_PM_MAX +}; + +/*! bmi mag sensor power mode enum */ +enum BMI_MAG_PM_TYPE { + BMI_MAG_PM_NORMAL = 0, + BMI_MAG_PM_LP1, + BMI_MAG_PM_SUSPEND, + BMI_MAG_PM_LP2, + BMI_MAG_PM_MAX +}; + + +/*! bmi sensor support type*/ +enum BMI_SENSOR_TYPE { + BMI_ACC_SENSOR, + BMI_GYRO_SENSOR, + BMI_MAG_SENSOR, + BMI_SENSOR_TYPE_MAX +}; + +/*!bmi sensor generic power mode enum */ +enum BMI_AXIS_TYPE { + X_AXIS = 0, + Y_AXIS, + Z_AXIS, + AXIS_MAX +}; + +/*!bmi sensor generic intterrupt enum */ +enum BMI_INT_TYPE { + BMI160_INT0 = 0, + BMI160_INT1, + BMI160_INT_MAX +}; + +/*! bmi sensor time resolution definition*/ +enum BMI_SENSOR_TIME_RS_TYPE { + TS_0_78_HZ = 1,/*0.78HZ*/ + TS_1_56_HZ,/*1.56HZ*/ + TS_3_125_HZ,/*3.125HZ*/ + TS_6_25_HZ,/*6.25HZ*/ + TS_12_5_HZ,/*12.5HZ*/ + TS_25_HZ,/*25HZ, odr=6*/ + TS_50_HZ,/*50HZ*/ + TS_100_HZ,/*100HZ*/ + TS_200_HZ,/*200HZ*/ + TS_400_HZ,/*400HZ*/ + TS_800_HZ,/*800HZ*/ + TS_1600_HZ,/*1600HZ*/ + TS_MAX_HZ +}; + +/*! bmi sensor interface mode */ +enum BMI_SENSOR_IF_MODE_TYPE { + /*primary interface:autoconfig/secondary interface off*/ + P_AUTO_S_OFF = 0, + /*primary interface:I2C/secondary interface:OIS*/ + P_I2C_S_OIS, + /*primary interface:autoconfig/secondary interface:Magnetometer*/ + P_AUTO_S_MAG, + /*interface mode reseved*/ + IF_MODE_RESEVED + +}; + +/*! bmi160 acc/gyro calibration status in H/W layer */ +enum BMI_CALIBRATION_STATUS_TYPE { + /*BMI FAST Calibration ready x/y/z status*/ + BMI_ACC_X_FAST_CALI_RDY = 0, + BMI_ACC_Y_FAST_CALI_RDY, + BMI_ACC_Z_FAST_CALI_RDY +}; + +unsigned int reg_op_addr; + +static const int bmi_pmu_cmd_acc_arr[BMI_ACC_PM_MAX] = { + /*!bmi pmu for acc normal, low power1, + * suspend, low power2 mode command */ + CMD_PMU_ACC_NORMAL, + CMD_PMU_ACC_LP1, + CMD_PMU_ACC_SUSPEND, + CMD_PMU_ACC_LP2 +}; + +static const int bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_MAX] = { + /*!bmi pmu for gyro normal, fast startup, + * suspend mode command */ + CMD_PMU_GYRO_NORMAL, + CMD_PMU_GYRO_FASTSTART, + CMD_PMU_GYRO_SUSPEND +}; + +static const int bmi_pmu_cmd_mag_arr[BMI_MAG_PM_MAX] = { + /*!bmi pmu for mag normal, low power1, + * suspend, low power2 mode command */ + CMD_PMU_MAG_NORMAL, + CMD_PMU_MAG_LP1, + CMD_PMU_MAG_SUSPEND, + CMD_PMU_MAG_LP2 +}; + +static const char *bmi_axis_name[AXIS_MAX] = {"x", "y", "z"}; + +static const int bmi_interrupt_type[] = { + /*!bmi interrupt type */ + /* Interrupt enable0 , index=0~6*/ + BMI160_ANY_MOTION_X_ENABLE, + BMI160_ANY_MOTION_Y_ENABLE, + BMI160_ANY_MOTION_Z_ENABLE, + BMI160_DOUBLE_TAP_ENABLE, + BMI160_SINGLE_TAP_ENABLE, + BMI160_ORIENT_ENABLE, + BMI160_FLAT_ENABLE, + /* Interrupt enable1, index=7~13*/ + BMI160_HIGH_G_X_ENABLE, + BMI160_HIGH_G_Y_ENABLE, + BMI160_HIGH_G_Z_ENABLE, + BMI160_LOW_G_ENABLE, + BMI160_DATA_RDY_ENABLE, + BMI160_FIFO_FULL_ENABLE, + BMI160_FIFO_WM_ENABLE, + /* Interrupt enable2, index = 14~17*/ + BMI160_NOMOTION_X_ENABLE, + BMI160_NOMOTION_Y_ENABLE, + BMI160_NOMOTION_Z_ENABLE, + BMI160_STEP_DETECTOR_EN +}; + +/*! bmi sensor time depend on ODR*/ +struct bmi_sensor_time_odr_tbl { + u32 ts_duration_lsb; + u32 ts_duration_us; + u32 ts_delat;/*sub current delat fifo_time*/ +}; + +struct bmi160_axis_data_t { + s16 x; + s16 y; + s16 z; +}; +struct bmi160_value_t { + struct bmi160_axis_data_t acc; + struct bmi160_axis_data_t gyro; +#ifdef BMI160_MAG_INTERFACE_SUPPORT + struct bmi160_axis_data_t mag; +#endif + int64_t ts_intvl; +}; +struct bmi160_type_mapping_type { + + /*! bmi16x sensor chip id */ + uint16_t chip_id; + + /*! bmi16x chip revision code */ + uint16_t revision_id; + + /*! bma2x2 sensor name */ + const char *sensor_name; +}; + +struct bmi160_store_info_t { + uint8_t current_frm_cnt; + uint64_t current_apts_us[2]; + uint8_t fifo_ts_total_frmcnt; + uint64_t fifo_time; +}; +static struct workqueue_struct *reportdata_wq; +#define FIFO_READ_LENGTH_RECOMMENDED (67) +#define FIFO_SENSORTIME_OVERFLOW_MASK (0x1000000) +#define FIFO_SENSORTIME_RESOLUTION (390625) + +static uint8_t s_fifo_data_buf[FIFO_DATA_BUFSIZE * 2] = {0}; +static uint64_t sensor_time_old = 0; +static uint64_t sensor_time_new = 0; +static uint64_t host_time_old = 0; +static uint64_t host_time_new = 0; + +#define BMI_RING_BUF_SIZE 100 + +static struct bmi160_value_t bmi_ring_buf[BMI_RING_BUF_SIZE]; +static int s_ring_buf_head = 0; +static int s_ring_buf_tail = 0; + + +uint64_t get_current_timestamp(void) +{ + uint64_t ts; + struct timeval tv; + + do_gettimeofday(&tv); + ts = (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec; + + return ts; +} + + +/*! sensor support type map */ +static const struct bmi160_type_mapping_type sensor_type_map[] = { + + {SENSOR_CHIP_ID_BMI, SENSOR_CHIP_REV_ID_BMI, "BMI160/162AB"}, + {SENSOR_CHIP_ID_BMI_C2, SENSOR_CHIP_REV_ID_BMI, "BMI160C2"}, + {SENSOR_CHIP_ID_BMI_C3, SENSOR_CHIP_REV_ID_BMI, "BMI160C3"}, + +}; + +/*!bmi160 sensor time depends on ODR */ +static const struct bmi_sensor_time_odr_tbl + sensortime_duration_tbl[TS_MAX_HZ] = { + {0x010000, 2560000, 0x00ffff},/*2560ms, 0.39hz, odr=resver*/ + {0x008000, 1280000, 0x007fff},/*1280ms, 0.78hz, odr_acc=1*/ + {0x004000, 640000, 0x003fff},/*640ms, 1.56hz, odr_acc=2*/ + {0x002000, 320000, 0x001fff},/*320ms, 3.125hz, odr_acc=3*/ + {0x001000, 160000, 0x000fff},/*160ms, 6.25hz, odr_acc=4*/ + {0x000800, 80000, 0x0007ff},/*80ms, 12.5hz*/ + {0x000400, 40000, 0x0003ff},/*40ms, 25hz, odr_acc = odr_gyro =6*/ + {0x000200, 20000, 0x0001ff},/*20ms, 50hz, odr = 7*/ + {0x000100, 10000, 0x0000ff},/*10ms, 100hz, odr=8*/ + {0x000080, 5000, 0x00007f},/*5ms, 200hz, odr=9*/ + {0x000040, 2500, 0x00003f},/*2.5ms, 400hz, odr=10*/ + {0x000020, 1250, 0x00001f},/*1.25ms, 800hz, odr=11*/ + {0x000010, 625, 0x00000f},/*0.625ms, 1600hz, odr=12*/ + +}; + +static void bmi_dump_reg(struct bmi_client_data *client_data) +{ + #define REG_MAX0 0x24 + #define REG_MAX1 0x56 + int i; + u8 dbg_buf0[REG_MAX0]; + u8 dbg_buf1[REG_MAX1]; + u8 dbg_buf_str0[REG_MAX0 * 3 + 1] = ""; + u8 dbg_buf_str1[REG_MAX1 * 3 + 1] = ""; + + dev_notice(client_data->dev, "\nFrom 0x00:\n"); + + client_data->device.bus_read(client_data->device.dev_addr, + BMI_REG_NAME(USER_CHIP_ID), dbg_buf0, REG_MAX0); + for (i = 0; i < REG_MAX0; i++) { + sprintf(dbg_buf_str0 + i * 3, "%02x%c", dbg_buf0[i], + (((i + 1) % BYTES_PER_LINE == 0) ? '\n' : ' ')); + } + dev_notice(client_data->dev, "%s\n", dbg_buf_str0); + + client_data->device.bus_read(client_data->device.dev_addr, + BMI160_USER_ACCEL_CONFIG_ADDR, dbg_buf1, REG_MAX1); + dev_notice(client_data->dev, "\nFrom 0x40:\n"); + for (i = 0; i < REG_MAX1; i++) { + sprintf(dbg_buf_str1 + i * 3, "%02x%c", dbg_buf1[i], + (((i + 1) % BYTES_PER_LINE == 0) ? '\n' : ' ')); + } + dev_notice(client_data->dev, "\n%s\n", dbg_buf_str1); + +} + +/*! +* BMI160 sensor remapping function +* need to give some parameter in BSP files first. +*/ +static const struct bosch_sensor_axis_remap + bst_axis_remap_tab_dft[MAX_AXIS_REMAP_TAB_SZ] = { + /* src_x src_y src_z sign_x sign_y sign_z */ + { 0, 1, 2, 1, 1, 1 }, /* P0 */ + { 1, 0, 2, 1, -1, 1 }, /* P1 */ + { 0, 1, 2, -1, -1, 1 }, /* P2 */ + { 1, 0, 2, -1, 1, 1 }, /* P3 */ + + { 0, 1, 2, -1, 1, -1 }, /* P4 */ + { 1, 0, 2, -1, -1, -1 }, /* P5 */ + { 0, 1, 2, 1, -1, -1 }, /* P6 */ + { 1, 0, 2, 1, 1, -1 }, /* P7 */ +}; + +static void bst_remap_sensor_data(struct bosch_sensor_data *data, + const struct bosch_sensor_axis_remap *remap) +{ + struct bosch_sensor_data tmp; + + tmp.x = data->v[remap->src_x] * remap->sign_x; + tmp.y = data->v[remap->src_y] * remap->sign_y; + tmp.z = data->v[remap->src_z] * remap->sign_z; + + memcpy(data, &tmp, sizeof(*data)); +} + +static void bst_remap_sensor_data_dft_tab(struct bosch_sensor_data *data, + int place) +{ +/* sensor with place 0 needs not to be remapped */ + if ((place <= 0) || (place >= MAX_AXIS_REMAP_TAB_SZ)) + return; + bst_remap_sensor_data(data, &bst_axis_remap_tab_dft[place]); +} + +static void bmi_remap_sensor_data(struct bmi160_axis_data_t *val, + struct bmi_client_data *client_data) +{ + struct bosch_sensor_data bsd; + + if ((NULL == client_data->bst_pd) || + (BOSCH_SENSOR_PLACE_UNKNOWN + == client_data->bst_pd->place)) + return; + + bsd.x = val->x; + bsd.y = val->y; + bsd.z = val->z; + + bst_remap_sensor_data_dft_tab(&bsd, + client_data->bst_pd->place); + + val->x = bsd.x; + val->y = bsd.y; + val->z = bsd.z; + +} + +static void bmi_remap_data_acc(struct bmi_client_data *client_data, + struct bmi160_accel_t *acc_frame) +{ + struct bosch_sensor_data bsd; + + if ((NULL == client_data->bst_pd) || + (BOSCH_SENSOR_PLACE_UNKNOWN + == client_data->bst_pd->place)) + return; + + bsd.x = acc_frame->x; + bsd.y = acc_frame->y; + bsd.z = acc_frame->z; + + bst_remap_sensor_data_dft_tab(&bsd, + client_data->bst_pd->place); + + acc_frame->x = bsd.x; + acc_frame->y = bsd.y; + acc_frame->z = bsd.z; + + +} + +static void bmi_remap_data_gyro(struct bmi_client_data *client_data, + struct bmi160_gyro_t *gyro_frame) +{ + struct bosch_sensor_data bsd; + + if ((NULL == client_data->bst_pd) || + (BOSCH_SENSOR_PLACE_UNKNOWN + == client_data->bst_pd->place)) + return; + + bsd.x = gyro_frame->x; + bsd.y = gyro_frame->y; + bsd.z = gyro_frame->z; + + bst_remap_sensor_data_dft_tab(&bsd, + client_data->bst_pd->place); + + gyro_frame->x = bsd.x; + gyro_frame->y = bsd.y; + gyro_frame->z = bsd.z; + + +} + +static void bmi_fifo_frame_bytes_extend_calc( + struct bmi_client_data *client_data, + unsigned int *fifo_frmbytes_extend) +{ + + switch (client_data->fifo_data_sel) { + case BMI_FIFO_A_SEL: + case BMI_FIFO_G_SEL: + *fifo_frmbytes_extend = 7; + break; + case BMI_FIFO_G_A_SEL: + *fifo_frmbytes_extend = 13; + break; + case BMI_FIFO_M_SEL: + *fifo_frmbytes_extend = 9; + break; + case BMI_FIFO_M_A_SEL: + case BMI_FIFO_M_G_SEL: + /*8(mag) + 6(gyro or acc) +1(head) = 15*/ + *fifo_frmbytes_extend = 15; + break; + case BMI_FIFO_M_G_A_SEL: + /*8(mag) + 6(gyro or acc) + 6 + 1 = 21*/ + *fifo_frmbytes_extend = 21; + break; + default: + *fifo_frmbytes_extend = 0; + break; + + }; + +} + +static int bmi_input_init(struct bmi_client_data *client_data) +{ + struct input_dev *dev; + int err = 0; + + dev = input_allocate_device(); + if (NULL == dev) + return -ENOMEM; + + dev->name = SENSOR_NAME; + dev->id.bustype = BUS_I2C; + + + input_set_capability(dev, EV_MSC, INPUT_EVENT_SGM); + input_set_capability(dev, EV_MSC, INPUT_EVENT_STEP_DETECTOR); + input_set_capability(dev, EV_MSC, INPUT_EVENT_FAST_ACC_CALIB_DONE); + input_set_capability(dev, EV_MSC, INPUT_EVENT_FAST_GYRO_CALIB_DONE); + + input_set_capability(dev, EV_REL, REL_X); + input_set_capability(dev, EV_REL, REL_Y); + input_set_capability(dev, EV_REL, REL_Z); + input_set_drvdata(dev, client_data); + + err = input_register_device(dev); + if (err < 0) { + input_free_device(dev); + dev_notice(client_data->dev, "bmi160 input free!\n"); + return err; + } + client_data->input = dev; + dev_notice(client_data->dev, + "bmi160 input register successfully, %s!\n", + client_data->input->name); + return err; +} + + +static void bmi_input_destroy(struct bmi_client_data *client_data) +{ + struct input_dev *dev = client_data->input; + + input_unregister_device(dev); + input_free_device(dev); +} + +static int bmi_check_chip_id(struct bmi_client_data *client_data) +{ + int8_t err = 0; + int8_t i = 0; + uint8_t chip_id = 0; + uint8_t read_count = 0; + u8 bmi_sensor_cnt = sizeof(sensor_type_map) + / sizeof(struct bmi160_type_mapping_type); + /* read and check chip id */ + while (read_count++ < CHECK_CHIP_ID_TIME_MAX) { + if (client_data->device.bus_read(client_data->device.dev_addr, + BMI_REG_NAME(USER_CHIP_ID), &chip_id, 1) < 0) { + + dev_err(client_data->dev, + "Bosch Sensortec Device not found" + "read chip_id:%d\n", chip_id); + continue; + } else { + for (i = 0; i < bmi_sensor_cnt; i++) { + if (sensor_type_map[i].chip_id == chip_id) { + client_data->chip_id = chip_id; + dev_notice(client_data->dev, + "Bosch Sensortec Device detected, " + "HW IC name: %s\n", sensor_type_map[i].sensor_name); + break; + } + } + if (i < bmi_sensor_cnt) + break; + else { + if (read_count == CHECK_CHIP_ID_TIME_MAX) { + dev_err(client_data->dev, + "Failed!Bosch Sensortec Device not found" + " mismatch chip_id:%d\n", chip_id); + err = -ENODEV; + return err; + } + } + mdelay(1); + } + } + return err; + +} + +static int bmi_pmu_set_suspend(struct bmi_client_data *client_data) +{ + int err = 0; + if (client_data == NULL) + return -EINVAL; + else { + err += BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_acc_arr[SENSOR_PM_SUSPEND]); + err += BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_gyro_arr[SENSOR_PM_SUSPEND]); + err += BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_mag_arr[SENSOR_PM_SUSPEND]); + client_data->pw.acc_pm = BMI_ACC_PM_SUSPEND; + client_data->pw.gyro_pm = BMI_GYRO_PM_SUSPEND; + client_data->pw.mag_pm = BMI_MAG_PM_SUSPEND; + } + + return err; +} + +static int bmi_get_err_status(struct bmi_client_data *client_data) +{ + int err = 0; + + err = BMI_CALL_API(get_error_status)(&client_data->err_st.fatal_err, + &client_data->err_st.err_code, &client_data->err_st.i2c_fail, + &client_data->err_st.drop_cmd, &client_data->err_st.mag_drdy_err); + return err; +} + + +static enum hrtimer_restart reportdata_timer_fun( + struct hrtimer *hrtimer) +{ + struct bmi_client_data *client_data = + container_of(hrtimer, struct bmi_client_data, timer); + int32_t delay = 0; + delay = atomic_read(&client_data->delay); + queue_work(reportdata_wq, &(client_data->report_data_work)); + client_data->work_delay_kt = ns_to_ktime(delay*1000000); + hrtimer_forward(hrtimer, ktime_get(), client_data->work_delay_kt); + + return HRTIMER_RESTART; +} + +static ssize_t bmi_show_enable_timer(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + return snprintf(buf, 16, "%d\n", client_data->is_timer_running); +} + +static ssize_t bmi_store_enable_timer(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int error; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + error = kstrtoul(buf, 10, &data); + if (error) + return error; + if (data) { + if (0 == client_data->is_timer_running) { + hrtimer_start(&client_data->timer, + ns_to_ktime(10000000), + HRTIMER_MODE_REL); + client_data->is_timer_running = 1; + //client_data->base_time = 0; + //client_data->timestamp = 0; + //client_data->gyro_count = 0; + } + } else { + if (1 == client_data->is_timer_running) { + hrtimer_cancel(&client_data->timer); + client_data->is_timer_running = 0; + //client_data->base_time = 0; + //client_data->timestamp = 0; + //client_data->gyro_count = 0; + //mutex_lock(&client_data->mutex_ring_buf); + //s_ring_buf_head = s_ring_buf_tail = 0; + //mutex_unlock(&client_data->mutex_ring_buf); + } + } + return count; +} + +#if 0 +static void bmi_work_func(struct work_struct *work) +{ + struct bmi_client_data *client_data = + container_of((struct delayed_work *)work, + struct bmi_client_data, work); + unsigned long delay = + msecs_to_jiffies(atomic_read(&client_data->delay)); + struct bmi160_accel_t data; + struct bmi160_axis_data_t bmi160_udata; + int err; + + err = BMI_CALL_API(read_accel_xyz)(&data); + if (err < 0) + return; + + bmi160_udata.x = data.x; + bmi160_udata.y = data.y; + bmi160_udata.z = data.z; + + bmi_remap_sensor_data(&bmi160_udata, client_data); + /*report current frame via input event*/ + input_event(client_data->input, EV_REL, REL_X, bmi160_udata.x); + input_event(client_data->input, EV_REL, REL_Y, bmi160_udata.y); + input_event(client_data->input, EV_REL, REL_Z, bmi160_udata.z); + input_sync(client_data->input); + + schedule_delayed_work(&client_data->work, delay); +} +#endif +static uint8_t dbg_buf_str[2048] = ""; +static void bmi_hrtimer_work_func(struct work_struct *work) +{ + struct bmi_client_data *client_data = + container_of((struct delayed_work *)work, + struct bmi_client_data, work); + + unsigned int fifo_len0 = 0; + unsigned int fifo_frmbytes_ext = 0; + unsigned int fifo_read_len = 0; + int i, err; + + bmi_fifo_frame_bytes_extend_calc(client_data, &fifo_frmbytes_ext); + + err = BMI_CALL_API(fifo_length)(&fifo_len0); + client_data->fifo_bytecount = fifo_len0; + + if (client_data->fifo_bytecount == 0 || err) { + //dev_notice(client_data->dev, "fifo_bytecount is 0!!"); + return ; + } + + fifo_read_len = client_data->fifo_bytecount + fifo_frmbytes_ext; + if (fifo_read_len > FIFO_DATA_BUFSIZE) { + fifo_read_len = FIFO_DATA_BUFSIZE; + } + + if (!err) { + err = bmi_burst_read_wrapper(client_data->device.dev_addr, + BMI160_USER_FIFO_DATA__REG, s_fifo_data_buf, + fifo_read_len); + } + + for (i = 0; i < fifo_read_len; i++) { + sprintf(dbg_buf_str + i * 3, "%02x%c", s_fifo_data_buf[i], + (((i + 1) % BYTES_PER_LINE == 0) ? '\n' : ' ')); + } + printk(KERN_INFO "%s\n", dbg_buf_str); + +} + +static ssize_t bmi160_chip_id_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + return sprintf(buf, "0x%x\n", client_data->chip_id); +} + +static ssize_t bmi160_err_st_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + int err = 0; + err = bmi_get_err_status(client_data); + if (err) + return err; + else { + return sprintf(buf, "fatal_err:0x%x, err_code:%d,\n\n" + "i2c_fail_err:%d, drop_cmd_err:%d, mag_drdy_err:%d\n", + client_data->err_st.fatal_err, + client_data->err_st.err_code, + client_data->err_st.i2c_fail, + client_data->err_st.drop_cmd, + client_data->err_st.mag_drdy_err); + } +} + +static ssize_t bmi160_sensor_time_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err = 0; + u32 sensor_time; + err = BMI_CALL_API(get_sensor_time)(&sensor_time); + if (err) + return err; + else + return sprintf(buf, "0x%x\n", (unsigned int)sensor_time); +} + +static ssize_t bmi160_fifo_flush_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int err; + unsigned long enable; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = kstrtoul(buf, 10, &enable); + if (err) + return err; + if (enable) + err = BMI_CALL_API(set_command_register)(CMD_CLR_FIFO_DATA); + + if (err) + dev_err(client_data->dev, "fifo flush failed!\n"); + + return count; + +} + + +static ssize_t bmi160_fifo_bytecount_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err; + unsigned int fifo_bytecount = 0; + + BMI_CALL_API(fifo_length)(&fifo_bytecount); + err = sprintf(buf, "%u\n", fifo_bytecount); + return err; +} + +static ssize_t bmi160_fifo_bytecount_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + int err; + unsigned long data; + err = kstrtoul(buf, 10, &data); + if (err) + return err; + client_data->fifo_bytecount = (unsigned int) data; + + return count; +} + +int bmi160_fifo_data_sel_get(struct bmi_client_data *client_data) +{ + int err = 0; + unsigned char fifo_acc_en, fifo_gyro_en, fifo_mag_en; + unsigned char fifo_datasel; + + err += BMI_CALL_API(get_fifo_accel_enable)(&fifo_acc_en); + err += BMI_CALL_API(get_fifo_gyro_enable)(&fifo_gyro_en); + err += BMI_CALL_API(get_fifo_mag_enable)(&fifo_mag_en); + + if (err) + return err; + + fifo_datasel = (fifo_acc_en << BMI_ACC_SENSOR) | + (fifo_gyro_en << BMI_GYRO_SENSOR) | + (fifo_mag_en << BMI_MAG_SENSOR); + + client_data->fifo_data_sel = fifo_datasel; + + return err; + + +} + +static ssize_t bmi160_fifo_data_sel_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err = 0; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + err = bmi160_fifo_data_sel_get(client_data); + if (err) + return -EINVAL; + return sprintf(buf, "%d\n", client_data->fifo_data_sel); +} + +/* write any value to clear all the fifo data. */ +static ssize_t bmi160_fifo_data_sel_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + int err; + unsigned long data; + unsigned char fifo_datasel; + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + /* data format: aimed 0b0000 0x(m)x(g)x(a), x:1 enable, 0:disable*/ + if (data > 7) + return -EINVAL; + + + fifo_datasel = (unsigned char)data; + + + err += BMI_CALL_API(set_fifo_accel_enable) + ((fifo_datasel & (1 << BMI_ACC_SENSOR)) ? 1 : 0); + err += BMI_CALL_API(set_fifo_gyro_enable) + (fifo_datasel & (1 << BMI_GYRO_SENSOR) ? 1 : 0); + err += BMI_CALL_API(set_fifo_mag_enable) + ((fifo_datasel & (1 << BMI_MAG_SENSOR)) ? 1 : 0); + + /*err += BMI_CALL_API(set_command_register)(CMD_CLR_FIFO_DATA);*/ + if (err) + return -EIO; + else { + dev_notice(client_data->dev, "FIFO A_en:%d, G_en:%d, M_en:%d\n", + (fifo_datasel & (1 << BMI_ACC_SENSOR)) ? 1 : 0, + (fifo_datasel & (1 << BMI_GYRO_SENSOR) ? 1 : 0), + ((fifo_datasel & (1 << BMI_MAG_SENSOR)) ? 1 : 0)); + client_data->fifo_data_sel = fifo_datasel; + } + + return count; +} + +static int bmi_fifo_analysis_handle(struct bmi_client_data *client_data, + u8 *fifo_data, u16 fifo_length, char *buf) +{ + u8 frame_head = 0;/* every frame head*/ + int len = 0; + + /*u8 skip_frame_cnt = 0;*/ + u8 acc_frm_cnt = 0;/*0~146*/ + u8 gyro_frm_cnt = 0; + u8 mag_frm_cnt = 0; + u8 tmp_frm_cnt = 0; + /*u8 tmp_odr = 0;*/ + /*uint64_t current_apts_us = 0;*/ + /*fifo data last frame start_index A G M*/ + u64 fifo_time = 0; + static uint32_t current_frm_ts; + u16 fifo_index = 0;/* fifo data buff index*/ + u16 fifo_index_tmp = 0; + u16 i = 0; + s8 last_return_st = 0; + int err = 0; + unsigned int frame_bytes = 0; + struct bmi160_mag_xyzr_t mag; + struct bmi160_mag_xyz_s32_t mag_comp_xyz; + struct bmi160_accel_t acc_frame_arr[FIFO_FRAME_CNT]; + struct bmi160_gyro_t gyro_frame_arr[FIFO_FRAME_CNT]; + struct bmi160_mag_xyzr_t mag_frame_arr[FIFO_FRAME_CNT]; + + struct odr_t odr; + + memset(&odr, 0, sizeof(odr)); + memset(&mag, 0, sizeof(mag)); + memset(&mag_comp_xyz, 0, sizeof(mag_comp_xyz)); + for (i = 0; i < FIFO_FRAME_CNT; i++) { + memset(&mag_frame_arr[i], 0, sizeof(struct bmi160_mag_xyzr_t)); + memset(&acc_frame_arr[i], 0, sizeof(struct bmi160_accel_t)); + memset(&gyro_frame_arr[i], 0, sizeof(struct bmi160_gyro_t)); + } + /*current_apts_us = get_current_timestamp();*/ + /* no fifo select for bmi sensor*/ + if (!client_data->fifo_data_sel) { + dev_err(client_data->dev, + "No select any sensor FIFO for BMI16x\n"); + return -EINVAL; + } + /*driver need read acc_odr/gyro_odr/mag_odr*/ + if ((client_data->fifo_data_sel) & (1 << BMI_ACC_SENSOR)) + odr.acc_odr = client_data->odr.acc_odr; + if ((client_data->fifo_data_sel) & (1 << BMI_GYRO_SENSOR)) + odr.gyro_odr = client_data->odr.gyro_odr; + if ((client_data->fifo_data_sel) & (1 << BMI_MAG_SENSOR)) + odr.mag_odr = client_data->odr.mag_odr; + bmi_fifo_frame_bytes_extend_calc(client_data, &frame_bytes); +/* search sensor time sub function firstly */ + for (fifo_index = 0; fifo_index < fifo_length;) { + /* conside limited HW i2c burst reading issue, + need to re-calc index 256 512 768 1024...*/ + if ((fifo_index_tmp >> 8) != (fifo_index >> 8)) { + if (fifo_data[fifo_index_tmp] == + fifo_data[(fifo_index >> 8)<<8]) { + fifo_index = (fifo_index >> 8) << 8; + fifo_length += + (fifo_index - fifo_index_tmp + 1); + } + } + fifo_index_tmp = fifo_index; + /* compare index with 256/512/ before doing parsing*/ + if (((fifo_index + frame_bytes) >> 8) != (fifo_index >> 8)) { + fifo_index = ((fifo_index + frame_bytes) >> 8) << 8; + continue; + } + + frame_head = fifo_data[fifo_index]; + + switch (frame_head) { + /*skip frame 0x40 22 0x84*/ + case FIFO_HEAD_SKIP_FRAME: + /*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + if (fifo_index + 1 > fifo_length) { + last_return_st = FIFO_SKIP_OVER_LEN; + break; + } + /*skip_frame_cnt = fifo_data[fifo_index];*/ + fifo_index = fifo_index + 1; + break; + + /*M & G & A*/ + case FIFO_HEAD_M_G_A: + {/*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + if (fifo_index + MGA_BYTES_FRM > fifo_length) { + last_return_st = FIFO_M_G_A_OVER_LEN; + break; + } + + /* mag frm index = gyro */ + mag_frm_cnt = gyro_frm_cnt; + mag_frame_arr[mag_frm_cnt].x = + fifo_data[fifo_index + 1] << 8 | + fifo_data[fifo_index + 0]; + mag_frame_arr[mag_frm_cnt].y = + fifo_data[fifo_index + 3] << 8 | + fifo_data[fifo_index + 2]; + mag_frame_arr[mag_frm_cnt].z = + fifo_data[fifo_index + 5] << 8 | + fifo_data[fifo_index + 4]; + mag_frame_arr[mag_frm_cnt].r = + fifo_data[fifo_index + 7] << 8 | + fifo_data[fifo_index + 6]; + + gyro_frame_arr[gyro_frm_cnt].x = + fifo_data[fifo_index + 9] << 8 | + fifo_data[fifo_index + 8]; + gyro_frame_arr[gyro_frm_cnt].y = + fifo_data[fifo_index + 11] << 8 | + fifo_data[fifo_index + 10]; + gyro_frame_arr[gyro_frm_cnt].z = + fifo_data[fifo_index + 13] << 8 | + fifo_data[fifo_index + 12]; + + acc_frame_arr[acc_frm_cnt].x = + fifo_data[fifo_index + 15] << 8 | + fifo_data[fifo_index + 14]; + acc_frame_arr[acc_frm_cnt].y = + fifo_data[fifo_index + 17] << 8 | + fifo_data[fifo_index + 16]; + acc_frame_arr[acc_frm_cnt].z = + fifo_data[fifo_index + 19] << 8 | + fifo_data[fifo_index + 18]; + + mag_frm_cnt++;/* M fram_cnt++ */ + gyro_frm_cnt++;/* G fram_cnt++ */ + acc_frm_cnt++;/* A fram_cnt++ */ + + fifo_index = fifo_index + MGA_BYTES_FRM; + break; + } + + case FIFO_HEAD_M_A: + {/*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + if (fifo_index + MA_BYTES_FRM > fifo_length) { + last_return_st = FIFO_M_A_OVER_LEN; + break; + } + + mag_frm_cnt = acc_frm_cnt; + + mag_frame_arr[mag_frm_cnt].x = + fifo_data[fifo_index + 1] << 8 | + fifo_data[fifo_index + 0]; + mag_frame_arr[mag_frm_cnt].y = + fifo_data[fifo_index + 3] << 8 | + fifo_data[fifo_index + 2]; + mag_frame_arr[mag_frm_cnt].z = + fifo_data[fifo_index + 5] << 8 | + fifo_data[fifo_index + 4]; + mag_frame_arr[mag_frm_cnt].r = + fifo_data[fifo_index + 7] << 8 | + fifo_data[fifo_index + 6]; + + acc_frame_arr[acc_frm_cnt].x = + fifo_data[fifo_index + 9] << 8 | + fifo_data[fifo_index + 8]; + acc_frame_arr[acc_frm_cnt].y = + fifo_data[fifo_index + 11] << 8 | + fifo_data[fifo_index + 10]; + acc_frame_arr[acc_frm_cnt].z = + fifo_data[fifo_index + 13] << 8 | + fifo_data[fifo_index + 12]; + + mag_frm_cnt++;/* M fram_cnt++ */ + acc_frm_cnt++;/* A fram_cnt++ */ + + fifo_index = fifo_index + MA_BYTES_FRM; + break; + } + + case FIFO_HEAD_M_G: + {/*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + if (fifo_index + MG_BYTES_FRM > fifo_length) { + last_return_st = FIFO_M_G_OVER_LEN; + break; + } + + mag_frm_cnt = gyro_frm_cnt; + mag_frame_arr[mag_frm_cnt].x = + fifo_data[fifo_index + 1] << 8 | + fifo_data[fifo_index + 0]; + mag_frame_arr[mag_frm_cnt].y = + fifo_data[fifo_index + 3] << 8 | + fifo_data[fifo_index + 2]; + mag_frame_arr[mag_frm_cnt].z = + fifo_data[fifo_index + 5] << 8 | + fifo_data[fifo_index + 4]; + mag_frame_arr[mag_frm_cnt].r = + fifo_data[fifo_index + 7] << 8 | + fifo_data[fifo_index + 6]; + + gyro_frame_arr[gyro_frm_cnt].x = + fifo_data[fifo_index + 9] << 8 | + fifo_data[fifo_index + 8]; + gyro_frame_arr[gyro_frm_cnt].y = + fifo_data[fifo_index + 11] << 8 | + fifo_data[fifo_index + 10]; + gyro_frame_arr[gyro_frm_cnt].z = + fifo_data[fifo_index + 13] << 8 | + fifo_data[fifo_index + 12]; + + mag_frm_cnt++;/* M fram_cnt++ */ + gyro_frm_cnt++;/* G fram_cnt++ */ + fifo_index = fifo_index + MG_BYTES_FRM; + break; + } + + case FIFO_HEAD_G_A: + { /*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + if (fifo_index + GA_BYTES_FRM > fifo_length) { + last_return_st = FIFO_G_A_OVER_LEN; + break; + } + gyro_frame_arr[gyro_frm_cnt].x = + fifo_data[fifo_index + 1] << 8 | + fifo_data[fifo_index + 0]; + gyro_frame_arr[gyro_frm_cnt].y = + fifo_data[fifo_index + 3] << 8 | + fifo_data[fifo_index + 2]; + gyro_frame_arr[gyro_frm_cnt].z = + fifo_data[fifo_index + 5] << 8 | + fifo_data[fifo_index + 4]; + + acc_frame_arr[acc_frm_cnt].x = + fifo_data[fifo_index + 7] << 8 | + fifo_data[fifo_index + 6]; + acc_frame_arr[acc_frm_cnt].y = + fifo_data[fifo_index + 9] << 8 | + fifo_data[fifo_index + 8]; + acc_frame_arr[acc_frm_cnt].z = + fifo_data[fifo_index + 11] << 8 | + fifo_data[fifo_index + 10]; + + bmi_remap_data_gyro(client_data, + &gyro_frame_arr[gyro_frm_cnt]); + bmi_remap_data_acc(client_data, + &acc_frame_arr[acc_frm_cnt]); + + gyro_frm_cnt++; + acc_frm_cnt++; + fifo_index = fifo_index + GA_BYTES_FRM; + + break; + } + case FIFO_HEAD_A: + { /*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + if (fifo_index + A_BYTES_FRM > fifo_length) { + last_return_st = FIFO_A_OVER_LEN; + break; + } + + acc_frame_arr[acc_frm_cnt].x = + fifo_data[fifo_index + 1] << 8 | + fifo_data[fifo_index + 0]; + acc_frame_arr[acc_frm_cnt].y = + fifo_data[fifo_index + 3] << 8 | + fifo_data[fifo_index + 2]; + acc_frame_arr[acc_frm_cnt].z = + fifo_data[fifo_index + 5] << 8 | + fifo_data[fifo_index + 4]; + + bmi_remap_data_acc(client_data, + &acc_frame_arr[acc_frm_cnt]); + + acc_frm_cnt++;/*acc_frm_cnt*/ + fifo_index = fifo_index + A_BYTES_FRM; + break; + } + case FIFO_HEAD_G: + { /*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + if (fifo_index + G_BYTES_FRM > fifo_length) { + last_return_st = FIFO_G_OVER_LEN; + break; + } + + gyro_frame_arr[gyro_frm_cnt].x = + fifo_data[fifo_index + 1] << 8 | + fifo_data[fifo_index + 0]; + gyro_frame_arr[gyro_frm_cnt].y = + fifo_data[fifo_index + 3] << 8 | + fifo_data[fifo_index + 2]; + gyro_frame_arr[gyro_frm_cnt].z = + fifo_data[fifo_index + 5] << 8 | + fifo_data[fifo_index + 4]; + + bmi_remap_data_gyro(client_data, + &gyro_frame_arr[gyro_frm_cnt]); + + gyro_frm_cnt++;/*gyro_frm_cnt*/ + + fifo_index = fifo_index + G_BYTES_FRM; + break; + } + case FIFO_HEAD_M: + { /*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + if (fifo_index + A_BYTES_FRM > fifo_length) { + last_return_st = FIFO_M_OVER_LEN; + break; + } + + mag_frame_arr[mag_frm_cnt].x = + fifo_data[fifo_index + 1] << 8 | + fifo_data[fifo_index + 0]; + mag_frame_arr[mag_frm_cnt].y = + fifo_data[fifo_index + 3] << 8 | + fifo_data[fifo_index + 2]; + mag_frame_arr[mag_frm_cnt].z = + fifo_data[fifo_index + 5] << 8 | + fifo_data[fifo_index + 4]; + mag_frame_arr[mag_frm_cnt].r = + fifo_data[fifo_index + 7] << 8 | + fifo_data[fifo_index + 6]; + + mag_frm_cnt++;/* M fram_cnt++ */ + + fifo_index = fifo_index + M_BYTES_FRM; + break; + } + + /* sensor time frame*/ + case FIFO_HEAD_SENSOR_TIME: + { + /*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + + if (fifo_index + 3 > fifo_length) { + last_return_st = FIFO_SENSORTIME_RETURN; + break; + } + fifo_time = + fifo_data[fifo_index + 2] << 16 | + fifo_data[fifo_index + 1] << 8 | + fifo_data[fifo_index + 0]; + + client_data->fifo_time = fifo_time; + /*fifo sensor time frame index + 3*/ + fifo_index = fifo_index + 3; + break; + } + case FIFO_HEAD_OVER_READ_LSB: + /*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + + if (fifo_index + 1 > fifo_length) { + last_return_st = FIFO_OVER_READ_RETURN; + break; + } + if (fifo_data[fifo_index] == + FIFO_HEAD_OVER_READ_MSB) { + /*fifo over read frame index + 1*/ + fifo_index = fifo_index + 1; + break; + } else { + last_return_st = FIFO_OVER_READ_RETURN; + break; + } + + default: + last_return_st = 1; + break; + + } + if (last_return_st) + break; + } + fifo_time = 0; +/*current_frm_ts = current_apts_us - +((fifo_time & (sensortime_duration_tbl[odr.acc_odr].ts_delat)) + +(sensortime_duration_tbl[odr.acc_odr].ts_duration_lsb +*(acc_frm_cnt - i - 1)))*625/16;*/ +/*Acc Only*/ + if (client_data->fifo_data_sel == BMI_FIFO_A_SEL) { + for (i = 0; i < acc_frm_cnt; i++) { + /*current_frm_ts += 256;*/ + current_frm_ts += + sensortime_duration_tbl[odr.acc_odr].ts_duration_us*LMADA; + + len = sprintf(buf, "%s %d %d %d %u ", + ACC_FIFO_HEAD, + acc_frame_arr[i].x, + acc_frame_arr[i].y, + acc_frame_arr[i].z, + current_frm_ts); + buf += len; + err += len; + } + } + + + /*only for G*/ + if (client_data->fifo_data_sel == BMI_FIFO_G_SEL) { + for (i = 0; i < gyro_frm_cnt; i++) { + /*current_frm_ts += 256;*/ + current_frm_ts += + sensortime_duration_tbl[odr.gyro_odr].ts_duration_us*LMADA; + + len = sprintf(buf, "%s %d %d %d %u ", + GYRO_FIFO_HEAD, + gyro_frame_arr[i].x, + gyro_frame_arr[i].y, + gyro_frame_arr[i].z, + current_frm_ts + ); + buf += len; + err += len; + } + } + + /*only for M*/ + if (client_data->fifo_data_sel == BMI_FIFO_M_SEL) { + for (i = 0; i < mag_frm_cnt; i++) { + /*current_frm_ts += 256;*/ + current_frm_ts += + sensortime_duration_tbl[odr.mag_odr].ts_duration_us*LMADA; +#ifdef BMI160_AKM09912_SUPPORT + mag_comp_xyz.x = mag_frame_arr[i].x; + mag_comp_xyz.y = mag_frame_arr[i].y; + mag_comp_xyz.z = mag_frame_arr[i].z; + bmi160_bst_akm09912_compensate_xyz_raw( + &mag_comp_xyz); +#else + mag.x = mag_frame_arr[i].x >> 3; + mag.y = mag_frame_arr[i].y >> 3; + mag.z = mag_frame_arr[i].z >> 1; + mag.r = mag_frame_arr[i].r >> 2; + bmi160_bmm150_mag_compensate_xyz_raw( + &mag_comp_xyz, mag); +#endif + len = sprintf(buf, "%s %d %d %d %u ", + MAG_FIFO_HEAD, + mag_comp_xyz.x, + mag_comp_xyz.y, + mag_comp_xyz.z, + current_frm_ts + ); + + buf += len; + err += len; + } + + } + +/*only for A M G*/ +if (client_data->fifo_data_sel == BMI_FIFO_M_G_A_SEL) { + + for (i = 0; i < gyro_frm_cnt; i++) { + /*sensor timeLSB*/ + /*dia(sensor_time) = fifo_time & (0xff), uint:LSB, 39.0625us*/ + /*AP tinmestamp 390625/10000 = 625 /16 */ + current_frm_ts += + sensortime_duration_tbl[odr.gyro_odr].ts_duration_us*LMADA; + + if (mag_frame_arr[i].x) { +#ifdef BMI160_AKM09912_SUPPORT + mag_comp_xyz.x = mag_frame_arr[i].x; + mag_comp_xyz.y = mag_frame_arr[i].y; + mag_comp_xyz.z = mag_frame_arr[i].z; + bmi160_bst_akm09912_compensate_xyz_raw( + &mag_comp_xyz); +#else + mag.x = mag_frame_arr[i].x >> 3; + mag.y = mag_frame_arr[i].y >> 3; + mag.z = mag_frame_arr[i].z >> 1; + mag.r = mag_frame_arr[i].r >> 2; + bmi160_bmm150_mag_compensate_xyz_raw( + &mag_comp_xyz, mag); +#endif + len = sprintf(buf, + "%s %d %d %d %u %s %d %d %d %u %s %d %d %d %u ", + GYRO_FIFO_HEAD, + gyro_frame_arr[i].x, + gyro_frame_arr[i].y, + gyro_frame_arr[i].z, + current_frm_ts, + ACC_FIFO_HEAD, + acc_frame_arr[i].x, + acc_frame_arr[i].y, + acc_frame_arr[i].z, + current_frm_ts, + MAG_FIFO_HEAD, + mag_comp_xyz.x, + mag_comp_xyz.y, + mag_comp_xyz.z, + current_frm_ts); + buf += len; + err += len; + } else { + len = sprintf(buf, + "%s %d %d %d %u %s %d %d %d %u ", + GYRO_FIFO_HEAD, + gyro_frame_arr[i].x, + gyro_frame_arr[i].y, + gyro_frame_arr[i].z, + current_frm_ts, + ACC_FIFO_HEAD, + acc_frame_arr[i].x, + acc_frame_arr[i].y, + acc_frame_arr[i].z, + current_frm_ts + ); + + buf += len; + err += len; + } + } + +} +/*only for A G*/ +if (client_data->fifo_data_sel == BMI_FIFO_G_A_SEL) { + + for (i = 0; i < gyro_frm_cnt; i++) { + /*sensor timeLSB*/ + /*dia(sensor_time) = fifo_time & (0xff), uint:LSB, 39.0625us*/ + /*AP tinmestamp 390625/10000 = 625 /16 */ + current_frm_ts += + sensortime_duration_tbl[odr.gyro_odr].ts_duration_us*LMADA; + len = sprintf(buf, + "%s %d %d %d %u %s %d %d %d %u ", + GYRO_FIFO_HEAD, + gyro_frame_arr[i].x, + gyro_frame_arr[i].y, + gyro_frame_arr[i].z, + current_frm_ts, + ACC_FIFO_HEAD, + acc_frame_arr[i].x, + acc_frame_arr[i].y, + acc_frame_arr[i].z, + current_frm_ts + ); + buf += len; + err += len; + } + } + +/*only for A M */ +if (client_data->fifo_data_sel == BMI_FIFO_M_A_SEL) { + for (i = 0; i < acc_frm_cnt; i++) { + /*sensor timeLSB*/ + /*dia(sensor_time) = fifo_time & (0xff), uint:LSB, 39.0625us*/ + /*AP tinmestamp 390625/10000 = 625 /16 */ + /*current_frm_ts += 256;*/ + current_frm_ts += + sensortime_duration_tbl[odr.acc_odr].ts_duration_us*LMADA; + + if (mag_frame_arr[i].x) { +#ifdef BMI160_AKM09912_SUPPORT + mag_comp_xyz.x = mag_frame_arr[i].x; + mag_comp_xyz.y = mag_frame_arr[i].y; + mag_comp_xyz.z = mag_frame_arr[i].z; + bmi160_bst_akm09912_compensate_xyz_raw( + &mag_comp_xyz); +#else + mag.x = mag_frame_arr[i].x >> 3; + mag.y = mag_frame_arr[i].y >> 3; + mag.z = mag_frame_arr[i].z >> 1; + mag.r = mag_frame_arr[i].r >> 2; + bmi160_bmm150_mag_compensate_xyz_raw( + &mag_comp_xyz, mag); +#endif + len = sprintf(buf, + "%s %d %d %d %u %s %d %d %d %u ", + ACC_FIFO_HEAD, + acc_frame_arr[i].x, + acc_frame_arr[i].y, + acc_frame_arr[i].z, + current_frm_ts, + MAG_FIFO_HEAD, + mag_comp_xyz.x, + mag_comp_xyz.y, + mag_comp_xyz.z, + current_frm_ts); + buf += len; + err += len; + } else { + len = sprintf(buf, "%s %d %d %d %u ", + ACC_FIFO_HEAD, + acc_frame_arr[i].x, + acc_frame_arr[i].y, + acc_frame_arr[i].z, + current_frm_ts + ); + + buf += len; + err += len; + } + } +} + +/*only forG M*/ +if (client_data->fifo_data_sel == BMI_FIFO_M_G_SEL) { + if (gyro_frm_cnt) { + tmp_frm_cnt = gyro_frm_cnt; + /*tmp_odr = odr.gyro_odr;*/ + } + + for (i = 0; i < tmp_frm_cnt; i++) { + current_frm_ts += + sensortime_duration_tbl[odr.gyro_odr].ts_duration_us*LMADA; + if (mag_frame_arr[i].x) { +#ifdef BMI160_AKM09912_SUPPORT + mag_comp_xyz.x = mag_frame_arr[i].x; + mag_comp_xyz.y = mag_frame_arr[i].y; + mag_comp_xyz.z = mag_frame_arr[i].z; + bmi160_bst_akm09912_compensate_xyz_raw( + &mag_comp_xyz); +#else + mag.x = mag_frame_arr[i].x >> 3; + mag.y = mag_frame_arr[i].y >> 3; + mag.z = mag_frame_arr[i].z >> 1; + mag.r = mag_frame_arr[i].r >> 2; + bmi160_bmm150_mag_compensate_xyz_raw( + &mag_comp_xyz, mag); +#endif + len = sprintf(buf, + "%s %d %d %d %u %s %d %d %d %u ", + GYRO_FIFO_HEAD, + gyro_frame_arr[i].x, + gyro_frame_arr[i].y, + gyro_frame_arr[i].z, + current_frm_ts, + MAG_FIFO_HEAD, + mag_comp_xyz.x, + mag_comp_xyz.y, + mag_comp_xyz.z, + current_frm_ts); + buf += len; + err += len; + } else { + len = sprintf(buf, "%s %d %d %d %u ", + GYRO_FIFO_HEAD, + gyro_frame_arr[i].x, + gyro_frame_arr[i].y, + gyro_frame_arr[i].z, + current_frm_ts + ); + + buf += len; + err += len; + } + } +} + + + return err; + + +} + + +static ssize_t bmi160_fifo_data_out_frame_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + int err = 0; + unsigned int fifo_bytecount_tmp; + + if (client_data->selftest > 0) { + dev_err(client_data->dev, + "in selftest no data available in fifo_data_frame\n"); + return -ENOMEM; + } + + if (NULL == g_fifo_data_arr) { + dev_err(client_data->dev, + "no memory available in fifo_data_frame\n"); + return -ENOMEM; + } + + if (client_data->pw.acc_pm == 2 && client_data->pw.gyro_pm == 2 + && client_data->pw.mag_pm == 2) { + dev_err(client_data->dev, "pw_acc: %d, pw_gyro: %d, pw_mag:%d\n", + client_data->pw.acc_pm, client_data->pw.gyro_pm, + client_data->pw.mag_pm); + return -EINVAL; + } + if (!client_data->fifo_data_sel) + return sprintf(buf, + "no selsect sensor fifo, fifo_data_sel:%d\n", + client_data->fifo_data_sel); + + if (client_data->fifo_bytecount == 0) + return -EINVAL; + + g_current_apts_us = get_current_timestamp(); + + BMI_CALL_API(fifo_length)(&fifo_bytecount_tmp); + if (fifo_bytecount_tmp > client_data->fifo_bytecount) + client_data->fifo_bytecount = fifo_bytecount_tmp; + if (client_data->fifo_bytecount > 210) { + /*err += BMI_CALL_API(set_command_register)( + CMD_CLR_FIFO_DATA);*/ + client_data->fifo_bytecount = 210; + } + if (!err) { + memset(g_fifo_data_arr, 0, 2048); + err = bmi_burst_read_wrapper(client_data->device.dev_addr, + BMI160_USER_FIFO_DATA__REG, g_fifo_data_arr, + client_data->fifo_bytecount); + } else + dev_err(client_data->dev, "read fifo leght err"); + if (err) { + dev_err(client_data->dev, "brust read fifo err\n"); + return err; + } + err = bmi_fifo_analysis_handle(client_data, g_fifo_data_arr, + client_data->fifo_bytecount, buf); + + + return err; +} + +static ssize_t bmi160_fifo_watermark_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err; + unsigned char data = 0xff; + + err = BMI_CALL_API(get_fifo_wm)(&data); + + if (err) + return err; + return sprintf(buf, "%d\n", data); +} + +static ssize_t bmi160_fifo_watermark_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int err; + unsigned long data; + unsigned char fifo_watermark; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + + fifo_watermark = (unsigned char)data; + err = BMI_CALL_API(set_fifo_wm)(fifo_watermark); + if (err) + return -EIO; + + printk(KERN_INFO "fifo_watermark count %d", count); + + if (BMI_CALL_API(set_intr_enable_1) + (BMI160_FIFO_WM_ENABLE, 1) < 0) { + printk(KERN_INFO "set fifo wm enable failed"); + return -EIO; + } + mutex_lock(&client_data->mutex_ring_buf); + s_ring_buf_head = s_ring_buf_tail = 0; + mutex_unlock(&client_data->mutex_ring_buf); + + return count; +} + + +static ssize_t bmi160_fifo_header_en_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err; + unsigned char data = 0xff; + + err = BMI_CALL_API(get_fifo_header_enable)(&data); + + if (err) + return err; + return sprintf(buf, "%d\n", data); +} + +static ssize_t bmi160_fifo_header_en_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + int err; + unsigned long data; + unsigned char fifo_header_en; + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + if (data > 1) + return -ENOENT; + + fifo_header_en = (unsigned char)data; + err = BMI_CALL_API(set_fifo_header_enable)(fifo_header_en); + if (err) + return -EIO; + + client_data->fifo_head_en = fifo_header_en; + + return count; +} + +static ssize_t bmi160_fifo_time_en_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err; + unsigned char data = 0; + + err = BMI_CALL_API(get_fifo_time_enable)(&data); + + if (!err) + err = sprintf(buf, "%d\n", data); + + return err; +} + +static ssize_t bmi160_fifo_time_en_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int err; + unsigned long data; + unsigned char fifo_ts_en; + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + + fifo_ts_en = (unsigned char)data; + + err = BMI_CALL_API(set_fifo_time_enable)(fifo_ts_en); + if (err) + return -EIO; + + return count; +} + +static ssize_t bmi160_fifo_int_tag_en_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err = 0; + unsigned char fifo_tag_int1 = 0; + unsigned char fifo_tag_int2 = 0; + unsigned char fifo_tag_int; + + err += BMI_CALL_API(get_fifo_tag_intr1_enable)(&fifo_tag_int1); + err += BMI_CALL_API(get_fifo_tag_intr2_enable)(&fifo_tag_int2); + + fifo_tag_int = (fifo_tag_int1 << BMI160_INT0) | + (fifo_tag_int2 << BMI160_INT1); + + if (!err) + err = sprintf(buf, "%d\n", fifo_tag_int); + + return err; +} + +static ssize_t bmi160_fifo_int_tag_en_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + int err; + unsigned long data; + unsigned char fifo_tag_int_en; + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + if (data > 3) + return -EINVAL; + + fifo_tag_int_en = (unsigned char)data; + + err += BMI_CALL_API(set_fifo_tag_intr1_enable) + ((fifo_tag_int_en & (1 << BMI160_INT0)) ? 1 : 0); + err += BMI_CALL_API(set_fifo_tag_intr2_enable) + ((fifo_tag_int_en & (1 << BMI160_INT1)) ? 1 : 0); + + if (err) { + dev_err(client_data->dev, "fifo int tag en err:%d\n", err); + return -EIO; + } + client_data->fifo_int_tag_en = fifo_tag_int_en; + + return count; +} + +static int bmi160_set_acc_op_mode(struct bmi_client_data *client_data, + unsigned long op_mode) +{ + int err = 0; + unsigned char stc_enable; + unsigned char std_enable; + mutex_lock(&client_data->mutex_op_mode); + + if (op_mode < BMI_ACC_PM_MAX) { + switch (op_mode) { + case BMI_ACC_PM_NORMAL: + err = BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_acc_arr[BMI_ACC_PM_NORMAL]); + client_data->pw.acc_pm = BMI_ACC_PM_NORMAL; + mdelay(10); + break; + case BMI_ACC_PM_LP1: + err = BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_acc_arr[BMI_ACC_PM_LP1]); + client_data->pw.acc_pm = BMI_ACC_PM_LP1; + mdelay(3); + break; + case BMI_ACC_PM_SUSPEND: + BMI_CALL_API(get_step_counter_enable)(&stc_enable); + BMI_CALL_API(get_step_detector_enable)(&std_enable); + if ((stc_enable == 0) && (std_enable == 0) && + (client_data->sig_flag == 0)) { + err = BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_acc_arr[BMI_ACC_PM_SUSPEND]); + client_data->pw.acc_pm = BMI_ACC_PM_SUSPEND; + mdelay(10); + } + break; + case BMI_ACC_PM_LP2: + err = BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_acc_arr[BMI_ACC_PM_LP2]); + client_data->pw.acc_pm = BMI_ACC_PM_LP2; + mdelay(3); + break; + default: + mutex_unlock(&client_data->mutex_op_mode); + return -EINVAL; + } + } else { + mutex_unlock(&client_data->mutex_op_mode); + return -EINVAL; + } + + mutex_unlock(&client_data->mutex_op_mode); + + return err; + + +} + +static ssize_t bmi160_temperature_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err; + s16 temp = 0xff; + + err = BMI_CALL_API(get_temp)(&temp); + + if (!err) + err = sprintf(buf, "0x%x\n", temp); + + return err; +} + +static ssize_t bmi160_place_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + int place = BOSCH_SENSOR_PLACE_UNKNOWN; + + if (NULL != client_data->bst_pd) + place = client_data->bst_pd->place; + + return sprintf(buf, "%d\n", place); +} + +static ssize_t bmi160_delay_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + return sprintf(buf, "%d\n", atomic_read(&client_data->delay)); + +} + +static ssize_t bmi160_delay_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + int err; + unsigned long data; + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + + if (data == 0) { + err = -EINVAL; + return err; + } + + if (data < BMI_DELAY_MIN) + data = BMI_DELAY_MIN; + + atomic_set(&client_data->delay, (unsigned int)data); + + return count; +} + +static ssize_t bmi160_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + return sprintf(buf, "%d\n", atomic_read(&client_data->wkqueue_en)); + +} + +static ssize_t bmi160_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + int err; + unsigned long enable; + int pre_enable = atomic_read(&client_data->wkqueue_en); + + err = kstrtoul(buf, 10, &enable); + if (err) + return err; + + enable = enable ? 1 : 0; + mutex_lock(&client_data->mutex_enable); + if (enable) { + if (pre_enable == 0) { + bmi160_set_acc_op_mode(client_data, + BMI_ACC_PM_NORMAL); + schedule_delayed_work(&client_data->work, + msecs_to_jiffies(atomic_read(&client_data->delay))); + atomic_set(&client_data->wkqueue_en, 1); + } + + } else { + if (pre_enable == 1) { + bmi160_set_acc_op_mode(client_data, + BMI_ACC_PM_SUSPEND); + + cancel_delayed_work_sync(&client_data->work); + atomic_set(&client_data->wkqueue_en, 0); + } + } + + mutex_unlock(&client_data->mutex_enable); + + mutex_lock(&client_data->mutex_ring_buf); + s_ring_buf_head = s_ring_buf_tail = 0; + mutex_unlock(&client_data->mutex_ring_buf); + + return count; +} + +#if defined(BMI160_ENABLE_INT1) || defined(BMI160_ENABLE_INT2) +/* accel sensor part */ +static ssize_t bmi160_anymot_duration_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err; + unsigned char data; + + err = BMI_CALL_API(get_intr_any_motion_durn)(&data); + + if (err < 0) + return err; + return sprintf(buf, "%d\n", data); +} + +static ssize_t bmi160_anymot_duration_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned long data; + int err; + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + + err = BMI_CALL_API(set_intr_any_motion_durn)((unsigned char)data); + if (err < 0) + return -EIO; + + return count; +} + +static ssize_t bmi160_anymot_threshold_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned char data; + int err; + + err = BMI_CALL_API(get_intr_any_motion_thres)(&data); + + if (err < 0) + return err; + return sprintf(buf, "%d\n", data); +} + +static ssize_t bmi160_anymot_threshold_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + + err = BMI_CALL_API(set_intr_any_motion_thres)((unsigned char)data); + + if (err < 0) + return -EIO; + return count; +} + +static ssize_t bmi160_step_detector_status_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data = 0; + u8 step_det; + int err; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + err = BMI_CALL_API(get_step_detector_enable)(&step_det); + /*bmi160_get_status0_step_int*/ + if (err < 0) + return err; +/*client_data->std will be updated in bmi_stepdetector_interrupt_handle */ + if ((step_det == 1) && (client_data->std == 1)) { + data = 1; + client_data->std = 0; + } + else { + data = 0; + } + return snprintf(buf, 16, "%d\n", data); +} + +static ssize_t bmi160_step_detector_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned char data; + int err; + + err = BMI_CALL_API(get_step_detector_enable)(&data); + + if (err < 0) + return err; + return sprintf(buf, "%d\n", data); +} + +static ssize_t bmi160_step_detector_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + + err = BMI_CALL_API(set_step_detector_enable)((unsigned char)data); + if (err < 0) + return -EIO; + if (data == 0) + client_data->pedo_data.wkar_step_detector_status = 0; + return count; +} + +static ssize_t bmi160_signification_motion_enable_store( + struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + /*0x62 (bit 1) INT_MOTION_3 int_sig_mot_sel*/ + err = BMI_CALL_API(set_intr_significant_motion_select)( + (unsigned char)data); + if (err < 0) + return -EIO; + if (data == 1) { + err = BMI_CALL_API(set_intr_enable_0) + (BMI160_ANY_MOTION_X_ENABLE, 1); + err += BMI_CALL_API(set_intr_enable_0) + (BMI160_ANY_MOTION_Y_ENABLE, 1); + err += BMI_CALL_API(set_intr_enable_0) + (BMI160_ANY_MOTION_Z_ENABLE, 1); + if (err < 0) + return -EIO; + client_data->sig_flag = 1; + } else { + err = BMI_CALL_API(set_intr_enable_0) + (BMI160_ANY_MOTION_X_ENABLE, 0); + err += BMI_CALL_API(set_intr_enable_0) + (BMI160_ANY_MOTION_Y_ENABLE, 0); + err += BMI_CALL_API(set_intr_enable_0) + (BMI160_ANY_MOTION_Z_ENABLE, 0); + if (err < 0) + return -EIO; + client_data->sig_flag = 0; + } + return count; +} + +static ssize_t bmi160_signification_motion_enable_show( + struct device *dev, struct device_attribute *attr, char *buf) +{ + unsigned char data; + int err; + /*0x62 (bit 1) INT_MOTION_3 int_sig_mot_sel*/ + err = BMI_CALL_API(get_intr_significant_motion_select)(&data); + + if (err < 0) + return err; + return sprintf(buf, "%d\n", data); +} + +static int sigmotion_init_interrupts(u8 sig_map_int_pin) +{ + int ret = 0; +/*0x60 */ + ret += bmi160_set_intr_any_motion_thres(0x1e); +/* 0x62(bit 3~2) 0=1.5s */ + ret += bmi160_set_intr_significant_motion_skip(0); +/*0x62(bit 5~4) 1=0.5s*/ + ret += bmi160_set_intr_significant_motion_proof(1); +/*0x50 (bit 0, 1, 2) INT_EN_0 anymo x y z*/ + ret += bmi160_map_significant_motion_intr(sig_map_int_pin); +/*0x62 (bit 1) INT_MOTION_3 int_sig_mot_sel +close the signification_motion*/ + ret += bmi160_set_intr_significant_motion_select(0); +/*close the anymotion interrupt*/ + ret += BMI_CALL_API(set_intr_enable_0) + (BMI160_ANY_MOTION_X_ENABLE, 0); + ret += BMI_CALL_API(set_intr_enable_0) + (BMI160_ANY_MOTION_Y_ENABLE, 0); + ret += BMI_CALL_API(set_intr_enable_0) + (BMI160_ANY_MOTION_Z_ENABLE, 0); + if (ret) + printk(KERN_ERR "bmi160 sig motion failed setting,%d!\n", ret); + return ret; + +} +#endif + +static ssize_t bmi160_acc_range_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err; + unsigned char range; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = BMI_CALL_API(get_accel_range)(&range); + if (err) + return err; + + client_data->range.acc_range = range; + return sprintf(buf, "%d\n", range); +} + +static ssize_t bmi160_acc_range_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int err; + unsigned long range; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + + err = kstrtoul(buf, 10, &range); + if (err) + return err; + + err = BMI_CALL_API(set_accel_range)(range); + if (err) + return -EIO; + + client_data->range.acc_range = range; + return count; +} + +static ssize_t bmi160_acc_odr_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err; + unsigned char acc_odr; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = BMI_CALL_API(get_accel_output_data_rate)(&acc_odr); + if (err) + return err; + + client_data->odr.acc_odr = acc_odr; + return sprintf(buf, "%d\n", acc_odr); +} + +static ssize_t bmi160_acc_odr_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int err; + unsigned long acc_odr; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = kstrtoul(buf, 10, &acc_odr); + if (err) + return err; + + if (acc_odr < 1 || acc_odr > 12) + return -EIO; + + if (acc_odr < 5) + err = BMI_CALL_API(set_accel_under_sampling_parameter)(1); + else + err = BMI_CALL_API(set_accel_under_sampling_parameter)(0); + + if (err) + return err; + + err = BMI_CALL_API(set_accel_output_data_rate)(acc_odr); + if (err) + return -EIO; + client_data->odr.acc_odr = acc_odr; + return count; +} + +static ssize_t bmi160_acc_op_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + int err = 0; + u8 accel_pmu_status = 0; + err = BMI_CALL_API(get_accel_power_mode_stat)( + &accel_pmu_status); + + if (err) + return err; + else + return sprintf(buf, "reg:%d, val:%d\n", accel_pmu_status, + client_data->pw.acc_pm); +} + +static ssize_t bmi160_acc_op_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + int err; + unsigned long op_mode; + err = kstrtoul(buf, 10, &op_mode); + if (err) + return err; + + err = bmi160_set_acc_op_mode(client_data, op_mode); + if (err) + return err; + else + return count; + +} + +static ssize_t bmi160_acc_value_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi160_accel_t data; + struct bmi160_axis_data_t bmi160_udata; + int err; + + err = BMI_CALL_API(read_accel_xyz)(&data); + if (err < 0) + return err; + + bmi160_udata.x = data.x; + bmi160_udata.y = data.y; + bmi160_udata.z = data.z; + + bmi_remap_sensor_data(&bmi160_udata, client_data); + return sprintf(buf, "%hd %hd %hd\n", + bmi160_udata.x, bmi160_udata.y, bmi160_udata.z); +} + +static ssize_t bmi160_acc_fast_calibration_x_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned char data; + int err; + + err = BMI_CALL_API(get_foc_accel_x)(&data); + + if (err < 0) + return err; + return sprintf(buf, "%d\n", data); +} + +static ssize_t bmi160_acc_fast_calibration_x_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + s8 accel_offset_x = 0; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + /* 0: disable, 1: +1g, 2: -1g, 3: 0g */ + if (data > 3) + return -EINVAL; + + err = BMI_CALL_API(set_accel_foc_trigger)(X_AXIS, + data, &accel_offset_x); + if (err) + return -EIO; + else + client_data->calib_status |= + BMI_FAST_CALI_TRUE << BMI_ACC_X_FAST_CALI_RDY; + return count; +} + +static ssize_t bmi160_acc_fast_calibration_y_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned char data; + int err; + + err = BMI_CALL_API(get_foc_accel_y)(&data); + + if (err < 0) + return err; + return sprintf(buf, "%d\n", data); +} + +static ssize_t bmi160_acc_fast_calibration_y_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + s8 accel_offset_y = 0; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + /* 0: disable, 1: +1g, 2: -1g, 3: 0g */ + if (data > 3) + return -EINVAL; + + err = BMI_CALL_API(set_accel_foc_trigger)(Y_AXIS, + data, &accel_offset_y); + if (err) + return -EIO; + else + client_data->calib_status |= + BMI_FAST_CALI_TRUE << BMI_ACC_Y_FAST_CALI_RDY; + return count; +} + +static ssize_t bmi160_acc_fast_calibration_z_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned char data; + int err; + + err = BMI_CALL_API(get_foc_accel_z)(&data); + + if (err < 0) + return err; + return sprintf(buf, "%d\n", data); +} + +static ssize_t bmi160_acc_fast_calibration_z_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + s8 accel_offset_z = 0; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + /* 0: disable, 1: +1g, 2: -1g, 3: 0g */ + if (data > 3) + return -EINVAL; + + err = BMI_CALL_API(set_accel_foc_trigger)(Z_AXIS, + data, &accel_offset_z); + if (err) + return -EIO; + else + client_data->calib_status |= + BMI_FAST_CALI_TRUE << BMI_ACC_Z_FAST_CALI_RDY; + + if (client_data->calib_status == BMI_FAST_CALI_ALL_RDY) { + input_event(client_data->input, EV_MSC, + INPUT_EVENT_FAST_ACC_CALIB_DONE, 1); + input_sync(client_data->input); + client_data->calib_status = 0; + } + + return count; +} + +static ssize_t bmi160_acc_offset_x_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned char data; + int err; + + err = BMI_CALL_API(get_accel_offset_compensation_xaxis)(&data); + + if (err < 0) + return err; + return sprintf(buf, "%d\n", data); +} + + +static ssize_t bmi160_acc_offset_x_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + + err = BMI_CALL_API(set_accel_offset_compensation_xaxis) + ((unsigned char)data); + + if (err < 0) + return -EIO; + return count; +} + +static ssize_t bmi160_acc_offset_y_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned char data; + int err; + + err = BMI_CALL_API(get_accel_offset_compensation_yaxis)(&data); + + if (err < 0) + return err; + return sprintf(buf, "%d\n", data); +} + +static ssize_t bmi160_acc_offset_y_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + + err = BMI_CALL_API(set_accel_offset_compensation_yaxis) + ((unsigned char)data); + + if (err < 0) + return -EIO; + return count; +} + +static ssize_t bmi160_acc_offset_z_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned char data; + int err; + + err = BMI_CALL_API(get_accel_offset_compensation_zaxis)(&data); + + if (err < 0) + return err; + return sprintf(buf, "%d\n", data); +} + +static ssize_t bmi160_acc_offset_z_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + + err = BMI_CALL_API(set_accel_offset_compensation_zaxis) + ((unsigned char)data); + + if (err < 0) + return -EIO; + return count; +} + +static ssize_t bmi160_test_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + u8 raw_data[15] = {0}; + unsigned int sensor_time = 0; + + int err; + memset(raw_data, 0, sizeof(raw_data)); + + err = client_data->device.bus_read(client_data->device.dev_addr, + BMI160_USER_DATA_8_GYRO_X_LSB__REG, raw_data, 15); + if (err) + return err; + + udelay(10); + sensor_time = (u32)(raw_data[14] << 16 | raw_data[13] << 8 + | raw_data[12]); + + return sprintf(buf, "%d %d %d %d %d %d %u", + (s16)(raw_data[1] << 8 | raw_data[0]), + (s16)(raw_data[3] << 8 | raw_data[2]), + (s16)(raw_data[5] << 8 | raw_data[4]), + (s16)(raw_data[7] << 8 | raw_data[6]), + (s16)(raw_data[9] << 8 | raw_data[8]), + (s16)(raw_data[11] << 8 | raw_data[10]), + sensor_time); + +} + +static ssize_t bmi160_step_counter_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned char data; + int err; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = BMI_CALL_API(get_step_counter_enable)(&data); + + client_data->stc_enable = data; + + if (err < 0) + return err; + return sprintf(buf, "%d\n", data); +} + +static ssize_t bmi160_step_counter_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + + err = BMI_CALL_API(set_step_counter_enable)((unsigned char)data); + + client_data->stc_enable = data; + + if (err < 0) + return -EIO; + return count; +} + + +static ssize_t bmi160_step_counter_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + + err = BMI_CALL_API(set_step_mode)((unsigned char)data); + + if (err < 0) + return -EIO; + return count; +} + +static ssize_t bmi160_step_counter_clc_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + + err = bmi160_clear_step_counter(); + + if (err < 0) + return -EIO; + return count; +} + +static ssize_t bmi160_step_counter_value_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + s16 data; + int err; + static u16 last_stc_value; + + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = BMI_CALL_API(read_step_count)(&data); + + if (err < 0) + return err; + if (data >= last_stc_value) { + client_data->pedo_data.last_step_counter_value += ( + data - last_stc_value); + last_stc_value = data; + } else + last_stc_value = data; + return sprintf(buf, "%d\n", + client_data->pedo_data.last_step_counter_value); +} + +static ssize_t bmi160_bmi_value_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + u8 raw_data[12] = {0}; + + int err; + memset(raw_data, 0, sizeof(raw_data)); + + err = client_data->device.bus_read(client_data->device.dev_addr, + BMI160_USER_DATA_8_GYRO_X_LSB__REG, raw_data, 12); + if (err) + return err; + /*output:gyro x y z acc x y z*/ + return sprintf(buf, "%hd %d %hd %hd %hd %hd\n", + (s16)(raw_data[1] << 8 | raw_data[0]), + (s16)(raw_data[3] << 8 | raw_data[2]), + (s16)(raw_data[5] << 8 | raw_data[4]), + (s16)(raw_data[7] << 8 | raw_data[6]), + (s16)(raw_data[9] << 8 | raw_data[8]), + (s16)(raw_data[11] << 8 | raw_data[10])); + +} + +static int bmi_ring_buf_get(struct bmi160_value_t *pData); +static ssize_t bmi160_ring_buf_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err = 0; + int len; + struct bmi160_value_t data; + char *tmp = buf; + + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + mutex_lock(&client_data->mutex_ring_buf); + while (bmi_ring_buf_get(&data) != 0) + { +#ifdef BMI160_MAG_INTERFACE_SUPPORT + len = sprintf(tmp, "%d %d %d %d %d %d %d %d %d %lld ", + data.acc.x, data.acc.y, data.acc.z, + data.gyro.x, data.gyro.y, data.gyro.z, + data.mag.x, data.mag.y, data.mag.z, + data.ts_intvl); +#else + len = sprintf(tmp, "%d %d %d %d %d %d %lld ", + data.acc.x, data.acc.y, data.acc.z, + data.gyro.x, data.gyro.y, data.gyro.z, + data.ts_intvl); +#endif + tmp += len; + err += len; + printk("%d %d %d %d %d %d %d %d %d %lld \n", + data.acc.x, data.acc.y, data.acc.z, + data.gyro.x, data.gyro.y, data.gyro.z, + data.mag.x, data.mag.y, data.mag.z, + data.ts_intvl); + + } + mutex_unlock(&client_data->mutex_ring_buf); + return err; + +} + +static ssize_t bmi160_selftest_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + return sprintf(buf, "0x%x\n", + atomic_read(&client_data->selftest_result)); +} + +static int bmi_restore_hw_cfg(struct bmi_client_data *client); +static void bmi_delay(u32 msec); +/*! + * @brief store selftest result which make up of acc and gyro + * format: 0b 0000 xxxx x:1 failed, 0 success + * bit3: gyro_self + * bit2..0: acc_self z y x + */ +static ssize_t bmi160_selftest_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + int err = 0; + int i = 0; + + u8 acc_selftest = 0; + u8 gyro_selftest = 0; + u8 bmi_selftest = 0; + s16 axis_p_value, axis_n_value; + u16 diff_axis[3] = {0xff, 0xff, 0xff}; + u8 acc_odr, range, acc_selftest_amp, acc_selftest_sign; + +#ifdef BMI160_MAG_INTERFACE_SUPPORT + struct bmi160_mag_xyz_s32_t pos_data; + struct bmi160_mag_xyz_s32_t neg_data; +#endif + + dev_notice(client_data->dev, "Selftest for BMI16x starting.\n"); + + client_data->selftest = 1; + +#ifdef BMI160_MAG_INTERFACE_SUPPORT + err += bmi160_set_mag_write_data(BMI160_BMM_POWER_MODE_REG); // Power mode value 0x06 + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + /*write 0x4C register to write set power mode to normal*/ + err += bmi160_set_mag_write_addr(BMI160_BMM150_POWE_MODE_REG); // write register 0x4C + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + + err += bmi160_set_mag_write_data(MAG_MODE_SUSPEND); // 0x18 Sets the PMU mode for the Magnetometer to suspend + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + err += bmi160_set_mag_write_addr(BMI160_USER_MAG_IF_3_ADDR); // write 0x18 to register 0x4E + /* write the Z repetitions*/ + /* The v_data_u8 have to write for the register + It write the value in the register 0x4F*/ + err += bmi160_set_mag_write_data(BMI160_MAG_REGULAR_REPZ); + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + err += bmi160_set_mag_write_addr(BMI160_BMM150_Z_REP); + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + + err += bmi160_set_mag_write_data(0xC2); // 0xC2 + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + err += bmi160_set_mag_write_addr(BMI160_BMM150_POWE_MODE_REG); // write register 0x4C + + bmi_delay(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + + err += bmi160_bmm150_mag_compensate_xyz(&pos_data); + bmi_delay(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + err += bmi160_set_mag_write_data(0x82); // 0x82 + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + err += bmi160_set_mag_write_addr(BMI160_BMM150_POWE_MODE_REG); // write register 0x4C + + bmi_delay(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + err += bmi160_bmm150_mag_compensate_xyz(&neg_data); + + diff_axis[2] = pos_data.z - neg_data.z; + dev_info(client_data->dev, + "pos_data.x:%d, pos_data.y:%d, pos_data.z:%d,\nneg_data.x:%d, neg_data.y:%d, neg_data.z:%d\n", + pos_data.x, pos_data.y, pos_data.z, neg_data.x, neg_data.y, neg_data.z); +#endif + + /*soft reset*/ + err = BMI_CALL_API(set_command_register)(CMD_RESET_USER_REG); + msleep(70); + err += BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_acc_arr[BMI_ACC_PM_NORMAL]); + err += BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_NORMAL]); + err += BMI_CALL_API(set_accel_under_sampling_parameter)(0); + err += BMI_CALL_API(set_accel_output_data_rate)( + BMI160_ACCEL_OUTPUT_DATA_RATE_1600HZ); + + /* set to 8G range*/ + err += BMI_CALL_API(set_accel_range)(BMI160_ACCEL_RANGE_8G); + /* set to self amp high */ + err += BMI_CALL_API(set_accel_selftest_amp)(BMI_SELFTEST_AMP_HIGH); + + + err += BMI_CALL_API(get_accel_output_data_rate)(&acc_odr); + err += BMI_CALL_API(get_accel_range)(&range); + err += BMI_CALL_API(get_accel_selftest_amp)(&acc_selftest_amp); + err += BMI_CALL_API(read_accel_x)(&axis_n_value); + + dev_info(client_data->dev, + "acc_odr:%d, acc_range:%d, acc_selftest_amp:%d, acc_x:%d\n", + acc_odr, range, acc_selftest_amp, axis_n_value); + + for (i = X_AXIS; i < AXIS_MAX; i++) { + axis_n_value = 0; + axis_p_value = 0; + /* set every selftest axis */ + /*set_acc_selftest_axis(param),param x:1, y:2, z:3 + * but X_AXIS:0, Y_AXIS:1, Z_AXIS:2 + * so we need to +1*/ + err += BMI_CALL_API(set_accel_selftest_axis)(i + 1); + msleep(50); + switch (i) { + case X_AXIS: + /* set negative sign */ + err += BMI_CALL_API(set_accel_selftest_sign)(0); + err += BMI_CALL_API(get_accel_selftest_sign)( + &acc_selftest_sign); + + msleep(60); + err += BMI_CALL_API(read_accel_x)(&axis_n_value); + dev_info(client_data->dev, + "acc_x_selftest_sign:%d, axis_n_value:%d\n", + acc_selftest_sign, axis_n_value); + + /* set postive sign */ + err += BMI_CALL_API(set_accel_selftest_sign)(1); + err += BMI_CALL_API(get_accel_selftest_sign)( + &acc_selftest_sign); + + msleep(60); + err += BMI_CALL_API(read_accel_x)(&axis_p_value); + dev_info(client_data->dev, + "acc_x_selftest_sign:%d, axis_p_value:%d\n", + acc_selftest_sign, axis_p_value); + diff_axis[i] = abs(axis_p_value - axis_n_value); + break; + + case Y_AXIS: + /* set negative sign */ + err += BMI_CALL_API(set_accel_selftest_sign)(0); + msleep(60); + err += BMI_CALL_API(read_accel_y)(&axis_n_value); + /* set postive sign */ + err += BMI_CALL_API(set_accel_selftest_sign)(1); + msleep(60); + err += BMI_CALL_API(read_accel_y)(&axis_p_value); + diff_axis[i] = abs(axis_p_value - axis_n_value); + break; + + case Z_AXIS: + /* set negative sign */ + err += BMI_CALL_API(set_accel_selftest_sign)(0); + msleep(60); + err += BMI_CALL_API(read_accel_z)(&axis_n_value); + /* set postive sign */ + err += BMI_CALL_API(set_accel_selftest_sign)(1); + msleep(60); + err += BMI_CALL_API(read_accel_z)(&axis_p_value); + /* also start gyro self test */ + err += BMI_CALL_API(set_gyro_selftest_start)(1); + msleep(60); + err += BMI_CALL_API(get_gyro_selftest)(&gyro_selftest); + + diff_axis[i] = abs(axis_p_value - axis_n_value); + break; + default: + err += -EINVAL; + break; + } + if (err) { + dev_err(client_data->dev, + "Failed selftest axis:%s, p_val=%d, n_val=%d\n", + bmi_axis_name[i], axis_p_value, axis_n_value); + client_data->selftest = 0; + return -EINVAL; + } + + /*400mg for acc z axis*/ + if (Z_AXIS == i) { + if (diff_axis[i] < 1639) { + acc_selftest |= 1 << i; + dev_err(client_data->dev, + "Over selftest minimum for " + "axis:%s,diff=%d,p_val=%d, n_val=%d\n", + bmi_axis_name[i], diff_axis[i], + axis_p_value, axis_n_value); + } + } else { + /*800mg for x or y axis*/ + if (diff_axis[i] < 3277) { + acc_selftest |= 1 << i; + + if (bmi_get_err_status(client_data) < 0) + return err; + dev_err(client_data->dev, + "Over selftest minimum for " + "axis:%s,diff=%d, p_val=%d, n_val=%d\n", + bmi_axis_name[i], diff_axis[i], + axis_p_value, axis_n_value); + dev_err(client_data->dev, "err_st:0x%x\n", + client_data->err_st.err_st_all); + + } + } + + } + /* gyro_selftest==1,gyro selftest successfully, + * but bmi_result bit4 0 is successful, 1 is failed*/ + bmi_selftest = (acc_selftest & 0x0f) | ((!gyro_selftest) << AXIS_MAX); + atomic_set(&client_data->selftest_result, bmi_selftest); + /*soft reset*/ + err = BMI_CALL_API(set_command_register)(CMD_RESET_USER_REG); + if (err) { + client_data->selftest = 0; + return err; + } + msleep(50); + + bmi_restore_hw_cfg(client_data); + + client_data->selftest = 0; + dev_notice(client_data->dev, "Selftest for BMI16x finished\n"); + + return count; +} + +/* gyro sensor part */ +static ssize_t bmi160_gyro_op_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + int err = 0; + u8 gyro_pmu_status = 0; + + err = BMI_CALL_API(get_gyro_power_mode_stat)( + &gyro_pmu_status); + + if (err) + return err; + else + return sprintf(buf, "reg:%d, val:%d\n", gyro_pmu_status, + client_data->pw.gyro_pm); +} + +static ssize_t bmi160_gyro_op_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + unsigned long op_mode; + int err; + + err = kstrtoul(buf, 10, &op_mode); + if (err) + return err; + + mutex_lock(&client_data->mutex_op_mode); + + if (op_mode < BMI_GYRO_PM_MAX) { + switch (op_mode) { + case BMI_GYRO_PM_NORMAL: + err = BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_NORMAL]); + client_data->pw.gyro_pm = BMI_GYRO_PM_NORMAL; + mdelay(60); + break; + case BMI_GYRO_PM_FAST_START: + err = BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_FAST_START]); + client_data->pw.gyro_pm = BMI_GYRO_PM_FAST_START; + mdelay(60); + break; + case BMI_GYRO_PM_SUSPEND: + err = BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_SUSPEND]); + client_data->pw.gyro_pm = BMI_GYRO_PM_SUSPEND; + mdelay(60); + break; + default: + mutex_unlock(&client_data->mutex_op_mode); + return -EINVAL; + } + } else { + mutex_unlock(&client_data->mutex_op_mode); + return -EINVAL; + } + + mutex_unlock(&client_data->mutex_op_mode); + + if (err) + return err; + else + return count; + +} + +static ssize_t bmi160_gyro_value_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi160_gyro_t data; + struct bmi160_axis_data_t bmi160_udata; + int err; + + err = BMI_CALL_API(read_gyro_xyz)(&data); + if (err < 0) + return err; + + bmi160_udata.x = data.x; + bmi160_udata.y = data.y; + bmi160_udata.z = data.z; + + bmi_remap_sensor_data(&bmi160_udata, client_data); + + return sprintf(buf, "%hd %hd %hd\n", bmi160_udata.x, + bmi160_udata.y, bmi160_udata.z); +} + +static ssize_t bmi160_gyro_range_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err; + unsigned char range; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = BMI_CALL_API(get_gyro_range)(&range); + if (err) + return err; + + client_data->range.gyro_range = range; + return sprintf(buf, "%d\n", range); +} + +static ssize_t bmi160_gyro_range_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int err; + unsigned long range; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = kstrtoul(buf, 10, &range); + if (err) + return err; + + err = BMI_CALL_API(set_gyro_range)(range); + if (err) + return -EIO; + + client_data->range.gyro_range = range; + return count; +} + +static ssize_t bmi160_gyro_odr_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err; + unsigned char gyro_odr; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = BMI_CALL_API(get_gyro_output_data_rate)(&gyro_odr); + if (err) + return err; + + client_data->odr.gyro_odr = gyro_odr; + return sprintf(buf, "%d\n", gyro_odr); +} + +static ssize_t bmi160_gyro_odr_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int err; + unsigned long gyro_odr; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = kstrtoul(buf, 10, &gyro_odr); + if (err) + return err; + + if (gyro_odr < 6 || gyro_odr > 13) + return -EIO; + + err = BMI_CALL_API(set_gyro_output_data_rate)(gyro_odr); + if (err) + return -EIO; + + client_data->odr.gyro_odr = gyro_odr; + return count; +} + +static ssize_t bmi160_gyro_fast_calibration_en_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned char data; + int err; + + err = BMI_CALL_API(get_foc_gyro_enable)(&data); + + if (err < 0) + return err; + return sprintf(buf, "%d\n", data); +} + +static ssize_t bmi160_gyro_fast_calibration_en_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long enable; + s8 err; + s16 gyr_off_x; + s16 gyr_off_y; + s16 gyr_off_z; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = kstrtoul(buf, 10, &enable); + if (err) + return err; + + err = BMI_CALL_API(set_foc_gyro_enable)((u8)enable, + &gyr_off_x, &gyr_off_y, &gyr_off_z); + + if (err < 0) + return -EIO; + else { + input_event(client_data->input, EV_MSC, + INPUT_EVENT_FAST_GYRO_CALIB_DONE, 1); + input_sync(client_data->input); + } + return count; +} + +static ssize_t bmi160_gyro_offset_x_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + s16 data = 0; + s8 err = 0; + + err = BMI_CALL_API(get_gyro_offset_compensation_xaxis)(&data); + + if (err < 0) + return err; + return sprintf(buf, "%d\n", data); +} + +static ssize_t bmi160_gyro_offset_x_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + s8 err; + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + + err = BMI_CALL_API(set_gyro_offset_compensation_xaxis)((s16)data); + + if (err < 0) + return -EIO; + return count; +} + +static ssize_t bmi160_gyro_offset_y_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + s16 data = 0; + s8 err = 0; + + err = BMI_CALL_API(get_gyro_offset_compensation_yaxis)(&data); + + if (err < 0) + return err; + return sprintf(buf, "%d\n", data); +} + +static ssize_t bmi160_gyro_offset_y_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + s8 err; + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + + err = BMI_CALL_API(set_gyro_offset_compensation_yaxis)((s16)data); + + if (err < 0) + return -EIO; + return count; +} + +static ssize_t bmi160_gyro_offset_z_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + s16 data = 0; + int err = 0; + + err = BMI_CALL_API(get_gyro_offset_compensation_zaxis)(&data); + + if (err < 0) + return err; + return sprintf(buf, "%d\n", data); +} + +static ssize_t bmi160_gyro_offset_z_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + + err = BMI_CALL_API(set_gyro_offset_compensation_zaxis)((s16)data); + + if (err < 0) + return -EIO; + return count; +} + + +/* mag sensor part */ +#ifdef BMI160_MAG_INTERFACE_SUPPORT +static ssize_t bmi160_mag_op_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + u8 mag_op_mode; + s8 err; + err = bmi160_get_mag_power_mode_stat(&mag_op_mode); + if (err) { + dev_err(client_data->dev, + "Failed to get BMI160 mag power mode:%d\n", err); + return err; + } else + return sprintf(buf, "%d, reg:%d\n", + client_data->pw.mag_pm, mag_op_mode); +} + +static ssize_t bmi160_mag_op_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + unsigned long op_mode; + int err; + + err = kstrtoul(buf, 10, &op_mode); + if (err) + return err; + + if (op_mode == client_data->pw.mag_pm) + return count; + + mutex_lock(&client_data->mutex_op_mode); + + + if (op_mode < BMI_MAG_PM_MAX) { + switch (op_mode) { + case BMI_MAG_PM_NORMAL: + /* need to modify as mag sensor connected, + * set write address to 0x4c and triggers + * write operation + * 0x4c(op mode control reg) + * enables normal mode in magnetometer */ +#ifdef BMI160_AKM09912_SUPPORT + err = bmi160_set_bst_akm_and_secondary_if_powermode + (BMI160_MAG_FORCE_MODE); +#else + err = bmi160_set_bmm150_mag_and_secondary_if_power_mode + (BMI160_MAG_FORCE_MODE); +#endif + client_data->pw.mag_pm = BMI_MAG_PM_NORMAL; + mdelay(5); + break; + case BMI_MAG_PM_LP1: + /* need to modify as mag sensor connected, + * set write address to 0x4 band triggers + * write operation + * 0x4b(bmm150, power control reg, bit0) + * enables power in magnetometer*/ +#ifdef BMI160_AKM09912_SUPPORT + err = bmi160_set_bst_akm_and_secondary_if_powermode + (BMI160_MAG_FORCE_MODE); +#else + err = bmi160_set_bmm150_mag_and_secondary_if_power_mode + (BMI160_MAG_FORCE_MODE); +#endif + client_data->pw.mag_pm = BMI_MAG_PM_LP1; + mdelay(5); + break; + case BMI_MAG_PM_SUSPEND: + case BMI_MAG_PM_LP2: +#ifdef BMI160_AKM09912_SUPPORT + err = bmi160_set_bst_akm_and_secondary_if_powermode + (BMI160_MAG_SUSPEND_MODE); +#else + err = bmi160_set_bmm150_mag_and_secondary_if_power_mode + (BMI160_MAG_SUSPEND_MODE); +#endif + client_data->pw.mag_pm = op_mode; + mdelay(5); + break; + default: + mutex_unlock(&client_data->mutex_op_mode); + return -EINVAL; + } + } else { + mutex_unlock(&client_data->mutex_op_mode); + return -EINVAL; + } + + mutex_unlock(&client_data->mutex_op_mode); + + if (err) { + dev_err(client_data->dev, + "Failed to switch BMI160 mag power mode:%d\n", + client_data->pw.mag_pm); + return err; + } else + return count; + +} + +static ssize_t bmi160_mag_odr_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err = 0; + unsigned char mag_odr = 0; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = BMI_CALL_API(get_mag_output_data_rate)(&mag_odr); + if (err) + return err; + + client_data->odr.mag_odr = mag_odr; + return sprintf(buf, "%d\n", mag_odr); +} + +static ssize_t bmi160_mag_odr_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int err; + unsigned long mag_odr; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = kstrtoul(buf, 10, &mag_odr); + if (err) + return err; + /*1~25/32hz,..6(25hz),7(50hz),... */ + err = BMI_CALL_API(set_mag_output_data_rate)(mag_odr); + if (err) + return -EIO; + + client_data->odr.mag_odr = mag_odr; + return count; +} + +static ssize_t bmi160_mag_i2c_address_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data; + s8 err; + + err = BMI_CALL_API(set_mag_manual_enable)(1); + err += BMI_CALL_API(get_i2c_device_addr)(&data); + err += BMI_CALL_API(set_mag_manual_enable)(0); + + if (err < 0) + return err; + return sprintf(buf, "0x%x\n", data); +} + +static ssize_t bmi160_mag_i2c_address_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + + err += BMI_CALL_API(set_mag_manual_enable)(1); + if (!err) + err += BMI_CALL_API(set_i2c_device_addr)((unsigned char)data); + err += BMI_CALL_API(set_mag_manual_enable)(0); + + if (err < 0) + return -EIO; + return count; +} + +static ssize_t bmi160_mag_value_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi160_mag_xyz_s32_t data; + + struct bmi160_axis_data_t bmi160_udata; + int err; + /* raw data with compensation */ +#ifdef BMI160_AKM09912_SUPPORT + err = bmi160_bst_akm09912_compensate_xyz(&data); +#else + err = bmi160_bmm150_mag_compensate_xyz(&data); +#endif + + if (err < 0) { + memset(&data, 0, sizeof(data)); + dev_err(client_data->dev, "mag not ready!\n"); + } + bmi160_udata.x = data.x; + bmi160_udata.y = data.y; + bmi160_udata.z = data.z; + + bmi_remap_sensor_data(&bmi160_udata, client_data); + return sprintf(buf, "%hd %hd %hd\n", bmi160_udata.x, + bmi160_udata.y, bmi160_udata.z); + +} + +static ssize_t bmi160_mag_offset_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err = 0; + unsigned char mag_offset; + err = BMI_CALL_API(get_mag_offset)(&mag_offset); + if (err) + return err; + + return sprintf(buf, "%d\n", mag_offset); + +} + +static ssize_t bmi160_mag_offset_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + + err += BMI_CALL_API(set_mag_manual_enable)(1); + if (err == 0) + err += BMI_CALL_API(set_mag_offset)((unsigned char)data); + err += BMI_CALL_API(set_mag_manual_enable)(0); + + if (err < 0) + return -EIO; + return count; +} + +static ssize_t bmi160_mag_chip_id_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + s8 err = 0; + u8 mag_chipid; + + err = bmi160_set_mag_manual_enable(0x01); + /* read mag chip_id value */ +#ifdef BMI160_AKM09912_SUPPORT + err += bmi160_set_mag_read_addr(AKM09912_CHIP_ID_REG); + /* 0x04 is mag_x lsb register */ + err += bmi160_read_reg(BMI160_USER_DATA_0_MAG_X_LSB__REG, + &mag_chipid, 1); + + /* Must add this commands to re-set data register addr of mag sensor */ + err += bmi160_set_mag_read_addr(AKM_DATA_REGISTER); +#else + err += bmi160_set_mag_read_addr(BMI160_BMM150_CHIP_ID); + /* 0x04 is mag_x lsb register */ + err += bmi160_read_reg(BMI160_USER_DATA_0_MAG_X_LSB__REG, + &mag_chipid, 1); + + /* Must add this commands to re-set data register addr of mag sensor */ + /* 0x42 is bmm150 data register address */ + err += bmi160_set_mag_read_addr(BMI160_BMM150_DATA_REG); +#endif + + err += bmi160_set_mag_manual_enable(0x00); + + if (err) + return err; + + return sprintf(buf, "chip_id:0x%x\n", mag_chipid); + +} + +#endif + +#if defined(BMI160_ENABLE_INT1) || defined(BMI160_ENABLE_INT2) +static ssize_t bmi_enable_int_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int interrupt_type, value; + + sscanf(buf, "%3d %3d", &interrupt_type, &value); + + if (interrupt_type < 0 || interrupt_type > 16) + return -EINVAL; + + if (interrupt_type <= BMI_FLAT_INT) { + if (BMI_CALL_API(set_intr_enable_0) + (bmi_interrupt_type[interrupt_type], value) < 0) + return -EINVAL; + } else if (interrupt_type <= BMI_FWM_INT) { + if (BMI_CALL_API(set_intr_enable_1) + (bmi_interrupt_type[interrupt_type], value) < 0) + return -EINVAL; + } else { + if (BMI_CALL_API(set_intr_enable_2) + (bmi_interrupt_type[interrupt_type], value) < 0) + return -EINVAL; + } + + return count; +} + +#endif + +static ssize_t bmi_register_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + bmi_dump_reg(client_data); + + return sprintf(buf, "Dump OK\n"); +} + +static ssize_t bmi_register_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int err; + int reg_addr = 0; + int data; + u8 write_reg_add = 0; + u8 write_data = 0; + struct input_dev *input = to_input_dev(dev); + struct bmi_client_data *client_data = input_get_drvdata(input); + + err = sscanf(buf, "%3d %3d", ®_addr, &data); + if (err < 2) + return err; + + if (data > 0xff) + return -EINVAL; + + write_reg_add = (u8)reg_addr; + write_data = (u8)data; + err += BMI_CALL_API(write_reg)(write_reg_add, &write_data, 1); + + if (!err) { + dev_info(client_data->dev, "write reg 0x%2x, value= 0x%2x\n", + reg_addr, data); + } else { + dev_err(client_data->dev, "write reg fail\n"); + return err; + } + return count; +} + +static DEVICE_ATTR(chip_id, S_IRUGO, + bmi160_chip_id_show, NULL); +static DEVICE_ATTR(err_st, S_IRUGO, + bmi160_err_st_show, NULL); +static DEVICE_ATTR(sensor_time, S_IRUGO, + bmi160_sensor_time_show, NULL); + +static DEVICE_ATTR(selftest, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_selftest_show, bmi160_selftest_store); +static DEVICE_ATTR(fifo_flush, S_IWUSR|S_IWGRP|S_IWOTH, + NULL, bmi160_fifo_flush_store); +static DEVICE_ATTR(fifo_bytecount, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_fifo_bytecount_show, bmi160_fifo_bytecount_store); +static DEVICE_ATTR(fifo_data_sel, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_fifo_data_sel_show, bmi160_fifo_data_sel_store); +static DEVICE_ATTR(fifo_data_frame, S_IRUGO, + bmi160_fifo_data_out_frame_show, NULL); + +static DEVICE_ATTR(fifo_watermark, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_fifo_watermark_show, bmi160_fifo_watermark_store); + +static DEVICE_ATTR(fifo_header_en, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_fifo_header_en_show, bmi160_fifo_header_en_store); +static DEVICE_ATTR(fifo_time_en, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_fifo_time_en_show, bmi160_fifo_time_en_store); +static DEVICE_ATTR(fifo_int_tag_en, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_fifo_int_tag_en_show, bmi160_fifo_int_tag_en_store); + +static DEVICE_ATTR(temperature, S_IRUGO, + bmi160_temperature_show, NULL); +static DEVICE_ATTR(place, S_IRUGO, + bmi160_place_show, NULL); +static DEVICE_ATTR(delay, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_delay_show, bmi160_delay_store); +static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_enable_show, bmi160_enable_store); +static DEVICE_ATTR(acc_range, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_acc_range_show, bmi160_acc_range_store); +static DEVICE_ATTR(acc_odr, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_acc_odr_show, bmi160_acc_odr_store); +static DEVICE_ATTR(acc_op_mode, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_acc_op_mode_show, bmi160_acc_op_mode_store); +static DEVICE_ATTR(acc_value, S_IRUGO, + bmi160_acc_value_show, NULL); +static DEVICE_ATTR(acc_fast_calibration_x, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_acc_fast_calibration_x_show, + bmi160_acc_fast_calibration_x_store); +static DEVICE_ATTR(acc_fast_calibration_y, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_acc_fast_calibration_y_show, + bmi160_acc_fast_calibration_y_store); +static DEVICE_ATTR(acc_fast_calibration_z, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_acc_fast_calibration_z_show, + bmi160_acc_fast_calibration_z_store); +static DEVICE_ATTR(acc_offset_x, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_acc_offset_x_show, + bmi160_acc_offset_x_store); +static DEVICE_ATTR(acc_offset_y, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_acc_offset_y_show, + bmi160_acc_offset_y_store); +static DEVICE_ATTR(acc_offset_z, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_acc_offset_z_show, + bmi160_acc_offset_z_store); +static DEVICE_ATTR(test, S_IRUGO, + bmi160_test_show, NULL); +static DEVICE_ATTR(stc_enable, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_step_counter_enable_show, + bmi160_step_counter_enable_store); +static DEVICE_ATTR(stc_mode, S_IWUSR|S_IWGRP|S_IWOTH, + NULL, bmi160_step_counter_mode_store); +static DEVICE_ATTR(stc_clc, S_IWUSR|S_IWGRP|S_IWOTH, + NULL, bmi160_step_counter_clc_store); +static DEVICE_ATTR(stc_value, S_IRUGO, + bmi160_step_counter_value_show, NULL); + + +/* gyro part */ +static DEVICE_ATTR(gyro_op_mode, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_gyro_op_mode_show, bmi160_gyro_op_mode_store); +static DEVICE_ATTR(gyro_value, S_IRUGO, + bmi160_gyro_value_show, NULL); +static DEVICE_ATTR(gyro_range, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_gyro_range_show, bmi160_gyro_range_store); +static DEVICE_ATTR(gyro_odr, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_gyro_odr_show, bmi160_gyro_odr_store); +static DEVICE_ATTR(gyro_fast_calibration_en, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, +bmi160_gyro_fast_calibration_en_show, bmi160_gyro_fast_calibration_en_store); +static DEVICE_ATTR(gyro_offset_x, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, +bmi160_gyro_offset_x_show, bmi160_gyro_offset_x_store); +static DEVICE_ATTR(gyro_offset_y, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, +bmi160_gyro_offset_y_show, bmi160_gyro_offset_y_store); +static DEVICE_ATTR(gyro_offset_z, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, +bmi160_gyro_offset_z_show, bmi160_gyro_offset_z_store); + +#ifdef BMI160_MAG_INTERFACE_SUPPORT +static DEVICE_ATTR(mag_op_mode, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_mag_op_mode_show, bmi160_mag_op_mode_store); +static DEVICE_ATTR(mag_odr, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_mag_odr_show, bmi160_mag_odr_store); +static DEVICE_ATTR(mag_i2c_addr, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_mag_i2c_address_show, bmi160_mag_i2c_address_store); +static DEVICE_ATTR(mag_value, S_IRUGO, + bmi160_mag_value_show, NULL); +static DEVICE_ATTR(mag_offset, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_mag_offset_show, bmi160_mag_offset_store); + +static DEVICE_ATTR(mag_chip_id, S_IRUGO, + bmi160_mag_chip_id_show, NULL); + +#endif + + +#if defined(BMI160_ENABLE_INT1) || defined(BMI160_ENABLE_INT2) +static DEVICE_ATTR(enable_int, S_IWUSR|S_IWGRP|S_IWOTH, + NULL, bmi_enable_int_store); +static DEVICE_ATTR(anymot_duration, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_anymot_duration_show, bmi160_anymot_duration_store); +static DEVICE_ATTR(anymot_threshold, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_anymot_threshold_show, bmi160_anymot_threshold_store); +static DEVICE_ATTR(std_stu, S_IRUGO, + bmi160_step_detector_status_show, NULL); +static DEVICE_ATTR(std_en, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_step_detector_enable_show, + bmi160_step_detector_enable_store); +static DEVICE_ATTR(sig_en, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_signification_motion_enable_show, + bmi160_signification_motion_enable_store); + +#endif +static DEVICE_ATTR(enable_timer, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi_show_enable_timer, bmi_store_enable_timer); + +static DEVICE_ATTR(register, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi_register_show, bmi_register_store); + +static DEVICE_ATTR(bmi_value, S_IRUGO, + bmi160_bmi_value_show, NULL); + +static DEVICE_ATTR(bmi_ring_buf, S_IRUGO, + bmi160_ring_buf_show, NULL); + + +static struct attribute *bmi160_attributes[] = { + &dev_attr_chip_id.attr, + &dev_attr_err_st.attr, + &dev_attr_sensor_time.attr, + &dev_attr_selftest.attr, + + &dev_attr_test.attr, + &dev_attr_fifo_flush.attr, + &dev_attr_fifo_header_en.attr, + &dev_attr_fifo_time_en.attr, + &dev_attr_fifo_int_tag_en.attr, + &dev_attr_fifo_bytecount.attr, + &dev_attr_fifo_data_sel.attr, + &dev_attr_fifo_data_frame.attr, + + &dev_attr_fifo_watermark.attr, + + &dev_attr_enable.attr, + &dev_attr_delay.attr, + &dev_attr_temperature.attr, + &dev_attr_place.attr, + + &dev_attr_acc_range.attr, + &dev_attr_acc_odr.attr, + &dev_attr_acc_op_mode.attr, + &dev_attr_acc_value.attr, + + &dev_attr_acc_fast_calibration_x.attr, + &dev_attr_acc_fast_calibration_y.attr, + &dev_attr_acc_fast_calibration_z.attr, + &dev_attr_acc_offset_x.attr, + &dev_attr_acc_offset_y.attr, + &dev_attr_acc_offset_z.attr, + + &dev_attr_stc_enable.attr, + &dev_attr_stc_mode.attr, + &dev_attr_stc_clc.attr, + &dev_attr_stc_value.attr, + + &dev_attr_gyro_op_mode.attr, + &dev_attr_gyro_value.attr, + &dev_attr_gyro_range.attr, + &dev_attr_gyro_odr.attr, + &dev_attr_gyro_fast_calibration_en.attr, + &dev_attr_gyro_offset_x.attr, + &dev_attr_gyro_offset_y.attr, + &dev_attr_gyro_offset_z.attr, + +#ifdef BMI160_MAG_INTERFACE_SUPPORT + &dev_attr_mag_chip_id.attr, + &dev_attr_mag_op_mode.attr, + &dev_attr_mag_odr.attr, + &dev_attr_mag_i2c_addr.attr, + &dev_attr_mag_value.attr, + &dev_attr_mag_offset.attr, + +#endif + +#if defined(BMI160_ENABLE_INT1) || defined(BMI160_ENABLE_INT2) + &dev_attr_enable_int.attr, + + &dev_attr_anymot_duration.attr, + &dev_attr_anymot_threshold.attr, + &dev_attr_std_stu.attr, + &dev_attr_std_en.attr, + &dev_attr_sig_en.attr, + +#endif + &dev_attr_enable_timer.attr, + &dev_attr_register.attr, + &dev_attr_bmi_value.attr, + &dev_attr_bmi_ring_buf.attr, + NULL +}; + +static struct attribute_group bmi160_attribute_group = { + .attrs = bmi160_attributes +}; + +static void bmi_delay(u32 msec) +{ + mdelay(msec); +} + +#if defined(BMI160_ENABLE_INT1) || defined(BMI160_ENABLE_INT2) +static void bmi_slope_interrupt_handle(struct bmi_client_data *client_data) +{ + /* anym_first[0..2]: x, y, z */ + u8 anym_first[3] = {0}; + u8 status2; + u8 anym_sign; + u8 i = 0; + + client_data->device.bus_read(client_data->device.dev_addr, + BMI160_USER_INTR_STAT_2_ADDR, &status2, 1); + anym_first[0] = BMI160_GET_BITSLICE(status2, + BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_X); + anym_first[1] = BMI160_GET_BITSLICE(status2, + BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y); + anym_first[2] = BMI160_GET_BITSLICE(status2, + BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z); + anym_sign = BMI160_GET_BITSLICE(status2, + BMI160_USER_INTR_STAT_2_ANY_MOTION_SIGN); + + for (i = 0; i < 3; i++) { + if (anym_first[i]) { + /*1: negative*/ + if (anym_sign) + dev_notice(client_data->dev, + "Anymotion interrupt happend!" + "%s axis, negative sign\n", bmi_axis_name[i]); + else + dev_notice(client_data->dev, + "Anymotion interrupt happend!" + "%s axis, postive sign\n", bmi_axis_name[i]); + } + } + + +} + +static uint64_t bmi_get_alarm_timestamp_ns(void) +{ + uint64_t ts_ap; + struct timespec tmp_time; + get_monotonic_boottime(&tmp_time); + ts_ap = (uint64_t)tmp_time.tv_sec * 1000000000L + tmp_time.tv_nsec; + return ts_ap; +} + + +static int bmi_ring_buf_empty(void) +{ + return s_ring_buf_head == s_ring_buf_tail; +} + +static int bmi_ring_buf_full(void) +{ + return (s_ring_buf_tail + 1) % BMI_RING_BUF_SIZE == s_ring_buf_head; +} + +static int bmi_ring_buf_put(struct bmi160_value_t data) +{ + if (bmi_ring_buf_full()) + return 0; + + bmi_ring_buf[s_ring_buf_tail].acc.x = data.acc.x; + bmi_ring_buf[s_ring_buf_tail].acc.y = data.acc.y; + bmi_ring_buf[s_ring_buf_tail].acc.z = data.acc.z; + bmi_ring_buf[s_ring_buf_tail].gyro.x = data.gyro.x; + bmi_ring_buf[s_ring_buf_tail].gyro.y = data.gyro.y; + bmi_ring_buf[s_ring_buf_tail].gyro.z = data.gyro.z; +#ifdef BMI160_MAG_INTERFACE_SUPPORT + bmi_ring_buf[s_ring_buf_tail].mag.x = data.mag.x; + bmi_ring_buf[s_ring_buf_tail].mag.y = data.mag.y; + bmi_ring_buf[s_ring_buf_tail].mag.z = data.mag.z; +#endif + bmi_ring_buf[s_ring_buf_tail].ts_intvl= data.ts_intvl; +/* printk(KERN_ERR "put bmi data %d, %d, %d, %d, %d, %d, %lld", + bmi_ring_buf[s_ring_buf_tail].acc.x, + bmi_ring_buf[s_ring_buf_tail].acc.y, + bmi_ring_buf[s_ring_buf_tail].acc.z, + bmi_ring_buf[s_ring_buf_tail].gyro.x, + bmi_ring_buf[s_ring_buf_tail].gyro.y, + bmi_ring_buf[s_ring_buf_tail].gyro.z, + + bmi_ring_buf[s_ring_buf_tail].ts_intvl); +*/ + s_ring_buf_tail = (s_ring_buf_tail + 1) % BMI_RING_BUF_SIZE; + + return 1; +} + +static int bmi_ring_buf_get(struct bmi160_value_t *pData) +{ + if (bmi_ring_buf_empty()) + return 0; + + pData->acc.x = bmi_ring_buf[s_ring_buf_head].acc.x; + pData->acc.y = bmi_ring_buf[s_ring_buf_head].acc.y; + pData->acc.z = bmi_ring_buf[s_ring_buf_head].acc.z; + pData->gyro.x = bmi_ring_buf[s_ring_buf_head].gyro.x; + pData->gyro.y = bmi_ring_buf[s_ring_buf_head].gyro.y; + pData->gyro.z = bmi_ring_buf[s_ring_buf_head].gyro.z; +#ifdef BMI160_MAG_INTERFACE_SUPPORT + pData->mag.x = bmi_ring_buf[s_ring_buf_head].mag.x; + pData->mag.y = bmi_ring_buf[s_ring_buf_head].mag.y; + pData->mag.z = bmi_ring_buf[s_ring_buf_head].mag.z; +#endif + pData->ts_intvl = bmi_ring_buf[s_ring_buf_head].ts_intvl; + + s_ring_buf_head = (s_ring_buf_head + 1) % BMI_RING_BUF_SIZE; + + return 1; +} + + +static int bmi_fifo_get_decode_data(struct bmi160_axis_data_t *acc, + struct bmi160_axis_data_t *gyro, + struct bmi160_axis_data_t *mag, + u8 *fifo_data, + u16 fifo_index) +{ + /* array index to get elements from fifo data*/ + u16 array_index = 0; + + /* get xyzr axis mag data */ + if (mag != NULL) + { + struct bmi160_mag_xyzr_t mag_valid; + struct bmi160_mag_xyzr_t mag_data; + struct bmi160_mag_xyz_s32_t mag_comp_xyz; + mag_data.x = fifo_data[fifo_index + 0] + | fifo_data[fifo_index + 1] << 8; + mag_data.y = fifo_data[fifo_index + 2] + | fifo_data[fifo_index + 3] << 8; + mag_data.z = fifo_data[fifo_index + 4] + | fifo_data[fifo_index + 5] << 8; + mag_data.r = fifo_data[fifo_index + 6] + | fifo_data[fifo_index + 7] << 8; + fifo_index += 8; + mag_valid.x = mag_data.x >> 3; + mag_valid.y = mag_data.y >> 3; + mag_valid.z = mag_data.z >> 1; + mag_valid.r = mag_data.r >> 2; + bmi160_bmm150_mag_compensate_xyz_raw(&mag_comp_xyz, mag_valid); + mag->x = mag_comp_xyz.x; + mag->y = mag_comp_xyz.y; + mag->z = mag_comp_xyz.z; + } + + /* get xyz axis gyro data */ + if (gyro != NULL) + { + gyro->x = fifo_data[fifo_index + 0] + | fifo_data[fifo_index + 1] << 8; + gyro->y = fifo_data[fifo_index + 2] + | fifo_data[fifo_index + 3] << 8; + gyro->z = fifo_data[fifo_index + 4] + | fifo_data[fifo_index + 5] << 8; + fifo_index += 6; + } + + /* get xyz axis accel data */ + if (acc != NULL) + { + acc->x = fifo_data[fifo_index + 0] + | fifo_data[fifo_index + 1] << 8; + acc->y = fifo_data[fifo_index + 2] + | fifo_data[fifo_index + 3] << 8; + acc->z = fifo_data[fifo_index + 4] + | fifo_data[fifo_index + 5] << 8; + fifo_index += 6; + } + + return array_index; + +} + +static int bmi_pow(int x, int y) +{ + int result = 1; + + if (y == 1) + return x; + + + if (y > 0) { + while (--y) { + result *= x; + } + } else { + result = 0; + } + + return result; +} + +/* +* Decoding of FIFO frames (only exemplary subset). Calculates accurate timestamps based on the +* drift information. Returns value of the SENSORTIME frame. +* +* fifo_data_buf pointer to fetched FIFO buffer +* fifo_length number of valid bytes in the FIFO buffer +* drift clock drift value, needed to calculate accurate timestamps +* timestamp initial timestamp for the first sample of the FIFO chunk +* acc_odr current value of the ACC_CONF.acc_odr register field +*/ +static uint64_t bmi_fifo_data_decode(uint8_t *fifo_data_buf, uint16_t fifo_length, + int drift, uint64_t timestamp, int odr_pow) +{ + int idx = 0; + uint8_t header; + //int16_t x, y, z; + uint64_t fifo_time = 0; + uint64_t timestamp_next = timestamp; + struct bmi160_value_t bmi160_value; + + while (idx < fifo_length) { + header = fifo_data_buf[idx]; + memset (&bmi160_value, 0, sizeof (bmi160_value)); + switch (header) { + case FIFO_HEAD_SENSOR_TIME: + /* sensortime frame, length = 4 bytes*/ + if (idx + 3 < fifo_length) { + fifo_time = fifo_data_buf[idx + 1] | + fifo_data_buf[idx + 2] << 8 | + fifo_data_buf[idx + 3] << 16; + //printk(KERN_INFO "sensorts %llu", fifo_time); + return fifo_time; + } + idx += 4; + break; + case FIFO_HEAD_A: + /* accel frame, length = 7 bytes */ + idx += 1; + if (idx + 6 < fifo_length) { + bmi_fifo_get_decode_data(&bmi160_value.acc, NULL, NULL, fifo_data_buf, idx); + bmi160_value.ts_intvl = (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + if (bmi_ring_buf_put(bmi160_value) == 0) + printk(KERN_INFO "bmi ring buf full head %d, tail %d", + s_ring_buf_head, s_ring_buf_tail); + if (drift > 0) + timestamp_next += (uint64_t)(625 * odr_pow * drift); + else + timestamp_next += (uint64_t)(625 * odr_pow * 1000); + //printk (KERN_INFO "drift %d, ts_next %llu, %d, %d, %d, %llu", + // drift, timestamp_next, x, y, z, (uint64_t)(625 * odr_pow * 1000)); + + idx += 6; + break; + case FIFO_HEAD_G: + /* gyro frame, length = 7 bytes */ + idx += 1; + if (idx + 6 < fifo_length) { + bmi_fifo_get_decode_data(NULL,&bmi160_value.gyro, NULL, fifo_data_buf, idx); + bmi160_value.ts_intvl = (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + if (bmi_ring_buf_put(bmi160_value) == 0) + printk(KERN_INFO "bmi ring buf full head %d, tail %d", + s_ring_buf_head, s_ring_buf_tail); + } + + idx += 6; + break; + case FIFO_HEAD_G_A: + idx += 1; + if (idx + 12 < fifo_length) { + bmi_fifo_get_decode_data(&bmi160_value.acc,&bmi160_value.gyro, NULL, fifo_data_buf, idx); + bmi160_value.ts_intvl = (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + if (bmi_ring_buf_put(bmi160_value) == 0) + printk(KERN_INFO "bmi ring buf full head %d, tail %d", + s_ring_buf_head, s_ring_buf_tail); + } + + idx += 12; + break; +#ifdef BMI160_MAG_INTERFACE_SUPPORT + case FIFO_HEAD_M: + idx +=1; + if (idx + 8 < fifo_length) { + bmi_fifo_get_decode_data(NULL, NULL, &bmi160_value.mag, fifo_data_buf, idx); + bmi160_value.ts_intvl = (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + if (bmi_ring_buf_put(bmi160_value) == 0) + printk(KERN_INFO "bmi ring buf full head %d, tail %d", + s_ring_buf_head, s_ring_buf_tail); + } + + idx += 8; + break; + case FIFO_HEAD_M_A: + idx +=1; + if (idx + 14 < fifo_length) { + bmi_fifo_get_decode_data(&bmi160_value.acc, NULL, &bmi160_value.mag, fifo_data_buf, idx); + bmi160_value.ts_intvl = (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + if (bmi_ring_buf_put(bmi160_value) == 0) + printk(KERN_INFO "bmi ring buf full head %d, tail %d", + s_ring_buf_head, s_ring_buf_tail); + } + + idx += 14; + break; + + case FIFO_HEAD_M_G: + idx +=1; + if (idx + 14 < fifo_length) { + bmi_fifo_get_decode_data(NULL, &bmi160_value.gyro, &bmi160_value.mag, fifo_data_buf, idx); + bmi160_value.ts_intvl = (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + if (bmi_ring_buf_put(bmi160_value) == 0) + printk(KERN_INFO "bmi ring buf full head %d, tail %d", + s_ring_buf_head, s_ring_buf_tail); + } + + idx += 14; + break; + case FIFO_HEAD_M_G_A: + idx +=1; + if (idx + 20 < fifo_length) { + bmi_fifo_get_decode_data(&bmi160_value.acc, &bmi160_value.gyro, &bmi160_value.mag, fifo_data_buf, idx); + bmi160_value.ts_intvl = (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + if (bmi_ring_buf_put(bmi160_value) == 0) + printk(KERN_INFO "bmi ring buf full head %d, tail %d", + s_ring_buf_head, s_ring_buf_tail); + } + + idx += 20; + printk (KERN_INFO "second interface mag"); + break; +#endif + case FIFO_HEAD_OVER_READ_LSB: + /* end of fifo chunk */ + idx = fifo_length; + break; + default: + printk (KERN_INFO "ERROR parsing FIFO!! header 0x%x", header); + idx = fifo_length; + break; + } + } + } + + return -1; +} + +static uint64_t bmi_fifo_next_timestamp_calc(uint64_t host_time_new, + uint64_t sensor_time_new, + int drift, int odr_pow, + uint8_t bmi_odr) +{ + uint64_t time_age = ((sensor_time_new & (0xFFFF >> bmi_odr)) * (drift > 0 ? drift : 1000)) * 390625; + return ((host_time_new - div64_u64(time_age, 10000000) + ((drift > 0 ? drift : 1000) * (625 * odr_pow)))); +} + +static int bmi_fifo_time_drift_calc(uint64_t host_time_new, uint64_t sensor_time_new, + uint64_t host_time_old, uint64_t sensor_time_old) +{ + uint64_t delta_st, delta_ht; + int drift = 0; + + if (host_time_old > 0) { + delta_st = sensor_time_new >= sensor_time_old ? + (sensor_time_new - sensor_time_old) : + (sensor_time_new + FIFO_SENSORTIME_OVERFLOW_MASK - sensor_time_old); + delta_ht = host_time_new - host_time_old; +// printk(KERN_INFO "delta_st %llu, delta_ht %llu s_new %llu, s_old %llu, h_new %llu, h_old %llu", +// delta_st, delta_ht,sensor_time_new, sensor_time_old, host_time_new, host_time_old); + if (delta_st != 0) + drift = (int )div64_u64(delta_ht * 10000, (delta_st * FIFO_SENSORTIME_RESOLUTION)); + else + drift = 0; + + } else { + drift = 0; + } + + return drift; +} + +static void bmi_fifo_watermark_interrupt_handle + (struct bmi_client_data *client_data) +{ + int err = 0; + unsigned int fifo_len0 = 0; + unsigned int fifo_frmbytes_ext = 0; + static int time_drift = 0; + static uint64_t timestamp_next = 0; +// static uint64_t host_timestamp = 0; + uint8_t bmi_odr = client_data->odr.acc_odr; + int odr_pow = bmi_pow(2, 12 - bmi_odr + 1); + /*TO DO*/ + + if (client_data->fifo_data_sel == 4) + { + bmi_odr = client_data->odr.mag_odr; + odr_pow = bmi_pow(2, 12 - bmi_odr + 1); + } + + bmi_fifo_frame_bytes_extend_calc(client_data, &fifo_frmbytes_ext); + + if (client_data->pw.acc_pm == 2 && client_data->pw.gyro_pm == 2 + && client_data->pw.mag_pm == 2) + printk(KERN_INFO "pw_acc: %d, pw_gyro: %d\n", + client_data->pw.acc_pm, client_data->pw.gyro_pm); + if (!client_data->fifo_data_sel) + printk(KERN_INFO "no selsect sensor fifo, fifo_data_sel:%d\n", + client_data->fifo_data_sel); + + err = BMI_CALL_API(fifo_length)(&fifo_len0); + client_data->fifo_bytecount = fifo_len0; + + if (client_data->fifo_bytecount == 0 || err) + { + printk(KERN_INFO "fifo_bytecount is 0!!"); + return ; + } + if (client_data->fifo_bytecount + fifo_frmbytes_ext > FIFO_DATA_BUFSIZE) + client_data->fifo_bytecount = FIFO_DATA_BUFSIZE; + /* need give attention for the time of burst read*/ + memset (s_fifo_data_buf, 0, sizeof (s_fifo_data_buf)); + if (!err) { + err = bmi_burst_read_wrapper(client_data->device.dev_addr, + BMI160_USER_FIFO_DATA__REG, s_fifo_data_buf, + client_data->fifo_bytecount + fifo_frmbytes_ext); + /* store host timestamp after reading fifo */ + host_time_new = bmi_get_alarm_timestamp_ns(); + if (timestamp_next == 0) { + sensor_time_new = bmi_fifo_data_decode(s_fifo_data_buf, + client_data->fifo_bytecount + fifo_frmbytes_ext, + time_drift, timestamp_next,odr_pow); + } else { + sensor_time_new = bmi_fifo_data_decode(s_fifo_data_buf, + client_data->fifo_bytecount + fifo_frmbytes_ext, + time_drift, host_time_new,odr_pow); + } + if (sensor_time_new >= 0) { + time_drift = bmi_fifo_time_drift_calc(host_time_new, + sensor_time_new,host_time_old, sensor_time_old); + timestamp_next = bmi_fifo_next_timestamp_calc(host_time_new, + sensor_time_new, time_drift, odr_pow, bmi_odr); + /* store current timestamps as the old ones for next delta calculation */ + host_time_old = host_time_new; + sensor_time_old = sensor_time_new; + } + } else { + dev_err(client_data->dev, "read fifo leght err"); + } + + if (err) + dev_err(client_data->dev, "brust read fifo err\n"); + /*err = bmi_fifo_analysis_handle(client_data, fifo_data, + client_data->fifo_bytecount + 20, fifo_out_data);*/ + + +} + +static void bmi_signification_motion_interrupt_handle( + struct bmi_client_data *client_data) +{ + printk(KERN_INFO "bmi_signification_motion_interrupt_handle\n"); + input_event(client_data->input, EV_MSC, INPUT_EVENT_SGM, 1); +/*input_report_rel(client_data->input,INPUT_EVENT_SGM,1);*/ + input_sync(client_data->input); + bmi160_set_command_register(CMD_RESET_INT_ENGINE); + +} +static void bmi_stepdetector_interrupt_handle( + struct bmi_client_data *client_data) +{ + u8 current_step_dector_st = 0; + client_data->pedo_data.wkar_step_detector_status++; + current_step_dector_st = + client_data->pedo_data.wkar_step_detector_status; + client_data->std = ((current_step_dector_st == 1) ? 0 : 1); +} + +static void bmi_irq_work_func(struct work_struct *work) +{ + struct bmi_client_data *client_data = + container_of((struct work_struct *)work, + struct bmi_client_data, irq_work); + + unsigned char int_status[4] = {0, 0, 0, 0}; + + client_data->device.bus_read(client_data->device.dev_addr, + BMI160_USER_INTR_STAT_0_ADDR, int_status, 4); + + if (BMI160_GET_BITSLICE(int_status[0], + BMI160_USER_INTR_STAT_0_ANY_MOTION)) + bmi_slope_interrupt_handle(client_data); + + if (BMI160_GET_BITSLICE(int_status[0], + BMI160_USER_INTR_STAT_0_STEP_INTR)) + bmi_stepdetector_interrupt_handle(client_data); + if (BMI160_GET_BITSLICE(int_status[1], + BMI160_USER_INTR_STAT_1_FIFO_WM_INTR)) + bmi_fifo_watermark_interrupt_handle(client_data); + + /* Clear ALL inputerrupt status after handler sig mition*/ + /* Put this commads intot the last one*/ + if (BMI160_GET_BITSLICE(int_status[0], + BMI160_USER_INTR_STAT_0_SIGNIFICANT_INTR)) + bmi_signification_motion_interrupt_handle(client_data); + +} + +static irqreturn_t bmi_irq_handler(int irq, void *handle) +{ + struct bmi_client_data *client_data = handle; + + if (client_data == NULL) + return IRQ_HANDLED; + if (client_data->dev == NULL) + return IRQ_HANDLED; + schedule_work(&client_data->irq_work); + + return IRQ_HANDLED; +} +#endif /* defined(BMI_ENABLE_INT1)||defined(BMI_ENABLE_INT2) */ + +static int bmi_restore_hw_cfg(struct bmi_client_data *client) +{ + int err = 0; + + if ((client->fifo_data_sel) & (1 << BMI_ACC_SENSOR)) { + err += BMI_CALL_API(set_accel_range)(client->range.acc_range); + err += BMI_CALL_API(set_accel_output_data_rate) + (client->odr.acc_odr); + err += BMI_CALL_API(set_fifo_accel_enable)(1); + } + if ((client->fifo_data_sel) & (1 << BMI_GYRO_SENSOR)) { + err += BMI_CALL_API(set_gyro_range)(client->range.gyro_range); + err += BMI_CALL_API(set_gyro_output_data_rate) + (client->odr.gyro_odr); + err += BMI_CALL_API(set_fifo_gyro_enable)(1); + } + if ((client->fifo_data_sel) & (1 << BMI_MAG_SENSOR)) { + err += BMI_CALL_API(set_mag_output_data_rate) + (client->odr.mag_odr); + err += BMI_CALL_API(set_fifo_mag_enable)(1); + } + err += BMI_CALL_API(set_command_register)(CMD_CLR_FIFO_DATA); + + mutex_lock(&client->mutex_op_mode); + if (client->pw.acc_pm != BMI_ACC_PM_SUSPEND) { + err += BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_acc_arr[BMI_ACC_PM_NORMAL]); + mdelay(3); + } + mutex_unlock(&client->mutex_op_mode); + + mutex_lock(&client->mutex_op_mode); + if (client->pw.gyro_pm != BMI_GYRO_PM_SUSPEND) { + err += BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_NORMAL]); + mdelay(3); + } + mutex_unlock(&client->mutex_op_mode); + + mutex_lock(&client->mutex_op_mode); + + if (client->pw.mag_pm != BMI_MAG_PM_SUSPEND) { +#ifdef BMI160_AKM09912_SUPPORT + err += bmi160_set_bst_akm_and_secondary_if_powermode + (BMI160_MAG_FORCE_MODE); +#else + err += bmi160_set_bmm150_mag_and_secondary_if_power_mode + (BMI160_MAG_FORCE_MODE); +#endif + mdelay(3); + } + mutex_unlock(&client->mutex_op_mode); + + return err; +} + + +int bmi_probe(struct bmi_client_data *client_data, struct device *dev) +{ + int err = 0; +#ifdef BMI160_MAG_INTERFACE_SUPPORT + u8 mag_dev_addr; + u8 mag_urst_len; + u8 mag_op_mode; +#endif + /* check chip id */ + err = bmi_check_chip_id(client_data); + if (err) + goto exit_err_clean; + + dev_set_drvdata(dev, client_data); + client_data->dev = dev; + + mutex_init(&client_data->mutex_enable); + mutex_init(&client_data->mutex_op_mode); + mutex_init(&client_data->mutex_ring_buf); + + /* input device init */ + err = bmi_input_init(client_data); + if (err < 0) + goto exit_err_clean; + + /* sysfs node creation */ + err = sysfs_create_group(&client_data->input->dev.kobj, + &bmi160_attribute_group); + + if (err < 0) + goto exit_err_sysfs; + + if (NULL != dev->platform_data) { + client_data->bst_pd = kzalloc(sizeof(*client_data->bst_pd), + GFP_KERNEL); + + if (NULL != client_data->bst_pd) { + memcpy(client_data->bst_pd, dev->platform_data, + sizeof(*client_data->bst_pd)); + dev_notice(dev, "%s sensor driver set place: p%d\n", + client_data->bst_pd->name, + client_data->bst_pd->place); + } + } + + if (NULL != client_data->bst_pd) { + memcpy(client_data->bst_pd, dev->platform_data, + sizeof(*client_data->bst_pd)); + dev_notice(dev, "%s sensor driver set place: p%d\n", + client_data->bst_pd->name, + client_data->bst_pd->place); + } + + +// /* workqueue init */ +// INIT_DELAYED_WORK(&client_data->work, bmi_work_func); +// atomic_set(&client_data->delay, BMI_DELAY_DEFAULT); +// atomic_set(&client_data->wkqueue_en, 0); + + /* h/w init */ + client_data->device.delay_msec = bmi_delay; + err = BMI_CALL_API(init)(&client_data->device); + + /*workqueue init*/ + INIT_WORK(&client_data->report_data_work, bmi_hrtimer_work_func); + reportdata_wq = create_singlethread_workqueue("bmi160_wq"); + if (NULL == reportdata_wq) { + printk(KERN_INFO "fail to create the reportdta_wq %d", -ENOMEM); + } + hrtimer_init(&client_data->timer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); + client_data->timer.function = reportdata_timer_fun; + client_data->work_delay_kt = ns_to_ktime(10000000); + client_data->is_timer_running = 0; + client_data->time_odr = 500000; /*200Hz*/ + + bmi_dump_reg(client_data); + + /*power on detected*/ + /*or softrest(cmd 0xB6) */ + /*fatal err check*/ + /*soft reset*/ + err += BMI_CALL_API(set_command_register)(CMD_RESET_USER_REG); + mdelay(3); + if (err) + dev_err(dev, "Failed soft reset, er=%d", err); + /*usr data config page*/ + err += BMI_CALL_API(set_target_page)(USER_DAT_CFG_PAGE); + if (err) + dev_err(dev, "Failed cffg page, er=%d", err); + err += bmi_get_err_status(client_data); + if (err) { + dev_err(dev, "Failed to bmi16x init!err_st=0x%x\n", + client_data->err_st.err_st_all); + goto exit_err_sysfs; + } + +#ifdef BMI160_MAG_INTERFACE_SUPPORT + err += bmi160_set_command_register(MAG_MODE_NORMAL); + mdelay(2); + err += bmi160_get_mag_power_mode_stat(&mag_op_mode); + mdelay(2); + err += BMI_CALL_API(get_i2c_device_addr)(&mag_dev_addr); + mdelay(2); +#ifdef BMI160_AKM09912_SUPPORT + err += BMI_CALL_API(set_i2c_device_addr)(BMI160_AKM09912_I2C_ADDRESS); + /*do not need to check the return value for mag 2nd interface*/ + bmi160_bst_akm_mag_interface_init(BMI160_AKM09912_I2C_ADDRESS); +#else + err += BMI_CALL_API(set_i2c_device_addr)(BMI160_AUX_BMM150_I2C_ADDRESS); + /*do not need to check the return value for mag 2nd interface*/ + bmi160_bmm150_mag_interface_init(); +#endif + err += bmi160_set_mag_burst(3); + err += bmi160_get_mag_burst(&mag_urst_len); + dev_info(client_data->dev, + "BMI160 mag_urst_len:%d, mag_add:0x%x, mag_op_mode:%d\n", + mag_urst_len, mag_dev_addr, mag_op_mode); +#endif + if (err < 0) + goto exit_err_sysfs; + + +#if defined(BMI160_ENABLE_INT1) || defined(BMI160_ENABLE_INT2) + client_data->gpio_pin = of_get_named_gpio_flags(dev->of_node, + "bmi,gpio_irq", 0, NULL); + dev_info(client_data->dev, "BMI160 qpio number:%d\n", + client_data->gpio_pin); + err += gpio_request_one(client_data->gpio_pin, + GPIOF_IN, "bmi160_int"); + err += gpio_direction_input(client_data->gpio_pin); + client_data->IRQ = gpio_to_irq(client_data->gpio_pin); + if (err) { + dev_err(client_data->dev, + "can not request gpio to irq number\n"); + client_data->gpio_pin = 0; + } + + +#ifdef BMI160_ENABLE_INT1 + /* maps interrupt to INT1/InT2 pin */ + BMI_CALL_API(set_intr_any_motion)(BMI_INT0, ENABLE); + BMI_CALL_API(set_intr_fifo_wm)(BMI_INT0, ENABLE); + /*BMI_CALL_API(set_int_drdy)(BMI_INT0, ENABLE);*/ + + /*Set interrupt trige level way */ + BMI_CALL_API(set_intr_edge_ctrl)(BMI_INT0, BMI_INT_LEVEL); + bmi160_set_intr_level(BMI_INT0, 1); + /*set interrupt latch temporary, 5 ms*/ + /*bmi160_set_latch_int(5);*/ + + BMI_CALL_API(set_output_enable)( + BMI160_INTR1_OUTPUT_ENABLE, ENABLE); + sigmotion_init_interrupts(BMI160_MAP_INTR1); + BMI_CALL_API(map_step_detector_intr)(BMI160_MAP_INTR1); + /*close step_detector in init function*/ + BMI_CALL_API(set_step_detector_enable)(0); +#endif + +#ifdef BMI160_ENABLE_INT2 + /* maps interrupt to INT1/InT2 pin */ + BMI_CALL_API(set_intr_any_motion)(BMI_INT1, ENABLE); + BMI_CALL_API(set_intr_fifo_wm)(BMI_INT1, ENABLE); + BMI_CALL_API(set_int_drdy)(BMI_INT1, ENABLE); + + /*Set interrupt trige level way */ + BMI_CALL_API(set_intr_edge_ctrl)(BMI_INT1, BMI_INT_LEVEL); + bmi160_set_intr_level(BMI_INT1, 1); + /*set interrupt latch temporary, 5 ms*/ + /*bmi160_set_latch_int(5);*/ + + BMI_CALL_API(set_output_enable)( + BMI160_INTR2_OUTPUT_ENABLE, ENABLE); + sigmotion_init_interrupts(BMI160_MAP_INTR2); + BMI_CALL_API(map_step_detector_intr)(BMI160_MAP_INTR2); + /*close step_detector in init function*/ + BMI_CALL_API(set_step_detector_enable)(0); +#endif + err = request_irq(client_data->IRQ, bmi_irq_handler, + IRQF_TRIGGER_RISING, "bmi160", client_data); + if (err) + dev_err(client_data->dev, "could not request irq\n"); + + INIT_WORK(&client_data->irq_work, bmi_irq_work_func); +#endif + + client_data->selftest = 0; + + client_data->fifo_data_sel = 0; + BMI_CALL_API(get_accel_output_data_rate)(&client_data->odr.acc_odr); + BMI_CALL_API(get_gyro_output_data_rate)(&client_data->odr.gyro_odr); + BMI_CALL_API(get_mag_output_data_rate)(&client_data->odr.mag_odr); + BMI_CALL_API(set_fifo_time_enable)(1); + BMI_CALL_API(get_accel_range)(&client_data->range.acc_range); + BMI_CALL_API(get_gyro_range)(&client_data->range.gyro_range); + /* now it's power on which is considered as resuming from suspend */ + + /* set sensor PMU into suspend power mode for all */ + if (bmi_pmu_set_suspend(client_data) < 0) { + dev_err(dev, "Failed to set BMI160 to suspend power mode\n"); + goto exit_err_sysfs; + } + + dev_notice(dev, "sensor_time:%d, %d", + sensortime_duration_tbl[0].ts_delat, + sensortime_duration_tbl[0].ts_duration_lsb); + dev_notice(dev, "sensor %s probed successfully", SENSOR_NAME); + + return 0; + +exit_err_sysfs: + if (err) + bmi_input_destroy(client_data); + +exit_err_clean: + if (err) { + if (client_data != NULL) { + if (NULL != client_data->bst_pd) { + kfree(client_data->bst_pd); + client_data->bst_pd = NULL; + } + } + } + + return err; +} +EXPORT_SYMBOL(bmi_probe); + +/*! + * @brief remove bmi client + * + * @param dev the pointer of device + * + * @return zero + * @retval zero +*/ +int bmi_remove(struct device *dev) +{ + int err = 0; + struct bmi_client_data *client_data = dev_get_drvdata(dev); + + if (NULL != client_data) { +#ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&client_data->early_suspend_handler); +#endif + mutex_lock(&client_data->mutex_enable); + if (BMI_ACC_PM_NORMAL == client_data->pw.acc_pm || + BMI_GYRO_PM_NORMAL == client_data->pw.gyro_pm || + BMI_MAG_PM_NORMAL == client_data->pw.mag_pm) { + cancel_delayed_work_sync(&client_data->work); + } + mutex_unlock(&client_data->mutex_enable); + + err = bmi_pmu_set_suspend(client_data); + + mdelay(5); + + sysfs_remove_group(&client_data->input->dev.kobj, + &bmi160_attribute_group); + bmi_input_destroy(client_data); + + if (NULL != client_data->bst_pd) { + kfree(client_data->bst_pd); + client_data->bst_pd = NULL; + } + kfree(client_data); + } + + return err; +} +EXPORT_SYMBOL(bmi_remove); + +static int bmi_post_resume(struct bmi_client_data *client_data) +{ + int err = 0; + + mutex_lock(&client_data->mutex_enable); + + if (atomic_read(&client_data->wkqueue_en) == 1) { + bmi160_set_acc_op_mode(client_data, BMI_ACC_PM_NORMAL); + schedule_delayed_work(&client_data->work, + msecs_to_jiffies( + atomic_read(&client_data->delay))); + } + mutex_unlock(&client_data->mutex_enable); + if (client_data->is_timer_running) { + hrtimer_start(&client_data->timer, + ns_to_ktime(client_data->time_odr), + HRTIMER_MODE_REL); + client_data->base_time = 0; + client_data->timestamp = 0; + client_data->is_timer_running = 1; + //client_data->gyro_count = 0; + } + + return err; +} + + +int bmi_suspend(struct device *dev) +{ + int err = 0; + struct bmi_client_data *client_data = dev_get_drvdata(dev); + unsigned char stc_enable; + unsigned char std_enable; + dev_err(client_data->dev, "bmi suspend function entrance"); + + if (client_data->is_timer_running) { + hrtimer_cancel(&client_data->timer); + client_data->base_time = 0; + client_data->timestamp = 0; + client_data->fifo_time = 0; + //client_data->gyro_count = 0; + } + + if (atomic_read(&client_data->wkqueue_en) == 1) { + bmi160_set_acc_op_mode(client_data, BMI_ACC_PM_SUSPEND); + cancel_delayed_work_sync(&client_data->work); + } + BMI_CALL_API(get_step_counter_enable)(&stc_enable); + BMI_CALL_API(get_step_detector_enable)(&std_enable); + if (client_data->pw.acc_pm != BMI_ACC_PM_SUSPEND && + (stc_enable != 1) && (std_enable != 1) && + (client_data->sig_flag != 1)) { + err += BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_acc_arr[BMI_ACC_PM_SUSPEND]); + /*client_data->pw.acc_pm = BMI_ACC_PM_SUSPEND;*/ + mdelay(3); + } + if (client_data->pw.gyro_pm != BMI_GYRO_PM_SUSPEND) { + err += BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_SUSPEND]); + /*client_data->pw.gyro_pm = BMI_GYRO_PM_SUSPEND;*/ + mdelay(3); + } + + if (client_data->pw.mag_pm != BMI_MAG_PM_SUSPEND) { +#ifdef BMI160_AKM09912_SUPPORT + err += bmi160_set_bst_akm_and_secondary_if_powermode + (BMI160_MAG_SUSPEND_MODE); +#else + err += bmi160_set_bmm150_mag_and_secondary_if_power_mode + (BMI160_MAG_SUSPEND_MODE); +#endif + /*client_data->pw.gyro_pm = BMI160_MAG_SUSPEND_MODE;*/ + mdelay(3); + } + + return err; +} +EXPORT_SYMBOL(bmi_suspend); + +int bmi_resume(struct device *dev) +{ + int err = 0; + struct bmi_client_data *client_data = dev_get_drvdata(dev); + if (client_data->pw.acc_pm != BMI_ACC_PM_SUSPEND) { + err += BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_acc_arr[BMI_ACC_PM_NORMAL]); + mdelay(3); + } + if (client_data->pw.gyro_pm != BMI_GYRO_PM_SUSPEND) { + err += BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_NORMAL]); + mdelay(3); + } + + if (client_data->pw.mag_pm != BMI_MAG_PM_SUSPEND) { +#ifdef BMI160_AKM09912_SUPPORT + err += bmi160_set_bst_akm_and_secondary_if_powermode + (BMI160_MAG_FORCE_MODE); +#else + err += bmi160_set_bmm150_mag_and_secondary_if_power_mode + (BMI160_MAG_FORCE_MODE); +#endif + mdelay(3); + } + /* post resume operation */ + err += bmi_post_resume(client_data); + + return err; +} +EXPORT_SYMBOL(bmi_resume); + diff --git a/drivers/input/misc/bmi160_driver.h b/drivers/input/misc/bmi160_driver.h new file mode 100755 index 0000000000000..9696687cb4825 --- /dev/null +++ b/drivers/input/misc/bmi160_driver.h @@ -0,0 +1,390 @@ +/*! + * @section LICENSE + * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved + * + * This software program is licensed subject to the GNU General + * Public License (GPL).Version 2,June 1991, + * available at http://www.fsf.org/copyleft/gpl.html + * + * @filename bmi160_driver.h + * @date 2015/08/17 14:40 + * @id "09afbe6" + * @version 1.4 + * + * @brief + * The head file of BMI160 device driver core code +*/ +#ifndef _BMI160_DRIVER_H +#define _BMI160_DRIVER_H + +#ifdef __KERNEL__ +#include +#include +#include +#include +#else +#include +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif + +#include "bmi160.h" + +/* sensor specific */ +#define SENSOR_NAME "bmi160" + +#define SENSOR_CHIP_ID_BMI (0xD0) +#define SENSOR_CHIP_ID_BMI_C2 (0xD1) +#define SENSOR_CHIP_ID_BMI_C3 (0xD3) + +#define SENSOR_CHIP_REV_ID_BMI (0x00) + +#define CHECK_CHIP_ID_TIME_MAX 5 + +#define BMI_REG_NAME(name) BMI160_##name##__REG +#define BMI_VAL_NAME(name) BMI160_##name +#define BMI_CALL_API(name) bmi160_##name + +#define BMI_I2C_WRITE_DELAY_TIME (1) + +/* generic */ +#define BMI_MAX_RETRY_I2C_XFER (100) +#define BMI_MAX_RETRY_WAKEUP (5) +#define BMI_MAX_RETRY_WAIT_DRDY (100) + +#define BMI_DELAY_MIN (1) +#define BMI_DELAY_DEFAULT (200) + +#define BMI_VALUE_MAX (32767) +#define BMI_VALUE_MIN (-32768) + +#define BYTES_PER_LINE (16) + +#define BUF_SIZE_PRINT (16) + +#define BMI_FAST_CALI_TRUE (1) +#define BMI_FAST_CALI_ALL_RDY (7) + +/*! FIFO 1024 byte, max fifo frame count not over 150 */ +#define FIFO_FRAME_CNT 20 +#define FIFO_DATA_BUFSIZE 1024 + + +#define FRAME_LEN_ACC 6 +#define FRAME_LEN_GYRO 6 +#define FRAME_LEN_MAG 8 + +/*! BMI Self test */ +#define BMI_SELFTEST_AMP_HIGH 1 + +/* CMD */ +#define CMD_FOC_START 0x03 +#define CMD_PMU_ACC_SUSPEND 0x10 +#define CMD_PMU_ACC_NORMAL 0x11 +#define CMD_PMU_ACC_LP1 0x12 +#define CMD_PMU_ACC_LP2 0x13 +#define CMD_PMU_GYRO_SUSPEND 0x14 +#define CMD_PMU_GYRO_NORMAL 0x15 +#define CMD_PMU_GYRO_FASTSTART 0x17 +#define CMD_PMU_MAG_SUSPEND 0x18 +#define CMD_PMU_MAG_NORMAL 0x19 +#define CMD_PMU_MAG_LP1 0x1A +#define CMD_PMU_MAG_LP2 0x1B +#define CMD_CLR_FIFO_DATA 0xB0 +#define CMD_RESET_INT_ENGINE 0xB1 +#define CMD_RESET_USER_REG 0xB6 + +#define USER_DAT_CFG_PAGE 0x00 + +/*! FIFO Head definition*/ +#define FIFO_HEAD_A 0x84 +#define FIFO_HEAD_G 0x88 +#define FIFO_HEAD_M 0x90 + +#define FIFO_HEAD_G_A (FIFO_HEAD_G | FIFO_HEAD_A) +#define FIFO_HEAD_M_A (FIFO_HEAD_M | FIFO_HEAD_A) +#define FIFO_HEAD_M_G (FIFO_HEAD_M | FIFO_HEAD_G) + +#define FIFO_HEAD_M_G_A (FIFO_HEAD_M | FIFO_HEAD_G | FIFO_HEAD_A) + +#define FIFO_HEAD_SENSOR_TIME 0x44 +#define FIFO_HEAD_SKIP_FRAME 0x40 +#define FIFO_HEAD_OVER_READ_LSB 0x80 +#define FIFO_HEAD_OVER_READ_MSB 0x00 + +/*! FIFO head mode Frame bytes number definition */ +#define A_BYTES_FRM 6 +#define G_BYTES_FRM 6 +#define M_BYTES_FRM 8 +#define GA_BYTES_FRM 12 +#define MG_BYTES_FRM 14 +#define MA_BYTES_FRM 14 +#define MGA_BYTES_FRM 20 + +#define ACC_FIFO_HEAD "acc" +#define GYRO_FIFO_HEAD "gyro" +#define MAG_FIFO_HEAD "mag" + +/*! Bosch sensor unknown place*/ +#define BOSCH_SENSOR_PLACE_UNKNOWN (-1) +/*! Bosch sensor remapping table size P0~P7*/ +#define MAX_AXIS_REMAP_TAB_SZ 8 + +#define ENABLE 1 +#define DISABLE 0 + +/* bmi sensor HW interrupt pin number */ +#define BMI_INT0 0 +#define BMI_INT1 1 + +#define BMI_INT_LEVEL 0 +#define BMI_INT_EDGE 1 + +/*! BMI mag interface */ + + +/* compensated output value returned if sensor had overflow */ +#define BMM050_OVERFLOW_OUTPUT -32768 +#define BMM050_OVERFLOW_OUTPUT_S32 ((s32)(-2147483647-1)) + +/* Trim Extended Registers */ +#define BMM050_DIG_X1 0x5D +#define BMM050_DIG_Y1 0x5E +#define BMM050_DIG_Z4_LSB 0x62 +#define BMM050_DIG_Z4_MSB 0x63 +#define BMM050_DIG_X2 0x64 +#define BMM050_DIG_Y2 0x65 +#define BMM050_DIG_Z2_LSB 0x68 +#define BMM050_DIG_Z2_MSB 0x69 +#define BMM050_DIG_Z1_LSB 0x6A +#define BMM050_DIG_Z1_MSB 0x6B +#define BMM050_DIG_XYZ1_LSB 0x6C +#define BMM050_DIG_XYZ1_MSB 0x6D +#define BMM050_DIG_Z3_LSB 0x6E +#define BMM050_DIG_Z3_MSB 0x6F +#define BMM050_DIG_XY2 0x70 +#define BMM050_DIG_XY1 0x71 + +struct bmi160mag_compensate_t { + signed char dig_x1; + signed char dig_y1; + + signed char dig_x2; + signed char dig_y2; + + u16 dig_z1; + s16 dig_z2; + s16 dig_z3; + s16 dig_z4; + + unsigned char dig_xy1; + signed char dig_xy2; + + u16 dig_xyz1; +}; + +/*bmi fifo sensor type combination*/ +enum BMI_FIFO_DATA_SELECT_T { + BMI_FIFO_A_SEL = 1, + BMI_FIFO_G_SEL, + BMI_FIFO_G_A_SEL, + BMI_FIFO_M_SEL, + BMI_FIFO_M_A_SEL, + BMI_FIFO_M_G_SEL, + BMI_FIFO_M_G_A_SEL, + BMI_FIFO_DATA_SEL_MAX +}; + +/*bmi interrupt about step_detector and sgm*/ +#define INPUT_EVENT_STEP_DETECTOR 5 +#define INPUT_EVENT_SGM REL_DIAL/*7*/ +#define INPUT_EVENT_FAST_ACC_CALIB_DONE 6 +#define INPUT_EVENT_FAST_GYRO_CALIB_DONE 4 + + +/*! +* Bst sensor common definition, +* please give parameters in BSP file. +*/ +struct bosch_sensor_specific { + char *name; + /* 0 to 7 */ + unsigned int place:3; + int irq; + int (*irq_gpio_cfg)(void); +}; + +/*! bmi160 sensor spec of power mode */ +struct pw_mode { + u8 acc_pm; + u8 gyro_pm; + u8 mag_pm; +}; + +/*! bmi160 sensor spec of odr */ +struct odr_t { + u8 acc_odr; + u8 gyro_odr; + u8 mag_odr; +}; + +/*! bmi160 sensor spec of range */ +struct range_t { + u8 acc_range; + u8 gyro_range; +}; + +/*! bmi160 sensor error status */ +struct err_status { + u8 fatal_err; + u8 err_code; + u8 i2c_fail; + u8 drop_cmd; + u8 mag_drdy_err; + u8 err_st_all; +}; + +/*! bmi160 fifo frame for all sensors */ +struct fifo_frame_t { + struct bmi160_accel_t *acc_farr; + struct bmi160_gyro_t *gyro_farr; + struct bmi160_mag_xyz_s32_t *mag_farr; + + unsigned char acc_frame_cnt; + unsigned char gyro_frame_cnt; + unsigned char mag_frame_cnt; + + u32 acc_lastf_ts; + u32 gyro_lastf_ts; + u32 mag_lastf_ts; +}; + +/*! bmi160 fifo sensor time */ +struct fifo_sensor_time_t { + u32 acc_ts; + u32 gyro_ts; + u32 mag_ts; +}; + +struct pedometer_data_t { + /*! Fix step detector misinformation for the first time*/ + u8 wkar_step_detector_status; + u_int32_t last_step_counter_value; +}; + +struct bmi_client_data { + struct bmi160_t device; + struct device *dev; + struct input_dev *input; + struct delayed_work work; + struct work_struct irq_work; + + struct work_struct report_data_work; + int is_timer_running; + struct hrtimer timer; + ktime_t work_delay_kt; + uint64_t timestamp; + uint64_t base_time; + uint64_t fifo_time; + uint64_t gyro_count; + uint64_t time_odr; + + u8 chip_id; + + struct pw_mode pw; + struct odr_t odr; + struct range_t range; /*TO DO*/ + struct err_status err_st; + struct pedometer_data_t pedo_data; + s8 place; + u8 selftest; + + atomic_t wkqueue_en; /*TO DO acc gyro mag*/ + atomic_t delay; + atomic_t selftest_result; + + u8 fifo_data_sel; + u16 fifo_bytecount; + u8 fifo_head_en; + unsigned char fifo_int_tag_en; + struct fifo_frame_t fifo_frame; + + unsigned char *fifo_data; + u8 stc_enable; + uint16_t gpio_pin; + u8 std; + u8 sig_flag; + unsigned char calib_status; + struct mutex mutex_op_mode; + struct mutex mutex_enable; + struct mutex mutex_ring_buf; + struct bosch_sensor_specific *bst_pd; + int IRQ; +#ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend early_suspend_handler; +#endif +}; + + +/*! + * we use a typedef to hide the detail, + * because this type might be changed + */ +struct bosch_sensor_axis_remap { + /* src means which source will be mapped to target x, y, z axis */ + /* if an target OS axis is remapped from (-)x, + * src is 0, sign_* is (-)1 */ + /* if an target OS axis is remapped from (-)y, + * src is 1, sign_* is (-)1 */ + /* if an target OS axis is remapped from (-)z, + * src is 2, sign_* is (-)1 */ + int src_x:3; + int src_y:3; + int src_z:3; + + int sign_x:2; + int sign_y:2; + int sign_z:2; +}; + + +struct bosch_sensor_data { + union { + int16_t v[3]; + struct { + int16_t x; + int16_t y; + int16_t z; + }; + }; +}; + +s8 bmi_burst_read_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u16 len); +int bmi_probe(struct bmi_client_data *client_data, struct device *dev); +int bmi_remove(struct device *dev); +int bmi_suspend(struct device *dev); +int bmi_resume(struct device *dev); + + + +#endif/*_BMI160_DRIVER_H*/ +/*@}*/ + diff --git a/drivers/input/misc/bmi160_i2c.c b/drivers/input/misc/bmi160_i2c.c new file mode 100755 index 0000000000000..810569e063c0d --- /dev/null +++ b/drivers/input/misc/bmi160_i2c.c @@ -0,0 +1,365 @@ +/*! + * @section LICENSE + * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved + * + * This software program is licensed subject to the GNU General + * Public License (GPL).Version 2,June 1991, + * available at http://www.fsf.org/copyleft/gpl.html + * + * @filename bmi160_i2c.c + * @date 2014/11/25 14:40 + * @id "ba266c5" + * @version 1.3 + * + * @brief + * This file implements moudle function, which add + * the driver to I2C core. +*/ + +#include +#include +#include +#include "bmi160_driver.h" + +/*! @defgroup bmi160_i2c_src + * @brief bmi160 i2c driver module + @{*/ + +static struct i2c_client *bmi_client; +/*! + * @brief define i2c wirte function + * + * @param client the pointer of i2c client + * @param reg_addr register address + * @param data the pointer of data buffer + * @param len block size need to write + * + * @return zero success, non-zero failed + * @retval zero success + * @retval non-zero failed +*/ +/* i2c read routine for API*/ +static s8 bmi_i2c_read(struct i2c_client *client, u8 reg_addr, + u8 *data, u8 len) + { +#if !defined BMI_USE_BASIC_I2C_FUNC + s32 dummy; + if (NULL == client) + return -EINVAL; + + while (0 != len--) { +#ifdef BMI_SMBUS + dummy = i2c_smbus_read_byte_data(client, reg_addr); + if (dummy < 0) { + dev_err(&client->dev, "i2c smbus read error"); + return -EIO; + } + *data = (u8)(dummy & 0xff); +#else + dummy = i2c_master_send(client, (char *)®_addr, 1); + if (dummy < 0) { + dev_err(&client->dev, "i2c bus master write error"); + return -EIO; + } + + dummy = i2c_master_recv(client, (char *)data, 1); + if (dummy < 0) { + dev_err(&client->dev, "i2c bus master read error"); + return -EIO; + } +#endif + reg_addr++; + data++; + } + return 0; +#else + int retry; + + struct i2c_msg msg[] = { + { + .addr = client->addr, + .flags = 0, + .len = 1, + .buf = ®_addr, + }, + + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = len, + .buf = data, + }, + }; + + for (retry = 0; retry < BMI_MAX_RETRY_I2C_XFER; retry++) { + if (i2c_transfer(client->adapter, msg, + ARRAY_SIZE(msg)) > 0) + break; + else + mdelay(BMI_I2C_WRITE_DELAY_TIME); + } + + if (BMI_MAX_RETRY_I2C_XFER <= retry) { + dev_err(&client->dev, "I2C xfer error"); + return -EIO; + } + + return 0; +#endif + } + + +static s8 bmi_i2c_burst_read(struct i2c_client *client, u8 reg_addr, + u8 *data, u16 len) +{ + int retry; + + struct i2c_msg msg[] = { + { + .addr = client->addr, + .flags = 0, + .len = 1, + .buf = ®_addr, + }, + + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = len, + .buf = data, + }, + }; + + for (retry = 0; retry < BMI_MAX_RETRY_I2C_XFER; retry++) { + if (i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)) > 0) + break; + else + mdelay(BMI_I2C_WRITE_DELAY_TIME); + } + + if (BMI_MAX_RETRY_I2C_XFER <= retry) { + dev_err(&client->dev, "I2C xfer error"); + return -EIO; + } + + return 0; +} + + +/* i2c write routine for */ +static s8 bmi_i2c_write(struct i2c_client *client, u8 reg_addr, + u8 *data, u8 len) +{ +#if !defined BMI_USE_BASIC_I2C_FUNC + s32 dummy; + +#ifndef BMI_SMBUS + u8 buffer[2]; +#endif + + if (NULL == client) + return -EPERM; + + while (0 != len--) { +#ifdef BMI_SMBUS + dummy = i2c_smbus_write_byte_data(client, reg_addr, *data); +#else + buffer[0] = reg_addr; + buffer[1] = *data; + dummy = i2c_master_send(client, (char *)buffer, 2); +#endif + reg_addr++; + data++; + if (dummy < 0) { + dev_err(&client->dev, "error writing i2c bus"); + return -EPERM; + } + + } + mdelay(2); + return 0; +#else + u8 buffer[2]; + int retry; + struct i2c_msg msg[] = { + { + .addr = client->addr, + .flags = 0, + .len = 2, + .buf = buffer, + }, + }; + + while (0 != len--) { + buffer[0] = reg_addr; + buffer[1] = *data; + for (retry = 0; retry < BMI_MAX_RETRY_I2C_XFER; retry++) { + if (i2c_transfer(client->adapter, msg, + ARRAY_SIZE(msg)) > 0) { + break; + } else { + mdelay(BMI_I2C_WRITE_DELAY_TIME); + } + } + if (BMI_MAX_RETRY_I2C_XFER <= retry) { + dev_err(&client->dev, "I2C xfer error"); + return -EIO; + } + reg_addr++; + data++; + } + + mdelay(2); + return 0; +#endif +} + + +static s8 bmi_i2c_read_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u8 len) +{ + int err = 0; + err = bmi_i2c_read(bmi_client, reg_addr, data, len); + return err; +} + +static s8 bmi_i2c_write_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u8 len) +{ + int err = 0; + err = bmi_i2c_write(bmi_client, reg_addr, data, len); + return err; +} + +s8 bmi_burst_read_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u16 len) +{ + int err = 0; + err = bmi_i2c_burst_read(bmi_client, reg_addr, data, len); + return err; +} +EXPORT_SYMBOL(bmi_burst_read_wrapper); +/*! + * @brief BMI probe function via i2c bus + * + * @param client the pointer of i2c client + * @param id the pointer of i2c device id + * + * @return zero success, non-zero failed + * @retval zero success + * @retval non-zero failed +*/ +static int bmi_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int err = 0; + struct bmi_client_data *client_data = NULL; + + dev_info(&client->dev, "BMI160 i2c function probe entrance"); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + dev_err(&client->dev, "i2c_check_functionality error!"); + err = -EIO; + goto exit_err_clean; + } + + if (NULL == bmi_client) { + bmi_client = client; + } else { + dev_err(&client->dev, + "this driver does not support multiple clients"); + err = -EBUSY; + goto exit_err_clean; + } + + client_data = kzalloc(sizeof(struct bmi_client_data), + GFP_KERNEL); + if (NULL == client_data) { + dev_err(&client->dev, "no memory available"); + err = -ENOMEM; + goto exit_err_clean; + } + + client_data->device.bus_read = bmi_i2c_read_wrapper; + client_data->device.bus_write = bmi_i2c_write_wrapper; + + return bmi_probe(client_data, &client->dev); + +exit_err_clean: + if (err) + bmi_client = NULL; + return err; +} + +static int bmi_i2c_suspend(struct i2c_client *client, pm_message_t mesg) +{ + int err = 0; + err = bmi_suspend(&client->dev); + return err; +} + +static int bmi_i2c_resume(struct i2c_client *client) +{ + int err = 0; + + /* post resume operation */ + err = bmi_resume(&client->dev); + + return err; +} + + +static int bmi_i2c_remove(struct i2c_client *client) +{ + int err = 0; + err = bmi_remove(&client->dev); + bmi_client = NULL; + + return err; +} + + + +static const struct i2c_device_id bmi_id[] = { + {SENSOR_NAME, 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, bmi_id); + +static const struct of_device_id bmi160_of_match[] = { + { .compatible = "bosch-sensortec,bmi160", }, + { .compatible = "bmi160", }, + { .compatible = "bosch, bmi160", }, + { } +}; +MODULE_DEVICE_TABLE(of, bmi160_of_match); + +static struct i2c_driver bmi_i2c_driver = { + .driver = { + .owner = THIS_MODULE, + .name = SENSOR_NAME, + .of_match_table = bmi160_of_match, + }, + .class = I2C_CLASS_HWMON, + .id_table = bmi_id, + .probe = bmi_i2c_probe, + .remove = bmi_i2c_remove, + .suspend = bmi_i2c_suspend, + .resume = bmi_i2c_resume, +}; + +static int __init BMI_i2c_init(void) +{ + return i2c_add_driver(&bmi_i2c_driver); +} + +static void __exit BMI_i2c_exit(void) +{ + i2c_del_driver(&bmi_i2c_driver); +} + +MODULE_AUTHOR("Contact "); +MODULE_DESCRIPTION("driver for " SENSOR_NAME); +MODULE_LICENSE("GPL v2"); + +module_init(BMI_i2c_init); +module_exit(BMI_i2c_exit); + diff --git a/drivers/input/misc/mmc3x30.c b/drivers/input/misc/mmc3x30.c new file mode 100755 index 0000000000000..9b42fede094a2 --- /dev/null +++ b/drivers/input/misc/mmc3x30.c @@ -0,0 +1,1268 @@ +/* + * Copyright (c) 2014, Linux Foundation. All rights reserved. + * Linux Foundation chooses to take subject only to the GPLv2 license + * terms, and distributes only under these terms. + * Copyright (C) 2010 MEMSIC, Inc. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +//#include "mmc3x30.h" + +#define MMC3X30_DELAY_TM_MS 10 + +#define MMC3X30_DELAY_SET_MS 75 +#define MMC3X30_DELAY_RESET_MS 75 + +#define MMC3X30_RETRY_COUNT 10 +#define MMC3X30_DEFAULT_INTERVAL_MS 100 +#define MMC3X30_TIMEOUT_SET_MS 15000 + +#define MMC3X30_PRODUCT_ID 0x09 + +/* POWER SUPPLY VOLTAGE RANGE */ +#define MMC3X30_VDD_MIN_UV 2000000 +#define MMC3X30_VDD_MAX_UV 3300000 +#define MMC3X30_VIO_MIN_UV 1750000 +#define MMC3X30_VIO_MAX_UV 1950000 + +enum { + OBVERSE_X_AXIS_FORWARD = 0, + OBVERSE_X_AXIS_RIGHTWARD, + OBVERSE_X_AXIS_BACKWARD, + OBVERSE_X_AXIS_LEFTWARD, + REVERSE_X_AXIS_FORWARD, + REVERSE_X_AXIS_RIGHTWARD, + REVERSE_X_AXIS_BACKWARD, + REVERSE_X_AXIS_LEFTWARD, + MMC3X30_DIR_COUNT, +}; + +static char *mmc3x30_dir[MMC3X30_DIR_COUNT] = { + [OBVERSE_X_AXIS_FORWARD] = "obverse-x-axis-forward", + [OBVERSE_X_AXIS_RIGHTWARD] = "obverse-x-axis-rightward", + [OBVERSE_X_AXIS_BACKWARD] = "obverse-x-axis-backward", + [OBVERSE_X_AXIS_LEFTWARD] = "obverse-x-axis-leftward", + [REVERSE_X_AXIS_FORWARD] = "reverse-x-axis-forward", + [REVERSE_X_AXIS_RIGHTWARD] = "reverse-x-axis-rightward", + [REVERSE_X_AXIS_BACKWARD] = "reverse-x-axis-backward", + [REVERSE_X_AXIS_LEFTWARD] = "reverse-x-axis-leftward", +}; + +static s8 mmc3x30_rotation_matrix[MMC3X30_DIR_COUNT][9] = { + [OBVERSE_X_AXIS_FORWARD] = {0, -1, 0, 1, 0, 0, 0, 0, 1}, + [OBVERSE_X_AXIS_RIGHTWARD] = {1, 0, 0, 0, 1, 0, 0, 0, 1}, + [OBVERSE_X_AXIS_BACKWARD] = {0, 1, 0, -1, 0, 0, 0, 0, 1}, + [OBVERSE_X_AXIS_LEFTWARD] = {-1, 0, 0, 0, -1, 0, 0, 0, 1}, + [REVERSE_X_AXIS_FORWARD] = {0, 1, 0, 1, 0, 0, 0, 0, -1}, + [REVERSE_X_AXIS_RIGHTWARD] = {1, 0, 0, 0, -1, 0, 0, 0, -1}, + [REVERSE_X_AXIS_BACKWARD] = {0, -1, 0, -1, 0, 0, 0, 0, -1}, + [REVERSE_X_AXIS_LEFTWARD] = {-1, 0, 0, 0, 1, 0, 0, 0, -1}, +}; + +struct mmc3x30_vec { + int x; + int y; + int z; +}; + +struct mmc3x30_data { + struct mutex ecompass_lock; + struct mutex ops_lock; + struct delayed_work dwork; + struct sensors_classdev cdev; + struct mmc3x30_vec last; + + struct i2c_client *i2c; + struct input_dev *idev; + struct regulator *vdd; + struct regulator *vio; + struct regmap *regmap; + + int dir; + int auto_report; + int enable; + int poll_interval; + int power_enabled; + unsigned long timeout; + unsigned int device_id; +}; + +static struct sensors_classdev sensors_cdev = { + .name = "mmc3x30-mag", + .vendor = "MEMSIC, Inc", + .version = 1, + .handle = SENSORS_MAGNETIC_FIELD_HANDLE, + .type = SENSOR_TYPE_MAGNETIC_FIELD, + .max_range = "1228.8", +// .resolution = "0.0488228125", //2048 + .resolution = "0.09765625", //1024 + .sensor_power = "0.35", + .min_delay = 20000, + .max_delay = 100000, //100ms + .fifo_reserved_event_count = 0, + .fifo_max_event_count = 0, + .enabled = 0, + .delay_msec = MMC3X30_DEFAULT_INTERVAL_MS, + .sensors_enable = NULL, + .sensors_poll_delay = NULL, +}; + +//static struct i2c_client *this_client; +//static struct regmap *this_regmap; +//static DEFINE_MUTEX(ecompass_ioctl_lock); +static struct mmc3x30_data *mmc3x30_data_struct; + +static int mmc3x30_read_xyz(struct mmc3x30_data *memsic, + struct mmc3x30_vec *vec) +{ + //int count = 0; + unsigned char data[6]; + //unsigned int status; + struct mmc3x30_vec tmp; + int rc = 0; + + mutex_lock(&memsic->ecompass_lock); +#if 0 + /* mmc3x30 need to be set periodly to avoid overflow */ + if (time_after(jiffies, memsic->timeout)) { + + if(memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) + { + rc = regmap_write(memsic->regmap, MMC35XX_REG_CTRL0, MMC35XX_SET); + if (rc) { + dev_err(&memsic->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC35XX_REG_CTRL0, __LINE__, rc); + goto exit; + } + + /* Wait time to complete SET/RESET */ + usleep_range(1000, 1500); + memsic->timeout = jiffies + msecs_to_jiffies(MMC3X30_TIMEOUT_SET_MS); + + dev_dbg(&memsic->i2c->dev, "mmc3x30 reset is done\n"); + + } + else if (memsic->device_id == MMC3630_DEVICE_ID ) + { + rc = regmap_write(memsic->regmap, MMC36XX_REG_CTRL0, MMC36XX_SET); + if (rc) { + dev_err(&memsic->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC36XX_REG_CTRL0, __LINE__, rc); + goto exit; + } + + /* Wait time to complete SET/RESET */ + usleep_range(1000, 1500); + memsic->timeout = jiffies + msecs_to_jiffies(MMC3X30_TIMEOUT_SET_MS); + + dev_dbg(&memsic->i2c->dev, "mmc3x30 reset is done\n"); + } + + } +#endif + /* read xyz raw data */ + rc = regmap_bulk_read(memsic->regmap, MMC3X30_REG_DATA, data, 6); + if (rc) { + dev_err(&memsic->i2c->dev, "read reg %d failed at %d.(%d)\n", + MMC3X30_REG_DATA, __LINE__, rc); + goto exit; + } + + + tmp.x = (((u8)data[1]) << 8 | (u8)data[0]) - 32768; + tmp.y = (((u8)data[3]) << 8 | (u8)data[2]) - (((u8)data[5]) << 8 | (u8)data[4]) ; + tmp.z = (((u8)data[3]) << 8 | (u8)data[2]) + (((u8)data[5]) << 8 | (u8)data[4]) - 32768 - 32768; + + vec->x = tmp.x; + vec->y = tmp.y; + vec->z = -tmp.z; + +exit: + /* send TM cmd before read */ + if(memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) + { + if (regmap_write(memsic->regmap, MMC35XX_REG_CTRL0, MMC35XX_SINGLE_TM)) { + + dev_warn(&memsic->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC35XX_REG_CTRL0, __LINE__, rc); + } + + } + else if(memsic->device_id == MMC3630_DEVICE_ID) + { + if (regmap_write(memsic->regmap, MMC36XX_REG_CTRL0, MMC36XX_SINGLE_TM)) { + + dev_warn(&memsic->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC36XX_REG_CTRL0, __LINE__, rc); + } + + } + + mutex_unlock(&memsic->ecompass_lock); + return rc; +} + +static void mmc3x30_poll(struct work_struct *work) +{ + int ret; + s8 *tmp; + struct mmc3x30_vec vec; + struct mmc3x30_vec report; + struct mmc3x30_data *memsic = container_of((struct delayed_work *)work, + struct mmc3x30_data, dwork); + + vec.x = vec.y = vec.z = 0; + + ret = mmc3x30_read_xyz(memsic, &vec); + if (ret) { + dev_warn(&memsic->i2c->dev, "read xyz failed\n"); + goto exit; + } + + tmp = &mmc3x30_rotation_matrix[memsic->dir][0]; + report.x = tmp[0] * vec.x + tmp[1] * vec.y + tmp[2] * vec.z; + report.y = tmp[3] * vec.x + tmp[4] * vec.y + tmp[5] * vec.z; + report.z = tmp[6] * vec.x + tmp[7] * vec.y + tmp[8] * vec.z; + + input_report_abs(memsic->idev, ABS_X, report.x); + input_report_abs(memsic->idev, ABS_Y, report.y); + input_report_abs(memsic->idev, ABS_Z, report.z); + input_sync(memsic->idev); + +exit: + schedule_delayed_work(&memsic->dwork, + msecs_to_jiffies(memsic->poll_interval)); +} + +static struct input_dev *mmc3x30_init_input(struct i2c_client *client) +{ + int status; + struct input_dev *input = NULL; + + input = devm_input_allocate_device(&client->dev); + if (!input) + return NULL; + + input->name = "compass"; + input->phys = "mmc3x30/input0"; + input->id.bustype = BUS_I2C; + + __set_bit(EV_ABS, input->evbit); + + input_set_abs_params(input, ABS_X, -1024*30, 1024*30, 0, 0); + input_set_abs_params(input, ABS_Y, -1024*30, 1024*30, 0, 0); + input_set_abs_params(input, ABS_Z, -1024*30, 1024*30, 0, 0); + + //input_set_capability(input, EV_ABS, ABS_X); + //input_set_capability(input, EV_ABS, ABS_Y); + //input_set_capability(input, EV_ABS, ABS_Z); + + status = input_register_device(input); + if (status) { + dev_err(&client->dev, + "error registering input device\n"); + return NULL; + } + + return input; +} + +static int mmc3x30_power_init(struct mmc3x30_data *data) +{ + int rc; + + data->vdd = devm_regulator_get(&data->i2c->dev, "vdd"); + if (IS_ERR(data->vdd)) { + rc = PTR_ERR(data->vdd); + dev_err(&data->i2c->dev, + "Regualtor get failed vdd rc=%d\n", rc); + return rc; + } + if (regulator_count_voltages(data->vdd) > 0) { + rc = regulator_set_voltage(data->vdd, + MMC3X30_VDD_MIN_UV, MMC3X30_VDD_MAX_UV); + if (rc) { + dev_err(&data->i2c->dev, + "Regulator set failed vdd rc=%d\n", + rc); + goto exit; + } + } + + rc = regulator_enable(data->vdd); + if (rc) { + dev_err(&data->i2c->dev, + "Regulator enable vdd failed rc=%d\n", rc); + goto exit; + } + data->vio = devm_regulator_get(&data->i2c->dev, "vio"); + if (IS_ERR(data->vio)) { + rc = PTR_ERR(data->vio); + dev_err(&data->i2c->dev, + "Regulator get failed vio rc=%d\n", rc); + goto reg_vdd_set; + } + + if (regulator_count_voltages(data->vio) > 0) { + rc = regulator_set_voltage(data->vio, + MMC3X30_VIO_MIN_UV, MMC3X30_VIO_MAX_UV); + if (rc) { + dev_err(&data->i2c->dev, + "Regulator set failed vio rc=%d\n", rc); + goto reg_vdd_set; + } + } + rc = regulator_enable(data->vio); + if (rc) { + dev_err(&data->i2c->dev, + "Regulator enable vio failed rc=%d\n", rc); + goto reg_vdd_set; + } + + /* The minimum time to operate device after VDD valid is 10 ms. */ + usleep_range(15000, 20000); + + data->power_enabled = true; + + return 0; + +reg_vdd_set: + regulator_disable(data->vdd); + if (regulator_count_voltages(data->vdd) > 0) + regulator_set_voltage(data->vdd, 0, MMC3X30_VDD_MAX_UV); +exit: + return rc; + +} + +static int mmc3x30_power_deinit(struct mmc3x30_data *data) +{ + if (!IS_ERR_OR_NULL(data->vio)) { + if (regulator_count_voltages(data->vio) > 0) + regulator_set_voltage(data->vio, 0, + MMC3X30_VIO_MAX_UV); + + regulator_disable(data->vio); + } + + if (!IS_ERR_OR_NULL(data->vdd)) { + if (regulator_count_voltages(data->vdd) > 0) + regulator_set_voltage(data->vdd, 0, + MMC3X30_VDD_MAX_UV); + + regulator_disable(data->vdd); + } + + data->power_enabled = false; + + return 0; +} + +static int mmc3x30_power_set(struct mmc3x30_data *memsic, bool on) +{ + int rc = 0; + + if (!on && memsic->power_enabled) { + mutex_lock(&memsic->ecompass_lock); + + rc = regulator_disable(memsic->vdd); + if (rc) { + dev_err(&memsic->i2c->dev, + "Regulator vdd disable failed rc=%d\n", rc); + goto err_vdd_disable; + } + + rc = regulator_disable(memsic->vio); + if (rc) { + dev_err(&memsic->i2c->dev, + "Regulator vio disable failed rc=%d\n", rc); + goto err_vio_disable; + } + memsic->power_enabled = false; + + mutex_unlock(&memsic->ecompass_lock); + return rc; + } else if (on && !memsic->power_enabled) { + mutex_lock(&memsic->ecompass_lock); + + rc = regulator_enable(memsic->vdd); + if (rc) { + dev_err(&memsic->i2c->dev, + "Regulator vdd enable failed rc=%d\n", rc); + goto err_vdd_enable; + } + + rc = regulator_enable(memsic->vio); + if (rc) { + dev_err(&memsic->i2c->dev, + "Regulator vio enable failed rc=%d\n", rc); + goto err_vio_enable; + } + memsic->power_enabled = true; + + mutex_unlock(&memsic->ecompass_lock); + + /* The minimum time to operate after VDD valid is 10 ms */ + usleep_range(15000, 20000); + + return rc; + } else { + dev_warn(&memsic->i2c->dev, + "Power on=%d. enabled=%d\n", + on, memsic->power_enabled); + return rc; + } + +err_vio_enable: + regulator_disable(memsic->vio); +err_vdd_enable: + mutex_unlock(&memsic->ecompass_lock); + return rc; + +err_vio_disable: + if (regulator_enable(memsic->vdd)) + dev_warn(&memsic->i2c->dev, "Regulator vdd enable failed\n"); +err_vdd_disable: + mutex_unlock(&memsic->ecompass_lock); + return rc; +} +static int mmc3x30_check_device(struct mmc3x30_data *memsic) +{ + unsigned int id[2]={0,0}; + unsigned int reg[2]={MMC35XX_REG_ID,MMC36XX_REG_ID}; + int rc[2]; + int i; + + for(i=0; i<2;i++) + { + rc[i] = regmap_read(memsic->regmap, reg[i], &id[i]); + } + //two id in the arrow + if(id[1] == MMC3630_DEVICE_ID) + memsic->device_id = MMC3630_DEVICE_ID; + else if(id[0] == MMC3530_DEVICE_ID) + memsic->device_id = MMC3530_DEVICE_ID; + else if(id[0] == MMC3524_DEVICE_ID) + memsic->device_id = MMC3524_DEVICE_ID; + else + return -ENODEV; + + return 0; +} + +static int mmc3x30_parse_dt(struct i2c_client *client, + struct mmc3x30_data *memsic) +{ + struct device_node *np = client->dev.of_node; + const char *tmp; + int rc; + int i; + + rc = of_property_read_string(np, "memsic,dir", &tmp); + + /* does not have a value or the string is not null-terminated */ + if (rc && (rc != -EINVAL)) { + dev_err(&client->dev, "Unable to read memsic,dir\n"); + return rc; + } + + for (i = 0; i < ARRAY_SIZE(mmc3x30_dir); i++) { + if (strcmp(mmc3x30_dir[i], tmp) == 0) + break; + } + + if (i >= ARRAY_SIZE(mmc3x30_dir)) { + dev_err(&client->dev, "Invalid memsic,dir property"); + return -EINVAL; + } + + /*PLEASE CONFIRM WITH SENSOR PROVIDER*/ + //memsic->dir = i; + memsic->dir = 1; + + if (of_property_read_bool(np, "memsic,auto-report")) + memsic->auto_report = 1; + else + memsic->auto_report = 0; + + return 0; +} + +static int mmc3x30_set_enable(struct sensors_classdev *sensors_cdev, + unsigned int enable) +{ + int rc = 0; + struct mmc3x30_data *memsic = container_of(sensors_cdev, + struct mmc3x30_data, cdev); + + mutex_lock(&memsic->ops_lock); + + if (enable && (!memsic->enable)) { + rc = mmc3x30_power_set(memsic, true); + if (rc) { + dev_err(&memsic->i2c->dev, "Power up failed\n"); + goto exit; + } + + /* send TM cmd before read */ + if(memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) + { + rc = regmap_write(memsic->regmap, MMC35XX_REG_CTRL0, + MMC35XX_SINGLE_TM); + if (rc) { + dev_err(&memsic->i2c->dev, "write reg %d failed.(%d)\n", + MMC35XX_REG_CTRL0, rc); + goto exit; + } + } + else if(memsic->device_id == MMC3630_DEVICE_ID) + { + rc = regmap_write(memsic->regmap, MMC36XX_REG_CTRL0, + MMC36XX_SINGLE_TM); + if (rc) { + dev_err(&memsic->i2c->dev, "write reg %d failed.(%d)\n", + MMC36XX_REG_CTRL0, rc); + goto exit; + } + } + + memsic->timeout = jiffies; + if (memsic->auto_report) + schedule_delayed_work(&memsic->dwork, + msecs_to_jiffies(memsic->poll_interval)); + } else if ((!enable) && memsic->enable) { + if (memsic->auto_report) + cancel_delayed_work_sync(&memsic->dwork); + + if (mmc3x30_power_set(memsic, false)) + dev_warn(&memsic->i2c->dev, "Power off failed\n"); + } else { + dev_warn(&memsic->i2c->dev, + "ignore enable state change from %d to %d\n", + memsic->enable, enable); + } + memsic->enable = enable; + +exit: + mutex_unlock(&memsic->ops_lock); + return rc; +} + +static int mmc3x30_set_poll_delay(struct sensors_classdev *sensors_cdev, + unsigned int delay_msec) +{ + struct mmc3x30_data *memsic = container_of(sensors_cdev, + struct mmc3x30_data, cdev); + + mutex_lock(&memsic->ops_lock); + if (memsic->poll_interval != delay_msec) + memsic->poll_interval = delay_msec; + + if (memsic->auto_report) + mod_delayed_work(system_wq, &memsic->dwork, + msecs_to_jiffies(delay_msec)); + mutex_unlock(&memsic->ops_lock); + + return 0; +} + +static struct regmap_config mmc3x30_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; +#ifdef INIT_SET +static int mmc3x30_device_initial(struct mmc3x30_data *memsic) +{ + int rc = -1; + + // Do SET operation + if(memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) + { + rc = regmap_write(mmc3x30_data_struct->regmap, MMC35XX_REG_CTRL0, + MMC35XX_SET); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC35XX_REG_CTRL0, __LINE__, rc); + + return -EFAULT; + } + + } + else if(memsic->device_id == MMC3630_DEVICE_ID) + { + rc = regmap_write(mmc3x30_data_struct->regmap, MMC36XX_REG_CTRL0, + MMC36XX_SET); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC36XX_REG_CTRL0, __LINE__, rc); + + return -EFAULT; + } + } + + msleep(1);//setting needd 1ms + + return 0; +} +#endif +static int mmc3x30_open(struct inode *inode, struct file *file) +{ + + return nonseekable_open(inode, file); +} + +static int mmc3x30_release(struct inode *inode, struct file *file) +{ + + return 0; +} + +static long mmc3x30_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ +/* + int vec[3] = {0}; + int reg; + short flag; + short delay; +*/ + void __user *pa = (void __user *)arg; +// int __user *pa_i = (void __user *)arg; + unsigned char data[16] = {0}; + unsigned char reg_addr; + unsigned char reg_num; + unsigned int reg_value; + int rc = -1; + + switch (cmd) { + case MMC3X30_IOC_SET: + if(mmc3x30_data_struct->device_id == MMC3524_DEVICE_ID || mmc3x30_data_struct->device_id == MMC3530_DEVICE_ID) + { + rc = regmap_write(mmc3x30_data_struct->regmap, MMC35XX_REG_CTRL0, + MMC35XX_SET); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC35XX_REG_CTRL0, __LINE__, rc); + return -EFAULT; + } + + } + else if(mmc3x30_data_struct->device_id == MMC3630_DEVICE_ID) + { + rc = regmap_write(mmc3x30_data_struct->regmap, MMC36XX_REG_CTRL0, + MMC36XX_SET); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC36XX_REG_CTRL0, __LINE__, rc); + return -EFAULT; + } + + } + msleep(1);//setting needd 1ms + break; + + case MMC3X30_IOC_RESET: + if(mmc3x30_data_struct->device_id == MMC3524_DEVICE_ID || mmc3x30_data_struct->device_id == MMC3530_DEVICE_ID) + { + rc = regmap_write(mmc3x30_data_struct->regmap, MMC35XX_REG_CTRL0, + MMC35XX_RESET); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC35XX_REG_CTRL0, __LINE__, rc); + return -EFAULT; + } + + } + else if(mmc3x30_data_struct->device_id == MMC3630_DEVICE_ID) + { + rc = regmap_write(mmc3x30_data_struct->regmap, MMC36XX_REG_CTRL0, + MMC36XX_RESET); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC36XX_REG_CTRL0, __LINE__, rc); + return -EFAULT; + } + + } + msleep(1);//setting needd 1ms + break; + + case MMC3X30_IOC_READ_REG: + if (copy_from_user(®_addr, pa, sizeof(reg_addr))) + return -EFAULT; + rc = regmap_read(mmc3x30_data_struct->regmap, reg_addr, ®_value); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "read reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); + } + printk("mmc3x30 Read register 0x%0x\n",reg_addr); + if (copy_to_user(pa, ®_value, sizeof(reg_value))) { + return -EFAULT; + } + break; + + case MMC3X30_IOC_WRITE_REG: + if (copy_from_user(&data, pa, sizeof(data))) + return -EFAULT; + + rc = regmap_write(mmc3x30_data_struct->regmap, data[1], data[0]); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", + data[1], __LINE__, rc); + return -EFAULT; + } + printk("mmc3x30 Write '0x%0x' to register 0x%0x\n", data[0], data[1]); + break; + + case MMC3X30_IOC_READ_REGS: + if (copy_from_user(&data, pa, sizeof(data))) + return -EFAULT; + reg_addr = data[0]; + reg_num = data[1]; + + rc = regmap_bulk_read(mmc3x30_data_struct->regmap, reg_addr, data, reg_num); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "read reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); + } + + printk("mmc3x30 data: %x %x %x \n%x %x %x\n", data[0], data[1], data[2], data[3], data[4], data[5]); + if (copy_to_user(pa, data, sizeof(data))) { + return -EFAULT; + } + break; + + default: + dev_dbg(&mmc3x30_data_struct->i2c->dev, "no ctl cmd !\n"); + return -EFAULT; + //break; + } + + return 0; + +} +#ifdef CONFIG_COMPAT +static long mmc3x30_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + void __user *arg64 = compat_ptr(arg); + int ret =-1; + + if(!file->f_op || !file->f_op->unlocked_ioctl) + { + dev_err(&mmc3x30_data_struct->i2c->dev, "file->f_op OR file->f_op->unlocked_ioctl is null!\n"); + return -EFAULT; + } + switch(cmd) + { + case COMPAT_MMC3X30_IOC_SET: + ret = file->f_op->unlocked_ioctl(file, MMC3X30_IOC_SET, (unsigned long)arg64); + if(ret < 0) + { + dev_err(&mmc3x30_data_struct->i2c->dev,"COMPAT_MMC3X30_IOC_SET is failed!\n"); + return -EFAULT; + } + break; + case COMPAT_MMC3X30_IOC_RESET: + ret = file->f_op->unlocked_ioctl(file, MMC3X30_IOC_RESET, (unsigned long)arg64); + if(ret < 0) + { + dev_err(&mmc3x30_data_struct->i2c->dev,"COMPAT_MMC3X30_IOC_RESET is failed!\n"); + return -EFAULT; + } + break; + case COMPAT_MMC3X30_IOC_READ_REG: + ret = file->f_op->unlocked_ioctl(file, COMPAT_MMC3X30_IOC_READ_REG, (unsigned long)arg64); + if(ret < 0) + { + dev_err(&mmc3x30_data_struct->i2c->dev, "COMPAT_MMC3X30_IOC_READ_REG is failed!\n"); + return -EFAULT; + } + break; + case COMPAT_MMC3X30_IOC_WRITE_REG: + ret = file->f_op->unlocked_ioctl(file, COMPAT_MMC3X30_IOC_WRITE_REG, (unsigned long)arg64); + if(ret < 0) + { + dev_err(&mmc3x30_data_struct->i2c->dev, "COMPAT_MMC3X30_IOC_WRITE_REG is failed!\n"); + return -EFAULT; + } + break; + case COMPAT_MMC3X30_IOC_READ_REGS: + ret = file->f_op->unlocked_ioctl(file, COMPAT_MMC3X30_IOC_READ_REGS, (unsigned long)arg64); + if(ret < 0) + { + dev_err(&mmc3x30_data_struct->i2c->dev, "COMPAT_MMC3X30_IOC_READ_REGS is failed!\n"); + return -EFAULT; + } + break; + default: + dev_dbg(&mmc3x30_data_struct->i2c->dev,"no compat ctl cmd !\n"); + return -EFAULT; + //break; + } + return 0; + +} + +#endif + +static struct file_operations mmc3x30_fops = { + .owner = THIS_MODULE, + .open = mmc3x30_open, + .release = mmc3x30_release, + .unlocked_ioctl = mmc3x30_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = mmc3x30_compat_ioctl, +#endif +}; + +static struct miscdevice mmc3x30_device = { + .minor = MISC_DYNAMIC_MINOR, + .name = MMC3X30_I2C_NAME, + .fops = &mmc3x30_fops, +}; +static ssize_t mmc3x30_otp_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + + char data[10] = {0}; + unsigned char reg_addr; + unsigned char reg_num; + int rc = -1; + + if(mmc3x30_data_struct->device_id == MMC3524_DEVICE_ID || mmc3x30_data_struct->device_id == MMC3530_DEVICE_ID) + { + reg_addr = MMC35XX_REG_OTP; + reg_num = 4; + rc = regmap_bulk_read(mmc3x30_data_struct->regmap, reg_addr, data, reg_num); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "read reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); + } + return sprintf(buf, "%x,%x,%x,%x\n", data[0],data[1],data[2],data[3]); + + } + else if(mmc3x30_data_struct->device_id == MMC3630_DEVICE_ID) + { + reg_addr = MMC36XX_REG_OTP_GATE0; + data[0] = MMC36XX_OTP_OPEN0; + rc = regmap_write(mmc3x30_data_struct->regmap, reg_addr, data[0]); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); + } + reg_addr = MMC36XX_REG_OTP_GATE1; + data[0] = MMC36XX_OTP_OPEN1; + rc = regmap_write(mmc3x30_data_struct->regmap, reg_addr, data[0]); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); + } + reg_addr = MMC36XX_REG_OTP_GATE2; + data[0] = MMC36XX_OTP_OPEN2; + rc = regmap_write(mmc3x30_data_struct->regmap, reg_addr, data[0]); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); + } + reg_addr = MMC36XX_REG_CTRL2; + data[0] = MMC36XX_OTP_OPEN2; + rc = regmap_write(mmc3x30_data_struct->regmap, reg_addr, data[0]); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); + } + + reg_addr = MMC36XX_REG_OTP; + reg_num = 2; + rc = regmap_bulk_read(mmc3x30_data_struct->regmap, reg_addr, data, reg_num); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "read reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); + } + return sprintf(buf, "%x,%x\n", data[0],data[1]); + } + else + { + dev_err(&mmc3x30_data_struct->i2c->dev, "No otp !\n"); + return -EFAULT; + } + +} + +static ssize_t mmc3x30_value_show(struct device *dev,struct device_attribute *attr, char *buf) +{ + int ret; + //s8 *tmp; + struct mmc3x30_vec vec; + //struct mmc3x30_vec report; + struct mmc3x30_data *memsic = dev_get_drvdata(dev); + + vec.x = vec.y = vec.z = 0; + + ret = mmc3x30_read_xyz(memsic, &vec); + if (ret) { + dev_warn(&memsic->i2c->dev, "read xyz failed\n"); + } + + /* + tmp = &mmc3x30_rotation_matrix[memsic->dir][0]; + report.x = tmp[0] * vec.x + tmp[1] * vec.y + tmp[2] * vec.z; + report.y = tmp[3] * vec.x + tmp[4] * vec.y + tmp[5] * vec.z; + report.z = tmp[6] * vec.x + tmp[7] * vec.y + tmp[8] * vec.z; + */ + + return sprintf(buf, "%d %d %d\n", vec.x,vec.y,vec.z); +} +static ssize_t mmc3x30_set_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + int rc = -1; + struct mmc3x30_data *memsic = dev_get_drvdata(dev); + + if(memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) + { + rc = regmap_write(memsic->regmap, MMC35XX_REG_CTRL0, + MMC35XX_SET); + if (rc) { + dev_err(&memsic->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC35XX_REG_CTRL0, __LINE__, rc); + return -EFAULT; + } + + } + else if(memsic->device_id == MMC3630_DEVICE_ID) + { + rc = regmap_write(memsic->regmap, MMC36XX_REG_CTRL0, + MMC36XX_SET); + if (rc) { + dev_err(&memsic->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC36XX_REG_CTRL0, __LINE__, rc); + return -EFAULT; + } + + } + msleep(1);//setting time + return count;//nothing return +} + +static ssize_t mmc3x30_reset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + + int rc = -1; + struct mmc3x30_data *memsic = dev_get_drvdata(dev); + + if(memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) + { + rc = regmap_write(memsic->regmap, MMC35XX_REG_CTRL0, + MMC35XX_RESET); + if (rc) { + dev_err(&memsic->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC35XX_REG_CTRL0, __LINE__, rc); + return -EFAULT; + } + + } + else if(memsic->device_id == MMC3630_DEVICE_ID) + { + rc = regmap_write(memsic->regmap, MMC36XX_REG_CTRL0, + MMC36XX_RESET); + if (rc) { + dev_err(&memsic->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC36XX_REG_CTRL0, __LINE__, rc); + return -EFAULT; + } + + } + msleep(1);//setting time + return count;//nothing return +} + +// add to create sysfs file node +static DEVICE_ATTR(otp, S_IRUSR|S_IRGRP, mmc3x30_otp_show, NULL); +static DEVICE_ATTR(value, S_IRUSR|S_IRGRP, mmc3x30_value_show, NULL); +static DEVICE_ATTR(set, S_IWUSR, NULL, mmc3x30_set_store); +static DEVICE_ATTR(reset, S_IWUSR, NULL, mmc3x30_reset_store); + +//static DEVICE_ATTR(set, S_IWUSR, NULL, mmc3x30_set_store); +//static DEVICE_ATTR(reset, S_IWUSR, NULL, mmc3x30_reset_store); + +static struct attribute *mmc3x30_attributes[] = { + &dev_attr_otp.attr, + &dev_attr_value.attr, + &dev_attr_set.attr, + &dev_attr_reset.attr, + NULL, +}; + +static const struct attribute_group mmc3x30_attr_group = { + .attrs = mmc3x30_attributes, +}; + + +static int mmc3x30_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + int res = 0; + struct mmc3x30_data *memsic; + + dev_info(&client->dev, "probing mmc3x30\n"); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + pr_err("mmc3x30 i2c functionality check failed.\n"); + res = -ENODEV; + goto out; + } + + memsic = devm_kzalloc(&client->dev, sizeof(struct mmc3x30_data), + GFP_KERNEL); + if (!memsic) { + dev_err(&client->dev, "memory allocation failed.\n"); + res = -ENOMEM; + goto out; + } + + mmc3x30_data_struct = memsic; + + if (client->dev.of_node) { + res = mmc3x30_parse_dt(client, memsic); + if (res) { + dev_err(&client->dev, + "Unable to parse platform data.(%d)", res); + goto out; + } + } else { + memsic->dir = 1; + memsic->auto_report = 1; + } + + memsic->i2c = client; + dev_set_drvdata(&client->dev, memsic); + + mutex_init(&memsic->ecompass_lock); + mutex_init(&memsic->ops_lock); + + memsic->regmap = devm_regmap_init_i2c(client, &mmc3x30_regmap_config); + if (IS_ERR(memsic->regmap)) { + dev_err(&client->dev, "Init regmap failed.(%ld)", + PTR_ERR(memsic->regmap)); + res = PTR_ERR(memsic->regmap); + goto out; + } + + res = mmc3x30_power_init(memsic); + if (res) { + dev_err(&client->dev, "Power up mmc3x30 failed\n"); + goto out; + } + + res = mmc3x30_check_device(memsic); + if (res) { + dev_err(&client->dev, "Check device failed\n"); + goto out_check_device; + } + + memsic->idev = mmc3x30_init_input(client); + if (!memsic->idev) { + dev_err(&client->dev, "init input device failed\n"); + res = -ENODEV; + goto out_init_input; + } + + + if (memsic->auto_report) { + dev_info(&client->dev, "auto report is enabled\n"); + INIT_DELAYED_WORK(&memsic->dwork, mmc3x30_poll); + } + + memsic->cdev = sensors_cdev; + memsic->cdev.sensors_enable = mmc3x30_set_enable; + memsic->cdev.sensors_poll_delay = mmc3x30_set_poll_delay; + res = sensors_classdev_register(&client->dev, &memsic->cdev); + if (res) { + dev_err(&client->dev, "sensors class register failed.\n"); + goto out_register_classdev; + } +#ifdef INIT_SET + res = mmc3x30_device_initial(memsic); + if(res){ + pr_err("mmc3x30_device initial failed\n"); + } + else{ + printk("mmc3x30_device initial OK\n"); + } +#endif + + res = misc_register(&mmc3x30_device); + if (res) { + pr_err("%s: mmc3x30_device register failed\n", __FUNCTION__); + goto out_deregister; + } + + + res = mmc3x30_power_set(memsic, false); + if (res) { + dev_err(&client->dev, "Power off failed\n"); + goto out_power_set; + } + + memsic->poll_interval = MMC3X30_DEFAULT_INTERVAL_MS; + + /* create sysfs group */ + res = sysfs_create_group(&client->dev.kobj, &mmc3x30_attr_group); + if (res){ + res = -EROFS; + dev_err(&client->dev,"Unable to creat sysfs group\n"); + } + + dev_info(&client->dev, "mmc3x30 successfully probed\n"); + + return 0; + +out_power_set: + sensors_classdev_unregister(&memsic->cdev); +out_deregister: + misc_deregister(&mmc3x30_device); +out_register_classdev: + input_unregister_device(memsic->idev); +out_init_input: +out_check_device: + mmc3x30_power_deinit(memsic); +out: + return res; +} + +static int mmc3x30_remove(struct i2c_client *client) +{ + struct mmc3x30_data *memsic = dev_get_drvdata(&client->dev); + + sensors_classdev_unregister(&memsic->cdev); + misc_deregister(&mmc3x30_device); + mmc3x30_power_deinit(memsic); + + if (memsic->idev) + input_unregister_device(memsic->idev); + + sysfs_remove_group(&client->dev.kobj, &mmc3x30_attr_group); + + return 0; +} + +static int mmc3x30_suspend(struct device *dev) +{ + int res = 0; + struct mmc3x30_data *memsic = dev_get_drvdata(dev); + + dev_dbg(dev, "suspended\n"); + + if (memsic->enable) { + if (memsic->auto_report) + cancel_delayed_work_sync(&memsic->dwork); + + res = mmc3x30_power_set(memsic, false); + if (res) { + dev_err(dev, "failed to suspend mmc3x30\n"); + goto exit; + } + } +exit: + return res; +} + +static int mmc3x30_resume(struct device *dev) +{ + int res = 0; + struct mmc3x30_data *memsic = dev_get_drvdata(dev); + + dev_dbg(dev, "resumed\n"); + + if (!memsic->enable) { + res = mmc3x30_power_set(memsic, true); + if (res) { + dev_err(&memsic->i2c->dev, "Power enable failed\n"); + goto exit; + } + + if (memsic->auto_report) + schedule_delayed_work(&memsic->dwork, + msecs_to_jiffies(memsic->poll_interval)); + } + +exit: + return res; +} + +static const struct i2c_device_id mmc3x30_id[] = { + { MMC3X30_I2C_NAME, 0 }, + { } +}; + +static struct of_device_id mmc3x30_match_table[] = { + { .compatible = "memsic,mmc3x30", }, + { }, +}; + +static const struct dev_pm_ops mmc3x30_pm_ops = { + .suspend = mmc3x30_suspend, + .resume = mmc3x30_resume, +}; + +static struct i2c_driver mmc3x30_driver = { + .probe = mmc3x30_probe, + .remove = mmc3x30_remove, + .id_table = mmc3x30_id, + .driver = { + .owner = THIS_MODULE, + .name = MMC3X30_I2C_NAME, + .of_match_table = mmc3x30_match_table, + .pm = &mmc3x30_pm_ops, + }, +}; + +static int __init mmc3x30_init(void) +{ + return i2c_add_driver(&mmc3x30_driver); +} + +static void __exit mmc3x30_exit(void) +{ + i2c_del_driver(&mmc3x30_driver); +} + +//module_i2c_driver(mmc3x30_driver); +late_initcall(mmc3x30_init); +module_exit(mmc3x30_exit); + +MODULE_DESCRIPTION("MEMSIC MMC3X30 Magnetic Sensor Driver"); +MODULE_LICENSE("GPL"); + diff --git a/include/linux/i2c/mmc3x30.h b/include/linux/i2c/mmc3x30.h new file mode 100755 index 0000000000000..a764d32553e65 --- /dev/null +++ b/include/linux/i2c/mmc3x30.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2010 MEMSIC, Inc. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* + * Definitions for mmc3x30 magnetic sensor chip. + */ +#ifndef __MMC3X30_H__ +#define __MMC3X30_H__ + +#include + + +#define MMC3X30_I2C_NAME "mmc3x30" + +#define MMC3X30_I2C_ADDR 0x30 + +//MEMSIC MMC3X30 Data +#define MMC3X30_REG_DATA 0x00 + +//MEMSIC MMC35XX REG +#define MMC35XX_REG_STATUS 0x06 +#define MMC35XX_REG_CTRL0 0x07 +#define MMC35XX_REG_CTRL1 0x08 +#define MMC35XX_REG_ID 0x20 +#define MMC35XX_REG_OTP 0x1B + +//MEMSIC MMC36XX REG +#define MMC36XX_REG_TMPT 0x06 +#define MMC36XX_REG_STATUS 0x07 +#define MMC36XX_REG_CTRL0 0x08 +#define MMC36XX_REG_CTRL1 0x09 +#define MMC36XX_REG_CTRL2 0x0A +#define MMC36XX_REG_X_THLD 0x0B +#define MMC36XX_REG_Y_THLD 0x0C +#define MMC36XX_REG_Z_THLD 0x0D +#define MMC36XX_REG_SELF_TEST 0x0E +#define MMC36XX_REG_OTP_GATE0 0x0F +#define MMC36XX_REG_OTP_GATE1 0x12 +#define MMC36XX_REG_OTP_GATE2 0x13 +#define MMC36XX_REG_OTP 0x2A +#define MMC36XX_REG_ID 0x2F + +//MEMSIC MMC35XX CMD +#define MMC35XX_SINGLE_TM 0x01 +#define MMC35XX_BW_16BIT_SLOW 0x00 +#define MMC35XX_BW_16BIT_FAST 0x01 +#define MMC35XX_BW_14BIT 0x02 +#define MMC35XX_CONT_MODE 0x02 +#define MMC35XX_CONT_FREQ_50HZ 0x00 +#define MMC35XX_CONT_FREQ_25HZ 0x04 +#define MMC35XX_CONT_FREQ_12HZ 0x08 +#define MMC35XX_CONT_FREQ_1_5HZ 0x0C + +//MEMSIC MMC36XX CMD +#define MMC36XX_OTP_OPEN0 0xE1 +#define MMC36XX_OTP_OPEN1 0x11 +#define MMC36XX_OTP_OPEN2 0x80 +#define MMC36XX_SINGLE_TM 0x01 +#define MMC36XX_SINGLE_TMPT 0x02 +#define MMC36XX_BW_16BIT_100HZ 0x00 +#define MMC36XX_BW_16BIT_200HZ 0x01 +#define MMC36XX_BW_16BIT_400HZ 0x02 +#define MMC36XX_BW_16BIT_600HZ 0x03 + +/*MMC35XX RESET*/ +#define MMC35XX_FILLCAP 0x80 +#define MMC35XX_RESET 0x40 +#define MMC35XX_SET 0x20 +#define MMC35XX_NOBOOST 0x10 +#define MMC35XX_ST_XYZ 0x20 +/*MEMSIC MMC35XX Status */ +#define MMC35XX_STATUS_MEASURE_DONE 0x01 +#define MMC35XX_STATUS_CHARGE_PUMP 0x02 +#define MMC35XX_STATUS_ST_XYZ 0x08 + +/*MMC36XX RESET*/ +#define MMC36XX_FILLCAP 0x20 +#define MMC36XX_RESET 0x10 +#define MMC36XX_SET 0x08 +#define MMC36XX_ST_POST 0x02 +#define MMC36XX_ST_NEGT 0x04 +#define MMC36XX_ST_DEFAULT 0x00 +#define MMC36XX_ST_DELTA_VALUE 100 +/*MEMSIC MMC36XX Status */ +#define MMC36XX_STATUS_MEASURE_DONE 0x01 +#define MMC36XX_STATUS_CHARGE_PUMP 0x08 + +/*DEVICE ID*/ +#define MMC3524_DEVICE_ID 0x08 +#define MMC3530_DEVICE_ID 0x09 +#define MMC3630_DEVICE_ID 0x0A + + +/* Use 'm' as magic number */ +#define MMC3X30_IOM 'm' +/* IOCTLs for MMC3X30 device */ +#define MMC3X30_IOC_TM _IO (MMC3X30_IOM, 0x00) +#define MMC3X30_IOC_SET _IO (MMC3X30_IOM, 0x01) +#define MMC3X30_IOC_READ _IOR(MMC3X30_IOM, 0x02, int[3]) +#define MMC3X30_IOC_READXYZ _IOR(MMC3X30_IOM, 0x03, int[3]) +#define MMC3X30_IOC_RESET _IO (MMC3X30_IOM, 0x04) +#define MMC3X30_IOC_NOBOOST _IO (MMC3X30_IOM, 0x05) +#define MMC3X30_IOC_ID _IOR(MMC3X30_IOM, 0x06, short) +#define MMC3X30_IOC_DIAG _IOR(MMC3X30_IOM, 0x14, int[1]) +#define MMC3X30_IOC_READ_REG _IOWR(MMC3X30_IOM, 0x15, unsigned char) +#define MMC3X30_IOC_WRITE_REG _IOW(MMC3X30_IOM, 0x16, unsigned char[2]) +#define MMC3X30_IOC_READ_REGS _IOWR(MMC3X30_IOM, 0x17, unsigned char[10]) +#define MMC3X30_IOC_WRITE_REGS _IOW(MMC3X30_IOM, 0x18, unsigned char[10]) + +#ifdef CONFIG_COMPAT +/* IOCTLs for MMC3X30 device */ +#define COMPAT_MMC3X30_IOC_TM _IO (MMC3X30_IOM, 0x00) +#define COMPAT_MMC3X30_IOC_SET _IO (MMC3X30_IOM, 0x01) +#define COMPAT_MMC3X30_IOC_READ _IOR(MMC3X30_IOM, 0x02, int[3]) +#define COMPAT_MMC3X30_IOC_READXYZ _IOR(MMC3X30_IOM, 0x03, int[3]) +#define COMPAT_MMC3X30_IOC_RESET _IO (MMC3X30_IOM, 0x04) +#define COMPAT_MMC3X30_IOC_NOBOOST _IO (MMC3X30_IOM, 0x05) +#define COMPAT_MMC3X30_IOC_ID _IOR(MMC3X30_IOM, 0x06, short) +#define COMPAT_MMC3X30_IOC_DIAG _IOR(MMC3X30_IOM, 0x14, int[1]) +#define COMPAT_MMC3X30_IOC_READ_REG _IOWR(MMC3X30_IOM, 0x15, unsigned char) +#define COMPAT_MMC3X30_IOC_WRITE_REG _IOW(MMC3X30_IOM, 0x16, unsigned char[2]) +#define COMPAT_MMC3X30_IOC_READ_REGS _IOWR(MMC3X30_IOM, 0x17, unsigned char[10]) +#define COMPAT_MMC3X30_IOC_WRITE_REGS _IOW(MMC3X30_IOM, 0x18, unsigned char[10]) +#endif + +#endif /* __MMC3X30_H__ */ + From 744330f4e5d70dce71c4c9e03c5b6a8b59bb0cda Mon Sep 17 00:00:00 2001 From: Siena Richard Date: Tue, 16 Aug 2016 13:03:56 -0700 Subject: [PATCH 217/320] misc: qcom: qdsp6v2: initialize wma_config_32 Not all memebers of wma_config_32 are set before they are used which might lead to invalid values being passed and used. To fix this issue initialize all member variables of struct wma_config_32 to 0 before assigning specific values individually. Change-Id: Ibb082ce691625527e9a9ffd4978dea7ba4df9e84 CRs-Fixed: 1054352 Signed-off-by: Siena Richard --- drivers/misc/qcom/qdsp6v2/audio_wma.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/misc/qcom/qdsp6v2/audio_wma.c b/drivers/misc/qcom/qdsp6v2/audio_wma.c index 98779373ac4c3..cb5a9b1c3157b 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_wma.c +++ b/drivers/misc/qcom/qdsp6v2/audio_wma.c @@ -162,6 +162,8 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_wma_config_v2 *wma_config; struct msm_audio_wma_config_v2_32 wma_config_32; + memset(&wma_config_32, 0, sizeof(wma_config_32)); + wma_config = (struct msm_audio_wma_config_v2 *)audio->codec_cfg; wma_config_32.format_tag = wma_config->format_tag; wma_config_32.numchannels = wma_config->numchannels; From 19dd98a729ced5477064a0f3bd624e9fdf126780 Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Mon, 2 Feb 2015 17:39:25 -0800 Subject: [PATCH 218/320] cfg80211: Add indoor only and GO concurrent channel attributes The FCC are clarifying some soft configuration requirements, which among other include the following: 1. Indoor operation, where a device can use channels requiring indoor operation, subject to that it can guarantee indoor operation, i.e., the device is connected to AC Power or the device is under the control of a local master that is acting as an AP and is connected to AC Power. 2. Concurrent GO operation, where devices may instantiate a P2P GO while they are under the guidance of an authorized master. For example, on a channel on which a BSS is connected to an authorized master, i.e., with DFS and radar detection capability in the UNII band. See https://apps.fcc.gov/eas/comments/GetPublishedDocument.html?id=327&tn=528122 Add support for advertising Indoor-only and GO-Concurrent channel properties. Change-Id: Icd3a21f6f9c539d1323200e3ccce245238cbff3b Signed-off-by: David Spinadel Signed-off-by: Ilan Peer Signed-off-by: Johannes Berg Git-commit: 570dbde137d4604e4e682a5855b4425233344c19 Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git CRs-Fixed: 754373 Signed-off-by: Samuel Ahn --- include/net/cfg80211.h | 5 +++++ include/uapi/linux/nl80211.h | 26 ++++++++++++++++++++++++++ net/wireless/nl80211.c | 6 ++++++ net/wireless/reg.c | 2 ++ 4 files changed, 39 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 48007b3ce5f45..de5f7fda9ae64 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -114,6 +114,9 @@ enum ieee80211_band { * channel as the control or any of the secondary channels. * This may be due to the driver or due to regulatory bandwidth * restrictions. + * @IEEE80211_CHAN_INDOOR_ONLY: see %NL80211_FREQUENCY_ATTR_INDOOR_ONLY + * @IEEE80211_CHAN_GO_CONCURRENT: see %NL80211_FREQUENCY_ATTR_GO_CONCURRENT + * */ enum ieee80211_channel_flags { IEEE80211_CHAN_DISABLED = 1<<0, @@ -125,6 +128,8 @@ enum ieee80211_channel_flags { IEEE80211_CHAN_NO_OFDM = 1<<6, IEEE80211_CHAN_NO_80MHZ = 1<<7, IEEE80211_CHAN_NO_160MHZ = 1<<8, + IEEE80211_CHAN_INDOOR_ONLY = 1<<9, + IEEE80211_CHAN_GO_CONCURRENT = 1<<10, }; #define IEEE80211_CHAN_NO_HT40 \ diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 7e670c0f95474..cd3209a48c786 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -2291,9 +2291,32 @@ enum nl80211_band_attr { * @NL80211_FREQUENCY_ATTR_NO_160MHZ: any 160 MHz (but not 80+80) channel * using this channel as the primary or any of the secondary channels * isn't possible + * @NL80211_FREQUENCY_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds. + * @NL80211_FREQUENCY_ATTR_INDOOR_ONLY: Only indoor use is permitted on this + * channel. A channel that has the INDOOR_ONLY attribute can only be + * used when there is a clear assessment that the device is operating in + * an indoor surroundings, i.e., it is connected to AC power (and not + * through portable DC inverters) or is under the control of a master + * that is acting as an AP and is connected to AC power. + * @NL80211_FREQUENCY_ATTR_GO_CONCURRENT: GO operation is allowed on this + * channel if it's connected concurrently to a BSS on the same channel on + * the 2 GHz band or to a channel in the same UNII band (on the 5 GHz + * band), and IEEE80211_CHAN_RADAR is not set. Instantiating a GO on a + * channel that has the GO_CONCURRENT attribute set can be done when there + * is a clear assessment that the device is operating under the guidance of + * an authorized master, i.e., setting up a GO while the device is also + * connected to an AP with DFS and radar detection on the UNII band (it is + * up to user-space, i.e., wpa_supplicant to perform the required + * verifications) * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number * currently defined * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use + * + * See + * https://apps.fcc.gov/eas/comments/GetPublishedDocument.html?id=327&tn=528122 + * for more information on the FCC description of the relaxations allowed + * by NL80211_FREQUENCY_ATTR_INDOOR_ONLY and + * NL80211_FREQUENCY_ATTR_GO_CONCURRENT. */ enum nl80211_frequency_attr { __NL80211_FREQUENCY_ATTR_INVALID, @@ -2309,6 +2332,9 @@ enum nl80211_frequency_attr { NL80211_FREQUENCY_ATTR_NO_HT40_PLUS, NL80211_FREQUENCY_ATTR_NO_80MHZ, NL80211_FREQUENCY_ATTR_NO_160MHZ, + NL80211_FREQUENCY_ATTR_DFS_CAC_TIME, + NL80211_FREQUENCY_ATTR_INDOOR_ONLY, + NL80211_FREQUENCY_ATTR_GO_CONCURRENT, /* keep last */ __NL80211_FREQUENCY_ATTR_AFTER_LAST, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 479d2ccca722a..4db9ee0ac5f1a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -613,6 +613,12 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) && nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ)) goto nla_put_failure; + if ((chan->flags & IEEE80211_CHAN_INDOOR_ONLY) && + nla_put_flag(msg, NL80211_FREQUENCY_ATTR_INDOOR_ONLY)) + goto nla_put_failure; + if ((chan->flags & IEEE80211_CHAN_GO_CONCURRENT) && + nla_put_flag(msg, NL80211_FREQUENCY_ATTR_GO_CONCURRENT)) + goto nla_put_failure; } if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, diff --git a/net/wireless/reg.c b/net/wireless/reg.c index b99215db7a5f7..527f7a712ae6b 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -712,6 +712,8 @@ static u32 map_regdom_flags(u32 rd_flags) channel_flags |= IEEE80211_CHAN_RADAR; if (rd_flags & NL80211_RRF_NO_OFDM) channel_flags |= IEEE80211_CHAN_NO_OFDM; + if (rd_flags & NL80211_RRF_NO_OUTDOOR) + channel_flags |= IEEE80211_CHAN_INDOOR_ONLY; return channel_flags; } From 779771e0fdbfd6c4c3cfb9f79c2cf0f3cdfbf9e2 Mon Sep 17 00:00:00 2001 From: Devi Sandeep Endluri V V Date: Sun, 28 Aug 2016 14:28:49 +0530 Subject: [PATCH 219/320] defconfig: Enabling config INET_DIAG_DESTROY Sockets that are opened before VPN is connected are supposed to be destroyed once it is connected. VPN related CTS testcases are failing without the ability to destroy sockets. Enabling INET_DIAG_DESTROY to fix these testcases. CRs-Fixed: 1043997 Change-Id: Iffd056fb29a7e16556ec9502a3d005c5bb35be50 Signed-off-by: Devi Sandeep Endluri V V --- arch/arm/configs/msm8909-1gb-perf_defconfig | 1 + arch/arm/configs/msm8909-1gb_defconfig | 1 + arch/arm/configs/msm8909-perf_defconfig | 1 + arch/arm/configs/msm8909_defconfig | 1 + arch/arm/configs/msm8916-512mb-perf_defconfig | 1 + arch/arm/configs/msm8916-512mb_defconfig | 1 + arch/arm/configs/msm8916-perf_defconfig | 1 + arch/arm/configs/msm8916_defconfig | 1 + arch/arm64/configs/msm-perf_defconfig | 1 + arch/arm64/configs/msm_defconfig | 1 + 10 files changed, 10 insertions(+) diff --git a/arch/arm/configs/msm8909-1gb-perf_defconfig b/arch/arm/configs/msm8909-1gb-perf_defconfig index 3163de0b95dcb..93a413802cfe9 100644 --- a/arch/arm/configs/msm8909-1gb-perf_defconfig +++ b/arch/arm/configs/msm8909-1gb-perf_defconfig @@ -104,6 +104,7 @@ CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_IPCOMP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y diff --git a/arch/arm/configs/msm8909-1gb_defconfig b/arch/arm/configs/msm8909-1gb_defconfig index 529d1cea2bf00..1b6f6e56eaa03 100644 --- a/arch/arm/configs/msm8909-1gb_defconfig +++ b/arch/arm/configs/msm8909-1gb_defconfig @@ -110,6 +110,7 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y diff --git a/arch/arm/configs/msm8909-perf_defconfig b/arch/arm/configs/msm8909-perf_defconfig index 28f641919597b..ae028558e22ee 100644 --- a/arch/arm/configs/msm8909-perf_defconfig +++ b/arch/arm/configs/msm8909-perf_defconfig @@ -98,6 +98,7 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y diff --git a/arch/arm/configs/msm8909_defconfig b/arch/arm/configs/msm8909_defconfig index cb95945356ca7..18cb595bd88a0 100644 --- a/arch/arm/configs/msm8909_defconfig +++ b/arch/arm/configs/msm8909_defconfig @@ -102,6 +102,7 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y diff --git a/arch/arm/configs/msm8916-512mb-perf_defconfig b/arch/arm/configs/msm8916-512mb-perf_defconfig index 923fd7cde0c61..dd53dd0386469 100755 --- a/arch/arm/configs/msm8916-512mb-perf_defconfig +++ b/arch/arm/configs/msm8916-512mb-perf_defconfig @@ -85,6 +85,7 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y diff --git a/arch/arm/configs/msm8916-512mb_defconfig b/arch/arm/configs/msm8916-512mb_defconfig index bfff5b603c384..77d5a053f549d 100644 --- a/arch/arm/configs/msm8916-512mb_defconfig +++ b/arch/arm/configs/msm8916-512mb_defconfig @@ -88,6 +88,7 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y diff --git a/arch/arm/configs/msm8916-perf_defconfig b/arch/arm/configs/msm8916-perf_defconfig index cd18ab7677e80..e7c0dc7da6629 100644 --- a/arch/arm/configs/msm8916-perf_defconfig +++ b/arch/arm/configs/msm8916-perf_defconfig @@ -94,6 +94,7 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y diff --git a/arch/arm/configs/msm8916_defconfig b/arch/arm/configs/msm8916_defconfig index 0609e27fe5a0e..34bd6bb65dd83 100755 --- a/arch/arm/configs/msm8916_defconfig +++ b/arch/arm/configs/msm8916_defconfig @@ -97,6 +97,7 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig index 6e7266a26ca82..6c010821dad03 100644 --- a/arch/arm64/configs/msm-perf_defconfig +++ b/arch/arm64/configs/msm-perf_defconfig @@ -73,6 +73,7 @@ CONFIG_INET_AH=y CONFIG_INET_ESP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig index f9101b66dc116..54ac2d7cc393d 100644 --- a/arch/arm64/configs/msm_defconfig +++ b/arch/arm64/configs/msm_defconfig @@ -77,6 +77,7 @@ CONFIG_INET_AH=y CONFIG_INET_ESP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y From b2e73ebbb487ff91dcb4e6e61d5584b4ccc7165f Mon Sep 17 00:00:00 2001 From: Venu Yeshala Date: Fri, 30 Oct 2015 16:35:13 +0530 Subject: [PATCH 220/320] msm-camera: isp: Use memory barriers in release function Use memory barriers in release function and trim down reset function called during release. Change-Id: I20afca9c6988b0a89153b2c2690ae8d0201bc3cd Signed-off-by: Venu Yeshala Signed-off-by: VijayaKumar T M --- .../platform/msm/camera_v2/ispif/msm_ispif.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c index 04acb08eba5dd..0e9b358408934 100644 --- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c +++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c @@ -106,9 +106,9 @@ static struct msm_cam_clk_info ispif_8974_reset_clk_info[] = { {"camss_csi_vfe1_clk", NO_SET_RATE}, }; -static int msm_ispif_reset_hw(struct ispif_device *ispif) +static int msm_ispif_reset_hw(struct ispif_device *ispif, int release) { - int rc = 0; + int rc = 0, i; long timeout = 0; struct clk *reset_clk[ARRAY_SIZE(ispif_8974_reset_clk_info)]; struct clk *reset_clk1[ARRAY_SIZE(ispif_8626_reset_clk_info)]; @@ -133,6 +133,17 @@ static int msm_ispif_reset_hw(struct ispif_device *ispif) ispif->clk_idx = 1; } + if (release) { + for (i = 0; i < ispif->vfe_info.num_vfe; i++) { + msm_camera_io_w_mb(ISPIF_STOP_INTF_IMMEDIATELY, + ispif->base + ISPIF_VFE_m_INTF_CMD_0(i)); + msm_camera_io_w_mb(ISPIF_STOP_INTF_IMMEDIATELY, + ispif->base + ISPIF_VFE_m_INTF_CMD_1(i)); + } + msm_camera_io_w_mb(ISPIF_IRQ_GLOBAL_CLEAR_CMD, + ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR); + } + init_completion(&ispif->reset_complete[VFE0]); if (ispif->hw_num_isps > 1) init_completion(&ispif->reset_complete[VFE1]); @@ -1235,7 +1246,7 @@ static int msm_ispif_init(struct ispif_device *ispif, goto error_ahb; } - msm_ispif_reset_hw(ispif); + msm_ispif_reset_hw(ispif, 0); rc = msm_ispif_reset(ispif); if (rc == 0) { @@ -1269,7 +1280,7 @@ static void msm_ispif_release(struct ispif_device *ispif) } /* make sure no streaming going on */ - msm_ispif_reset(ispif); + msm_ispif_reset_hw(ispif, 1); msm_ispif_clk_ahb_enable(ispif, 0); From 573db8d78bbe759e116e361e693c6683e9212d77 Mon Sep 17 00:00:00 2001 From: Venu Yeshala Date: Wed, 6 Jan 2016 15:44:14 +0530 Subject: [PATCH 221/320] msm-camera: isp: Handle ISPIF reset and close properly ISPIF close and shutdown should not be executed in parallel. Guard this situation using a mutex. Also enable AHB clock when resetting ISPIF hardware. Change-Id: I54eb02e2732c3a93b3f8dc8aefee2066d6d830ed Signed-off-by: Venu Yeshala Signed-off-by: VijayaKumar T M --- .../media/platform/msm/camera_v2/ispif/msm_ispif.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c index 0e9b358408934..6ac76b7b7048f 100644 --- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c +++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c @@ -579,6 +579,12 @@ static int msm_ispif_config(struct ispif_device *ispif, BUG_ON(!ispif); BUG_ON(!params); + if (!ispif->base) { + pr_err("%s: ispif base is NULL\n", __func__); + rc = -EPERM; + return rc; + } + if (ispif->ispif_state != ISPIF_POWER_UP) { pr_err("%s: ispif invalid state %d\n", __func__, ispif->ispif_state); @@ -1279,6 +1285,8 @@ static void msm_ispif_release(struct ispif_device *ispif) return; } + msm_ispif_clk_ahb_enable(ispif, 1); + /* make sure no streaming going on */ msm_ispif_reset_hw(ispif, 1); @@ -1365,8 +1373,11 @@ static long msm_ispif_subdev_ioctl(struct v4l2_subdev *sd, case MSM_SD_SHUTDOWN: { struct ispif_device *ispif = (struct ispif_device *)v4l2_get_subdevdata(sd); - if (ispif && ispif->base) + if (ispif && ispif->base) { + mutex_lock(&ispif->mutex); msm_ispif_release(ispif); + mutex_unlock(&ispif->mutex); + } return 0; } default: From 51f9d96ad9f0adfad2137780e8b9af05195b82b6 Mon Sep 17 00:00:00 2001 From: Jin Fu Date: Fri, 5 Aug 2016 17:06:31 +0800 Subject: [PATCH 222/320] ARM: dts: msm: add node of green and red leds for msm8909 QSIP Add device tree node for green and red leds connected via gpio. CRs-Fixed: 1058749 Change-Id: I4f29a785b9fbffd14379afaa1529b4bf315a0397 Signed-off-by: Jin Fu Signed-off-by: Changmin Liu --- arch/arm/boot/dts/qcom/msm8909-pinctrl.dtsi | 11 +++++++++ .../dts/qcom/msm8909-pm8916-qrd-skuq.dtsi | 23 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msm8909-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msm8909-pinctrl.dtsi index c33e6bda0f242..7787956b35e29 100644 --- a/arch/arm/boot/dts/qcom/msm8909-pinctrl.dtsi +++ b/arch/arm/boot/dts/qcom/msm8909-pinctrl.dtsi @@ -1206,6 +1206,17 @@ }; }; + gpio_led_pins { + qcom,pins = <&gp 91>, <&gp 92>; + qcom,num-grp-pins = <2>; + label = "gpio-led-pins"; + gpio_led_off: led_off { + drive-strength = <2>; + bias-disable; /* no pullup */ + output-low; + }; + }; + /* add pingrp for touchscreen */ pmx_ts_int_active { qcom,pins = <&gp 13>; diff --git a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi index c11f8cfc215be..bda573b3740dc 100644 --- a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi +++ b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi @@ -83,6 +83,29 @@ asoc-codec = <&stub_codec>, <&pm8916_tombak_dig>; asoc-codec-names = "msm-stub-codec.1", "tombak_codec"; }; + + gpio-leds { + compatible = "gpio-leds"; + STAtus = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&gpio_led_off>; + + red { + gpios = <&msm_gpio 91 0>; + label = "red"; + linux,default-trigger = "none"; + default-state = "off"; + retain-state-suspended; + }; + + green { + gpios = <&msm_gpio 92 0>; + label = "green"; + linux,default-trigger = "none"; + default-state = "off"; + retain-state-suspended; + }; + }; }; &pm8916_mpps { mpp@a300 { /* MPP 4 */ From 30bca796e4c5e222cc4690394da3363b070287ea Mon Sep 17 00:00:00 2001 From: Jin Fu Date: Fri, 19 Aug 2016 16:57:37 +0800 Subject: [PATCH 223/320] ARM: dts: msm: Add MSM8909 QSIP volume up key support MSM8909 QSIP volume up gpio key is connected to GPIO 91. Add definition for GPIO 91. CRs-Fixed: 1058742 Change-Id: I65ed76e0f728dae411feaae8196cb82b1ac4db78 Signed-off-by: Jin Fu Signed-off-by: Changmin Liu --- .../boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi index bda573b3740dc..4030bfc1d7b1e 100644 --- a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi +++ b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi @@ -106,7 +106,25 @@ retain-state-suspended; }; }; + + gpio_keys { + compatible = "gpio-keys"; + input-name = "gpio-keys"; + pinctrl-names = "tlmm_gpio_key_active","tlmm_gpio_key_suspend"; + pinctrl-0 = <&gpio_key_active>; + pinctrl-1 = <&gpio_key_suspend>; + + vol_up { + label = "volume_up"; + gpios = <&msm_gpio 90 0x1>; + linux,input-type = <1>; + linux,code = <115>; + gpio-key,wakeup; + debounce-interval = <15>; + }; + }; }; + &pm8916_mpps { mpp@a300 { /* MPP 4 */ /* Backlight PWM */ From b45d98a91da7d02add26607eeb346626422252a5 Mon Sep 17 00:00:00 2001 From: Haynes Mathew George Date: Wed, 3 Aug 2016 11:55:07 -0700 Subject: [PATCH 224/320] misc: qcom: qdsp6v2: Add missing initialization Use vars in driver context after proper initialization Change-Id: I3e59e27534b8e1088d74b42c72e0075d2fe910e6 Signed-off-by: Haynes Mathew George --- drivers/misc/qcom/qdsp6v2/audio_utils.c | 3 ++- drivers/misc/qcom/qdsp6v2/audio_utils_aio.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils.c b/drivers/misc/qcom/qdsp6v2/audio_utils.c index 30f207810e3aa..9dd52b6391816 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -588,6 +588,7 @@ long audio_in_compat_ioctl(struct file *file, } case AUDIO_GET_CONFIG_32: { struct msm_audio_config32 cfg_32; + memset(&cfg_32, 0, sizeof(cfg_32)); cfg_32.buffer_size = audio->pcm_cfg.buffer_size; cfg_32.buffer_count = audio->pcm_cfg.buffer_count; cfg_32.channel_count = audio->pcm_cfg.channel_count; diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c index 6db7519dcbf43..a1d5e461a7c42 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c @@ -1875,6 +1875,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, case AUDIO_GET_CONFIG_32: { struct msm_audio_config32 cfg_32; mutex_lock(&audio->lock); + memset(&cfg_32, 0, sizeof(cfg_32)); cfg_32.buffer_size = audio->pcm_cfg.buffer_size; cfg_32.buffer_count = audio->pcm_cfg.buffer_count; cfg_32.channel_count = audio->pcm_cfg.channel_count; From bd7a06bccdcdb9d0e4768500d089d627da37436b Mon Sep 17 00:00:00 2001 From: Xiaogang Cui Date: Wed, 24 Aug 2016 15:56:04 +0800 Subject: [PATCH 225/320] ARM: dts: msm: remove incorrect volume down setting Remove incorrect setting of volume down key which causes msm8909 QRD SKUQ board enter into safe mode every time. CRs-Fixed: 1058752 Change-Id: I1791b5c4371ef0f06665300502619010d67f0be2 Signed-off-by: Xiaogang Cui Signed-off-by: c_yinbin --- arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi index 4030bfc1d7b1e..abddc3adeadc6 100644 --- a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi +++ b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi @@ -122,6 +122,8 @@ gpio-key,wakeup; debounce-interval = <15>; }; + + /delete-node/ vol_down; }; }; From aff982f224d45a7faf7ad4e74633d1a8510a1c04 Mon Sep 17 00:00:00 2001 From: Divya Ponnusamy Date: Wed, 24 Aug 2016 17:06:54 +0530 Subject: [PATCH 226/320] msm: kgsl: Change %p to %pK in debug messages The format specifier %p can leak kernel addresses while not valuing the kptr_restrict system settings. Use %pK instead of %p, which evaluates whether kptr_restrict is set. Change-Id: I0778e43e0a03852ca2944377256a7b401586a747 Signed-off-by: Divya Ponnusamy Signed-off-by: Sudeep Yedalapure --- drivers/gpu/msm/adreno_debugfs.c | 4 ++-- drivers/gpu/msm/kgsl.c | 7 +++---- drivers/gpu/msm/kgsl_cffdump.c | 9 +-------- drivers/gpu/msm/kgsl_iommu.c | 18 +++++++++--------- drivers/gpu/msm/kgsl_pwrctrl.c | 4 ++-- drivers/gpu/msm/kgsl_snapshot.c | 5 +---- 6 files changed, 18 insertions(+), 29 deletions(-) mode change 100755 => 100644 drivers/gpu/msm/kgsl_pwrctrl.c diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c index b487df4f55aeb..16eaf4ead0741 100644 --- a/drivers/gpu/msm/adreno_debugfs.c +++ b/drivers/gpu/msm/adreno_debugfs.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2008-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2008-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -48,7 +48,7 @@ static void sync_event_print(struct seq_file *s, break; } case KGSL_CMD_SYNCPOINT_TYPE_FENCE: - seq_printf(s, "sync: [%p] %s", sync_event->handle, + seq_printf(s, "sync: [%pK] %s", sync_event->handle, (sync_event->handle && sync_event->handle->fence) ? sync_event->handle->fence->name : "NULL"); break; diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index f4b6c83f8b7fd..ecfe64061ccd9 100755 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1595,7 +1595,7 @@ void kgsl_dump_syncpoints(struct kgsl_device *device, } case KGSL_CMD_SYNCPOINT_TYPE_FENCE: if (event->handle) - dev_err(device->dev, " fence: [%p] %s\n", + dev_err(device->dev, " fence: [%pK] %s\n", event->handle->fence, event->handle->name); else @@ -4670,9 +4670,8 @@ int kgsl_device_platform_probe(struct kgsl_device *device) disable_irq(device->pwrctrl.interrupt_num); KGSL_DRV_INFO(device, - "dev_id %d regs phys 0x%08lx size 0x%08x virt %p\n", - device->id, device->reg_phys, device->reg_len, - device->reg_virt); + "dev_id %d regs phys 0x%08lx size 0x%08x\n", + device->id, device->reg_phys, device->reg_len); rwlock_init(&device->context_lock); diff --git a/drivers/gpu/msm/kgsl_cffdump.c b/drivers/gpu/msm/kgsl_cffdump.c index 670a4f4fe307f..120d1a44a0d76 100644 --- a/drivers/gpu/msm/kgsl_cffdump.c +++ b/drivers/gpu/msm/kgsl_cffdump.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -515,10 +515,6 @@ EXPORT_SYMBOL(kgsl_cffdump_waitirq); static int subbuf_start_handler(struct rchan_buf *buf, void *subbuf, void *prev_subbuf, size_t prev_padding) { - pr_debug("kgsl: cffdump: subbuf_start_handler(subbuf=%p, prev_subbuf" - "=%p, prev_padding=%08zx)\n", subbuf, prev_subbuf, - prev_padding); - if (relay_buf_full(buf)) { if (!suspended) { suspended = 1; @@ -575,9 +571,6 @@ static struct rchan *create_channel(unsigned subbuf_size, unsigned n_subbufs) { struct rchan *chan; - pr_info("kgsl: cffdump: relay: create_channel: subbuf_size %u, " - "n_subbufs %u, dir 0x%p\n", subbuf_size, n_subbufs, dir); - chan = relay_open("cpu", dir, subbuf_size, n_subbufs, &relay_callbacks, NULL); if (!chan) { diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index a4d24159823fb..123edf426aad3 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -333,7 +333,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain, iommu_dev = get_iommu_device(iommu_unit, dev); if (!iommu_dev) { - KGSL_CORE_ERR("Invalid IOMMU device %p\n", dev); + KGSL_CORE_ERR("Invalid IOMMU device %pK\n", dev); ret = -ENOSYS; goto done; } @@ -723,8 +723,8 @@ static void kgsl_detach_pagetable_iommu_domain(struct kgsl_mmu *mmu) iommu_detach_device(iommu_pt->domain, iommu_unit->dev[j].dev); iommu_unit->dev[j].attached = false; - KGSL_MEM_INFO(mmu->device, "iommu %p detached " - "from user dev of MMU: %p\n", + KGSL_MEM_INFO(mmu->device, "iommu %pK detached " + "from user dev of MMU: %pK\n", iommu_pt->domain, mmu); } } @@ -788,7 +788,7 @@ static int kgsl_attach_pagetable_iommu_domain(struct kgsl_mmu *mmu) } iommu_unit->dev[j].attached = true; KGSL_MEM_INFO(mmu->device, - "iommu pt %p attached to dev %p, ctx_id %d\n", + "iommu pt %pK attached to dev %pK, ctx_id %d\n", iommu_pt->domain, iommu_unit->dev[j].dev, iommu_unit->dev[j].ctx_id); /* Init IOMMU unit clks here */ @@ -863,7 +863,7 @@ static int _get_iommu_ctxs(struct kgsl_mmu *mmu, iommu_unit->dev[iommu_unit->dev_count].kgsldev = mmu->device; KGSL_DRV_INFO(mmu->device, - "Obtained dev handle %p for iommu context %s\n", + "Obtained dev handle %pK for iommu context %s\n", iommu_unit->dev[iommu_unit->dev_count].dev, data->iommu_ctxs[i].iommu_ctx_name); @@ -1695,7 +1695,7 @@ kgsl_iommu_unmap(struct kgsl_pagetable *pt, } else ret = iommu_unmap_range(iommu_pt->domain, gpuaddr, range); if (ret) { - KGSL_CORE_ERR("iommu_unmap_range(%p, %x, %d) failed " + KGSL_CORE_ERR("iommu_unmap_range(%pK, %x, %d) failed " "with err: %d\n", iommu_pt->domain, gpuaddr, range, ret); return ret; @@ -1807,7 +1807,7 @@ kgsl_iommu_map(struct kgsl_pagetable *pt, sg_temp ? sg_temp : memdesc->sg, size, protflags); if (ret) { - KGSL_CORE_ERR("iommu_map_range(%p, %x, %p, %zd, %x) err: %d\n", + KGSL_CORE_ERR("iommu_map_range(%pK, %x, %pK, %zd, %x) err: %d\n", iommu_pt->domain, iommu_virt_addr, sg_temp ? sg_temp : memdesc->sg, size, protflags, ret); @@ -1820,7 +1820,7 @@ kgsl_iommu_map(struct kgsl_pagetable *pt, page_to_phys(kgsl_guard_page), PAGE_SIZE, protflags & ~IOMMU_WRITE); if (ret) { - KGSL_CORE_ERR("iommu_map(%p, %zx, guard, %x) err: %d\n", + KGSL_CORE_ERR("iommu_map(%pK, %zx, guard, %x) err: %d\n", iommu_pt->domain, iommu_virt_addr + size, protflags & ~IOMMU_WRITE, ret); diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c old mode 100755 new mode 100644 index f774b89bf0dc3..4915087256fbf --- a/drivers/gpu/msm/kgsl_pwrctrl.c +++ b/drivers/gpu/msm/kgsl_pwrctrl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1358,7 +1358,7 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) if (!pwr->pcl) { KGSL_PWR_ERR(device, "msm_bus_scale_register_client failed: " - "id %d table %p %p", device->id, + "id %d table %pK %pK", device->id, pdata->bus_scale_table, ocmem_scale_table); result = -EINVAL; diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c index a37aaf09c2c98..2f3a7f305f523 100644 --- a/drivers/gpu/msm/kgsl_snapshot.c +++ b/drivers/gpu/msm/kgsl_snapshot.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1110,9 +1110,6 @@ void kgsl_snapshot_save_frozen_objs(struct work_struct *work) goto done; snapshot->mempool = vmalloc(size); - if (snapshot->mempool != NULL) - KGSL_CORE_ERR("snapshot: mempool address %p, size %zx\n", - snapshot->mempool, size); ptr = snapshot->mempool; snapshot->mempool_size = 0; From 78f4bb451b029ccfad4ec5a4d5ea69f8ca128db4 Mon Sep 17 00:00:00 2001 From: Divya Ponnusamy Date: Wed, 24 Aug 2016 17:06:54 +0530 Subject: [PATCH 227/320] msm: kgsl: Change %p to %pK in debug messages The format specifier %p can leak kernel addresses while not valuing the kptr_restrict system settings. Use %pK instead of %p, which evaluates whether kptr_restrict is set. Change-Id: I0778e43e0a03852ca2944377256a7b401586a747 Signed-off-by: Divya Ponnusamy Signed-off-by: Sudeep Yedalapure --- drivers/gpu/msm/adreno_debugfs.c | 4 ++-- drivers/gpu/msm/kgsl.c | 7 +++---- drivers/gpu/msm/kgsl_cffdump.c | 9 +-------- drivers/gpu/msm/kgsl_iommu.c | 18 +++++++++--------- drivers/gpu/msm/kgsl_pwrctrl.c | 4 ++-- drivers/gpu/msm/kgsl_snapshot.c | 5 +---- 6 files changed, 18 insertions(+), 29 deletions(-) mode change 100755 => 100644 drivers/gpu/msm/kgsl_pwrctrl.c diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c index b487df4f55aeb..16eaf4ead0741 100644 --- a/drivers/gpu/msm/adreno_debugfs.c +++ b/drivers/gpu/msm/adreno_debugfs.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2008-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2008-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -48,7 +48,7 @@ static void sync_event_print(struct seq_file *s, break; } case KGSL_CMD_SYNCPOINT_TYPE_FENCE: - seq_printf(s, "sync: [%p] %s", sync_event->handle, + seq_printf(s, "sync: [%pK] %s", sync_event->handle, (sync_event->handle && sync_event->handle->fence) ? sync_event->handle->fence->name : "NULL"); break; diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index f4b6c83f8b7fd..ecfe64061ccd9 100755 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1595,7 +1595,7 @@ void kgsl_dump_syncpoints(struct kgsl_device *device, } case KGSL_CMD_SYNCPOINT_TYPE_FENCE: if (event->handle) - dev_err(device->dev, " fence: [%p] %s\n", + dev_err(device->dev, " fence: [%pK] %s\n", event->handle->fence, event->handle->name); else @@ -4670,9 +4670,8 @@ int kgsl_device_platform_probe(struct kgsl_device *device) disable_irq(device->pwrctrl.interrupt_num); KGSL_DRV_INFO(device, - "dev_id %d regs phys 0x%08lx size 0x%08x virt %p\n", - device->id, device->reg_phys, device->reg_len, - device->reg_virt); + "dev_id %d regs phys 0x%08lx size 0x%08x\n", + device->id, device->reg_phys, device->reg_len); rwlock_init(&device->context_lock); diff --git a/drivers/gpu/msm/kgsl_cffdump.c b/drivers/gpu/msm/kgsl_cffdump.c index 670a4f4fe307f..120d1a44a0d76 100644 --- a/drivers/gpu/msm/kgsl_cffdump.c +++ b/drivers/gpu/msm/kgsl_cffdump.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -515,10 +515,6 @@ EXPORT_SYMBOL(kgsl_cffdump_waitirq); static int subbuf_start_handler(struct rchan_buf *buf, void *subbuf, void *prev_subbuf, size_t prev_padding) { - pr_debug("kgsl: cffdump: subbuf_start_handler(subbuf=%p, prev_subbuf" - "=%p, prev_padding=%08zx)\n", subbuf, prev_subbuf, - prev_padding); - if (relay_buf_full(buf)) { if (!suspended) { suspended = 1; @@ -575,9 +571,6 @@ static struct rchan *create_channel(unsigned subbuf_size, unsigned n_subbufs) { struct rchan *chan; - pr_info("kgsl: cffdump: relay: create_channel: subbuf_size %u, " - "n_subbufs %u, dir 0x%p\n", subbuf_size, n_subbufs, dir); - chan = relay_open("cpu", dir, subbuf_size, n_subbufs, &relay_callbacks, NULL); if (!chan) { diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index a4d24159823fb..123edf426aad3 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -333,7 +333,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain, iommu_dev = get_iommu_device(iommu_unit, dev); if (!iommu_dev) { - KGSL_CORE_ERR("Invalid IOMMU device %p\n", dev); + KGSL_CORE_ERR("Invalid IOMMU device %pK\n", dev); ret = -ENOSYS; goto done; } @@ -723,8 +723,8 @@ static void kgsl_detach_pagetable_iommu_domain(struct kgsl_mmu *mmu) iommu_detach_device(iommu_pt->domain, iommu_unit->dev[j].dev); iommu_unit->dev[j].attached = false; - KGSL_MEM_INFO(mmu->device, "iommu %p detached " - "from user dev of MMU: %p\n", + KGSL_MEM_INFO(mmu->device, "iommu %pK detached " + "from user dev of MMU: %pK\n", iommu_pt->domain, mmu); } } @@ -788,7 +788,7 @@ static int kgsl_attach_pagetable_iommu_domain(struct kgsl_mmu *mmu) } iommu_unit->dev[j].attached = true; KGSL_MEM_INFO(mmu->device, - "iommu pt %p attached to dev %p, ctx_id %d\n", + "iommu pt %pK attached to dev %pK, ctx_id %d\n", iommu_pt->domain, iommu_unit->dev[j].dev, iommu_unit->dev[j].ctx_id); /* Init IOMMU unit clks here */ @@ -863,7 +863,7 @@ static int _get_iommu_ctxs(struct kgsl_mmu *mmu, iommu_unit->dev[iommu_unit->dev_count].kgsldev = mmu->device; KGSL_DRV_INFO(mmu->device, - "Obtained dev handle %p for iommu context %s\n", + "Obtained dev handle %pK for iommu context %s\n", iommu_unit->dev[iommu_unit->dev_count].dev, data->iommu_ctxs[i].iommu_ctx_name); @@ -1695,7 +1695,7 @@ kgsl_iommu_unmap(struct kgsl_pagetable *pt, } else ret = iommu_unmap_range(iommu_pt->domain, gpuaddr, range); if (ret) { - KGSL_CORE_ERR("iommu_unmap_range(%p, %x, %d) failed " + KGSL_CORE_ERR("iommu_unmap_range(%pK, %x, %d) failed " "with err: %d\n", iommu_pt->domain, gpuaddr, range, ret); return ret; @@ -1807,7 +1807,7 @@ kgsl_iommu_map(struct kgsl_pagetable *pt, sg_temp ? sg_temp : memdesc->sg, size, protflags); if (ret) { - KGSL_CORE_ERR("iommu_map_range(%p, %x, %p, %zd, %x) err: %d\n", + KGSL_CORE_ERR("iommu_map_range(%pK, %x, %pK, %zd, %x) err: %d\n", iommu_pt->domain, iommu_virt_addr, sg_temp ? sg_temp : memdesc->sg, size, protflags, ret); @@ -1820,7 +1820,7 @@ kgsl_iommu_map(struct kgsl_pagetable *pt, page_to_phys(kgsl_guard_page), PAGE_SIZE, protflags & ~IOMMU_WRITE); if (ret) { - KGSL_CORE_ERR("iommu_map(%p, %zx, guard, %x) err: %d\n", + KGSL_CORE_ERR("iommu_map(%pK, %zx, guard, %x) err: %d\n", iommu_pt->domain, iommu_virt_addr + size, protflags & ~IOMMU_WRITE, ret); diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c old mode 100755 new mode 100644 index f774b89bf0dc3..4915087256fbf --- a/drivers/gpu/msm/kgsl_pwrctrl.c +++ b/drivers/gpu/msm/kgsl_pwrctrl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1358,7 +1358,7 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) if (!pwr->pcl) { KGSL_PWR_ERR(device, "msm_bus_scale_register_client failed: " - "id %d table %p %p", device->id, + "id %d table %pK %pK", device->id, pdata->bus_scale_table, ocmem_scale_table); result = -EINVAL; diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c index a37aaf09c2c98..2f3a7f305f523 100644 --- a/drivers/gpu/msm/kgsl_snapshot.c +++ b/drivers/gpu/msm/kgsl_snapshot.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1110,9 +1110,6 @@ void kgsl_snapshot_save_frozen_objs(struct work_struct *work) goto done; snapshot->mempool = vmalloc(size); - if (snapshot->mempool != NULL) - KGSL_CORE_ERR("snapshot: mempool address %p, size %zx\n", - snapshot->mempool, size); ptr = snapshot->mempool; snapshot->mempool_size = 0; From 725c65ce9fe047f0af223e52eb8fb8d90e4dd0df Mon Sep 17 00:00:00 2001 From: Mohamad Ayyash Date: Tue, 24 May 2016 12:57:16 -0700 Subject: [PATCH 228/320] Replace %p with %pK to prevent leaking kernel address BUG: 27532522 Change-Id: Ic0710a9a8cfc682acd88ecf3bbfeece2d798c4a4 Signed-off-by: Mohamad Ayyash --- net/netfilter/xt_qtaguid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c index 82b06f91fb488..c690e0f19b454 100644 --- a/net/netfilter/xt_qtaguid.c +++ b/net/netfilter/xt_qtaguid.c @@ -1923,7 +1923,7 @@ static int qtaguid_ctrl_proc_show(struct seq_file *m, void *v) ); f_count = atomic_long_read( &sock_tag_entry->socket->file->f_count); - seq_printf(m, "sock=%p tag=0x%llx (uid=%u) pid=%u " + seq_printf(m, "sock=%pK tag=0x%llx (uid=%u) pid=%u " "f_count=%lu\n", sock_tag_entry->sk, sock_tag_entry->tag, uid, From 30a6b8007211e71f3903a9a8d6ffab3331b31e0d Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Mon, 25 Apr 2016 15:52:05 -0700 Subject: [PATCH 229/320] BACKPORT: f2fs: add a max block check for get_data_block_bmap (cherry pick from commit 179448bfe4cd201e98e728391c6b01b25c849fe8) This patch adds a max block check for get_data_block_bmap. Trinity test program will send a block number as parameter into ioctl_fibmap, which will be used in get_node_path(), when the block number large than f2fs max blocks, it will trigger kernel bug. Signed-off-by: Yunlei He Signed-off-by: Xue Liu [Jaegeuk Kim: fix missing condition, pointed by Chao Yu] Signed-off-by: Jaegeuk Kim Bug: 28271368 Change-Id: Ia5acae04522993d5b60a0bcb5ccc184c66532be8 Git-commit: 3c714201e02ec08652be4b9544a5267e79bde3a9 Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: Srinivasarao P --- fs/f2fs/data.c | 11 ++++++++++- fs/f2fs/f2fs.h | 1 + fs/f2fs/super.c | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 91ff93b0b0f40..96234982c26f2 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -445,6 +445,15 @@ static int get_data_block_ro(struct inode *inode, sector_t iblock, return 0; } +static int get_data_block_bmap(struct inode *inode, sector_t iblock, + struct buffer_head *bh_result, int create) +{ + /* Block number less than F2FS MAX BLOCKS */ + if (unlikely(iblock >= max_file_size(0))) + return -EFBIG; + return get_data_block_ro(inode, iblock, bh_result, create); +} + static int f2fs_read_data_page(struct file *file, struct page *page) { return mpage_readpage(page, get_data_block_ro); @@ -731,7 +740,7 @@ static int f2fs_set_data_page_dirty(struct page *page) static sector_t f2fs_bmap(struct address_space *mapping, sector_t block) { - return generic_block_bmap(mapping, block, get_data_block_ro); + return generic_block_bmap(mapping, block, get_data_block_bmap); } const struct address_space_operations f2fs_dblock_aops = { diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 20aab02f2a427..8aeea5dbce5ad 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -928,6 +928,7 @@ static inline int f2fs_add_link(struct dentry *dentry, struct inode *inode) /* * super.c */ +loff_t max_file_size(unsigned bits); int f2fs_sync_fs(struct super_block *, int); extern __printf(3, 4) void f2fs_msg(struct super_block *, const char *, const char *, ...); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 8555f7df82c79..f9806eef6a1a4 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -376,7 +376,7 @@ static int parse_options(struct super_block *sb, struct f2fs_sb_info *sbi, return 0; } -static loff_t max_file_size(unsigned bits) +loff_t max_file_size(unsigned bits) { loff_t result = ADDRS_PER_INODE; loff_t leaf_count = ADDRS_PER_BLOCK; From d2c25a8a850460d971b04a91f76795bbf3396dea Mon Sep 17 00:00:00 2001 From: Shaoqing Liu Date: Mon, 29 Aug 2016 19:26:09 +0800 Subject: [PATCH 230/320] input: sensors: modify bmi160 and mmc3x30 driver for msm8909 Add power manage and sensor hal interface in bmi160 and mmc3x30 init drivers for msm8909 QRD SKUQ board. Change-Id: Idb4427601f85531036dbc816c23fe3a46fe77262 Signed-off-by: Shaoqing Liu --- .../devicetree/bindings/input/misc/bmi160.txt | 49 + .../bindings/input/misc/mmc3x30.txt | 58 + drivers/input/misc/Kconfig | 43 + drivers/input/misc/Makefile | 18 + drivers/input/misc/bmi160.c | 0 drivers/input/misc/bmi160.h | 209 --- drivers/input/misc/bmi160_driver.c | 1160 ++++++++++++----- drivers/input/misc/bmi160_driver.h | 43 +- drivers/input/misc/bmi160_i2c.c | 3 +- drivers/input/misc/mmc3x30.c | 433 +++--- include/linux/i2c/mmc3x30.h | 108 +- 11 files changed, 1267 insertions(+), 857 deletions(-) create mode 100644 Documentation/devicetree/bindings/input/misc/bmi160.txt create mode 100644 Documentation/devicetree/bindings/input/misc/mmc3x30.txt mode change 100755 => 100644 drivers/input/misc/bmi160.c mode change 100755 => 100644 drivers/input/misc/bmi160.h mode change 100755 => 100644 drivers/input/misc/bmi160_driver.c mode change 100755 => 100644 drivers/input/misc/bmi160_driver.h mode change 100755 => 100644 drivers/input/misc/bmi160_i2c.c mode change 100755 => 100644 drivers/input/misc/mmc3x30.c mode change 100755 => 100644 include/linux/i2c/mmc3x30.h diff --git a/Documentation/devicetree/bindings/input/misc/bmi160.txt b/Documentation/devicetree/bindings/input/misc/bmi160.txt new file mode 100644 index 0000000000000..7fe6eedb09b0f --- /dev/null +++ b/Documentation/devicetree/bindings/input/misc/bmi160.txt @@ -0,0 +1,49 @@ +BOSCH 6-axis accelerometer and gyroscope sensor driver. + +Required properties: + + - compatible : Should be "bosch,bmi160". + - reg : i2c slave address of the device. + - pinctrl-names : Pinctrl configuration names of this sensor driver. + Should be "default". + - pinctrl-0 : The pinctrl node corresponding to "default", + should be <&bmi160_int1_default &bmi160_int2_default>. + - interrupt-parent : Parent of interrupt. + - interrupts : Accelerometer interrupts to indicate new data ready or events. + - vdd-supply : Analog power supply needed to power device. + - vio-supply : Digital IO power supply needed for IO and I2C. + - bosch,init-interval : Initial data polling interval in millisecond. + - bosch,place : The placing of the accelerometer on board. There are 8 + patterns of placing described as below: + 0: 1st pin is right down + 1: 1st pin is left down + 2: 1st pin is left top + 3: 1st pin is right top + 4: 1st pin is left down (from top view) + 5: 1st pin is left top (from top view) + 6: 1st pin is right top (from top view) + 7: 1st pin is right down (from top view) + +Optional properties: + + - bosch,gpio-int1 : 1st irq gpio which is to provide interrupts + to host, interrupt events can be route to any of + these two irq pins according device configuration. + - bosch,gpio-int2 : 2nd irq gpio which is to provide interrupts + to host. +Example: +&i2c_0 { /* BLSP1 QUP2 */ + bosch@68 { /* Accelerometer and Gyroscope sensor */ + compatible = "bosch,bmi160"; + reg = <0x68>; + pinctrl-names = "default"; + pinctrl-0 = <&bmi160_int1_default>; + interrupt-parent = <&msm_gpio>; + interrupts = <96 0x2002>; + vdd-supply = <&pm8916_l17>; + vio-supply = <&pm8916_l6>; + bosch,init-interval = <200>; + bosch,place = <1>; + bosch,gpio-int1 = <&msm_gpio 96 0x2002>; + }; +}; diff --git a/Documentation/devicetree/bindings/input/misc/mmc3x30.txt b/Documentation/devicetree/bindings/input/misc/mmc3x30.txt new file mode 100644 index 0000000000000..f050cdc8cc918 --- /dev/null +++ b/Documentation/devicetree/bindings/input/misc/mmc3x30.txt @@ -0,0 +1,58 @@ +MEMSIC MMC3x30 3-axis magnetic sensor + +The MEMSIC 3-axis magnetic sensor is a complete 3-axis magnetic sensor with +on-chip signal processing and intergrated i2c bus. It can be connected to host +processor via i2c. It can measure magnetic fields within the full scale range +from -16 Gauss to +16 Gauss. + +Required properties: + + - compatible : Should be "memsic,mmc3x30". + - reg : i2c address of the device. + - vdd-supply : Analog power supply needed to power up the device. + - vio-supply : Digital IO power supply needed for IO and I2C. + - memsic,dir : String value of the direction of the ecompass sensor + chip. There are 8 patterns of direction: + + + x > 0 /___________o + / /| + / / |* 1st pin is here + /________/ /| + |_______/|/ |/ z > 0 + / + |/ y > 0 + + + The above graph shows the coordinate of the sensor chip. Specify the + following string to memsic,dir to convert it into Android coordinate. + Note the definition of sensor placement on target board is relative to + Android portrait mode. + + left right up down + obverse-x-axis-forward Y+ Y- X+ X- + obverse-x-axis-rightward X- X+ Y+ Y- + obverse-x-axis-backward Y- Y+ X- X+ + obverse-x-axis-leftward X+ X- Y- Y+ + reverse-x-axis-forward Y- Y+ X+ X- + reverse-x-axis-rightward X- X+ Y- Y+ + reverse-x-axis-backward Y+ Y- X- X+ + reverse-x-axis-leftward X+ X- Y+ Y- + +Optional properites: + + - memsic,auto-report : Boolean value to indicate if enable auto-report mode. + + Example: + A chip on 8916 platform with the pattern as the above graph: + &i2c_0 { /* BLSP1 QUP2 */ + memsic@30 { + compatible = "memsic,mmc3x30"; + reg = <0x30>; + vdd-supply = <&pm8916_l17>; + vio-supply = <&pm8916_l6>; + memsic,dir = "obverse-x-axis-forward"; + memsic,auto-report; + }; + }; + diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 99ceadfca66ab..9f8ce15c1b01a 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -765,6 +765,16 @@ config SENSORS_MMC3416X To compile this driver as a module, choose M here: the module will be called mmc3416x. +config SENSORS_MMC3X30 + tristate "MMC3X30KJ 3-axis magnetic sensor driver" + depends on I2C + help + Say Y here if you want to enable the MMC3X30KJ magnetic sensor + driver. + + To compile this driver as a module, choose M here: the + module will be called mmc3X30. + config SENSORS_AKM09911 tristate "AKM09911 3-axis electronic compass sensor driver" depends on I2C @@ -850,5 +860,38 @@ config SENSORS_BMI058 If you say yes here, you get support for Bosch Sensortec's sensor driver of BMI058. +config SENSORS_BMI160 + tristate "BMI160 Sensor Support" + depends on I2C || SPI_MASTER + help + If you say yes here, you get support for Bosch Sensortec's + sensor driver of BMI160. + +config SENSORS_BMI160_I2C + tristate "support I2C bus communication" + depends on SENSORS_BMI160 && I2C + help + If you say yes here, you get support Bosch Sensortec's BMI160 sensor hooked to an I2C bus. + +config BMI160_MAG_INTERFACE_SUPPORT + tristate "BMI160 Sensor mag interface support" + depends on SENSORS_BMI160 + help + If you say yes here, you get support for Bosch Sensortec's + sensor driver of BMI160 with mag sensor support. + +config SENSORS_BMI160_ENABLE_INT1 + tristate "BMI160 sensor interrupt INT1 support" + depends on SENSORS_BMI160 + help + If you say yes here, you get INT1 support for Bosch Sensortec + sensors BMI160. + +config SENSORS_BMI160_ENABLE_INT2 + tristate "BMI160 sensor interrupt INT2 support" + depends on SENSORS_BMI160 + help + If you say yes here, you get INT2 support for Bosch Sensortec + sensors BMI160. endif diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 99a162f888100..8ce1a977576e3 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -66,6 +66,7 @@ obj-$(CONFIG_INPUT_YEALINK) += yealink.o obj-$(CONFIG_BMP18X) += bmp18x-core.o obj-$(CONFIG_BMP18X_I2C) += bmp18x-i2c.o obj-$(CONFIG_SENSORS_MMC3416X) += mmc3416x.o +obj-$(CONFIG_SENSORS_MMC3X30) += mmc3x30.o obj-$(CONFIG_SENSORS_MMA8X5X) += mma8x5x.o obj-$(CONFIG_SENSORS_STK3X1X) += stk3x1x.o obj-$(CONFIG_SENSORS_CAPELLA_CM36283) += cm36283.o @@ -86,3 +87,20 @@ endif ifeq ($(CONFIG_BOSCH_BMA2X2_ENABLE_INT2),y) EXTRA_CFLAGS += -DBMA2X2_ENABLE_INT2 endif + +obj-$(CONFIG_SENSORS_BMI160) += bmi160_driver.o bmi160.o +ifeq ($(CONFIG_BMI160_MAG_INTERFACE_SUPPORT),y) + EXTRA_CFLAGS += -DBMI160_MAG_INTERFACE_SUPPORT +endif +ifeq ($(CONFIG_SENSORS_BMI160_ENABLE_INT1),y) + EXTRA_CFLAGS += -DBMI160_ENABLE_INT1 +endif + +ifeq ($(CONFIG_SENSORS_BMI160_ENABLE_INT2),y) + EXTRA_CFLAGS += -DBMI160_ENABLE_INT2 +endif + +obj-$(CONFIG_SENSORS_BMI160_I2C) += bmi160_i2c.o +ifeq ($(CONFIG_SENSORS_BMI160_I2C),y) + EXTRA_CFLAGS += -DBMI_USE_BASIC_I2C_FUNC +endif diff --git a/drivers/input/misc/bmi160.c b/drivers/input/misc/bmi160.c old mode 100755 new mode 100644 diff --git a/drivers/input/misc/bmi160.h b/drivers/input/misc/bmi160.h old mode 100755 new mode 100644 index 1c1b4355cc2ed..fdfa5b7700140 --- a/drivers/input/misc/bmi160.h +++ b/drivers/input/misc/bmi160.h @@ -86,218 +86,9 @@ #ifndef __BMI160_H__ #define __BMI160_H__ -/*! -* @brief The following definition uses for define the data types -* -* @note While porting the API please consider the following -* @note Please check the version of C standard -* @note Are you using Linux platform -*/ - -/*! -* @brief For the Linux platform support -* Please use the types.h for your data types definitions -*/ -#ifdef __KERNEL__ #include -#else /* ! __KERNEL__ */ -/********************************************************** -* These definition uses for define the C -* standard version data types -***********************************************************/ -# if !defined(__STDC_VERSION__) - -/************************************************ - * compiler is C11 C standard -************************************************/ -#if (__STDC_VERSION__ == 201112L) - -/************************************************/ -#include -/************************************************/ - -/*unsigned integer types*/ -#define u8 uint8_t -#define u16 uint16_t -#define u32 uint32_t -#define u64 uint64_t - -/*signed integer types*/ -#define s8 int8_t -#define s16 int16_t -#define s32 int32_t -#define s64 int64_t -/************************************************ - * compiler is C99 C standard -************************************************/ - -#elif (__STDC_VERSION__ == 199901L) - -/* stdint.h is a C99 supported c library. -which is used to fixed the integer size*/ -/************************************************/ -#include -/************************************************/ - -/*unsigned integer types*/ -#define u8 uint8_t -#define u16 uint16_t -#define u32 uint32_t -#define u64 uint64_t - -/*signed integer types*/ -#define s8 int8_t -#define s16 int16_t -#define s32 int32_t -#define s64 int64_t -/************************************************ - * compiler is C89 or other C standard -************************************************/ -#else /* !defined(__STDC_VERSION__) */ -/* By default it is defined as 32 bit machine configuration*/ -/* define the definition based on your machine configuration*/ -/* define the data types based on your - machine/compiler/controller configuration*/ -#define MACHINE_32_BIT - -/* If your machine support 16 bit -define the MACHINE_16_BIT*/ -#ifdef MACHINE_16_BIT -#include -/*signed integer types*/ -#define s8 signed char -#define s16 signed short int -#define s32 signed long int - -#if defined(LONG_MAX) && LONG_MAX == 0x7fffffffffffffffL -#define s64 long int -#define u64 unsigned long int -#elif defined(LLONG_MAX) && (LLONG_MAX == 0x7fffffffffffffffLL) -#define s64 long long int -#define u64 unsigned long long int -#else -#warning Either the correct data type for signed 64 bit integer \ -could not be found, or 64 bit integers are not supported in your environment. -#warning If 64 bit integers are supported on your platform, \ -please set s64 manually. -#endif - -/*unsigned integer types*/ -#define u8 unsigned char -#define u16 unsigned short int -#define u32 unsigned long int - -/* If your machine support 32 bit -define the MACHINE_32_BIT*/ -#elif defined MACHINE_32_BIT -/*signed integer types*/ -#define s8 signed char -#define s16 signed short int -#define s32 signed int -#define s64 signed long long int - -/*unsigned integer types*/ -#define u8 unsigned char -#define u16 unsigned short int -#define u32 unsigned int -#define u64 unsigned long long int - -/* If your machine support 64 bit -define the MACHINE_64_BIT*/ -#elif defined MACHINE_64_BIT -/*signed integer types*/ -#define s8 signed char -#define s16 signed short int -#define s32 signed int -#define s64 signed long int - -/*unsigned integer types*/ -#define u8 unsigned char -#define u16 unsigned short int -#define u32 unsigned int -#define u64 unsigned long int - -#else -#warning The data types defined above which not supported \ -define the data types manually -#endif -#endif - -/*** This else will execute for the compilers - * which are not supported the C standards - * Like C89/C99/C11***/ -#else -/* By default it is defined as 32 bit machine configuration*/ -/* define the definition based on your machine configuration*/ -/* define the data types based on your - machine/compiler/controller configuration*/ -#define MACHINE_32_BIT - -/* If your machine support 16 bit -define the MACHINE_16_BIT*/ -#ifdef MACHINE_16_BIT -#include -/*signed integer types*/ -#define s8 signed char -#define s16 signed short int -#define s32 signed long int - -#if defined(LONG_MAX) && LONG_MAX == 0x7fffffffffffffffL -#define s64 long int -#define u64 unsigned long int -#elif defined(LLONG_MAX) && (LLONG_MAX == 0x7fffffffffffffffLL) -#define s64 long long int -#define u64 unsigned long long int -#else -#warning Either the correct data type for signed 64 bit integer \ -could not be found, or 64 bit integers are not supported in your environment. -#warning If 64 bit integers are supported on your platform, \ -please set s64 manually. -#endif - -/*unsigned integer types*/ -#define u8 unsigned char -#define u16 unsigned short int -#define u32 unsigned long int - -/* If your machine support 32 bit -define the MACHINE_32_BIT*/ -#elif defined MACHINE_32_BIT -/*signed integer types*/ -#define s8 signed char -#define s16 signed short int -#define s32 signed int -#define s64 signed long long int - -/*unsigned integer types*/ -#define u8 unsigned char -#define u16 unsigned short int -#define u32 unsigned int -#define u64 unsigned long long int - -/* If your machine support 64 bit -define the MACHINE_64_BIT*/ -#elif defined MACHINE_64_BIT -/*signed integer types*/ -#define s8 signed char -#define s16 signed short int -#define s32 signed int -#define s64 signed long int - -/*unsigned integer types*/ -#define u8 unsigned char -#define u16 unsigned short int -#define u32 unsigned int -#define u64 unsigned long int - -#else -#warning The data types defined above which not supported \ -define the data types manually -#endif -#endif -#endif /***************************************************************/ /**\name BUS READ AND WRITE FUNCTION POINTERS */ /***************************************************************/ diff --git a/drivers/input/misc/bmi160_driver.c b/drivers/input/misc/bmi160_driver.c old mode 100755 new mode 100644 index 9152399cdc5b8..692203386af95 --- a/drivers/input/misc/bmi160_driver.c +++ b/drivers/input/misc/bmi160_driver.c @@ -20,20 +20,66 @@ * device attribute files, etc. */ -#include "bmi160.h" #include "bmi160_driver.h" #include #include #include #include - #define I2C_BURST_READ_MAX_LEN (256) #define BMI160_STORE_COUNT (6000) #define LMADA (1) uint64_t g_current_apts_us; static unsigned char g_fifo_data_arr[2048];/*1024 + 12*4*/ +/*BMI power supply VDD 1.71V-3.6V VIO 1.2-3.6V */ +#define BMI160_VDD_MIN_UV 1750000 +#define BMI160_VDD_MAX_UV 3600000 +#define BMI160_VIO_MIN_UV 1200000 +#define BMI160_VIO_MAX_UV 3600000 + +static struct sensors_classdev accel_cdev = { + .name = "bmi160-accel", + .vendor = "Bosch Corporation", + .version = 1, + .handle = SENSORS_ACCELERATION_HANDLE, + .type = SENSOR_TYPE_ACCELEROMETER, + .max_range = "156.8", + .resolution = "0.00781", + .sensor_power = "0.13", + .min_delay = 1000, + .fifo_reserved_event_count = 0, + .fifo_max_event_count = 0, + .enabled = 0, + .delay_msec = 200, + .sensors_enable = NULL, + .sensors_poll_delay = NULL, + .sensors_calibrate = NULL, + .sensors_write_cal_params = NULL, + .params = NULL, +}; + +static struct sensors_classdev gyro_cdev = { + .name = "bmi160-gyro", + .vendor = "Bosch Corporation", + .version = 1, + .handle = SENSORS_GYROSCOPE_HANDLE, + .type = SENSOR_TYPE_GYROSCOPE, + .max_range = "35", + .resolution = "0.06", + .sensor_power = "0.13", + .min_delay = 2000, + .fifo_reserved_event_count = 0, + .fifo_max_event_count = 0, + .enabled = 0, + .delay_msec = 200, + .sensors_enable = NULL, + .sensors_poll_delay = NULL, + .sensors_calibrate = NULL, + .sensors_write_cal_params = NULL, + .params = NULL, +}; + enum BMI_SENSOR_INT_T { /* Interrupt enable0*/ BMI_ANYMO_X_INT = 0, @@ -264,7 +310,7 @@ struct bmi160_type_mapping_type { /*! bmi16x chip revision code */ uint16_t revision_id; - /*! bma2x2 sensor name */ + /*! bmi160 sensor name */ const char *sensor_name; }; @@ -381,6 +427,124 @@ static const struct bosch_sensor_axis_remap { 1, 0, 2, 1, 1, -1 }, /* P7 */ }; +static int bmi160_power_ctl(struct bmi_client_data *data, bool enable) +{ + int ret = 0; + int err = 0; + + if (!enable && data->power_enabled) { + ret = regulator_disable(data->vdd); + if (ret) { + dev_err(&data->i2c->dev, + "Regulator vdd disable failed ret=%d\n", ret); + return ret; + } + + ret = regulator_disable(data->vio); + if (ret) { + dev_err(&data->i2c->dev, + "Regulator vio disable failed ret=%d\n", ret); + err = regulator_enable(data->vdd); + return ret; + } + data->power_enabled = enable; + } else if (enable && !data->power_enabled) { + ret = regulator_enable(data->vdd); + if (ret) { + dev_err(&data->i2c->dev, + "Regulator vdd enable failed ret=%d\n", ret); + return ret; + } + + ret = regulator_enable(data->vio); + if (ret) { + dev_err(&data->i2c->dev, + "Regulator vio enable failed ret=%d\n", ret); + err = regulator_disable(data->vdd); + return ret; + } + data->power_enabled = enable; + } else { + dev_info(&data->i2c->dev, + "Power on=%d. enabled=%d\n", + enable, data->power_enabled); + } + + return ret; +} + +static int bmi160_power_init(struct bmi_client_data *data) +{ + int ret; + + data->vdd = regulator_get(&data->i2c->dev, "vdd"); + if (IS_ERR(data->vdd)) { + ret = PTR_ERR(data->vdd); + dev_err(&data->i2c->dev, + "Regulator get failed vdd ret=%d\n", ret); + return ret; + } + + if (regulator_count_voltages(data->vdd) > 0) { + ret = regulator_set_voltage(data->vdd, + BMI160_VDD_MIN_UV, + BMI160_VDD_MAX_UV); + if (ret) { + dev_err(&data->i2c->dev, + "Regulator set failed vdd ret=%d\n", + ret); + goto reg_vdd_put; + } + } + + data->vio = regulator_get(&data->i2c->dev, "vio"); + if (IS_ERR(data->vio)) { + ret = PTR_ERR(data->vio); + dev_err(&data->i2c->dev, + "Regulator get failed vio ret=%d\n", ret); + goto reg_vdd_set; + } + + if (regulator_count_voltages(data->vio) > 0) { + ret = regulator_set_voltage(data->vio, + BMI160_VIO_MIN_UV, + BMI160_VIO_MAX_UV); + if (ret) { + dev_err(&data->i2c->dev, + "Regulator set failed vio ret=%d\n", ret); + goto reg_vio_put; + } + } + + return 0; + +reg_vio_put: + regulator_put(data->vio); +reg_vdd_set: + if (regulator_count_voltages(data->vdd) > 0) + regulator_set_voltage(data->vdd, 0, BMI160_VDD_MAX_UV); +reg_vdd_put: + regulator_put(data->vdd); + return ret; +} + +static int bmi160_power_deinit(struct bmi_client_data *data) +{ + if (regulator_count_voltages(data->vdd) > 0) + regulator_set_voltage(data->vdd, + 0, BMI160_VDD_MAX_UV); + + regulator_put(data->vdd); + + if (regulator_count_voltages(data->vio) > 0) + regulator_set_voltage(data->vio, + 0, BMI160_VIO_MAX_UV); + + regulator_put(data->vio); + + return 0; +} + static void bst_remap_sensor_data(struct bosch_sensor_data *data, const struct bosch_sensor_axis_remap *remap) { @@ -511,44 +675,69 @@ static int bmi_input_init(struct bmi_client_data *client_data) struct input_dev *dev; int err = 0; - dev = input_allocate_device(); + dev = devm_input_allocate_device(&client_data->i2c->dev); if (NULL == dev) return -ENOMEM; - dev->name = SENSOR_NAME; + dev->name = BMI160_ACCEL_INPUT_NAME; dev->id.bustype = BUS_I2C; + input_set_capability(dev, EV_ABS, ABS_MISC); + input_set_abs_params(dev, ABS_X, ABSMIN, ABSMAX, 0, 0); + input_set_abs_params(dev, ABS_Y, ABSMIN, ABSMAX, 0, 0); + input_set_abs_params(dev, ABS_Z, ABSMIN, ABSMAX, 0, 0); + + input_set_drvdata(dev, client_data); + err = input_register_device(dev); + if (err < 0) { + input_free_device(dev); + dev_notice(client_data->dev, "bmi160 accel input free!\n"); + return err; + } + client_data->input_accel = dev; + dev_notice(client_data->dev, + "bmi160 accel input register successfully, %s!\n", + client_data->input_accel->name); + + dev = devm_input_allocate_device(&client_data->i2c->dev); + if (NULL == dev) + return -ENOMEM; + + dev->name = BMI160_GYRO_INPUT_NAME; + dev->id.bustype = BUS_I2C; - input_set_capability(dev, EV_MSC, INPUT_EVENT_SGM); - input_set_capability(dev, EV_MSC, INPUT_EVENT_STEP_DETECTOR); - input_set_capability(dev, EV_MSC, INPUT_EVENT_FAST_ACC_CALIB_DONE); - input_set_capability(dev, EV_MSC, INPUT_EVENT_FAST_GYRO_CALIB_DONE); - input_set_capability(dev, EV_REL, REL_X); - input_set_capability(dev, EV_REL, REL_Y); - input_set_capability(dev, EV_REL, REL_Z); + input_set_capability(dev, EV_ABS, ABS_MISC); + input_set_abs_params(dev, ABS_RX, GYRO_MAX_VALUE, GYRO_MIN_VALUE, 0, 0); + input_set_abs_params(dev, ABS_RY, GYRO_MAX_VALUE, GYRO_MIN_VALUE, 0, 0); + input_set_abs_params(dev, ABS_RZ, GYRO_MAX_VALUE, GYRO_MIN_VALUE, 0, 0); input_set_drvdata(dev, client_data); err = input_register_device(dev); if (err < 0) { input_free_device(dev); - dev_notice(client_data->dev, "bmi160 input free!\n"); + dev_notice(client_data->dev, "bmi160 accel input free!\n"); return err; } - client_data->input = dev; + client_data->input_gyro = dev; dev_notice(client_data->dev, - "bmi160 input register successfully, %s!\n", - client_data->input->name); + "bmi160 gyro input register successfully, %s!\n", + client_data->input_gyro->name); + return err; } static void bmi_input_destroy(struct bmi_client_data *client_data) { - struct input_dev *dev = client_data->input; + struct input_dev *dev = client_data->input_accel; input_unregister_device(dev); input_free_device(dev); + + dev = client_data->input_gyro; + input_unregister_device(dev); + input_free_device(dev); } static int bmi_check_chip_id(struct bmi_client_data *client_data) @@ -644,8 +833,7 @@ static enum hrtimer_restart reportdata_timer_fun( static ssize_t bmi_show_enable_timer(struct device *dev, struct device_attribute *attr, char *buf) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); return snprintf(buf, 16, "%d\n", client_data->is_timer_running); } @@ -656,8 +844,7 @@ static ssize_t bmi_store_enable_timer(struct device *dev, { unsigned long data; int error; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); error = kstrtoul(buf, 10, &data); if (error) return error; @@ -667,26 +854,16 @@ static ssize_t bmi_store_enable_timer(struct device *dev, ns_to_ktime(10000000), HRTIMER_MODE_REL); client_data->is_timer_running = 1; - //client_data->base_time = 0; - //client_data->timestamp = 0; - //client_data->gyro_count = 0; } } else { if (1 == client_data->is_timer_running) { hrtimer_cancel(&client_data->timer); client_data->is_timer_running = 0; - //client_data->base_time = 0; - //client_data->timestamp = 0; - //client_data->gyro_count = 0; - //mutex_lock(&client_data->mutex_ring_buf); - //s_ring_buf_head = s_ring_buf_tail = 0; - //mutex_unlock(&client_data->mutex_ring_buf); } } return count; } -#if 0 static void bmi_work_func(struct work_struct *work) { struct bmi_client_data *client_data = @@ -708,14 +885,43 @@ static void bmi_work_func(struct work_struct *work) bmi_remap_sensor_data(&bmi160_udata, client_data); /*report current frame via input event*/ - input_event(client_data->input, EV_REL, REL_X, bmi160_udata.x); - input_event(client_data->input, EV_REL, REL_Y, bmi160_udata.y); - input_event(client_data->input, EV_REL, REL_Z, bmi160_udata.z); - input_sync(client_data->input); + input_event(client_data->input_accel, EV_ABS, ABS_X, bmi160_udata.x); + input_event(client_data->input_accel, EV_ABS, ABS_Y, bmi160_udata.y); + input_event(client_data->input_accel, EV_ABS, ABS_Z, bmi160_udata.z); + input_sync(client_data->input_accel); schedule_delayed_work(&client_data->work, delay); } -#endif + +static void bmi_gyro_work_func(struct work_struct *work) +{ + struct bmi_client_data *client_data = container_of( + (struct delayed_work *)work, + struct bmi_client_data, gyro_work); + unsigned long delay = + msecs_to_jiffies(atomic_read(&client_data->delay)); + struct bmi160_gyro_t data; + struct bmi160_axis_data_t bmi160_udata; + int err; + + err = BMI_CALL_API(read_gyro_xyz)(&data); + if (err < 0) + return; + + bmi160_udata.x = data.x; + bmi160_udata.y = data.y; + bmi160_udata.z = data.z; + + bmi_remap_sensor_data(&bmi160_udata, client_data); + /*report current frame via input event*/ + input_event(client_data->input_gyro, EV_ABS, ABS_RX, bmi160_udata.x); + input_event(client_data->input_gyro, EV_ABS, ABS_RY, bmi160_udata.y); + input_event(client_data->input_gyro, EV_ABS, ABS_RZ, bmi160_udata.z); + input_sync(client_data->input_gyro); + + schedule_delayed_work(&client_data->gyro_work, delay); +} + static uint8_t dbg_buf_str[2048] = ""; static void bmi_hrtimer_work_func(struct work_struct *work) { @@ -734,7 +940,6 @@ static void bmi_hrtimer_work_func(struct work_struct *work) client_data->fifo_bytecount = fifo_len0; if (client_data->fifo_bytecount == 0 || err) { - //dev_notice(client_data->dev, "fifo_bytecount is 0!!"); return ; } @@ -753,15 +958,14 @@ static void bmi_hrtimer_work_func(struct work_struct *work) sprintf(dbg_buf_str + i * 3, "%02x%c", s_fifo_data_buf[i], (((i + 1) % BYTES_PER_LINE == 0) ? '\n' : ' ')); } - printk(KERN_INFO "%s\n", dbg_buf_str); + pr_info("%s\n", dbg_buf_str); } static ssize_t bmi160_chip_id_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); return sprintf(buf, "0x%x\n", client_data->chip_id); } @@ -769,8 +973,7 @@ static ssize_t bmi160_chip_id_show(struct device *dev, static ssize_t bmi160_err_st_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); int err = 0; err = bmi_get_err_status(client_data); if (err) @@ -804,8 +1007,7 @@ static ssize_t bmi160_fifo_flush_store(struct device *dev, { int err; unsigned long enable; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = kstrtoul(buf, 10, &enable); if (err) @@ -836,8 +1038,7 @@ static ssize_t bmi160_fifo_bytecount_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); int err; unsigned long data; err = kstrtoul(buf, 10, &data); @@ -876,8 +1077,7 @@ static ssize_t bmi160_fifo_data_sel_show(struct device *dev, struct device_attribute *attr, char *buf) { int err = 0; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = bmi160_fifo_data_sel_get(client_data); if (err) return -EINVAL; @@ -889,8 +1089,7 @@ static ssize_t bmi160_fifo_data_sel_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); int err; unsigned long data; unsigned char fifo_datasel; @@ -1593,8 +1792,7 @@ if (client_data->fifo_data_sel == BMI_FIFO_M_G_SEL) { static ssize_t bmi160_fifo_data_out_frame_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); int err = 0; unsigned int fifo_bytecount_tmp; @@ -1673,9 +1871,7 @@ static ssize_t bmi160_fifo_watermark_store(struct device *dev, int err; unsigned long data; unsigned char fifo_watermark; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); - + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = kstrtoul(buf, 10, &data); if (err) @@ -1686,11 +1882,11 @@ static ssize_t bmi160_fifo_watermark_store(struct device *dev, if (err) return -EIO; - printk(KERN_INFO "fifo_watermark count %d", count); + pr_info("fifo_watermark count %d", count); if (BMI_CALL_API(set_intr_enable_1) (BMI160_FIFO_WM_ENABLE, 1) < 0) { - printk(KERN_INFO "set fifo wm enable failed"); + pr_info("set fifo wm enable failed"); return -EIO; } mutex_lock(&client_data->mutex_ring_buf); @@ -1718,8 +1914,7 @@ static ssize_t bmi160_fifo_header_en_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); int err; unsigned long data; unsigned char fifo_header_en; @@ -1799,8 +1994,7 @@ static ssize_t bmi160_fifo_int_tag_en_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); int err; unsigned long data; unsigned char fifo_tag_int_en; @@ -1882,6 +2076,47 @@ static int bmi160_set_acc_op_mode(struct bmi_client_data *client_data, } +static int bmi160_set_gyro_op_mode(struct bmi_client_data *client_data, + unsigned long op_mode) +{ + int err = 0; + + mutex_lock(&client_data->mutex_op_mode); + + if (op_mode < BMI_GYRO_PM_MAX) { + switch (op_mode) { + case BMI_GYRO_PM_NORMAL: + err = BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_NORMAL]); + client_data->pw.gyro_pm = BMI_GYRO_PM_NORMAL; + msleep(60); + break; + case BMI_GYRO_PM_FAST_START: + err = BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_FAST_START]); + client_data->pw.gyro_pm = BMI_GYRO_PM_FAST_START; + msleep(60); + break; + case BMI_GYRO_PM_SUSPEND: + err = BMI_CALL_API(set_command_register) + (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_SUSPEND]); + client_data->pw.gyro_pm = BMI_GYRO_PM_SUSPEND; + msleep(60); + break; + default: + mutex_unlock(&client_data->mutex_op_mode); + return -EINVAL; + } + } else { + mutex_unlock(&client_data->mutex_op_mode); + return -EINVAL; + } + + mutex_unlock(&client_data->mutex_op_mode); + return err; + +} + static ssize_t bmi160_temperature_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1899,8 +2134,7 @@ static ssize_t bmi160_temperature_show(struct device *dev, static ssize_t bmi160_place_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); int place = BOSCH_SENSOR_PLACE_UNKNOWN; if (NULL != client_data->bst_pd) @@ -1912,8 +2146,7 @@ static ssize_t bmi160_place_show(struct device *dev, static ssize_t bmi160_delay_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); return sprintf(buf, "%d\n", atomic_read(&client_data->delay)); @@ -1923,8 +2156,7 @@ static ssize_t bmi160_delay_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); int err; unsigned long data; @@ -1948,8 +2180,7 @@ static ssize_t bmi160_delay_store(struct device *dev, static ssize_t bmi160_enable_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); return sprintf(buf, "%d\n", atomic_read(&client_data->wkqueue_en)); @@ -1959,8 +2190,7 @@ static ssize_t bmi160_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); int err; unsigned long enable; int pre_enable = atomic_read(&client_data->wkqueue_en); @@ -1973,6 +2203,10 @@ static ssize_t bmi160_enable_store(struct device *dev, mutex_lock(&client_data->mutex_enable); if (enable) { if (pre_enable == 0) { + if (bmi160_power_ctl(client_data, true)) { + dev_err(dev, "power up sensor failed.\n"); + goto mutex_exit; + } bmi160_set_acc_op_mode(client_data, BMI_ACC_PM_NORMAL); schedule_delayed_work(&client_data->work, @@ -1987,9 +2221,14 @@ static ssize_t bmi160_enable_store(struct device *dev, cancel_delayed_work_sync(&client_data->work); atomic_set(&client_data->wkqueue_en, 0); + if (bmi160_power_ctl(client_data, false)) { + dev_err(dev, "power up sensor failed.\n"); + goto mutex_exit; + } } } +mutex_exit: mutex_unlock(&client_data->mutex_enable); mutex_lock(&client_data->mutex_ring_buf); @@ -2068,8 +2307,7 @@ static ssize_t bmi160_step_detector_status_show(struct device *dev, u8 data = 0; u8 step_det; int err; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = BMI_CALL_API(get_step_detector_enable)(&step_det); /*bmi160_get_status0_step_int*/ if (err < 0) @@ -2104,8 +2342,7 @@ static ssize_t bmi160_step_detector_enable_store(struct device *dev, { unsigned long data; int err; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = kstrtoul(buf, 10, &data); if (err) @@ -2125,8 +2362,7 @@ static ssize_t bmi160_signification_motion_enable_store( { unsigned long data; int err; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = kstrtoul(buf, 10, &data); if (err) @@ -2195,7 +2431,7 @@ close the signification_motion*/ ret += BMI_CALL_API(set_intr_enable_0) (BMI160_ANY_MOTION_Z_ENABLE, 0); if (ret) - printk(KERN_ERR "bmi160 sig motion failed setting,%d!\n", ret); + pr_info("bmi160 sig motion failed setting,%d!\n", ret); return ret; } @@ -2206,8 +2442,7 @@ static ssize_t bmi160_acc_range_show(struct device *dev, { int err; unsigned char range; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = BMI_CALL_API(get_accel_range)(&range); if (err) @@ -2223,9 +2458,7 @@ static ssize_t bmi160_acc_range_store(struct device *dev, { int err; unsigned long range; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); - + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = kstrtoul(buf, 10, &range); if (err) @@ -2244,8 +2477,7 @@ static ssize_t bmi160_acc_odr_show(struct device *dev, { int err; unsigned char acc_odr; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = BMI_CALL_API(get_accel_output_data_rate)(&acc_odr); if (err) @@ -2261,8 +2493,7 @@ static ssize_t bmi160_acc_odr_store(struct device *dev, { int err; unsigned long acc_odr; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = kstrtoul(buf, 10, &acc_odr); if (err) @@ -2289,8 +2520,7 @@ static ssize_t bmi160_acc_odr_store(struct device *dev, static ssize_t bmi160_acc_op_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); int err = 0; u8 accel_pmu_status = 0; err = BMI_CALL_API(get_accel_power_mode_stat)( @@ -2307,8 +2537,7 @@ static ssize_t bmi160_acc_op_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); int err; unsigned long op_mode; err = kstrtoul(buf, 10, &op_mode); @@ -2326,8 +2555,7 @@ static ssize_t bmi160_acc_op_mode_store(struct device *dev, static ssize_t bmi160_acc_value_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); struct bmi160_accel_t data; struct bmi160_axis_data_t bmi160_udata; int err; @@ -2365,8 +2593,7 @@ static ssize_t bmi160_acc_fast_calibration_x_store(struct device *dev, unsigned long data; int err; s8 accel_offset_x = 0; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = kstrtoul(buf, 10, &data); if (err) @@ -2405,8 +2632,7 @@ static ssize_t bmi160_acc_fast_calibration_y_store(struct device *dev, unsigned long data; int err; s8 accel_offset_y = 0; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = kstrtoul(buf, 10, &data); if (err) @@ -2445,8 +2671,7 @@ static ssize_t bmi160_acc_fast_calibration_z_store(struct device *dev, unsigned long data; int err; s8 accel_offset_z = 0; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = kstrtoul(buf, 10, &data); if (err) @@ -2464,9 +2689,9 @@ static ssize_t bmi160_acc_fast_calibration_z_store(struct device *dev, BMI_FAST_CALI_TRUE << BMI_ACC_Z_FAST_CALI_RDY; if (client_data->calib_status == BMI_FAST_CALI_ALL_RDY) { - input_event(client_data->input, EV_MSC, + input_event(client_data->input_accel, EV_MSC, INPUT_EVENT_FAST_ACC_CALIB_DONE, 1); - input_sync(client_data->input); + input_sync(client_data->input_accel); client_data->calib_status = 0; } @@ -2573,8 +2798,7 @@ static ssize_t bmi160_acc_offset_z_store(struct device *dev, static ssize_t bmi160_test_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); u8 raw_data[15] = {0}; unsigned int sensor_time = 0; @@ -2606,8 +2830,7 @@ static ssize_t bmi160_step_counter_enable_show(struct device *dev, { unsigned char data; int err; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = BMI_CALL_API(get_step_counter_enable)(&data); @@ -2624,8 +2847,7 @@ static ssize_t bmi160_step_counter_enable_store(struct device *dev, { unsigned long data; int err; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = kstrtoul(buf, 10, &data); if (err) @@ -2683,9 +2905,7 @@ static ssize_t bmi160_step_counter_value_show(struct device *dev, s16 data; int err; static u16 last_stc_value; - - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = BMI_CALL_API(read_step_count)(&data); @@ -2704,8 +2924,7 @@ static ssize_t bmi160_step_counter_value_show(struct device *dev, static ssize_t bmi160_bmi_value_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); u8 raw_data[12] = {0}; int err; @@ -2735,32 +2954,37 @@ static ssize_t bmi160_ring_buf_show(struct device *dev, struct bmi160_value_t data; char *tmp = buf; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); mutex_lock(&client_data->mutex_ring_buf); while (bmi_ring_buf_get(&data) != 0) { #ifdef BMI160_MAG_INTERFACE_SUPPORT - len = sprintf(tmp, "%d %d %d %d %d %d %d %d %d %lld ", - data.acc.x, data.acc.y, data.acc.z, - data.gyro.x, data.gyro.y, data.gyro.z, - data.mag.x, data.mag.y, data.mag.z, - data.ts_intvl); + len = snprintf(tmp, PAGE_SIZE, + "%d %d %d %d %d %d %d %d %d %lld", + data.acc.x, data.acc.y, data.acc.z, + data.gyro.x, data.gyro.y, data.gyro.z, + data.mag.x, data.mag.y, data.mag.z, + data.ts_intvl); + pr_info("%d %d %d %lld\n", + data.mag.x, + data.mag.y, + data.mag.z, + data.ts_intvl); #else - len = sprintf(tmp, "%d %d %d %d %d %d %lld ", - data.acc.x, data.acc.y, data.acc.z, - data.gyro.x, data.gyro.y, data.gyro.z, - data.ts_intvl); + len = snprintf(tmp, PAGE_SIZE, + "%d %d %d %d %d %d %lld", + data.acc.x, data.acc.y, data.acc.z, + data.gyro.x, data.gyro.y, data.gyro.z, + data.ts_intvl); #endif tmp += len; - err += len; - printk("%d %d %d %d %d %d %d %d %d %lld \n", + err += len; + pr_info("%d %d %d %d %d %d %lld\n", data.acc.x, data.acc.y, data.acc.z, data.gyro.x, data.gyro.y, data.gyro.z, - data.mag.x, data.mag.y, data.mag.z, data.ts_intvl); - + } mutex_unlock(&client_data->mutex_ring_buf); return err; @@ -2770,8 +2994,7 @@ static ssize_t bmi160_ring_buf_show(struct device *dev, static ssize_t bmi160_selftest_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); return sprintf(buf, "0x%x\n", atomic_read(&client_data->selftest_result)); @@ -2789,8 +3012,7 @@ static ssize_t bmi160_selftest_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); int err = 0; int i = 0; @@ -2811,42 +3033,48 @@ static ssize_t bmi160_selftest_store(struct device *dev, client_data->selftest = 1; #ifdef BMI160_MAG_INTERFACE_SUPPORT - err += bmi160_set_mag_write_data(BMI160_BMM_POWER_MODE_REG); // Power mode value 0x06 - bmi_delay(BMI160_GEN_READ_WRITE_DELAY); - /*write 0x4C register to write set power mode to normal*/ - err += bmi160_set_mag_write_addr(BMI160_BMM150_POWE_MODE_REG); // write register 0x4C - bmi_delay(BMI160_GEN_READ_WRITE_DELAY); - - err += bmi160_set_mag_write_data(MAG_MODE_SUSPEND); // 0x18 Sets the PMU mode for the Magnetometer to suspend - bmi_delay(BMI160_GEN_READ_WRITE_DELAY); - err += bmi160_set_mag_write_addr(BMI160_USER_MAG_IF_3_ADDR); // write 0x18 to register 0x4E - /* write the Z repetitions*/ - /* The v_data_u8 have to write for the register - It write the value in the register 0x4F*/ - err += bmi160_set_mag_write_data(BMI160_MAG_REGULAR_REPZ); - bmi_delay(BMI160_GEN_READ_WRITE_DELAY); - err += bmi160_set_mag_write_addr(BMI160_BMM150_Z_REP); - bmi_delay(BMI160_GEN_READ_WRITE_DELAY); - - err += bmi160_set_mag_write_data(0xC2); // 0xC2 - bmi_delay(BMI160_GEN_READ_WRITE_DELAY); - err += bmi160_set_mag_write_addr(BMI160_BMM150_POWE_MODE_REG); // write register 0x4C - - bmi_delay(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); - - err += bmi160_bmm150_mag_compensate_xyz(&pos_data); - bmi_delay(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); - err += bmi160_set_mag_write_data(0x82); // 0x82 - bmi_delay(BMI160_GEN_READ_WRITE_DELAY); - err += bmi160_set_mag_write_addr(BMI160_BMM150_POWE_MODE_REG); // write register 0x4C - - bmi_delay(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); - err += bmi160_bmm150_mag_compensate_xyz(&neg_data); - - diff_axis[2] = pos_data.z - neg_data.z; - dev_info(client_data->dev, - "pos_data.x:%d, pos_data.y:%d, pos_data.z:%d,\nneg_data.x:%d, neg_data.y:%d, neg_data.z:%d\n", - pos_data.x, pos_data.y, pos_data.z, neg_data.x, neg_data.y, neg_data.z); + /* Power mode value 0x06 */ + err += bmi160_set_mag_write_data(BMI160_BMM_POWER_MODE_REG); + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + /*write 0x4C register to write set power mode to normal*/ + err += bmi160_set_mag_write_addr(BMI160_BMM150_POWE_MODE_REG); + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + + /* 0x18 Sets the PMU mode for the Magnetometer to suspend */ + err += bmi160_set_mag_write_data(MAG_MODE_SUSPEND); + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + /* write 0x18 to register 0x4E */ + err += bmi160_set_mag_write_addr(BMI160_USER_MAG_IF_3_ADDR); + /* write the Z repetitions*/ + /* The v_data_u8 have to write for the register + It write the value in the register 0x4F*/ + err += bmi160_set_mag_write_data(BMI160_MAG_REGULAR_REPZ); + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + err += bmi160_set_mag_write_addr(BMI160_BMM150_Z_REP); + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + + /* 0xC2 */ + err += bmi160_set_mag_write_data(0xC2); + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + /* write register 0x4C */ + err += bmi160_set_mag_write_addr(BMI160_BMM150_POWE_MODE_REG); + bmi_delay(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + + err += bmi160_bmm150_mag_compensate_xyz(&pos_data); + bmi_delay(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + /* 0X82 */ + err += bmi160_set_mag_write_data(0x82); + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + /* write register 0x4C */ + err += bmi160_set_mag_write_addr(BMI160_BMM150_POWE_MODE_REG); + + bmi_delay(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + err += bmi160_bmm150_mag_compensate_xyz(&neg_data); + + diff_axis[2] = pos_data.z - neg_data.z; + dev_info(client_data->dev, + "pos_data.x:%d, pos_data.y:%d, pos_data.z:%d,\nneg_data.x:%d, neg_data.y:%d, neg_data.z:%d\n", + pos_data.x, pos_data.y, pos_data.z, neg_data.x, neg_data.y, neg_data.z); #endif /*soft reset*/ @@ -3003,8 +3231,7 @@ static ssize_t bmi160_selftest_store(struct device *dev, static ssize_t bmi160_gyro_op_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); int err = 0; u8 gyro_pmu_status = 0; @@ -3022,8 +3249,7 @@ static ssize_t bmi160_gyro_op_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); unsigned long op_mode; int err; @@ -3074,8 +3300,7 @@ static ssize_t bmi160_gyro_op_mode_store(struct device *dev, static ssize_t bmi160_gyro_value_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); struct bmi160_gyro_t data; struct bmi160_axis_data_t bmi160_udata; int err; @@ -3099,8 +3324,7 @@ static ssize_t bmi160_gyro_range_show(struct device *dev, { int err; unsigned char range; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = BMI_CALL_API(get_gyro_range)(&range); if (err) @@ -3116,8 +3340,7 @@ static ssize_t bmi160_gyro_range_store(struct device *dev, { int err; unsigned long range; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = kstrtoul(buf, 10, &range); if (err) @@ -3136,8 +3359,7 @@ static ssize_t bmi160_gyro_odr_show(struct device *dev, { int err; unsigned char gyro_odr; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = BMI_CALL_API(get_gyro_output_data_rate)(&gyro_odr); if (err) @@ -3153,8 +3375,7 @@ static ssize_t bmi160_gyro_odr_store(struct device *dev, { int err; unsigned long gyro_odr; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = kstrtoul(buf, 10, &gyro_odr); if (err) @@ -3193,8 +3414,7 @@ static ssize_t bmi160_gyro_fast_calibration_en_store(struct device *dev, s16 gyr_off_x; s16 gyr_off_y; s16 gyr_off_z; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = kstrtoul(buf, 10, &enable); if (err) @@ -3206,9 +3426,9 @@ static ssize_t bmi160_gyro_fast_calibration_en_store(struct device *dev, if (err < 0) return -EIO; else { - input_event(client_data->input, EV_MSC, + input_event(client_data->input_gyro, EV_MSC, INPUT_EVENT_FAST_GYRO_CALIB_DONE, 1); - input_sync(client_data->input); + input_sync(client_data->input_gyro); } return count; } @@ -3312,8 +3532,7 @@ static ssize_t bmi160_gyro_offset_z_store(struct device *dev, static ssize_t bmi160_mag_op_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); u8 mag_op_mode; s8 err; err = bmi160_get_mag_power_mode_stat(&mag_op_mode); @@ -3330,8 +3549,7 @@ static ssize_t bmi160_mag_op_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); unsigned long op_mode; int err; @@ -3417,8 +3635,7 @@ static ssize_t bmi160_mag_odr_show(struct device *dev, { int err = 0; unsigned char mag_odr = 0; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = BMI_CALL_API(get_mag_output_data_rate)(&mag_odr); if (err) @@ -3434,8 +3651,7 @@ static ssize_t bmi160_mag_odr_store(struct device *dev, { int err; unsigned long mag_odr; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = kstrtoul(buf, 10, &mag_odr); if (err) @@ -3488,8 +3704,7 @@ static ssize_t bmi160_mag_i2c_address_store(struct device *dev, static ssize_t bmi160_mag_value_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); struct bmi160_mag_xyz_s32_t data; struct bmi160_axis_data_t bmi160_udata; @@ -3621,9 +3836,7 @@ static ssize_t bmi_enable_int_store(struct device *dev, static ssize_t bmi_register_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); - + struct bmi_client_data *client_data = dev_get_drvdata(dev); bmi_dump_reg(client_data); return sprintf(buf, "Dump OK\n"); @@ -3637,8 +3850,7 @@ static ssize_t bmi_register_store(struct device *dev, int data; u8 write_reg_add = 0; u8 write_data = 0; - struct input_dev *input = to_input_dev(dev); - struct bmi_client_data *client_data = input_get_drvdata(input); + struct bmi_client_data *client_data = dev_get_drvdata(dev); err = sscanf(buf, "%3d %3d", ®_addr, &data); if (err < 2) @@ -3960,18 +4172,8 @@ static int bmi_ring_buf_put(struct bmi160_value_t data) bmi_ring_buf[s_ring_buf_tail].mag.z = data.mag.z; #endif bmi_ring_buf[s_ring_buf_tail].ts_intvl= data.ts_intvl; -/* printk(KERN_ERR "put bmi data %d, %d, %d, %d, %d, %d, %lld", - bmi_ring_buf[s_ring_buf_tail].acc.x, - bmi_ring_buf[s_ring_buf_tail].acc.y, - bmi_ring_buf[s_ring_buf_tail].acc.z, - bmi_ring_buf[s_ring_buf_tail].gyro.x, - bmi_ring_buf[s_ring_buf_tail].gyro.y, - bmi_ring_buf[s_ring_buf_tail].gyro.z, - - bmi_ring_buf[s_ring_buf_tail].ts_intvl); -*/ s_ring_buf_tail = (s_ring_buf_tail + 1) % BMI_RING_BUF_SIZE; - + return 1; } @@ -4042,7 +4244,7 @@ static int bmi_fifo_get_decode_data(struct bmi160_axis_data_t *acc, | fifo_data[fifo_index + 3] << 8; gyro->z = fifo_data[fifo_index + 4] | fifo_data[fifo_index + 5] << 8; - fifo_index += 6; + fifo_index += 6; } /* get xyz axis accel data */ @@ -4084,25 +4286,24 @@ static int bmi_pow(int x, int y) * Decoding of FIFO frames (only exemplary subset). Calculates accurate timestamps based on the * drift information. Returns value of the SENSORTIME frame. * -* fifo_data_buf pointer to fetched FIFO buffer -* fifo_length number of valid bytes in the FIFO buffer -* drift clock drift value, needed to calculate accurate timestamps -* timestamp initial timestamp for the first sample of the FIFO chunk -* acc_odr current value of the ACC_CONF.acc_odr register field +* fifo_data_buf - pointer to fetched FIFO buffer +* fifo_length - number of valid bytes in the FIFO buffer +* drift - clock drift value, needed to calculate accurate timestamps +* timestamp - initial timestamp for the first sample of the FIFO chunk +* acc_odr - current value of the ACC_CONF.acc_odr register field */ static uint64_t bmi_fifo_data_decode(uint8_t *fifo_data_buf, uint16_t fifo_length, int drift, uint64_t timestamp, int odr_pow) { int idx = 0; uint8_t header; - //int16_t x, y, z; uint64_t fifo_time = 0; uint64_t timestamp_next = timestamp; struct bmi160_value_t bmi160_value; while (idx < fifo_length) { header = fifo_data_buf[idx]; - memset (&bmi160_value, 0, sizeof (bmi160_value)); + memset(&bmi160_value, 0, sizeof (bmi160_value)); switch (header) { case FIFO_HEAD_SENSOR_TIME: /* sensortime frame, length = 4 bytes*/ @@ -4110,7 +4311,6 @@ static uint64_t bmi_fifo_data_decode(uint8_t *fifo_data_buf, uint16_t fifo_lengt fifo_time = fifo_data_buf[idx + 1] | fifo_data_buf[idx + 2] << 8 | fifo_data_buf[idx + 3] << 16; - //printk(KERN_INFO "sensorts %llu", fifo_time); return fifo_time; } idx += 4; @@ -4119,28 +4319,33 @@ static uint64_t bmi_fifo_data_decode(uint8_t *fifo_data_buf, uint16_t fifo_lengt /* accel frame, length = 7 bytes */ idx += 1; if (idx + 6 < fifo_length) { - bmi_fifo_get_decode_data(&bmi160_value.acc, NULL, NULL, fifo_data_buf, idx); - bmi160_value.ts_intvl = (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + bmi_fifo_get_decode_data( + &bmi160_value.acc, + NULL, NULL, + fifo_data_buf, idx); + bmi160_value.ts_intvl = + (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); if (bmi_ring_buf_put(bmi160_value) == 0) - printk(KERN_INFO "bmi ring buf full head %d, tail %d", + pr_info("bmi ring buf full head %d, tail %d", s_ring_buf_head, s_ring_buf_tail); if (drift > 0) timestamp_next += (uint64_t)(625 * odr_pow * drift); else timestamp_next += (uint64_t)(625 * odr_pow * 1000); - //printk (KERN_INFO "drift %d, ts_next %llu, %d, %d, %d, %llu", - // drift, timestamp_next, x, y, z, (uint64_t)(625 * odr_pow * 1000)); - - idx += 6; - break; + } + idx += 6; + break; case FIFO_HEAD_G: /* gyro frame, length = 7 bytes */ idx += 1; if (idx + 6 < fifo_length) { - bmi_fifo_get_decode_data(NULL,&bmi160_value.gyro, NULL, fifo_data_buf, idx); - bmi160_value.ts_intvl = (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + bmi_fifo_get_decode_data(NULL, + &bmi160_value.gyro, + NULL, fifo_data_buf, idx); + bmi160_value.ts_intvl = + (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); if (bmi_ring_buf_put(bmi160_value) == 0) - printk(KERN_INFO "bmi ring buf full head %d, tail %d", + pr_info("bmi ring buf full head %d, tail %d", s_ring_buf_head, s_ring_buf_tail); } @@ -4149,10 +4354,13 @@ static uint64_t bmi_fifo_data_decode(uint8_t *fifo_data_buf, uint16_t fifo_lengt case FIFO_HEAD_G_A: idx += 1; if (idx + 12 < fifo_length) { - bmi_fifo_get_decode_data(&bmi160_value.acc,&bmi160_value.gyro, NULL, fifo_data_buf, idx); - bmi160_value.ts_intvl = (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + bmi_fifo_get_decode_data(&bmi160_value.acc, + &bmi160_value.gyro, + NULL, fifo_data_buf, idx); + bmi160_value.ts_intvl = + (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); if (bmi_ring_buf_put(bmi160_value) == 0) - printk(KERN_INFO "bmi ring buf full head %d, tail %d", + pr_info("bmi ring buf full head %d, tail %d", s_ring_buf_head, s_ring_buf_tail); } @@ -4162,10 +4370,13 @@ static uint64_t bmi_fifo_data_decode(uint8_t *fifo_data_buf, uint16_t fifo_lengt case FIFO_HEAD_M: idx +=1; if (idx + 8 < fifo_length) { - bmi_fifo_get_decode_data(NULL, NULL, &bmi160_value.mag, fifo_data_buf, idx); - bmi160_value.ts_intvl = (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + bmi_fifo_get_decode_data(NULL, NULL, + &bmi160_value.mag, + fifo_data_buf, idx); + bmi160_value.ts_intvl = + (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); if (bmi_ring_buf_put(bmi160_value) == 0) - printk(KERN_INFO "bmi ring buf full head %d, tail %d", + pr_info("bmi ring buf full head %d, tail %d", s_ring_buf_head, s_ring_buf_tail); } @@ -4174,10 +4385,12 @@ static uint64_t bmi_fifo_data_decode(uint8_t *fifo_data_buf, uint16_t fifo_lengt case FIFO_HEAD_M_A: idx +=1; if (idx + 14 < fifo_length) { - bmi_fifo_get_decode_data(&bmi160_value.acc, NULL, &bmi160_value.mag, fifo_data_buf, idx); - bmi160_value.ts_intvl = (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + bmi_fifo_get_decode_data(&bmi160_value.acc, NULL, + &bmi160_value.mag, fifo_data_buf, idx); + bmi160_value.ts_intvl = + (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); if (bmi_ring_buf_put(bmi160_value) == 0) - printk(KERN_INFO "bmi ring buf full head %d, tail %d", + pr_info("bmi ring buf full head %d, tail %d", s_ring_buf_head, s_ring_buf_tail); } @@ -4187,10 +4400,12 @@ static uint64_t bmi_fifo_data_decode(uint8_t *fifo_data_buf, uint16_t fifo_lengt case FIFO_HEAD_M_G: idx +=1; if (idx + 14 < fifo_length) { - bmi_fifo_get_decode_data(NULL, &bmi160_value.gyro, &bmi160_value.mag, fifo_data_buf, idx); - bmi160_value.ts_intvl = (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + bmi_fifo_get_decode_data(NULL, &bmi160_value.gyro, + &bmi160_value.mag, fifo_data_buf, idx); + bmi160_value.ts_intvl = + (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); if (bmi_ring_buf_put(bmi160_value) == 0) - printk(KERN_INFO "bmi ring buf full head %d, tail %d", + pr_info("bmi ring buf full head %d, tail %d", s_ring_buf_head, s_ring_buf_tail); } @@ -4199,26 +4414,28 @@ static uint64_t bmi_fifo_data_decode(uint8_t *fifo_data_buf, uint16_t fifo_lengt case FIFO_HEAD_M_G_A: idx +=1; if (idx + 20 < fifo_length) { - bmi_fifo_get_decode_data(&bmi160_value.acc, &bmi160_value.gyro, &bmi160_value.mag, fifo_data_buf, idx); - bmi160_value.ts_intvl = (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + bmi_fifo_get_decode_data(&bmi160_value.acc, + &bmi160_value.gyro, + &bmi160_value.mag, fifo_data_buf, idx); + bmi160_value.ts_intvl = + (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); if (bmi_ring_buf_put(bmi160_value) == 0) - printk(KERN_INFO "bmi ring buf full head %d, tail %d", + pr_info("bmi ring buf full head %d, tail %d", s_ring_buf_head, s_ring_buf_tail); } idx += 20; - printk (KERN_INFO "second interface mag"); + pr_info("second interface mag"); break; #endif case FIFO_HEAD_OVER_READ_LSB: - /* end of fifo chunk */ - idx = fifo_length; - break; - default: - printk (KERN_INFO "ERROR parsing FIFO!! header 0x%x", header); - idx = fifo_length; - break; - } + /* end of fifo chunk */ + idx = fifo_length; + break; + default: + pr_info("ERROR parsing FIFO!! header 0x%x", header); + idx = fifo_length; + break; } } @@ -4230,12 +4447,16 @@ static uint64_t bmi_fifo_next_timestamp_calc(uint64_t host_time_new, int drift, int odr_pow, uint8_t bmi_odr) { - uint64_t time_age = ((sensor_time_new & (0xFFFF >> bmi_odr)) * (drift > 0 ? drift : 1000)) * 390625; - return ((host_time_new - div64_u64(time_age, 10000000) + ((drift > 0 ? drift : 1000) * (625 * odr_pow)))); + uint64_t time_age = ((sensor_time_new & (0xFFFF >> bmi_odr)) + * (drift > 0 ? drift : 1000)) * 390625; + return ((host_time_new - div64_u64(time_age, 10000000) + + ((drift > 0 ? drift : 1000) * (625 * odr_pow)))); } -static int bmi_fifo_time_drift_calc(uint64_t host_time_new, uint64_t sensor_time_new, - uint64_t host_time_old, uint64_t sensor_time_old) +static int bmi_fifo_time_drift_calc(uint64_t host_time_new, + uint64_t sensor_time_new, + uint64_t host_time_old, + uint64_t sensor_time_old) { uint64_t delta_st, delta_ht; int drift = 0; @@ -4245,13 +4466,12 @@ static int bmi_fifo_time_drift_calc(uint64_t host_time_new, uint64_t sensor_time (sensor_time_new - sensor_time_old) : (sensor_time_new + FIFO_SENSORTIME_OVERFLOW_MASK - sensor_time_old); delta_ht = host_time_new - host_time_old; -// printk(KERN_INFO "delta_st %llu, delta_ht %llu s_new %llu, s_old %llu, h_new %llu, h_old %llu", -// delta_st, delta_ht,sensor_time_new, sensor_time_old, host_time_new, host_time_old); if (delta_st != 0) - drift = (int )div64_u64(delta_ht * 10000, (delta_st * FIFO_SENSORTIME_RESOLUTION)); + drift = (int)div64_u64(delta_ht * 10000, + (delta_st * FIFO_SENSORTIME_RESOLUTION)); else drift = 0; - + } else { drift = 0; } @@ -4267,7 +4487,6 @@ static void bmi_fifo_watermark_interrupt_handle unsigned int fifo_frmbytes_ext = 0; static int time_drift = 0; static uint64_t timestamp_next = 0; -// static uint64_t host_timestamp = 0; uint8_t bmi_odr = client_data->odr.acc_odr; int odr_pow = bmi_pow(2, 12 - bmi_odr + 1); /*TO DO*/ @@ -4277,15 +4496,15 @@ static void bmi_fifo_watermark_interrupt_handle bmi_odr = client_data->odr.mag_odr; odr_pow = bmi_pow(2, 12 - bmi_odr + 1); } - + bmi_fifo_frame_bytes_extend_calc(client_data, &fifo_frmbytes_ext); if (client_data->pw.acc_pm == 2 && client_data->pw.gyro_pm == 2 && client_data->pw.mag_pm == 2) - printk(KERN_INFO "pw_acc: %d, pw_gyro: %d\n", + pr_info("pw_acc: %d, pw_gyro: %d\n", client_data->pw.acc_pm, client_data->pw.gyro_pm); if (!client_data->fifo_data_sel) - printk(KERN_INFO "no selsect sensor fifo, fifo_data_sel:%d\n", + pr_info("no selsect sensor fifo, fifo_data_sel:%d\n", client_data->fifo_data_sel); err = BMI_CALL_API(fifo_length)(&fifo_len0); @@ -4293,7 +4512,7 @@ static void bmi_fifo_watermark_interrupt_handle if (client_data->fifo_bytecount == 0 || err) { - printk(KERN_INFO "fifo_bytecount is 0!!"); + pr_info("fifo_bytecount is 0!!"); return ; } if (client_data->fifo_bytecount + fifo_frmbytes_ext > FIFO_DATA_BUFSIZE) @@ -4308,19 +4527,20 @@ static void bmi_fifo_watermark_interrupt_handle host_time_new = bmi_get_alarm_timestamp_ns(); if (timestamp_next == 0) { sensor_time_new = bmi_fifo_data_decode(s_fifo_data_buf, - client_data->fifo_bytecount + fifo_frmbytes_ext, - time_drift, timestamp_next,odr_pow); + client_data->fifo_bytecount + fifo_frmbytes_ext, + time_drift, timestamp_next, odr_pow); } else { sensor_time_new = bmi_fifo_data_decode(s_fifo_data_buf, - client_data->fifo_bytecount + fifo_frmbytes_ext, - time_drift, host_time_new,odr_pow); + client_data->fifo_bytecount + fifo_frmbytes_ext, + time_drift, host_time_new, odr_pow); } if (sensor_time_new >= 0) { time_drift = bmi_fifo_time_drift_calc(host_time_new, - sensor_time_new,host_time_old, sensor_time_old); + sensor_time_new, host_time_old, sensor_time_old); timestamp_next = bmi_fifo_next_timestamp_calc(host_time_new, - sensor_time_new, time_drift, odr_pow, bmi_odr); - /* store current timestamps as the old ones for next delta calculation */ + sensor_time_new, time_drift, odr_pow, bmi_odr); + /* store current timestamps as the old ones + for next delta calculation */ host_time_old = host_time_new; sensor_time_old = sensor_time_new; } @@ -4330,19 +4550,17 @@ static void bmi_fifo_watermark_interrupt_handle if (err) dev_err(client_data->dev, "brust read fifo err\n"); - /*err = bmi_fifo_analysis_handle(client_data, fifo_data, - client_data->fifo_bytecount + 20, fifo_out_data);*/ - } static void bmi_signification_motion_interrupt_handle( struct bmi_client_data *client_data) { - printk(KERN_INFO "bmi_signification_motion_interrupt_handle\n"); - input_event(client_data->input, EV_MSC, INPUT_EVENT_SGM, 1); -/*input_report_rel(client_data->input,INPUT_EVENT_SGM,1);*/ - input_sync(client_data->input); + pr_info("bmi_signification_motion_interrupt_handle\n"); + input_event(client_data->input_accel, EV_MSC, INPUT_EVENT_SGM, 1); + input_sync(client_data->input_accel); + input_event(client_data->input_gyro, EV_MSC, INPUT_EVENT_SGM, 1); + input_sync(client_data->input_gyro); bmi160_set_command_register(CMD_RESET_INT_ENGINE); } @@ -4456,6 +4674,179 @@ static int bmi_restore_hw_cfg(struct bmi_client_data *client) return err; } +static void bmi160_set_acc_enable(struct device *dev, unsigned int enable) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bmi_client_data *client_data = i2c_get_clientdata(client); + int acc_pre_enable = atomic_read(&client_data->wkqueue_en); + int gyro_current_enable; + + mutex_lock(&client_data->mutex_enable); + if (enable) { + if (acc_pre_enable == 0) { + if (!client_data->power_enabled) { + if (bmi160_power_ctl(client_data, true)) { + dev_err(dev, "power up sensor failed.\n"); + goto mutex_exit; + } + } + + bmi160_set_acc_op_mode(client_data, BMI_ACC_PM_NORMAL); + schedule_delayed_work(&client_data->work, + msecs_to_jiffies(atomic_read(&client_data->delay))); + atomic_set(&client_data->wkqueue_en, 1); + } + } else { + if ((acc_pre_enable == 1) && client_data->power_enabled) { + bmi160_set_acc_op_mode(client_data, BMI_ACC_PM_SUSPEND); + cancel_delayed_work_sync(&client_data->work); + atomic_set(&client_data->wkqueue_en, 0); + gyro_current_enable = atomic_read(&client_data->gyro_en); + if (!gyro_current_enable) { + if (bmi160_power_ctl(client_data, false)) { + dev_err(dev, "power up sensor failed.\n"); + goto mutex_exit; + } + } + } + } + +mutex_exit: + mutex_unlock(&client_data->mutex_enable); + dev_notice(dev, + "acc_enable en_state=%d\n", + atomic_read(&client_data->wkqueue_en)); +} + + +static void bmi160_set_gyro_enable(struct device *dev, unsigned int enable) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bmi_client_data *client_data = i2c_get_clientdata(client); + int gyro_pre_enable = atomic_read(&client_data->gyro_en); + int acc_current_enable; + + mutex_lock(&client_data->mutex_enable); + if (enable) { + if (gyro_pre_enable == 0) { + if (!client_data->power_enabled) { + if (bmi160_power_ctl(client_data, true)) { + dev_err(dev, "power up sensor failed.\n"); + goto mutex_exit; + } + } + bmi160_set_gyro_op_mode(client_data, BMI_GYRO_PM_NORMAL); + schedule_delayed_work(&client_data->gyro_work, + msecs_to_jiffies(atomic_read(&client_data->delay))); + atomic_set(&client_data->gyro_en, 1); + } + } else { + if ((gyro_pre_enable == 1) && client_data->power_enabled) { + bmi160_set_gyro_op_mode(client_data, BMI_GYRO_PM_SUSPEND); + cancel_delayed_work_sync(&client_data->gyro_work); + atomic_set(&client_data->gyro_en, 0); + acc_current_enable = atomic_read(&client_data->wkqueue_en); + if (!acc_current_enable) { + if (bmi160_power_ctl(client_data, false)) { + dev_err(dev, "power up sensor failed.\n"); + goto mutex_exit; + } + } + } + } + +mutex_exit: + mutex_unlock(&client_data->mutex_enable); + dev_notice(&client->dev, "gyro_enable en_state=%d\n", + atomic_read(&client_data->gyro_en)); +} + + +static int bmi160_self_calibration_xyz(struct sensors_classdev *sensors_cdev, + int axis, int apply_now) +{ + int err = 0; + s8 accel_offset_x = 0; + s8 accel_offset_y = 0; + s8 accel_offset_z = 0; + + struct bmi_client_data *client_data = container_of(sensors_cdev, + struct bmi_client_data, accel_cdev); + + err = BMI_CALL_API(set_accel_foc_trigger)(X_AXIS, + 1, &accel_offset_x); + if (!err) + client_data->calib_status |= + BMI_FAST_CALI_TRUE << BMI_ACC_X_FAST_CALI_RDY; + else + return -EIO; + + err = BMI_CALL_API(set_accel_foc_trigger)(Y_AXIS, + 1, &accel_offset_y); + if (!err) + client_data->calib_status |= + BMI_FAST_CALI_TRUE << BMI_ACC_Y_FAST_CALI_RDY; + else + return -EIO; + + err = BMI_CALL_API(set_accel_foc_trigger)(Z_AXIS, + 1, &accel_offset_z); + if (!err) + client_data->calib_status |= + BMI_FAST_CALI_TRUE << BMI_ACC_Z_FAST_CALI_RDY; + else + return -EIO; + + return 0; +} + +static int bmi160_accel_poll_delay(struct sensors_classdev *sensors_cdev, + unsigned int delay_ms) +{ + struct bmi_client_data *data = container_of(sensors_cdev, + struct bmi_client_data, accel_cdev); + + if (delay_ms < 10) + delay_ms = 10; + if (delay_ms > 10) + delay_ms = 10; + atomic_set(&data->delay, (unsigned int) delay_ms); + return 0; +} + +static int bmi160_cdev_enable_accel(struct sensors_classdev *sensors_cdev, + unsigned int enable) +{ + struct bmi_client_data *client_data = container_of(sensors_cdev, + struct bmi_client_data, accel_cdev); + bmi160_set_acc_enable(&client_data->i2c->dev, enable); + return 0; +} + +static int bmi160_gyro_poll_delay(struct sensors_classdev *sensors_cdev, + unsigned int delay_ms) +{ + struct bmi_client_data *data = container_of(sensors_cdev, + struct bmi_client_data, gyro_cdev); + + if (delay_ms < 10) + delay_ms = 10; + if (delay_ms > 10) + delay_ms = 10; + atomic_set(&data->delay, (unsigned int) delay_ms); + return 0; +} + + +static int bmi160_cdev_enable_gyro(struct sensors_classdev *sensors_cdev, + unsigned int enable) +{ + struct bmi_client_data *client_data = container_of(sensors_cdev, + struct bmi_client_data, gyro_cdev); + bmi160_set_gyro_enable(&client_data->i2c->dev, enable); + return 0; +} + int bmi_probe(struct bmi_client_data *client_data, struct device *dev) { @@ -4465,10 +4856,25 @@ int bmi_probe(struct bmi_client_data *client_data, struct device *dev) u8 mag_urst_len; u8 mag_op_mode; #endif + err = bmi160_power_init(client_data); + if (err) { + dev_err(&client_data->i2c->dev, + "Failed to get sensor regulators\n"); + err = -EINVAL; + goto exit_err_clean; + } + err = bmi160_power_ctl(client_data, true); + if (err) { + dev_err(&client_data->i2c->dev, + "Failed to enable sensor power\n"); + err = -EINVAL; + goto deinit_power_exit; + } + /* check chip id */ err = bmi_check_chip_id(client_data); if (err) - goto exit_err_clean; + goto disable_power_exit; dev_set_drvdata(dev, client_data); client_data->dev = dev; @@ -4480,15 +4886,37 @@ int bmi_probe(struct bmi_client_data *client_data, struct device *dev) /* input device init */ err = bmi_input_init(client_data); if (err < 0) - goto exit_err_clean; + goto disable_power_exit; /* sysfs node creation */ - err = sysfs_create_group(&client_data->input->dev.kobj, + err = sysfs_create_group(&client_data->i2c->dev.kobj, &bmi160_attribute_group); if (err < 0) goto exit_err_sysfs; + /*to do*/ + client_data->accel_cdev = accel_cdev; + client_data->accel_cdev.sensors_enable = bmi160_cdev_enable_accel; + client_data->accel_cdev.sensors_poll_delay = bmi160_accel_poll_delay; + client_data->accel_cdev.sensors_calibrate = bmi160_self_calibration_xyz; + err = sensors_classdev_register(&client_data->input_accel->dev, + &client_data->accel_cdev); + if (err) { + dev_err(&client_data->i2c->dev, "sensors class register failed.\n"); + return err; + } + + client_data->gyro_cdev = gyro_cdev; + client_data->gyro_cdev.sensors_enable = bmi160_cdev_enable_gyro; + client_data->gyro_cdev.sensors_poll_delay = bmi160_gyro_poll_delay; + err = sensors_classdev_register(&client_data->input_gyro->dev, + &client_data->gyro_cdev); + if (err) { + dev_err(&client_data->i2c->dev, "sensors class register failed.\n"); + return err; + } + if (NULL != dev->platform_data) { client_data->bst_pd = kzalloc(sizeof(*client_data->bst_pd), GFP_KERNEL); @@ -4503,18 +4931,19 @@ int bmi_probe(struct bmi_client_data *client_data, struct device *dev) } if (NULL != client_data->bst_pd) { - memcpy(client_data->bst_pd, dev->platform_data, - sizeof(*client_data->bst_pd)); - dev_notice(dev, "%s sensor driver set place: p%d\n", - client_data->bst_pd->name, - client_data->bst_pd->place); - } - + memcpy(client_data->bst_pd, dev->platform_data, + sizeof(*client_data->bst_pd)); + dev_notice(dev, "%s sensor driver set place: p%d\n", + client_data->bst_pd->name, + client_data->bst_pd->place); + } -// /* workqueue init */ -// INIT_DELAYED_WORK(&client_data->work, bmi_work_func); -// atomic_set(&client_data->delay, BMI_DELAY_DEFAULT); -// atomic_set(&client_data->wkqueue_en, 0); + /* workqueue init */ + INIT_DELAYED_WORK(&client_data->work, bmi_work_func); + INIT_DELAYED_WORK(&client_data->gyro_work, bmi_gyro_work_func); + atomic_set(&client_data->delay, BMI_DELAY_DEFAULT); + atomic_set(&client_data->wkqueue_en, 0); + atomic_set(&client_data->gyro_en, 0); /* h/w init */ client_data->device.delay_msec = bmi_delay; @@ -4524,7 +4953,7 @@ int bmi_probe(struct bmi_client_data *client_data, struct device *dev) INIT_WORK(&client_data->report_data_work, bmi_hrtimer_work_func); reportdata_wq = create_singlethread_workqueue("bmi160_wq"); if (NULL == reportdata_wq) { - printk(KERN_INFO "fail to create the reportdta_wq %d", -ENOMEM); + pr_info("fail to create the reportdta_wq %d", -ENOMEM); } hrtimer_init(&client_data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); @@ -4579,69 +5008,76 @@ int bmi_probe(struct bmi_client_data *client_data, struct device *dev) if (err < 0) goto exit_err_sysfs; - -#if defined(BMI160_ENABLE_INT1) || defined(BMI160_ENABLE_INT2) - client_data->gpio_pin = of_get_named_gpio_flags(dev->of_node, - "bmi,gpio_irq", 0, NULL); - dev_info(client_data->dev, "BMI160 qpio number:%d\n", - client_data->gpio_pin); - err += gpio_request_one(client_data->gpio_pin, - GPIOF_IN, "bmi160_int"); - err += gpio_direction_input(client_data->gpio_pin); - client_data->IRQ = gpio_to_irq(client_data->gpio_pin); - if (err) { - dev_err(client_data->dev, - "can not request gpio to irq number\n"); - client_data->gpio_pin = 0; - } - - #ifdef BMI160_ENABLE_INT1 - /* maps interrupt to INT1/InT2 pin */ - BMI_CALL_API(set_intr_any_motion)(BMI_INT0, ENABLE); - BMI_CALL_API(set_intr_fifo_wm)(BMI_INT0, ENABLE); - /*BMI_CALL_API(set_int_drdy)(BMI_INT0, ENABLE);*/ - - /*Set interrupt trige level way */ - BMI_CALL_API(set_intr_edge_ctrl)(BMI_INT0, BMI_INT_LEVEL); - bmi160_set_intr_level(BMI_INT0, 1); - /*set interrupt latch temporary, 5 ms*/ - /*bmi160_set_latch_int(5);*/ - - BMI_CALL_API(set_output_enable)( - BMI160_INTR1_OUTPUT_ENABLE, ENABLE); - sigmotion_init_interrupts(BMI160_MAP_INTR1); - BMI_CALL_API(map_step_detector_intr)(BMI160_MAP_INTR1); - /*close step_detector in init function*/ - BMI_CALL_API(set_step_detector_enable)(0); + client_data->gpio_pin = of_get_named_gpio_flags(dev->of_node, + "bosch,gpio-int1", 0, NULL); + dev_info(client_data->dev, "BMI160 qpio number:%d\n", + client_data->gpio_pin); + err += gpio_request_one(client_data->gpio_pin, + GPIOF_IN, "bmi160_int"); + err += gpio_direction_input(client_data->gpio_pin); + client_data->IRQ = gpio_to_irq(client_data->gpio_pin); + if (err) { + dev_err(client_data->dev, + "can not request gpio to irq number\n"); + client_data->gpio_pin = 0; + } + /* maps interrupt to INT1/InT2 pin */ + BMI_CALL_API(set_intr_any_motion)(BMI_INT0, ENABLE); + BMI_CALL_API(set_intr_fifo_wm)(BMI_INT0, ENABLE); + /*BMI_CALL_API(set_int_drdy)(BMI_INT0, ENABLE);*/ + + /*Set interrupt trige level way */ + BMI_CALL_API(set_intr_edge_ctrl)(BMI_INT0, BMI_INT_LEVEL); + bmi160_set_intr_level(BMI_INT0, 1); + /*set interrupt latch temporary, 5 ms*/ + /*bmi160_set_latch_int(5);*/ + + BMI_CALL_API(set_output_enable)( + BMI160_INTR1_OUTPUT_ENABLE, ENABLE); + sigmotion_init_interrupts(BMI160_MAP_INTR1); + BMI_CALL_API(map_step_detector_intr)(BMI160_MAP_INTR1); + /*close step_detector in init function*/ + BMI_CALL_API(set_step_detector_enable)(0); #endif #ifdef BMI160_ENABLE_INT2 - /* maps interrupt to INT1/InT2 pin */ - BMI_CALL_API(set_intr_any_motion)(BMI_INT1, ENABLE); - BMI_CALL_API(set_intr_fifo_wm)(BMI_INT1, ENABLE); - BMI_CALL_API(set_int_drdy)(BMI_INT1, ENABLE); - - /*Set interrupt trige level way */ - BMI_CALL_API(set_intr_edge_ctrl)(BMI_INT1, BMI_INT_LEVEL); - bmi160_set_intr_level(BMI_INT1, 1); - /*set interrupt latch temporary, 5 ms*/ - /*bmi160_set_latch_int(5);*/ - - BMI_CALL_API(set_output_enable)( - BMI160_INTR2_OUTPUT_ENABLE, ENABLE); - sigmotion_init_interrupts(BMI160_MAP_INTR2); - BMI_CALL_API(map_step_detector_intr)(BMI160_MAP_INTR2); - /*close step_detector in init function*/ - BMI_CALL_API(set_step_detector_enable)(0); -#endif - err = request_irq(client_data->IRQ, bmi_irq_handler, - IRQF_TRIGGER_RISING, "bmi160", client_data); - if (err) - dev_err(client_data->dev, "could not request irq\n"); - - INIT_WORK(&client_data->irq_work, bmi_irq_work_func); + client_data->gpio_pin = of_get_named_gpio_flags(dev->of_node, + "bosch,gpio-int2", 0, NULL); + dev_info(client_data->dev, "BMI160 qpio number:%d\n", + client_data->gpio_pin); + err += gpio_request_one(client_data->gpio_pin, + GPIOF_IN, "bmi160_int"); + err += gpio_direction_input(client_data->gpio_pin); + client_data->IRQ = gpio_to_irq(client_data->gpio_pin); + if (err) { + dev_err(client_data->dev, + "can not request gpio to irq number\n"); + client_data->gpio_pin = 0; + } + /* maps interrupt to INT1/InT2 pin */ + BMI_CALL_API(set_intr_any_motion)(BMI_INT1, ENABLE); + BMI_CALL_API(set_intr_fifo_wm)(BMI_INT1, ENABLE); + BMI_CALL_API(set_int_drdy)(BMI_INT1, ENABLE); + + /*Set interrupt trige level way */ + BMI_CALL_API(set_intr_edge_ctrl)(BMI_INT1, BMI_INT_LEVEL); + bmi160_set_intr_level(BMI_INT1, 1); + /*set interrupt latch temporary, 5 ms*/ + /*bmi160_set_latch_int(5);*/ + + BMI_CALL_API(set_output_enable)( + BMI160_INTR2_OUTPUT_ENABLE, ENABLE); + sigmotion_init_interrupts(BMI160_MAP_INTR2); + BMI_CALL_API(map_step_detector_intr)(BMI160_MAP_INTR2); + /*close step_detector in init function*/ + BMI_CALL_API(set_step_detector_enable)(0); #endif + err = request_irq(client_data->IRQ, bmi_irq_handler, + IRQF_TRIGGER_RISING, "bmi160", client_data); + if (err) + dev_err(client_data->dev, "could not request irq\n"); + INIT_WORK(&client_data->irq_work, bmi_irq_work_func); client_data->selftest = 0; @@ -4660,6 +5096,8 @@ int bmi_probe(struct bmi_client_data *client_data, struct device *dev) goto exit_err_sysfs; } + bmi160_power_ctl(client_data, false); + dev_notice(dev, "sensor_time:%d, %d", sensortime_duration_tbl[0].ts_delat, sensortime_duration_tbl[0].ts_duration_lsb); @@ -4670,7 +5108,10 @@ int bmi_probe(struct bmi_client_data *client_data, struct device *dev) exit_err_sysfs: if (err) bmi_input_destroy(client_data); - +disable_power_exit: + bmi160_power_ctl(client_data, false); +deinit_power_exit: + bmi160_power_deinit(client_data); exit_err_clean: if (err) { if (client_data != NULL) { @@ -4714,7 +5155,7 @@ int bmi_remove(struct device *dev) mdelay(5); - sysfs_remove_group(&client_data->input->dev.kobj, + sysfs_remove_group(&client_data->i2c->dev.kobj, &bmi160_attribute_group); bmi_input_destroy(client_data); @@ -4722,9 +5163,8 @@ int bmi_remove(struct device *dev) kfree(client_data->bst_pd); client_data->bst_pd = NULL; } - kfree(client_data); + kfree(client_data); } - return err; } EXPORT_SYMBOL(bmi_remove); @@ -4749,7 +5189,6 @@ static int bmi_post_resume(struct bmi_client_data *client_data) client_data->base_time = 0; client_data->timestamp = 0; client_data->is_timer_running = 1; - //client_data->gyro_count = 0; } return err; @@ -4769,7 +5208,6 @@ int bmi_suspend(struct device *dev) client_data->base_time = 0; client_data->timestamp = 0; client_data->fifo_time = 0; - //client_data->gyro_count = 0; } if (atomic_read(&client_data->wkqueue_en) == 1) { diff --git a/drivers/input/misc/bmi160_driver.h b/drivers/input/misc/bmi160_driver.h old mode 100755 new mode 100644 index 9696687cb4825..70a432a5e170f --- a/drivers/input/misc/bmi160_driver.h +++ b/drivers/input/misc/bmi160_driver.h @@ -14,20 +14,10 @@ * @brief * The head file of BMI160 device driver core code */ -#ifndef _BMI160_DRIVER_H -#define _BMI160_DRIVER_H - -#ifdef __KERNEL__ #include #include #include #include -#else -#include -#include -#include -#endif - #include #include #include @@ -38,6 +28,9 @@ #include #include #include +#include +#include +#include #include #include @@ -50,6 +43,12 @@ /* sensor specific */ #define SENSOR_NAME "bmi160" +#define BMI160_ACCEL_INPUT_NAME "bmi160-accel" +#define BMI160_GYRO_INPUT_NAME "bmi160-gyro" +#define ABSMIN -512 +#define ABSMAX 512 +#define GYRO_MIN_VALUE -32768 +#define GYRO_MAX_VALUE 32767 #define SENSOR_CHIP_ID_BMI (0xD0) #define SENSOR_CHIP_ID_BMI_C2 (0xD1) @@ -183,6 +182,13 @@ #define BMM050_DIG_XY2 0x70 #define BMM050_DIG_XY1 0x71 +struct regulator_map { + struct regulator *regulator; + int min_uv; + int max_uv; + char *supply; +}; + struct bmi160mag_compensate_t { signed char dig_x1; signed char dig_y1; @@ -292,11 +298,18 @@ struct pedometer_data_t { struct bmi_client_data { struct bmi160_t device; + struct i2c_client *i2c; struct device *dev; - struct input_dev *input; + struct input_dev *input_accel; + struct input_dev *input_gyro; + struct sensors_classdev accel_cdev; + struct sensors_classdev gyro_cdev; + struct regulator *vdd; + struct regulator *vio; struct delayed_work work; + struct delayed_work gyro_work; struct work_struct irq_work; - + struct work_struct report_data_work; int is_timer_running; struct hrtimer timer; @@ -318,6 +331,7 @@ struct bmi_client_data { u8 selftest; atomic_t wkqueue_en; /*TO DO acc gyro mag*/ + atomic_t gyro_en; atomic_t delay; atomic_t selftest_result; @@ -337,6 +351,7 @@ struct bmi_client_data { struct mutex mutex_enable; struct mutex mutex_ring_buf; struct bosch_sensor_specific *bst_pd; + bool power_enabled; int IRQ; #ifdef CONFIG_HAS_EARLYSUSPEND struct early_suspend early_suspend_handler; @@ -384,7 +399,3 @@ int bmi_suspend(struct device *dev); int bmi_resume(struct device *dev); - -#endif/*_BMI160_DRIVER_H*/ -/*@}*/ - diff --git a/drivers/input/misc/bmi160_i2c.c b/drivers/input/misc/bmi160_i2c.c old mode 100755 new mode 100644 index 810569e063c0d..64648529ce5d8 --- a/drivers/input/misc/bmi160_i2c.c +++ b/drivers/input/misc/bmi160_i2c.c @@ -277,6 +277,7 @@ static int bmi_i2c_probe(struct i2c_client *client, goto exit_err_clean; } + client_data->i2c = client; client_data->device.bus_read = bmi_i2c_read_wrapper; client_data->device.bus_write = bmi_i2c_write_wrapper; @@ -327,7 +328,7 @@ MODULE_DEVICE_TABLE(i2c, bmi_id); static const struct of_device_id bmi160_of_match[] = { { .compatible = "bosch-sensortec,bmi160", }, { .compatible = "bmi160", }, - { .compatible = "bosch, bmi160", }, + { .compatible = "bosch,bmi160", }, { } }; MODULE_DEVICE_TABLE(of, bmi160_of_match); diff --git a/drivers/input/misc/mmc3x30.c b/drivers/input/misc/mmc3x30.c old mode 100755 new mode 100644 index 9b42fede094a2..08364d6ea0099 --- a/drivers/input/misc/mmc3x30.c +++ b/drivers/input/misc/mmc3x30.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Linux Foundation. All rights reserved. + * Copyright (c) 2014, 2016 Linux Foundation. All rights reserved. * Linux Foundation chooses to take subject only to the GPLv2 license * terms, and distributes only under these terms. * Copyright (C) 2010 MEMSIC, Inc. @@ -40,8 +40,6 @@ #include -//#include "mmc3x30.h" - #define MMC3X30_DELAY_TM_MS 10 #define MMC3X30_DELAY_SET_MS 75 @@ -128,11 +126,10 @@ static struct sensors_classdev sensors_cdev = { .handle = SENSORS_MAGNETIC_FIELD_HANDLE, .type = SENSOR_TYPE_MAGNETIC_FIELD, .max_range = "1228.8", -// .resolution = "0.0488228125", //2048 - .resolution = "0.09765625", //1024 + .resolution = "0.09765625", /* 1024 */ .sensor_power = "0.35", .min_delay = 20000, - .max_delay = 100000, //100ms + .max_delay = 100000, /* 100ms */ .fifo_reserved_event_count = 0, .fifo_max_event_count = 0, .enabled = 0, @@ -141,9 +138,6 @@ static struct sensors_classdev sensors_cdev = { .sensors_poll_delay = NULL, }; -//static struct i2c_client *this_client; -//static struct regmap *this_regmap; -//static DEFINE_MUTEX(ecompass_ioctl_lock); static struct mmc3x30_data *mmc3x30_data_struct; static int mmc3x30_read_xyz(struct mmc3x30_data *memsic, @@ -159,8 +153,8 @@ static int mmc3x30_read_xyz(struct mmc3x30_data *memsic, #if 0 /* mmc3x30 need to be set periodly to avoid overflow */ if (time_after(jiffies, memsic->timeout)) { - - if(memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) + + if (memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) { rc = regmap_write(memsic->regmap, MMC35XX_REG_CTRL0, MMC35XX_SET); if (rc) { @@ -174,9 +168,8 @@ static int mmc3x30_read_xyz(struct mmc3x30_data *memsic, memsic->timeout = jiffies + msecs_to_jiffies(MMC3X30_TIMEOUT_SET_MS); dev_dbg(&memsic->i2c->dev, "mmc3x30 reset is done\n"); - - } - else if (memsic->device_id == MMC3630_DEVICE_ID ) + + } else if (memsic->device_id == MMC3630_DEVICE_ID) { rc = regmap_write(memsic->regmap, MMC36XX_REG_CTRL0, MMC36XX_SET); if (rc) { @@ -191,7 +184,7 @@ static int mmc3x30_read_xyz(struct mmc3x30_data *memsic, dev_dbg(&memsic->i2c->dev, "mmc3x30 reset is done\n"); } - + } #endif /* read xyz raw data */ @@ -203,7 +196,7 @@ static int mmc3x30_read_xyz(struct mmc3x30_data *memsic, } - tmp.x = (((u8)data[1]) << 8 | (u8)data[0]) - 32768; + tmp.x = (((u8)data[1]) << 8 | (u8)data[0]) - 32768; tmp.y = (((u8)data[3]) << 8 | (u8)data[2]) - (((u8)data[5]) << 8 | (u8)data[4]) ; tmp.z = (((u8)data[3]) << 8 | (u8)data[2]) + (((u8)data[5]) << 8 | (u8)data[4]) - 32768 - 32768; @@ -213,25 +206,23 @@ static int mmc3x30_read_xyz(struct mmc3x30_data *memsic, exit: /* send TM cmd before read */ - if(memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) + if (memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) { if (regmap_write(memsic->regmap, MMC35XX_REG_CTRL0, MMC35XX_SINGLE_TM)) { - + dev_warn(&memsic->i2c->dev, "write reg %d failed at %d.(%d)\n", MMC35XX_REG_CTRL0, __LINE__, rc); - } - - } - else if(memsic->device_id == MMC3630_DEVICE_ID) - { + } + + } else if (memsic->device_id == MMC3630_DEVICE_ID) { if (regmap_write(memsic->regmap, MMC36XX_REG_CTRL0, MMC36XX_SINGLE_TM)) { - + dev_warn(&memsic->i2c->dev, "write reg %d failed at %d.(%d)\n", MMC36XX_REG_CTRL0, __LINE__, rc); - } - + } + } - + mutex_unlock(&memsic->ecompass_lock); return rc; } @@ -282,11 +273,11 @@ static struct input_dev *mmc3x30_init_input(struct i2c_client *client) input->id.bustype = BUS_I2C; __set_bit(EV_ABS, input->evbit); - + input_set_abs_params(input, ABS_X, -1024*30, 1024*30, 0, 0); input_set_abs_params(input, ABS_Y, -1024*30, 1024*30, 0, 0); input_set_abs_params(input, ABS_Z, -1024*30, 1024*30, 0, 0); - + //input_set_capability(input, EV_ABS, ABS_X); //input_set_capability(input, EV_ABS, ABS_Y); //input_set_capability(input, EV_ABS, ABS_Z); @@ -462,24 +453,22 @@ static int mmc3x30_power_set(struct mmc3x30_data *memsic, bool on) } static int mmc3x30_check_device(struct mmc3x30_data *memsic) { - unsigned int id[2]={0,0}; - unsigned int reg[2]={MMC35XX_REG_ID,MMC36XX_REG_ID}; + unsigned int id[2] = {0, 0}; + unsigned int reg[2] = {MMC35XX_REG_ID, MMC36XX_REG_ID}; int rc[2]; - int i; - - for(i=0; i<2;i++) - { - rc[i] = regmap_read(memsic->regmap, reg[i], &id[i]); - } - //two id in the arrow - if(id[1] == MMC3630_DEVICE_ID) - memsic->device_id = MMC3630_DEVICE_ID; - else if(id[0] == MMC3530_DEVICE_ID) - memsic->device_id = MMC3530_DEVICE_ID; - else if(id[0] == MMC3524_DEVICE_ID) - memsic->device_id = MMC3524_DEVICE_ID; - else - return -ENODEV; + int i; + + for (i = 0; i < 2; i++) + rc[i] = regmap_read(memsic->regmap, reg[i], &id[i]); + /* two id in the arrow */ + if (id[1] == MMC3630_DEVICE_ID) + memsic->device_id = MMC3630_DEVICE_ID; + else if (id[0] == MMC3530_DEVICE_ID) + memsic->device_id = MMC3530_DEVICE_ID; + else if (id[0] == MMC3524_DEVICE_ID) + memsic->device_id = MMC3524_DEVICE_ID; + else + return -ENODEV; return 0; } @@ -510,9 +499,8 @@ static int mmc3x30_parse_dt(struct i2c_client *client, return -EINVAL; } - /*PLEASE CONFIRM WITH SENSOR PROVIDER*/ - //memsic->dir = i; - memsic->dir = 1; + /*PLEASE CONFIRM WITH SENSOR PROVIDER*/ + memsic->dir = 1; if (of_property_read_bool(np, "memsic,auto-report")) memsic->auto_report = 1; @@ -539,7 +527,7 @@ static int mmc3x30_set_enable(struct sensors_classdev *sensors_cdev, } /* send TM cmd before read */ - if(memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) + if (memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) { rc = regmap_write(memsic->regmap, MMC35XX_REG_CTRL0, MMC35XX_SINGLE_TM); @@ -548,9 +536,7 @@ static int mmc3x30_set_enable(struct sensors_classdev *sensors_cdev, MMC35XX_REG_CTRL0, rc); goto exit; } - } - else if(memsic->device_id == MMC3630_DEVICE_ID) - { + } else if (memsic->device_id == MMC3630_DEVICE_ID) { rc = regmap_write(memsic->regmap, MMC36XX_REG_CTRL0, MMC36XX_SINGLE_TM); if (rc) { @@ -559,7 +545,6 @@ static int mmc3x30_set_enable(struct sensors_classdev *sensors_cdev, goto exit; } } - memsic->timeout = jiffies; if (memsic->auto_report) schedule_delayed_work(&memsic->dwork, @@ -610,32 +595,30 @@ static int mmc3x30_device_initial(struct mmc3x30_data *memsic) int rc = -1; // Do SET operation - if(memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) + if (memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) { rc = regmap_write(mmc3x30_data_struct->regmap, MMC35XX_REG_CTRL0, MMC35XX_SET); if (rc) { dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", MMC35XX_REG_CTRL0, __LINE__, rc); - + return -EFAULT; } - - } - else if(memsic->device_id == MMC3630_DEVICE_ID) - { + + } else if (memsic->device_id == MMC3630_DEVICE_ID) { rc = regmap_write(mmc3x30_data_struct->regmap, MMC36XX_REG_CTRL0, MMC36XX_SET); if (rc) { dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", MMC36XX_REG_CTRL0, __LINE__, rc); - + return -EFAULT; } } - - msleep(1);//setting needd 1ms - + + msleep(20);/* setting need 20ms */ + return 0; } #endif @@ -653,14 +636,7 @@ static int mmc3x30_release(struct inode *inode, struct file *file) static long mmc3x30_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { -/* - int vec[3] = {0}; - int reg; - short flag; - short delay; -*/ void __user *pa = (void __user *)arg; -// int __user *pa_i = (void __user *)arg; unsigned char data[16] = {0}; unsigned char reg_addr; unsigned char reg_num; @@ -669,7 +645,7 @@ static long mmc3x30_ioctl(struct file *file, unsigned int cmd, unsigned long arg switch (cmd) { case MMC3X30_IOC_SET: - if(mmc3x30_data_struct->device_id == MMC3524_DEVICE_ID || mmc3x30_data_struct->device_id == MMC3530_DEVICE_ID) + if (mmc3x30_data_struct->device_id == MMC3524_DEVICE_ID || mmc3x30_data_struct->device_id == MMC3530_DEVICE_ID) { rc = regmap_write(mmc3x30_data_struct->regmap, MMC35XX_REG_CTRL0, MMC35XX_SET); @@ -678,10 +654,8 @@ static long mmc3x30_ioctl(struct file *file, unsigned int cmd, unsigned long arg MMC35XX_REG_CTRL0, __LINE__, rc); return -EFAULT; } - - } - else if(mmc3x30_data_struct->device_id == MMC3630_DEVICE_ID) - { + + } else if (mmc3x30_data_struct->device_id == MMC3630_DEVICE_ID) { rc = regmap_write(mmc3x30_data_struct->regmap, MMC36XX_REG_CTRL0, MMC36XX_SET); if (rc) { @@ -689,13 +663,13 @@ static long mmc3x30_ioctl(struct file *file, unsigned int cmd, unsigned long arg MMC36XX_REG_CTRL0, __LINE__, rc); return -EFAULT; } - + } - msleep(1);//setting needd 1ms + msleep(20);/* setting need 20ms */ break; - + case MMC3X30_IOC_RESET: - if(mmc3x30_data_struct->device_id == MMC3524_DEVICE_ID || mmc3x30_data_struct->device_id == MMC3530_DEVICE_ID) + if (mmc3x30_data_struct->device_id == MMC3524_DEVICE_ID || mmc3x30_data_struct->device_id == MMC3530_DEVICE_ID) { rc = regmap_write(mmc3x30_data_struct->regmap, MMC35XX_REG_CTRL0, MMC35XX_RESET); @@ -704,10 +678,8 @@ static long mmc3x30_ioctl(struct file *file, unsigned int cmd, unsigned long arg MMC35XX_REG_CTRL0, __LINE__, rc); return -EFAULT; } - - } - else if(mmc3x30_data_struct->device_id == MMC3630_DEVICE_ID) - { + + } else if (mmc3x30_data_struct->device_id == MMC3630_DEVICE_ID) { rc = regmap_write(mmc3x30_data_struct->regmap, MMC36XX_REG_CTRL0, MMC36XX_RESET); if (rc) { @@ -715,56 +687,63 @@ static long mmc3x30_ioctl(struct file *file, unsigned int cmd, unsigned long arg MMC36XX_REG_CTRL0, __LINE__, rc); return -EFAULT; } - + } - msleep(1);//setting needd 1ms + msleep(20);/* setting need 20ms */ break; - + case MMC3X30_IOC_READ_REG: if (copy_from_user(®_addr, pa, sizeof(reg_addr))) return -EFAULT; rc = regmap_read(mmc3x30_data_struct->regmap, reg_addr, ®_value); if (rc) { - dev_err(&mmc3x30_data_struct->i2c->dev, "read reg %d failed at %d.(%d)\n", + dev_err(&mmc3x30_data_struct->i2c->dev, + "read reg %d failed at %d.(%d)\n", reg_addr, __LINE__, rc); - } - printk("mmc3x30 Read register 0x%0x\n",reg_addr); + } + pr_info("mmc3x30 Read register 0x%0x\n", reg_addr); if (copy_to_user(pa, ®_value, sizeof(reg_value))) { return -EFAULT; - } - break; - + } + break; + case MMC3X30_IOC_WRITE_REG: if (copy_from_user(&data, pa, sizeof(data))) return -EFAULT; - - rc = regmap_write(mmc3x30_data_struct->regmap, data[1], data[0]); + + rc = regmap_write(mmc3x30_data_struct->regmap, + data[1], data[0]); if (rc) { - dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", - data[1], __LINE__, rc); + dev_err(&mmc3x30_data_struct->i2c->dev, + "write reg %d failed at %d.(%d)\n", + data[1], __LINE__, rc); return -EFAULT; } - printk("mmc3x30 Write '0x%0x' to register 0x%0x\n", data[0], data[1]); - break; - + pr_info("mmc3x30 Write '0x%0x' to register 0x%0x\n", + data[0], data[1]); + break; + case MMC3X30_IOC_READ_REGS: if (copy_from_user(&data, pa, sizeof(data))) return -EFAULT; reg_addr = data[0]; reg_num = data[1]; - - rc = regmap_bulk_read(mmc3x30_data_struct->regmap, reg_addr, data, reg_num); + + rc = regmap_bulk_read(mmc3x30_data_struct->regmap, + reg_addr, data, reg_num); if (rc) { - dev_err(&mmc3x30_data_struct->i2c->dev, "read reg %d failed at %d.(%d)\n", - reg_addr, __LINE__, rc); + dev_err(&mmc3x30_data_struct->i2c->dev, + "read reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); } - - printk("mmc3x30 data: %x %x %x \n%x %x %x\n", data[0], data[1], data[2], data[3], data[4], data[5]); + pr_info("mmc3x30 data: %x %x %x \n%x %x %x\n", + data[0], data[1], data[2], + data[3], data[4], data[5]); if (copy_to_user(pa, data, sizeof(data))) { return -EFAULT; - } - break; - + } + break; + default: dev_dbg(&mmc3x30_data_struct->i2c->dev, "no ctl cmd !\n"); return -EFAULT; @@ -775,60 +754,76 @@ static long mmc3x30_ioctl(struct file *file, unsigned int cmd, unsigned long arg } #ifdef CONFIG_COMPAT -static long mmc3x30_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static long mmc3x30_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) { void __user *arg64 = compat_ptr(arg); int ret =-1; - - if(!file->f_op || !file->f_op->unlocked_ioctl) + + if (!file->f_op || !file->f_op->unlocked_ioctl) { - dev_err(&mmc3x30_data_struct->i2c->dev, "file->f_op OR file->f_op->unlocked_ioctl is null!\n"); + dev_err(&mmc3x30_data_struct->i2c->dev, + "file->f_op OR file->f_op->unlocked_ioctl is null!\n"); return -EFAULT; } switch(cmd) { case COMPAT_MMC3X30_IOC_SET: - ret = file->f_op->unlocked_ioctl(file, MMC3X30_IOC_SET, (unsigned long)arg64); - if(ret < 0) + ret = file->f_op->unlocked_ioctl(file, + MMC3X30_IOC_SET, (unsigned long)arg64); + if (ret < 0) { - dev_err(&mmc3x30_data_struct->i2c->dev,"COMPAT_MMC3X30_IOC_SET is failed!\n"); + dev_err(&mmc3x30_data_struct->i2c->dev, + "COMPAT_MMC3X30_IOC_SET is failed!\n"); return -EFAULT; } break; case COMPAT_MMC3X30_IOC_RESET: - ret = file->f_op->unlocked_ioctl(file, MMC3X30_IOC_RESET, (unsigned long)arg64); - if(ret < 0) + ret = file->f_op->unlocked_ioctl(file, + MMC3X30_IOC_RESET, (unsigned long)arg64); + if (ret < 0) { - dev_err(&mmc3x30_data_struct->i2c->dev,"COMPAT_MMC3X30_IOC_RESET is failed!\n"); + dev_err(&mmc3x30_data_struct->i2c->dev, + "COMPAT_MMC3X30_IOC_RESET is failed!\n"); return -EFAULT; } break; case COMPAT_MMC3X30_IOC_READ_REG: - ret = file->f_op->unlocked_ioctl(file, COMPAT_MMC3X30_IOC_READ_REG, (unsigned long)arg64); - if(ret < 0) + ret = file->f_op->unlocked_ioctl(file, + COMPAT_MMC3X30_IOC_READ_REG, + (unsigned long)arg64); + if (ret < 0) { - dev_err(&mmc3x30_data_struct->i2c->dev, "COMPAT_MMC3X30_IOC_READ_REG is failed!\n"); + dev_err(&mmc3x30_data_struct->i2c->dev, + "COMPAT_MMC3X30_IOC_READ_REG is failed!\n"); return -EFAULT; } break; case COMPAT_MMC3X30_IOC_WRITE_REG: - ret = file->f_op->unlocked_ioctl(file, COMPAT_MMC3X30_IOC_WRITE_REG, (unsigned long)arg64); - if(ret < 0) + ret = file->f_op->unlocked_ioctl(file, + COMPAT_MMC3X30_IOC_WRITE_REG, + (unsigned long)arg64); + if (ret < 0) { - dev_err(&mmc3x30_data_struct->i2c->dev, "COMPAT_MMC3X30_IOC_WRITE_REG is failed!\n"); + dev_err(&mmc3x30_data_struct->i2c->dev, + "COMPAT_MMC3X30_IOC_WRITE_REG is failed!\n"); return -EFAULT; } break; case COMPAT_MMC3X30_IOC_READ_REGS: - ret = file->f_op->unlocked_ioctl(file, COMPAT_MMC3X30_IOC_READ_REGS, (unsigned long)arg64); - if(ret < 0) + ret = file->f_op->unlocked_ioctl(file, + COMPAT_MMC3X30_IOC_READ_REGS, + (unsigned long)arg64); + if (ret < 0) { - dev_err(&mmc3x30_data_struct->i2c->dev, "COMPAT_MMC3X30_IOC_READ_REGS is failed!\n"); + dev_err(&mmc3x30_data_struct->i2c->dev, + "COMPAT_MMC3X30_IOC_READ_REGS is failed!\n"); return -EFAULT; } break; default: - dev_dbg(&mmc3x30_data_struct->i2c->dev,"no compat ctl cmd !\n"); + dev_dbg(&mmc3x30_data_struct->i2c->dev, + "no compat ctl cmd !\n"); return -EFAULT; //break; } @@ -856,78 +851,87 @@ static struct miscdevice mmc3x30_device = { static ssize_t mmc3x30_otp_show(struct device *dev, struct device_attribute *attr, char *buf) { - char data[10] = {0}; unsigned char reg_addr; unsigned char reg_num; int rc = -1; - - if(mmc3x30_data_struct->device_id == MMC3524_DEVICE_ID || mmc3x30_data_struct->device_id == MMC3530_DEVICE_ID) + + if (mmc3x30_data_struct->device_id == MMC3524_DEVICE_ID + || mmc3x30_data_struct->device_id == MMC3530_DEVICE_ID) { reg_addr = MMC35XX_REG_OTP; reg_num = 4; - rc = regmap_bulk_read(mmc3x30_data_struct->regmap, reg_addr, data, reg_num); + rc = regmap_bulk_read(mmc3x30_data_struct->regmap, + reg_addr, data, reg_num); if (rc) { - dev_err(&mmc3x30_data_struct->i2c->dev, "read reg %d failed at %d.(%d)\n", - reg_addr, __LINE__, rc); + dev_err(&mmc3x30_data_struct->i2c->dev, + "read reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); } - return sprintf(buf, "%x,%x,%x,%x\n", data[0],data[1],data[2],data[3]); + return snprintf(buf, PAGE_SIZE, "%x,%x,%x,%x\n", + data[0], data[1], data[2], data[3]); - } - else if(mmc3x30_data_struct->device_id == MMC3630_DEVICE_ID) - { - reg_addr = MMC36XX_REG_OTP_GATE0; + } else if (mmc3x30_data_struct->device_id == MMC3630_DEVICE_ID) { + reg_addr = MMC36XX_REG_OTP_GATE0; data[0] = MMC36XX_OTP_OPEN0; - rc = regmap_write(mmc3x30_data_struct->regmap, reg_addr, data[0]); + rc = regmap_write(mmc3x30_data_struct->regmap, + reg_addr, data[0]); if (rc) { - dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", - reg_addr, __LINE__, rc); + dev_err(&mmc3x30_data_struct->i2c->dev, + "write reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); } - reg_addr = MMC36XX_REG_OTP_GATE1; + reg_addr = MMC36XX_REG_OTP_GATE1; data[0] = MMC36XX_OTP_OPEN1; - rc = regmap_write(mmc3x30_data_struct->regmap, reg_addr, data[0]); + rc = regmap_write(mmc3x30_data_struct->regmap, + reg_addr, data[0]); if (rc) { - dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", - reg_addr, __LINE__, rc); + dev_err(&mmc3x30_data_struct->i2c->dev, + "write reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); } - reg_addr = MMC36XX_REG_OTP_GATE2; + reg_addr = MMC36XX_REG_OTP_GATE2; data[0] = MMC36XX_OTP_OPEN2; - rc = regmap_write(mmc3x30_data_struct->regmap, reg_addr, data[0]); + rc = regmap_write(mmc3x30_data_struct->regmap, + reg_addr, data[0]); if (rc) { - dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", - reg_addr, __LINE__, rc); + dev_err(&mmc3x30_data_struct->i2c->dev, + "write reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); } - reg_addr = MMC36XX_REG_CTRL2; + reg_addr = MMC36XX_REG_CTRL2; data[0] = MMC36XX_OTP_OPEN2; - rc = regmap_write(mmc3x30_data_struct->regmap, reg_addr, data[0]); + rc = regmap_write(mmc3x30_data_struct->regmap, + reg_addr, data[0]); if (rc) { - dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", - reg_addr, __LINE__, rc); + dev_err(&mmc3x30_data_struct->i2c->dev, + "write reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); } - + reg_addr = MMC36XX_REG_OTP; reg_num = 2; - rc = regmap_bulk_read(mmc3x30_data_struct->regmap, reg_addr, data, reg_num); + rc = regmap_bulk_read(mmc3x30_data_struct->regmap, + reg_addr, data, reg_num); if (rc) { - dev_err(&mmc3x30_data_struct->i2c->dev, "read reg %d failed at %d.(%d)\n", - reg_addr, __LINE__, rc); - } - return sprintf(buf, "%x,%x\n", data[0],data[1]); + dev_err(&mmc3x30_data_struct->i2c->dev, + "read reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); + } + return snprintf(buf, PAGE_SIZE, "%x,%x\n", data[0], data[1]); } else { dev_err(&mmc3x30_data_struct->i2c->dev, "No otp !\n"); return -EFAULT; } - } -static ssize_t mmc3x30_value_show(struct device *dev,struct device_attribute *attr, char *buf) +static ssize_t mmc3x30_value_show(struct device *dev, + struct device_attribute *attr, char *buf) { int ret; - //s8 *tmp; struct mmc3x30_vec vec; - //struct mmc3x30_vec report; struct mmc3x30_data *memsic = dev_get_drvdata(dev); vec.x = vec.y = vec.z = 0; @@ -936,88 +940,84 @@ static ssize_t mmc3x30_value_show(struct device *dev,struct device_attribute *at if (ret) { dev_warn(&memsic->i2c->dev, "read xyz failed\n"); } - - /* - tmp = &mmc3x30_rotation_matrix[memsic->dir][0]; - report.x = tmp[0] * vec.x + tmp[1] * vec.y + tmp[2] * vec.z; - report.y = tmp[3] * vec.x + tmp[4] * vec.y + tmp[5] * vec.z; - report.z = tmp[6] * vec.x + tmp[7] * vec.y + tmp[8] * vec.z; - */ - return sprintf(buf, "%d %d %d\n", vec.x,vec.y,vec.z); + return snprintf(buf, PAGE_SIZE, "%d %d %d\n", vec.x, vec.y, vec.z); } -static ssize_t mmc3x30_set_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t mmc3x30_set_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { int rc = -1; struct mmc3x30_data *memsic = dev_get_drvdata(dev); - - if(memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) + + if (memsic->device_id == MMC3524_DEVICE_ID + || memsic->device_id == MMC3530_DEVICE_ID) { rc = regmap_write(memsic->regmap, MMC35XX_REG_CTRL0, - MMC35XX_SET); + MMC35XX_SET); if (rc) { - dev_err(&memsic->i2c->dev, "write reg %d failed at %d.(%d)\n", - MMC35XX_REG_CTRL0, __LINE__, rc); + dev_err(&memsic->i2c->dev, + "write reg %d failed at %d.(%d)\n", + MMC35XX_REG_CTRL0, __LINE__, rc); return -EFAULT; } - - } - else if(memsic->device_id == MMC3630_DEVICE_ID) - { + + } else if (memsic->device_id == MMC3630_DEVICE_ID) { rc = regmap_write(memsic->regmap, MMC36XX_REG_CTRL0, - MMC36XX_SET); + MMC36XX_SET); if (rc) { - dev_err(&memsic->i2c->dev, "write reg %d failed at %d.(%d)\n", - MMC36XX_REG_CTRL0, __LINE__, rc); + dev_err(&memsic->i2c->dev, + "write reg %d failed at %d.(%d)\n", + MMC36XX_REG_CTRL0, __LINE__, rc); return -EFAULT; } - + } - msleep(1);//setting time - return count;//nothing return + msleep(20);/* setting time */ + return count;/* nothing return */ } -static ssize_t mmc3x30_reset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t mmc3x30_reset_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { int rc = -1; struct mmc3x30_data *memsic = dev_get_drvdata(dev); - - if(memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) + + if (memsic->device_id == MMC3524_DEVICE_ID + || memsic->device_id == MMC3530_DEVICE_ID) { rc = regmap_write(memsic->regmap, MMC35XX_REG_CTRL0, - MMC35XX_RESET); + MMC35XX_RESET); if (rc) { - dev_err(&memsic->i2c->dev, "write reg %d failed at %d.(%d)\n", - MMC35XX_REG_CTRL0, __LINE__, rc); + dev_err(&memsic->i2c->dev, + "write reg %d failed at %d.(%d)\n", + MMC35XX_REG_CTRL0, __LINE__, rc); return -EFAULT; } - - } - else if(memsic->device_id == MMC3630_DEVICE_ID) - { + + } else if (memsic->device_id == MMC3630_DEVICE_ID) { rc = regmap_write(memsic->regmap, MMC36XX_REG_CTRL0, MMC36XX_RESET); if (rc) { - dev_err(&memsic->i2c->dev, "write reg %d failed at %d.(%d)\n", - MMC36XX_REG_CTRL0, __LINE__, rc); + dev_err(&memsic->i2c->dev, + "write reg %d failed at %d.(%d)\n", + MMC36XX_REG_CTRL0, __LINE__, rc); return -EFAULT; } - + } - msleep(1);//setting time - return count;//nothing return + msleep(20);/* setting time */ + return count;/* nothing return */ } -// add to create sysfs file node +/* add to create sysfs file node */ static DEVICE_ATTR(otp, S_IRUSR|S_IRGRP, mmc3x30_otp_show, NULL); static DEVICE_ATTR(value, S_IRUSR|S_IRGRP, mmc3x30_value_show, NULL); static DEVICE_ATTR(set, S_IWUSR, NULL, mmc3x30_set_store); static DEVICE_ATTR(reset, S_IWUSR, NULL, mmc3x30_reset_store); -//static DEVICE_ATTR(set, S_IWUSR, NULL, mmc3x30_set_store); -//static DEVICE_ATTR(reset, S_IWUSR, NULL, mmc3x30_reset_store); - static struct attribute *mmc3x30_attributes[] = { &dev_attr_otp.attr, &dev_attr_value.attr, @@ -1031,7 +1031,8 @@ static const struct attribute_group mmc3x30_attr_group = { }; -static int mmc3x30_probe(struct i2c_client *client, const struct i2c_device_id *id) +static int mmc3x30_probe(struct i2c_client *client, + const struct i2c_device_id *id) { int res = 0; struct mmc3x30_data *memsic; @@ -1053,7 +1054,7 @@ static int mmc3x30_probe(struct i2c_client *client, const struct i2c_device_id * } mmc3x30_data_struct = memsic; - + if (client->dev.of_node) { res = mmc3x30_parse_dt(client, memsic); if (res) { @@ -1079,7 +1080,7 @@ static int mmc3x30_probe(struct i2c_client *client, const struct i2c_device_id * res = PTR_ERR(memsic->regmap); goto out; } - + res = mmc3x30_power_init(memsic); if (res) { dev_err(&client->dev, "Power up mmc3x30 failed\n"); @@ -1115,11 +1116,11 @@ static int mmc3x30_probe(struct i2c_client *client, const struct i2c_device_id * } #ifdef INIT_SET res = mmc3x30_device_initial(memsic); - if(res){ + if (res) { pr_err("mmc3x30_device initial failed\n"); } else{ - printk("mmc3x30_device initial OK\n"); + pr_info("mmc3x30_device initial OK\n"); } #endif @@ -1137,10 +1138,10 @@ static int mmc3x30_probe(struct i2c_client *client, const struct i2c_device_id * } memsic->poll_interval = MMC3X30_DEFAULT_INTERVAL_MS; - + /* create sysfs group */ res = sysfs_create_group(&client->dev.kobj, &mmc3x30_attr_group); - if (res){ + if (res) { res = -EROFS; dev_err(&client->dev,"Unable to creat sysfs group\n"); } @@ -1173,7 +1174,7 @@ static int mmc3x30_remove(struct i2c_client *client) if (memsic->idev) input_unregister_device(memsic->idev); - sysfs_remove_group(&client->dev.kobj, &mmc3x30_attr_group); + sysfs_remove_group(&client->dev.kobj, &mmc3x30_attr_group); return 0; } diff --git a/include/linux/i2c/mmc3x30.h b/include/linux/i2c/mmc3x30.h old mode 100755 new mode 100644 index a764d32553e65..38a78c83c4ef0 --- a/include/linux/i2c/mmc3x30.h +++ b/include/linux/i2c/mmc3x30.h @@ -42,7 +42,7 @@ //MEMSIC MMC36XX REG #define MMC36XX_REG_TMPT 0x06 -#define MMC36XX_REG_STATUS 0x07 +#define MMC36XX_REG_STATUS 0x07 #define MMC36XX_REG_CTRL0 0x08 #define MMC36XX_REG_CTRL1 0x09 #define MMC36XX_REG_CTRL2 0x0A @@ -57,49 +57,49 @@ #define MMC36XX_REG_ID 0x2F //MEMSIC MMC35XX CMD -#define MMC35XX_SINGLE_TM 0x01 -#define MMC35XX_BW_16BIT_SLOW 0x00 -#define MMC35XX_BW_16BIT_FAST 0x01 -#define MMC35XX_BW_14BIT 0x02 -#define MMC35XX_CONT_MODE 0x02 -#define MMC35XX_CONT_FREQ_50HZ 0x00 -#define MMC35XX_CONT_FREQ_25HZ 0x04 -#define MMC35XX_CONT_FREQ_12HZ 0x08 -#define MMC35XX_CONT_FREQ_1_5HZ 0x0C +#define MMC35XX_SINGLE_TM 0x01 +#define MMC35XX_BW_16BIT_SLOW 0x00 +#define MMC35XX_BW_16BIT_FAST 0x01 +#define MMC35XX_BW_14BIT 0x02 +#define MMC35XX_CONT_MODE 0x02 +#define MMC35XX_CONT_FREQ_50HZ 0x00 +#define MMC35XX_CONT_FREQ_25HZ 0x04 +#define MMC35XX_CONT_FREQ_12HZ 0x08 +#define MMC35XX_CONT_FREQ_1_5HZ 0x0C //MEMSIC MMC36XX CMD -#define MMC36XX_OTP_OPEN0 0xE1 -#define MMC36XX_OTP_OPEN1 0x11 -#define MMC36XX_OTP_OPEN2 0x80 -#define MMC36XX_SINGLE_TM 0x01 -#define MMC36XX_SINGLE_TMPT 0x02 -#define MMC36XX_BW_16BIT_100HZ 0x00 -#define MMC36XX_BW_16BIT_200HZ 0x01 -#define MMC36XX_BW_16BIT_400HZ 0x02 -#define MMC36XX_BW_16BIT_600HZ 0x03 +#define MMC36XX_OTP_OPEN0 0xE1 +#define MMC36XX_OTP_OPEN1 0x11 +#define MMC36XX_OTP_OPEN2 0x80 +#define MMC36XX_SINGLE_TM 0x01 +#define MMC36XX_SINGLE_TMPT 0x02 +#define MMC36XX_BW_16BIT_100HZ 0x00 +#define MMC36XX_BW_16BIT_200HZ 0x01 +#define MMC36XX_BW_16BIT_400HZ 0x02 +#define MMC36XX_BW_16BIT_600HZ 0x03 /*MMC35XX RESET*/ -#define MMC35XX_FILLCAP 0x80 -#define MMC35XX_RESET 0x40 -#define MMC35XX_SET 0x20 -#define MMC35XX_NOBOOST 0x10 -#define MMC35XX_ST_XYZ 0x20 +#define MMC35XX_FILLCAP 0x80 +#define MMC35XX_RESET 0x40 +#define MMC35XX_SET 0x20 +#define MMC35XX_NOBOOST 0x10 +#define MMC35XX_ST_XYZ 0x20 /*MEMSIC MMC35XX Status */ -#define MMC35XX_STATUS_MEASURE_DONE 0x01 -#define MMC35XX_STATUS_CHARGE_PUMP 0x02 -#define MMC35XX_STATUS_ST_XYZ 0x08 +#define MMC35XX_STATUS_MEASURE_DONE 0x01 +#define MMC35XX_STATUS_CHARGE_PUMP 0x02 +#define MMC35XX_STATUS_ST_XYZ 0x08 /*MMC36XX RESET*/ -#define MMC36XX_FILLCAP 0x20 -#define MMC36XX_RESET 0x10 -#define MMC36XX_SET 0x08 -#define MMC36XX_ST_POST 0x02 -#define MMC36XX_ST_NEGT 0x04 -#define MMC36XX_ST_DEFAULT 0x00 -#define MMC36XX_ST_DELTA_VALUE 100 +#define MMC36XX_FILLCAP 0x20 +#define MMC36XX_RESET 0x10 +#define MMC36XX_SET 0x08 +#define MMC36XX_ST_POST 0x02 +#define MMC36XX_ST_NEGT 0x04 +#define MMC36XX_ST_DEFAULT 0x00 +#define MMC36XX_ST_DELTA_VALUE 100 /*MEMSIC MMC36XX Status */ #define MMC36XX_STATUS_MEASURE_DONE 0x01 -#define MMC36XX_STATUS_CHARGE_PUMP 0x08 +#define MMC36XX_STATUS_CHARGE_PUMP 0x08 /*DEVICE ID*/ #define MMC3524_DEVICE_ID 0x08 @@ -110,30 +110,30 @@ /* Use 'm' as magic number */ #define MMC3X30_IOM 'm' /* IOCTLs for MMC3X30 device */ -#define MMC3X30_IOC_TM _IO (MMC3X30_IOM, 0x00) -#define MMC3X30_IOC_SET _IO (MMC3X30_IOM, 0x01) -#define MMC3X30_IOC_READ _IOR(MMC3X30_IOM, 0x02, int[3]) -#define MMC3X30_IOC_READXYZ _IOR(MMC3X30_IOM, 0x03, int[3]) -#define MMC3X30_IOC_RESET _IO (MMC3X30_IOM, 0x04) -#define MMC3X30_IOC_NOBOOST _IO (MMC3X30_IOM, 0x05) -#define MMC3X30_IOC_ID _IOR(MMC3X30_IOM, 0x06, short) -#define MMC3X30_IOC_DIAG _IOR(MMC3X30_IOM, 0x14, int[1]) -#define MMC3X30_IOC_READ_REG _IOWR(MMC3X30_IOM, 0x15, unsigned char) -#define MMC3X30_IOC_WRITE_REG _IOW(MMC3X30_IOM, 0x16, unsigned char[2]) -#define MMC3X30_IOC_READ_REGS _IOWR(MMC3X30_IOM, 0x17, unsigned char[10]) -#define MMC3X30_IOC_WRITE_REGS _IOW(MMC3X30_IOM, 0x18, unsigned char[10]) +#define MMC3X30_IOC_TM _IO(MMC3X30_IOM, 0x00) +#define MMC3X30_IOC_SET _IO(MMC3X30_IOM, 0x01) +#define MMC3X30_IOC_READ _IOR(MMC3X30_IOM, 0x02, int[3]) +#define MMC3X30_IOC_READXYZ _IOR(MMC3X30_IOM, 0x03, int[3]) +#define MMC3X30_IOC_RESET _IO(MMC3X30_IOM, 0x04) +#define MMC3X30_IOC_NOBOOST _IO(MMC3X30_IOM, 0x05) +#define MMC3X30_IOC_ID _IOR(MMC3X30_IOM, 0x06, short) +#define MMC3X30_IOC_DIAG _IOR(MMC3X30_IOM, 0x14, int[1]) +#define MMC3X30_IOC_READ_REG _IOWR(MMC3X30_IOM, 0x15, unsigned char) +#define MMC3X30_IOC_WRITE_REG _IOW(MMC3X30_IOM, 0x16, unsigned char[2]) +#define MMC3X30_IOC_READ_REGS _IOWR(MMC3X30_IOM, 0x17, unsigned char[10]) +#define MMC3X30_IOC_WRITE_REGS _IOW(MMC3X30_IOM, 0x18, unsigned char[10]) #ifdef CONFIG_COMPAT /* IOCTLs for MMC3X30 device */ -#define COMPAT_MMC3X30_IOC_TM _IO (MMC3X30_IOM, 0x00) -#define COMPAT_MMC3X30_IOC_SET _IO (MMC3X30_IOM, 0x01) -#define COMPAT_MMC3X30_IOC_READ _IOR(MMC3X30_IOM, 0x02, int[3]) -#define COMPAT_MMC3X30_IOC_READXYZ _IOR(MMC3X30_IOM, 0x03, int[3]) -#define COMPAT_MMC3X30_IOC_RESET _IO (MMC3X30_IOM, 0x04) -#define COMPAT_MMC3X30_IOC_NOBOOST _IO (MMC3X30_IOM, 0x05) +#define COMPAT_MMC3X30_IOC_TM _IO(MMC3X30_IOM, 0x00) +#define COMPAT_MMC3X30_IOC_SET _IO(MMC3X30_IOM, 0x01) +#define COMPAT_MMC3X30_IOC_READ _IOR(MMC3X30_IOM, 0x02, int[3]) +#define COMPAT_MMC3X30_IOC_READXYZ _IOR(MMC3X30_IOM, 0x03, int[3]) +#define COMPAT_MMC3X30_IOC_RESET _IO(MMC3X30_IOM, 0x04) +#define COMPAT_MMC3X30_IOC_NOBOOST _IO(MMC3X30_IOM, 0x05) #define COMPAT_MMC3X30_IOC_ID _IOR(MMC3X30_IOM, 0x06, short) #define COMPAT_MMC3X30_IOC_DIAG _IOR(MMC3X30_IOM, 0x14, int[1]) -#define COMPAT_MMC3X30_IOC_READ_REG _IOWR(MMC3X30_IOM, 0x15, unsigned char) +#define COMPAT_MMC3X30_IOC_READ_REG _IOWR(MMC3X30_IOM, 0x15, unsigned char) #define COMPAT_MMC3X30_IOC_WRITE_REG _IOW(MMC3X30_IOM, 0x16, unsigned char[2]) #define COMPAT_MMC3X30_IOC_READ_REGS _IOWR(MMC3X30_IOM, 0x17, unsigned char[10]) #define COMPAT_MMC3X30_IOC_WRITE_REGS _IOW(MMC3X30_IOM, 0x18, unsigned char[10]) From e16b0696ebb06f776d82bd5cbaf28a8f02111a07 Mon Sep 17 00:00:00 2001 From: Shaoqing Liu Date: Mon, 29 Aug 2016 19:46:32 +0800 Subject: [PATCH 231/320] Enable bmi160,mmc3x30 and stk3x1x sensor for msm8909 Enable bmi160,mmc3x30 and stk3x1x sensor for msm8909 QRD SKUQ board. Change-Id: I03805d5f1c62110a5050c91e894a06e7f0582cd2 Signed-off-by: Shaoqing Liu --- arch/arm/configs/msm8909-1gb-perf_defconfig | 8 ++++++++ arch/arm/configs/msm8909-1gb_defconfig | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/arch/arm/configs/msm8909-1gb-perf_defconfig b/arch/arm/configs/msm8909-1gb-perf_defconfig index 3163de0b95dcb..677d4eb451ead 100644 --- a/arch/arm/configs/msm8909-1gb-perf_defconfig +++ b/arch/arm/configs/msm8909-1gb-perf_defconfig @@ -319,10 +319,18 @@ CONFIG_APDS9930=y CONFIG_SENSORS_LTR553=y CONFIG_SENSORS_MPU6050=y CONFIG_SENSORS_MMC3416X=y +CONFIG_SENSORS_MMC3X30=y CONFIG_SENSORS_AKM8963=y CONFIG_SENSORS_AKM09911=y CONFIG_SENSORS_BMA2X2=y CONFIG_SENSORS_AP3426=y +CONFIG_SENSORS_STK3X1X=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_SENSORS_BMI160=y +CONFIG_SENSORS_BMI160_I2C=y +# CONFIG_BMI160_MAG_INTERFACE_SUPPORT is not set +CONFIG_SENSORS_BMI160_ENABLE_INT1=y +# CONFIG_SENSORS_BMI160_ENABLE_INT2 is not set CONFIG_SENSORS_HALL=y #CONFIG_SERIAL_MSM_HSL is not set #CONFIG_SERIAL_MSM_HSL_CONSOLE is not set diff --git a/arch/arm/configs/msm8909-1gb_defconfig b/arch/arm/configs/msm8909-1gb_defconfig index 529d1cea2bf00..f69782554ad75 100644 --- a/arch/arm/configs/msm8909-1gb_defconfig +++ b/arch/arm/configs/msm8909-1gb_defconfig @@ -326,10 +326,18 @@ CONFIG_APDS9930=y CONFIG_SENSORS_LTR553=y CONFIG_SENSORS_MPU6050=y CONFIG_SENSORS_MMC3416X=y +CONFIG_SENSORS_MMC3X30=y CONFIG_SENSORS_AKM8963=y CONFIG_SENSORS_AKM09911=y CONFIG_SENSORS_BMA2X2=y CONFIG_SENSORS_AP3426=y +CONFIG_SENSORS_STK3X1X=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_SENSORS_BMI160=y +CONFIG_SENSORS_BMI160_I2C=y +# CONFIG_BMI160_MAG_INTERFACE_SUPPORT is not set +CONFIG_SENSORS_BMI160_ENABLE_INT1=y +# CONFIG_SENSORS_BMI160_ENABLE_INT2 is not set CONFIG_SENSORS_HALL=y CONFIG_SERIAL_MSM_HSL=y CONFIG_SERIAL_MSM_HSL_CONSOLE=y From a0b95ba8b9f96fc9920a17585c548ec509a64897 Mon Sep 17 00:00:00 2001 From: Shaoqing Liu Date: Fri, 8 Jul 2016 13:19:41 +0800 Subject: [PATCH 232/320] ARM: dts: msm: Add sensor dts nodes for msm8909 QRD SKUQ board Add bmi160,mmc3x30 and stk3x1x sensor dts nodes for QSIP msm8909 QRD SKUQ board Change-Id: I270d799be1ef154897218f82a8961ce503f4e18f Signed-off-by: Shaoqing Liu Signed-off-by: c_yinbin --- .../dts/qcom/msm8909-pm8916-qrd-skuq.dtsi | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi index 4030bfc1d7b1e..840f4706723a4 100644 --- a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi +++ b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi @@ -22,6 +22,19 @@ <300 0>; }; +&tlmm_pinmux { + bmi160_int1_pin { + qcom,pins = <&gp 96>; + qcom,num-grp-pins = <1>; + label = "bmi160_int1_pin"; + bmi160_int1_default: int1_default { + drive-strength = <6>; + bias-pull-up; + }; + }; + +}; + &pm8916_chg { status = "ok"; }; @@ -123,6 +136,49 @@ debounce-interval = <15>; }; }; + + i2c@78b5000 { + bosch@68 { /* Accelerometer and gyroscope sensor */ + compatible = "bosch,bmi160"; + reg = <0x68>; + pinctrl-names = "default"; + pinctrl-0 = <&bmi160_int1_default>; + interrupt-parent = <&msm_gpio>; + interrupts = <96 0x2002>; + vdd-supply = <&pm8916_l17>; + vio-supply = <&pm8916_l6>; + bosch,place = <5>; + bosch,gpio-int1 = <&msm_gpio 96 0x2002>; + }; + + memsic@30 { /* Magnetic field sensor */ + compatible = "memsic,mmc3x30"; + reg = <0x30>; + vdd-supply = <&pm8916_l17>; + vio-supply = <&pm8916_l6>; + memsic,dir = "obverse-x-axis-forward"; + memsic,auto-report; + }; + + stk@48 { + compatible = "stk,stk3x1x"; + reg = <0x48>; + interrupt-parent = <&msm_gpio>; + interrupts = <80 0x2>; + vdd-supply = <&pm8916_l17>; + vio-supply = <&pm8916_l6>; + stk,irq-gpio = <&msm_gpio 80 0x02>; + stk,transmittance = <340>; + stk,state-reg = <0x00>; + stk,psctrl-reg = <0x71>; + stk,alsctrl-reg = <0x38>; + stk,ledctrl-reg = <0xFF>; + stk,wait-reg = <0x07>; + stk,ps-thdh = <150>; + stk,ps-thdl = <100>; + stk,use-fir; + }; + }; }; &pm8916_mpps { From f61026c44364365698aa8b2af7f25504905b9d90 Mon Sep 17 00:00:00 2001 From: VijayaKumar T M Date: Wed, 31 Aug 2016 16:39:36 +0530 Subject: [PATCH 233/320] msm: sensor: Avoid potential stack overflow Add a check to validate the user input data is not greater than expected stack buffer size to avoid out of bounds array accesses CRs-Fixed: 1056307 Change-Id: I8b31006772367a120828269243b1971d33a4d7d3 Signed-off-by: VijayaKumar T M --- .../platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c | 8 +++++++- .../platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c index 47c3649860975..edc40c95ee6e6 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -234,6 +234,12 @@ int32_t msm_camera_cci_i2c_write_seq_table( client_addr_type = client->addr_type; client->addr_type = write_setting->addr_type; + if (reg_setting->reg_data_size > I2C_SEQ_REG_DATA_MAX) { + pr_err("%s: number of bytes %u exceeding the max supported %d\n", + __func__, reg_setting->reg_data_size, I2C_SEQ_REG_DATA_MAX); + return rc; + } + for (i = 0; i < write_setting->size; i++) { rc = msm_camera_cci_i2c_write_seq(client, reg_setting->reg_addr, reg_setting->reg_data, reg_setting->reg_data_size); diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c index 3177e1f1931bd..a40c84eb53dea 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011, 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011, 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -516,6 +516,12 @@ int32_t msm_camera_qup_i2c_write_seq_table(struct msm_camera_i2c_client *client, client_addr_type = client->addr_type; client->addr_type = write_setting->addr_type; + if (reg_setting->reg_data_size > I2C_SEQ_REG_DATA_MAX) { + pr_err("%s: number of bytes %u exceeding the max supported %d\n", + __func__, reg_setting->reg_data_size, I2C_SEQ_REG_DATA_MAX); + return rc; + } + for (i = 0; i < write_setting->size; i++) { rc = msm_camera_qup_i2c_write_seq(client, reg_setting->reg_addr, reg_setting->reg_data, reg_setting->reg_data_size); From 1f57e7cc512cebf0c17f34094ac6aa2f0bead9bd Mon Sep 17 00:00:00 2001 From: Ashwanth Goli Date: Fri, 26 Aug 2016 15:03:49 +0530 Subject: [PATCH 234/320] rmnet_data: Changing format specifier to %pK Using %pK instead of %p to hide kernel pointers based on kptr_restrict. Change-Id: I065cff2a9e092d74d0e8c35da6551fab3805e83e Signed-off-by: Ashwanth Goli --- net/rmnet_data/rmnet_data_vnd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/rmnet_data/rmnet_data_vnd.c b/net/rmnet_data/rmnet_data_vnd.c index ef8b8a62a3a88..f6ef21464850c 100644 --- a/net/rmnet_data/rmnet_data_vnd.c +++ b/net/rmnet_data/rmnet_data_vnd.c @@ -921,7 +921,7 @@ int rmnet_vnd_add_tc_flow(uint32_t id, uint32_t map_flow, uint32_t tc_flow) list_add(&(itm->list), &(dev_conf->flow_head)); write_unlock_irqrestore(&dev_conf->flow_map_lock, flags); - LOGD("Created flow mapping [%s][0x%08X][0x%08X]@%p", + LOGD("Created flow mapping [%s][0x%08X][0x%08X]@%pK", dev->name, itm->map_flow_id, itm->tc_flow_id[0], itm); return RMNET_CONFIG_OK; From 3b8d787fc5738cc9493cc36e95f058f1a528a2fc Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Mon, 25 Apr 2016 15:52:05 -0700 Subject: [PATCH 235/320] BACKPORT: f2fs: add a max block check for get_data_block_bmap (cherry pick from commit 179448bfe4cd201e98e728391c6b01b25c849fe8) This patch adds a max block check for get_data_block_bmap. Trinity test program will send a block number as parameter into ioctl_fibmap, which will be used in get_node_path(), when the block number large than f2fs max blocks, it will trigger kernel bug. Signed-off-by: Yunlei He Signed-off-by: Xue Liu [Jaegeuk Kim: fix missing condition, pointed by Chao Yu] Signed-off-by: Jaegeuk Kim Bug: 28271368 Change-Id: Ia5acae04522993d5b60a0bcb5ccc184c66532be8 Git-commit: 3c714201e02ec08652be4b9544a5267e79bde3a9 Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: Srinivasarao P --- fs/f2fs/data.c | 11 ++++++++++- fs/f2fs/f2fs.h | 1 + fs/f2fs/super.c | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 91ff93b0b0f40..96234982c26f2 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -445,6 +445,15 @@ static int get_data_block_ro(struct inode *inode, sector_t iblock, return 0; } +static int get_data_block_bmap(struct inode *inode, sector_t iblock, + struct buffer_head *bh_result, int create) +{ + /* Block number less than F2FS MAX BLOCKS */ + if (unlikely(iblock >= max_file_size(0))) + return -EFBIG; + return get_data_block_ro(inode, iblock, bh_result, create); +} + static int f2fs_read_data_page(struct file *file, struct page *page) { return mpage_readpage(page, get_data_block_ro); @@ -731,7 +740,7 @@ static int f2fs_set_data_page_dirty(struct page *page) static sector_t f2fs_bmap(struct address_space *mapping, sector_t block) { - return generic_block_bmap(mapping, block, get_data_block_ro); + return generic_block_bmap(mapping, block, get_data_block_bmap); } const struct address_space_operations f2fs_dblock_aops = { diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 20aab02f2a427..8aeea5dbce5ad 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -928,6 +928,7 @@ static inline int f2fs_add_link(struct dentry *dentry, struct inode *inode) /* * super.c */ +loff_t max_file_size(unsigned bits); int f2fs_sync_fs(struct super_block *, int); extern __printf(3, 4) void f2fs_msg(struct super_block *, const char *, const char *, ...); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 8555f7df82c79..f9806eef6a1a4 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -376,7 +376,7 @@ static int parse_options(struct super_block *sb, struct f2fs_sb_info *sbi, return 0; } -static loff_t max_file_size(unsigned bits) +loff_t max_file_size(unsigned bits) { loff_t result = ADDRS_PER_INODE; loff_t leaf_count = ADDRS_PER_BLOCK; From 75cbc880b7ea168f9953ee83801da4329f7ce498 Mon Sep 17 00:00:00 2001 From: Siena Richard Date: Tue, 16 Aug 2016 13:03:56 -0700 Subject: [PATCH 236/320] misc: qcom: qdsp6v2: initialize wma_config_32 Not all memebers of wma_config_32 are set before they are used which might lead to invalid values being passed and used. To fix this issue initialize all member variables of struct wma_config_32 to 0 before assigning specific values individually. Change-Id: Ibb082ce691625527e9a9ffd4978dea7ba4df9e84 CRs-Fixed: 1054352 Signed-off-by: Siena Richard --- drivers/misc/qcom/qdsp6v2/audio_wma.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/misc/qcom/qdsp6v2/audio_wma.c b/drivers/misc/qcom/qdsp6v2/audio_wma.c index 98779373ac4c3..cb5a9b1c3157b 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_wma.c +++ b/drivers/misc/qcom/qdsp6v2/audio_wma.c @@ -162,6 +162,8 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_wma_config_v2 *wma_config; struct msm_audio_wma_config_v2_32 wma_config_32; + memset(&wma_config_32, 0, sizeof(wma_config_32)); + wma_config = (struct msm_audio_wma_config_v2 *)audio->codec_cfg; wma_config_32.format_tag = wma_config->format_tag; wma_config_32.numchannels = wma_config->numchannels; From 1f95390564f6a1827d9912075a64a2374ae0d0c4 Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Fri, 20 Jun 2014 12:45:54 -0700 Subject: [PATCH 237/320] kthread: Fix the race condition when kthread is parked While stressing the CPU hotplug path, sometimes we hit a problem as shown below. [57056.416774] ------------[ cut here ]------------ [57056.489232] ksoftirqd/1 (14): undefined instruction: pc=c01931e8 [57056.489245] Code: e594a000 eb085236 e15a0000 0a000000 (e7f001f2) [57056.489259] ------------[ cut here ]------------ [57056.492840] kernel BUG at kernel/kernel/smpboot.c:134! [57056.513236] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM [57056.519055] Modules linked in: wlan(O) mhi(O) [57056.523394] CPU: 0 PID: 14 Comm: ksoftirqd/1 Tainted: G W O 3.10.0-g3677c61-00008-g180c060 #1 [57056.532595] task: f0c8b000 ti: f0e78000 task.ti: f0e78000 [57056.537991] PC is at smpboot_thread_fn+0x124/0x218 [57056.542750] LR is at smpboot_thread_fn+0x11c/0x218 [57056.547528] pc : [] lr : [] psr: 200f0013 [57056.547528] sp : f0e79f30 ip : 00000000 fp : 00000000 [57056.558983] r10: 00000001 r9 : 00000000 r8 : f0e78000 [57056.564192] r7 : 00000001 r6 : c1195758 r5 : f0e78000 r4 : f0e5fd00 [57056.570701] r3 : 00000001 r2 : f0e79f20 r1 : 00000000 r0 : 00000000 This issue was always seen in the context of "ksoftirqd". It seems to be happening because of a potential race condition in __kthread_parkme where just after completing the parked completion, before the ksoftirqd task has been scheduled again, it can go into running state. Fix this by waiting for the task state to parked after waiting the parked completion. CRs-Fixed: 659674 Change-Id: If3f0e9b706eeb5d30d5a32f84378d35bb03fe794 Signed-off-by: Subbaraman Narayanamurthy --- kernel/kthread.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/kthread.c b/kernel/kthread.c index 760e86df8c204..c56c6f8ec6078 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -398,6 +398,8 @@ int kthread_park(struct task_struct *k) if (k != current) { wake_up_process(k); wait_for_completion(&kthread->parked); + while (k->state != TASK_PARKED) + cond_resched(); } } ret = 0; From 7ac94b6c3ae94b118923ec699103b53382ab220c Mon Sep 17 00:00:00 2001 From: Archana Sathyakumar Date: Mon, 22 Aug 2016 15:20:02 -0600 Subject: [PATCH 238/320] msm-core: debug: Update the number of supported pstates Update the number of power-freq pair value supported in the debug interface. Parse the arguments as uint32_t instead of uint64_t which might cause memory corruption. CRs-fixed: 1054344 Change-Id: I30492b79b96356177cdcc72e4e2ee656317de500 Signed-off-by: Archana Sathyakumar --- drivers/power/qcom/debug_core.c | 51 ++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/drivers/power/qcom/debug_core.c b/drivers/power/qcom/debug_core.c index e1375ff95ee53..f0333cbcbf491 100644 --- a/drivers/power/qcom/debug_core.c +++ b/drivers/power/qcom/debug_core.c @@ -83,15 +83,28 @@ static struct debugfs_blob_wrapper help_msg = { }; -static void add_to_ptable(uint64_t *arg) +static void add_to_ptable(unsigned int *arg) { struct core_debug *node; int i, cpu = arg[CPU_OFFSET]; + uint32_t freq = arg[FREQ_OFFSET]; + uint32_t power = arg[POWER_OFFSET]; if (!cpu_possible(cpu)) return; + if ((freq == 0) || (power == 0)) { + pr_warn("Incorrect power data\n"); + return; + } + node = &per_cpu(c_dgfs, cpu); + + if (node->len >= MAX_PSTATES) { + pr_warn("Dropped ptable update - no space left.\n"); + return; + } + if (!node->head) { node->head = kzalloc(sizeof(struct cpu_pstate_pwr) * (MAX_PSTATES + 1), @@ -99,24 +112,18 @@ static void add_to_ptable(uint64_t *arg) if (!node->head) return; } - for (i = 0; i < MAX_PSTATES; i++) { - if (node->head[i].freq == arg[FREQ_OFFSET]) { - node->head[i].power = arg[POWER_OFFSET]; + + for (i = 0; i < node->len; i++) { + if (node->head[i].freq == freq) { + node->head[i].power = power; return; } - if (node->head[i].freq == 0) - break; - } - - if (i == MAX_PSTATES) { - pr_warn("Dropped ptable update - no space left.\n"); - return; } /* Insert a new frequency (may need to move things around to keep in ascending order). */ for (i = MAX_PSTATES - 1; i > 0; i--) { - if (node->head[i-1].freq > arg[FREQ_OFFSET]) { + if (node->head[i-1].freq > freq) { node->head[i].freq = node->head[i-1].freq; node->head[i].power = node->head[i-1].power; } else if (node->head[i-1].freq != 0) { @@ -124,15 +131,17 @@ static void add_to_ptable(uint64_t *arg) } } - node->head[i].freq = arg[FREQ_OFFSET]; - node->head[i].power = arg[POWER_OFFSET]; - node->len++; + if (node->len < MAX_PSTATES) { + node->head[i].freq = freq; + node->head[i].power = power; + node->len++; + } if (node->ptr) node->ptr->len = node->len; } -static int split_ptable_args(char *line, uint64_t *arg, uint32_t n) +static int split_ptable_args(char *line, unsigned int *arg, uint32_t n) { char *args; int i; @@ -142,7 +151,9 @@ static int split_ptable_args(char *line, uint64_t *arg, uint32_t n) if (!line) break; args = strsep(&line, " "); - ret = kstrtoull(args, 10, &arg[i]); + ret = kstrtouint(args, 10, &arg[i]); + if (ret) + return ret; } return ret; } @@ -152,7 +163,7 @@ static ssize_t msm_core_ptable_write(struct file *file, { char *kbuf; int ret; - uint64_t arg[3]; + unsigned int arg[3]; if (len == 0) return 0; @@ -204,7 +215,7 @@ static int msm_core_ptable_read(struct seq_file *m, void *data) seq_printf(m, "--- CPU%d - Live numbers at %ldC---\n", cpu, node->ptr->temp); print_table(m, msm_core_data[cpu].ptable, - msm_core_data[cpu].len); + node->driver_len); } } return 0; @@ -215,7 +226,7 @@ static ssize_t msm_core_enable_write(struct file *file, { char *kbuf; int ret; - uint64_t arg[3]; + unsigned int arg[3]; int cpu; if (len == 0) From 152497e88fbe81ccb881fe732d78c943a7b35cbe Mon Sep 17 00:00:00 2001 From: Walter Yang Date: Wed, 27 Jul 2016 15:07:53 +0800 Subject: [PATCH 239/320] ASoC: msm: set pointers to NULL after kfree In lsm-related driver files, some pointers are not set as NULL after the memory is freed, which will leave many dangling pointers. Set them to NULL explicitly to avoid potential risk. CRs-Fixed: 880388 Change-Id: I44925240705608510266a51225cc02611637c571 Signed-off-by: Walter Yang --- sound/soc/msm/msm-cpe-lsm.c | 7 +++++++ sound/soc/msm/qdsp6v2/msm-dai-slim.c | 2 ++ sound/soc/msm/qdsp6v2/q6lsm.c | 1 + 3 files changed, 10 insertions(+) diff --git a/sound/soc/msm/msm-cpe-lsm.c b/sound/soc/msm/msm-cpe-lsm.c index b9c7784fca4ac..d7153eadec1ff 100644 --- a/sound/soc/msm/msm-cpe-lsm.c +++ b/sound/soc/msm/msm-cpe-lsm.c @@ -1170,6 +1170,7 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: No memory for sound model\n", __func__); kfree(session->conf_levels); + session->conf_levels = NULL; return -ENOMEM; } session->snd_model_size = snd_model.data_size; @@ -1181,6 +1182,8 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream, __func__); kfree(session->conf_levels); kfree(session->snd_model_data); + session->conf_levels = NULL; + session->snd_model_data = NULL; return -EFAULT; } @@ -1192,6 +1195,8 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream, __func__, rc); kfree(session->snd_model_data); kfree(session->conf_levels); + session->snd_model_data = NULL; + session->conf_levels = NULL; return rc; } @@ -1205,6 +1210,8 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream, lsm_ops->lsm_shmem_dealloc(cpe->core_handle, session); kfree(session->snd_model_data); kfree(session->conf_levels); + session->snd_model_data = NULL; + session->conf_levels = NULL; return rc; } diff --git a/sound/soc/msm/qdsp6v2/msm-dai-slim.c b/sound/soc/msm/qdsp6v2/msm-dai-slim.c index a93dfa6ec853c..618da977ef1ef 100644 --- a/sound/soc/msm/qdsp6v2/msm-dai-slim.c +++ b/sound/soc/msm/qdsp6v2/msm-dai-slim.c @@ -446,7 +446,9 @@ static void msm_dai_slim_remove_dai_data( dai_data_t = &drv_data->slim_dai_data[i]; kfree(dai_data_t->chan_h); + dai_data_t->chan_h = NULL; kfree(dai_data_t->sh_ch); + dai_data_t->sh_ch = NULL; } } diff --git a/sound/soc/msm/qdsp6v2/q6lsm.c b/sound/soc/msm/qdsp6v2/q6lsm.c index cde790a432791..29d0ba3f2ca12 100644 --- a/sound/soc/msm/qdsp6v2/q6lsm.c +++ b/sound/soc/msm/qdsp6v2/q6lsm.c @@ -347,6 +347,7 @@ void q6lsm_client_free(struct lsm_client *client) q6lsm_mmap_apr_dereg(); mutex_destroy(&client->cmd_lock); kfree(client); + client = NULL; } /* From cca0739c2812850b4811ffe92c77c8d09aa5ca33 Mon Sep 17 00:00:00 2001 From: Abhijit Kulkarni Date: Wed, 15 Jun 2016 10:30:50 -0700 Subject: [PATCH 240/320] msm: mdss: hide kernel addresses from unprevileged users for printing kernel pointers which should be hidden from unprivileged users, use %pK which evaluates whether kptr_restrict is set. CRs-Fixed: 987021 Change-Id: Ie49eee9478f4657cfb2a994ba60da1ec4c356339 Signed-off-by: Abhijit Kulkarni Signed-off-by: Nirmal Abraham --- drivers/video/msm/mdss/mdp3.c | 16 ++++++++-------- drivers/video/msm/mdss/mdp3_ppp_hwio.c | 8 +++++--- drivers/video/msm/mdss/mdss_debug.c | 8 ++++---- drivers/video/msm/mdss/mdss_dsi.c | 14 +++++++------- drivers/video/msm/mdss/mdss_dsi_host.c | 2 +- drivers/video/msm/mdss/mdss_dsi_panel.c | 12 ++++++------ drivers/video/msm/mdss/mdss_fb.c | 6 +++--- drivers/video/msm/mdss/mdss_hdmi_tx.c | 6 +++--- drivers/video/msm/mdss/mdss_hdmi_util.c | 4 ++-- drivers/video/msm/mdss/mdss_mdp.c | 4 ++-- drivers/video/msm/mdss/mdss_mdp_debug.c | 6 +++--- drivers/video/msm/mdss/mdss_mdp_intf_cmd.c | 6 +++--- drivers/video/msm/mdss/mdss_mdp_intf_video.c | 6 +++--- drivers/video/msm/mdss/mdss_mdp_pipe.c | 2 +- drivers/video/msm/mdss/mdss_mdp_pp.c | 14 +++++++------- drivers/video/msm/mdss/mdss_mdp_util.c | 8 ++++---- drivers/video/msm/mdss/mdss_mdp_wb.c | 10 +++++----- drivers/video/msm/mdss/mdss_util.c | 5 ++--- 18 files changed, 69 insertions(+), 68 deletions(-) diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c index 2a9c9156ac5e1..521eb7e59e9f2 100644 --- a/drivers/video/msm/mdss/mdp3.c +++ b/drivers/video/msm/mdss/mdp3.c @@ -1096,7 +1096,7 @@ static int mdp3_res_init(void) mdp3_res->ion_client = msm_ion_client_create(mdp3_res->pdev->name); if (IS_ERR_OR_NULL(mdp3_res->ion_client)) { - pr_err("msm_ion_client_create() return error (%p)\n", + pr_err("msm_ion_client_create() return error (%pK)\n", mdp3_res->ion_client); mdp3_res->ion_client = NULL; return -EINVAL; @@ -1528,7 +1528,7 @@ void mdp3_unmap_iommu(struct ion_client *client, struct ion_handle *handle) mutex_lock(&mdp3_res->iommu_lock); meta = mdp3_iommu_meta_lookup(table); if (!meta) { - WARN(1, "%s: buffer was never mapped for %p\n", __func__, + WARN(1, "%s: buffer was never mapped for %pK\n", __func__, handle); mutex_unlock(&mdp3_res->iommu_lock); goto out; @@ -1556,7 +1556,7 @@ static void mdp3_iommu_meta_add(struct mdp3_iommu_meta *meta) } else if (meta->table > entry->table) { p = &(*p)->rb_right; } else { - pr_err("%s: handle %p already exists\n", __func__, + pr_err("%s: handle %pK already exists\n", __func__, entry->handle); BUG(); } @@ -1618,7 +1618,7 @@ static int mdp3_iommu_map_iommu(struct mdp3_iommu_meta *meta, ret = iommu_map_range(domain, meta->iova_addr + padding, table->sgl, size, prot); if (ret) { - pr_err("%s: could not map %pa in domain %p\n", + pr_err("%s: could not map %pa in domain %pK\n", __func__, &meta->iova_addr, domain); unmap_size = padding; goto out2; @@ -1741,12 +1741,12 @@ int mdp3_self_map_iommu(struct ion_client *client, struct ion_handle *handle, } } else { if (iommu_meta->flags != iommu_flags) { - pr_err("%s: handle %p is already mapped with diff flag\n", + pr_err("%s: handle %pK is already mapped with diff flag\n", __func__, handle); ret = -EINVAL; goto out_unlock; } else if (iommu_meta->mapped_size != iova_length) { - pr_err("%s: handle %p is already mapped with diff len\n", + pr_err("%s: handle %pK is already mapped with diff len\n", __func__, handle); ret = -EINVAL; goto out_unlock; @@ -1868,7 +1868,7 @@ int mdp3_get_img(struct msmfb_data *img, struct mdp3_img_data *data, int client) data->addr += img->offset; data->len -= img->offset; - pr_debug("mem=%d ihdl=%p buf=0x%pa len=0x%x\n", img->memory_id, + pr_debug("mem=%d ihdl=%pK buf=0x%pa len=0x%x\n", img->memory_id, data->srcp_ihdl, &data->addr, data->len); } else { mdp3_put_img(data, client); @@ -2101,7 +2101,7 @@ static int mdp3_alloc(struct msm_fb_data_type *mfd) return ret; } - pr_info("allocating %u bytes at %p (%lx phys) for fb %d\n", + pr_info("allocating %u bytes at %pK (%lx phys) for fb %d\n", size, virt, phys, mfd->index); mfd->fbi->screen_base = virt; diff --git a/drivers/video/msm/mdss/mdp3_ppp_hwio.c b/drivers/video/msm/mdss/mdp3_ppp_hwio.c index d8c4168e5ead1..43177262fc4b8 100644 --- a/drivers/video/msm/mdss/mdp3_ppp_hwio.c +++ b/drivers/video/msm/mdss/mdp3_ppp_hwio.c @@ -1291,7 +1291,8 @@ int config_ppp_op_mode(struct ppp_blit_op *blit_op) bg_mdp_ops = 0; } pr_debug("BLIT FG Param Fmt %d (x %d,y %d,w %d,h %d), ROI(x %d,y %d, w\ - %d, h %d) Addr_P0 %p, Stride S0 %d Addr_P1 %p, Stride S1 %d\n", + %d, h %d) Addr_P0 %pK, Stride S0 %d Addr_P1 %pK,\ + Stride S1 %d\n", blit_op->src.color_fmt, blit_op->src.prop.x, blit_op->src.prop.y, blit_op->src.prop.width, blit_op->src.prop.height, blit_op->src.roi.x, blit_op->src.roi.y, blit_op->src.roi.width, @@ -1299,14 +1300,15 @@ int config_ppp_op_mode(struct ppp_blit_op *blit_op) blit_op->src.p1, blit_op->src.stride1); if (blit_op->bg.p0 != blit_op->dst.p0) pr_debug("BLIT BG Param Fmt %d (x %d,y %d,w %d,h %d), ROI(x %d,y %d, w\ - %d, h %d) Addr %p, Stride S0 %d Addr_P1 %p, Stride S1 %d\n", + %d, h %d) Addr %pK, Stride S0 %d Addr_P1 %pK,\ + Stride S1 %d\n", blit_op->bg.color_fmt, blit_op->bg.prop.x, blit_op->bg.prop.y, blit_op->bg.prop.width, blit_op->bg.prop.height, blit_op->bg.roi.x, blit_op->bg.roi.y, blit_op->bg.roi.width, blit_op->bg.roi.height, blit_op->bg.p0, blit_op->bg.stride0, blit_op->bg.p1, blit_op->bg.stride1); pr_debug("BLIT FB Param Fmt %d (x %d,y %d,w %d,h %d), ROI(x %d,y %d, w\ - %d, h %d) Addr %p, Stride S0 %d Addr_P1 %p, Stride S1 %d\n", + %d, h %d) Addr %pK, Stride S0 %d Addr_P1 %pK, Stride S1 %d\n", blit_op->dst.color_fmt, blit_op->dst.prop.x, blit_op->dst.prop.y, blit_op->dst.prop.width, blit_op->dst.prop.height, blit_op->dst.roi.x, blit_op->dst.roi.y, blit_op->dst.roi.width, diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c index 3513540f0ae4b..15d7dea14558b 100644 --- a/drivers/video/msm/mdss/mdss_debug.c +++ b/drivers/video/msm/mdss/mdss_debug.c @@ -178,7 +178,7 @@ static ssize_t panel_debug_base_reg_write(struct file *file, for (i = 0; i < len; i++) { p = buf + i * 3; p[2] = 0; - pr_debug("p[%d] = %p:%s\n", i, p, p); + pr_debug("p[%d] = %pK:%s\n", i, p, p); cnt = sscanf(p, "%x", &tmp); reg[i] = tmp; pr_debug("reg[%d] = %x\n", i, (int)reg[i]); @@ -1072,7 +1072,7 @@ void mdss_dump_reg(char __iomem *base, int len) x4 = readl_relaxed(addr+0x4); x8 = readl_relaxed(addr+0x8); xc = readl_relaxed(addr+0xc); - pr_info("%p : %08x %08x %08x %08x\n", addr, x0, x4, x8, xc); + pr_info("%pK : %08x %08x %08x %08x\n", addr, x0, x4, x8, xc); addr += 16; } mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); @@ -1192,7 +1192,7 @@ static inline struct mdss_mdp_misr_map *mdss_misr_get_map(u32 block_id, return NULL; } - pr_debug("MISR Module(%d) CTRL(0x%x) SIG(0x%x) intf_base(0x%p)\n", + pr_debug("MISR Module(%d) CTRL(0x%x) SIG(0x%x) intf_base(0x%pK)\n", block_id, map->ctrl_reg, map->value_reg, intf_base); return map; } @@ -1235,7 +1235,7 @@ int mdss_misr_set(struct mdss_data_type *mdata, bool use_mdp_up_misr = false; if (!mdata || !req || !ctl) { - pr_err("Invalid input params: mdata = %p req = %p ctl = %p", + pr_err("Invalid input params: mdata = %pK req = %pK ctl = %pK", mdata, req, ctl); return -EINVAL; } diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c index 9d12dfb457d92..62c6f120b24f7 100644 --- a/drivers/video/msm/mdss/mdss_dsi.c +++ b/drivers/video/msm/mdss/mdss_dsi.c @@ -471,7 +471,7 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata, int power_state) panel_info = &ctrl_pdata->panel_data.panel_info; - pr_debug("%s+: ctrl=%p ndx=%d power_state=%d\n", + pr_debug("%s+: ctrl=%pK ndx=%d power_state=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx, power_state); if (power_state == panel_info->panel_power_state) { @@ -559,7 +559,7 @@ int mdss_dsi_on(struct mdss_panel_data *pdata) panel_data); cur_power_state = pdata->panel_info.panel_power_state; - pr_debug("%s+: ctrl=%p ndx=%d cur_power_state=%d\n", __func__, + pr_debug("%s+: ctrl=%pK ndx=%d cur_power_state=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx, cur_power_state); pinfo = &pdata->panel_info; @@ -703,7 +703,7 @@ static int mdss_dsi_unblank(struct mdss_panel_data *pdata) panel_data); mipi = &pdata->panel_info.mipi; - pr_debug("%s+: ctrl=%p ndx=%d cur_blank_state=%d\n", __func__, + pr_debug("%s+: ctrl=%pK ndx=%d cur_blank_state=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx, pdata->panel_info.blank_state); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); @@ -756,7 +756,7 @@ static int mdss_dsi_blank(struct mdss_panel_data *pdata, int power_state) panel_data); mipi = &pdata->panel_info.mipi; - pr_debug("%s+: ctrl=%p ndx=%d power_state=%d\n", + pr_debug("%s+: ctrl=%pK ndx=%d power_state=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx, power_state); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); @@ -826,7 +826,7 @@ static int mdss_dsi_post_panel_on(struct mdss_panel_data *pdata) ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s+: ctrl=%p ndx=%d\n", __func__, + pr_debug("%s+: ctrl=%pK ndx=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); @@ -858,7 +858,7 @@ int mdss_dsi_cont_splash_on(struct mdss_panel_data *pdata) ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s+: ctrl=%p ndx=%d\n", __func__, + pr_debug("%s+: ctrl=%pK ndx=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx); WARN((ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT), @@ -1700,7 +1700,7 @@ int mdss_dsi_retrieve_ctrl_resources(struct platform_device *pdev, int mode, return rc; } - pr_info("%s: ctrl_base=%p ctrl_size=%x phy_base=%p phy_size=%x\n", + pr_info("%s: ctrl_base=%pK ctrl_size=%x phy_base=%pK phy_size=%x\n", __func__, ctrl->ctrl_base, ctrl->reg_size, ctrl->phy_io.base, ctrl->phy_io.len); diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c index 24c3e63b13717..c9e56758e7532 100644 --- a/drivers/video/msm/mdss/mdss_dsi_host.c +++ b/drivers/video/msm/mdss/mdss_dsi_host.c @@ -95,7 +95,7 @@ void mdss_dsi_ctrl_init(struct device *ctrl_dev, if (ctrl->mdss_util->register_irq(ctrl->dsi_hw)) pr_err("%s: mdss_register_irq failed.\n", __func__); - pr_debug("%s: ndx=%d base=%p\n", __func__, ctrl->ndx, ctrl->ctrl_base); + pr_debug("%s: ndx=%d base=%pK\n", __func__, ctrl->ndx, ctrl->ctrl_base); init_completion(&ctrl->dma_comp); init_completion(&ctrl->mdp_comp); diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c index 8c57c9b8902ab..b1687692357cb 100644 --- a/drivers/video/msm/mdss/mdss_dsi_panel.c +++ b/drivers/video/msm/mdss/mdss_dsi_panel.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -611,7 +611,7 @@ static int mdss_dsi_panel_on(struct mdss_panel_data *pdata) ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx); + pr_debug("%s: ctrl=%pK ndx=%d\n", __func__, ctrl, ctrl->ndx); if (pinfo->dcs_cmd_by_left) { if (ctrl->ndx != DSI_CTRL_LEFT) @@ -641,7 +641,7 @@ static int mdss_dsi_post_panel_on(struct mdss_panel_data *pdata) ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx); + pr_debug("%s: ctrl=%pK ndx=%d\n", __func__, ctrl, ctrl->ndx); pinfo = &pdata->panel_info; if (pinfo->dcs_cmd_by_left) { @@ -651,7 +651,7 @@ static int mdss_dsi_post_panel_on(struct mdss_panel_data *pdata) on_cmds = &ctrl->post_panel_on_cmds; - pr_debug("%s: ctrl=%p cmd_cnt=%d\n", __func__, ctrl, on_cmds->cmd_cnt); + pr_debug("%s: ctrl=%pK cmd_cnt=%d\n", __func__, ctrl, on_cmds->cmd_cnt); if (on_cmds->cmd_cnt) { msleep(50); /* wait for 3 vsync passed */ @@ -677,7 +677,7 @@ static int mdss_dsi_panel_off(struct mdss_panel_data *pdata) ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx); + pr_debug("%s: ctrl=%pK ndx=%d\n", __func__, ctrl, ctrl->ndx); if (pinfo->dcs_cmd_by_left) { if (ctrl->ndx != DSI_CTRL_LEFT) @@ -708,7 +708,7 @@ static int mdss_dsi_panel_low_power_config(struct mdss_panel_data *pdata, ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s: ctrl=%p ndx=%d enable=%d\n", __func__, ctrl, ctrl->ndx, + pr_debug("%s: ctrl=%pK ndx=%d enable=%d\n", __func__, ctrl, ctrl->ndx, enable); /* Any panel specific low power commands/config */ diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c index c06abd3d95167..6f09747da6c05 100644 --- a/drivers/video/msm/mdss/mdss_fb.c +++ b/drivers/video/msm/mdss/mdss_fb.c @@ -1642,7 +1642,7 @@ int mdss_fb_alloc_fb_ion_memory(struct msm_fb_data_type *mfd, size_t fb_size) goto fb_mmap_failed; } - pr_debug("alloc 0x%zuB vaddr = %p (%pa iova) for fb%d\n", fb_size, + pr_debug("alloc 0x%zuB vaddr = %pK (%pa iova) for fb%d\n", fb_size, vaddr, &mfd->iova, mfd->index); mfd->fbi->screen_base = (char *) vaddr; @@ -1735,7 +1735,7 @@ static int mdss_fb_fbmem_ion_mmap(struct fb_info *info, vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); - pr_debug("vma=%p, addr=%x len=%ld\n", + pr_debug("vma=%pK, addr=%x len=%ld\n", vma, (unsigned int)addr, len); pr_debug("vm_start=%x vm_end=%x vm_page_prot=%ld\n", (unsigned int)vma->vm_start, @@ -1905,7 +1905,7 @@ static int mdss_fb_alloc_fbmem_iommu(struct msm_fb_data_type *mfd, int dom) if (rc) pr_warn("Cannot map fb_mem %pa to IOMMU. rc=%d\n", &phys, rc); - pr_debug("alloc 0x%zxB @ (%pa phys) (0x%p virt) (%pa iova) for fb%d\n", + pr_debug("alloc 0x%zxB @ (%pa phys) (0x%pK virt) (%pa iova) for fb%d\n", size, &phys, virt, &mfd->iova, mfd->index); mfd->fbi->screen_base = virt; diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c index 90f92678948c7..140a460b2acb7 100644 --- a/drivers/video/msm/mdss/mdss_hdmi_tx.c +++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1035,7 +1035,7 @@ static int hdmi_tx_sysfs_create(struct hdmi_tx_ctrl *hdmi_ctrl, return rc; } hdmi_ctrl->kobj = &fbi->dev->kobj; - DEV_DBG("%s: sysfs group %p\n", __func__, hdmi_ctrl->kobj); + DEV_DBG("%s: sysfs group %pK\n", __func__, hdmi_ctrl->kobj); return 0; } /* hdmi_tx_sysfs_create */ @@ -3556,7 +3556,7 @@ static int hdmi_tx_init_resource(struct hdmi_tx_ctrl *hdmi_ctrl) DEV_DBG("%s: '%s' remap failed or not available\n", __func__, hdmi_tx_io_name(i)); } - DEV_INFO("%s: '%s': start = 0x%p, len=0x%x\n", __func__, + DEV_INFO("%s: '%s': start = 0x%pK, len=0x%x\n", __func__, hdmi_tx_io_name(i), pdata->io[i].base, pdata->io[i].len); } diff --git a/drivers/video/msm/mdss/mdss_hdmi_util.c b/drivers/video/msm/mdss/mdss_hdmi_util.c index b40ff288551c4..b50aee3483284 100644 --- a/drivers/video/msm/mdss/mdss_hdmi_util.c +++ b/drivers/video/msm/mdss/mdss_hdmi_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -178,7 +178,7 @@ static void hdmi_ddc_print_data(struct hdmi_tx_ddc_data *ddc_data, return; } - DEV_DBG("%s: buf=%p, d_len=0x%x, d_addr=0x%x, no_align=%d\n", + DEV_DBG("%s: buf=%pK, d_len=0x%x, d_addr=0x%x, no_align=%d\n", caller, ddc_data->data_buf, ddc_data->data_len, ddc_data->dev_addr, ddc_data->no_align); DEV_DBG("%s: offset=0x%x, req_len=0x%x, retry=%d, what=%s\n", diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c index 14514f32ee82a..3a53359acb717 100644 --- a/drivers/video/msm/mdss/mdss_mdp.c +++ b/drivers/video/msm/mdss/mdss_mdp.c @@ -1207,7 +1207,7 @@ static u32 mdss_mdp_res_init(struct mdss_data_type *mdata) mdata->iclient = msm_ion_client_create(mdata->pdev->name); if (IS_ERR_OR_NULL(mdata->iclient)) { - pr_err("msm_ion_client_create() return error (%p)\n", + pr_err("msm_ion_client_create() return error (%pK)\n", mdata->iclient); mdata->iclient = NULL; } @@ -1526,7 +1526,7 @@ static int mdss_mdp_probe(struct platform_device *pdev) if (rc) pr_debug("unable to map MDSS VBIF non-realtime base\n"); else - pr_debug("MDSS VBIF NRT HW Base addr=%p len=0x%x\n", + pr_debug("MDSS VBIF NRT HW Base addr=%pK len=0x%x\n", mdata->vbif_nrt_io.base, mdata->vbif_nrt_io.len); res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); diff --git a/drivers/video/msm/mdss/mdss_mdp_debug.c b/drivers/video/msm/mdss/mdss_mdp_debug.c index 39230d1968421..9b1ab8d9ab269 100644 --- a/drivers/video/msm/mdss/mdss_mdp_debug.c +++ b/drivers/video/msm/mdss/mdss_mdp_debug.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -57,13 +57,13 @@ static void __dump_pipe(struct seq_file *s, struct mdss_mdp_pipe *pipe) seq_puts(s, "Data:\n"); if (pipe->front_buf.num_planes) { buf = pipe->front_buf.p; - seq_printf(s, "\tfront_buf ihdl=0x%p addr=%pa size=%lu\n", + seq_printf(s, "\tfront_buf ihdl=0x%pK addr=%pa size=%lu\n", buf->srcp_ihdl, &buf->addr, buf->len); } if (pipe->back_buf.num_planes) { buf = pipe->back_buf.p; - seq_printf(s, "\tback_buf ihdl=0x%p addr=%pa size=%lu\n", + seq_printf(s, "\tback_buf ihdl=0x%pK addr=%pa size=%lu\n", buf->srcp_ihdl, &buf->addr, buf->len); } } diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c index 6f6fc91b16b85..b07b3c523e5e1 100644 --- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -581,7 +581,7 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg) ctx->rdptr_enabled, ctl->roi_bkup.w, ctl->roi_bkup.h); - pr_debug("%s: intf_num=%d ctx=%p koff_cnt=%d\n", __func__, + pr_debug("%s: intf_num=%d ctx=%pK koff_cnt=%d\n", __func__, ctl->intf_num, ctx, atomic_read(&ctx->koff_cnt)); rc = wait_event_timeout(ctx->pp_waitq, @@ -1164,7 +1164,7 @@ static int mdss_mdp_cmd_intfs_setup(struct mdss_mdp_ctl *ctl, ctx->intf_stopped = 0; - pr_debug("%s: ctx=%p num=%d mixer=%d\n", __func__, + pr_debug("%s: ctx=%pK num=%d mixer=%d\n", __func__, ctx, ctx->pp_num, mixer->num); MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), ctx->clk_enabled, ctx->rdptr_enabled); diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c index 2bc8a1db0b109..9ce6885af7544 100644 --- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c +++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c @@ -116,7 +116,7 @@ int mdss_mdp_video_addr_setup(struct mdss_data_type *mdata, for (i = 0; i < count; i++) { head[i].base = mdata->mdss_io.base + offsets[i]; - pr_debug("adding Video Intf #%d offset=0x%x virt=%p\n", i, + pr_debug("adding Video Intf #%d offset=0x%x virt=%pK\n", i, offsets[i], head[i].base); head[i].ref_cnt = 0; head[i].intf_num = i + MDSS_MDP_INTF0; @@ -442,7 +442,7 @@ static int mdss_mdp_video_intfs_stop(struct mdss_mdp_ctl *ctl, pr_err("Intf %d not in use\n", (inum + MDSS_MDP_INTF0)); return -ENODEV; } - pr_debug("stop ctl=%d video Intf #%d base=%p", ctl->num, + pr_debug("stop ctl=%d video Intf #%d base=%pK", ctl->num, ctx->intf_num, ctx->base); } else { pr_err("Invalid intf number: %d\n", (inum + MDSS_MDP_INTF0)); @@ -1158,7 +1158,7 @@ static int mdss_mdp_video_intfs_setup(struct mdss_mdp_ctl *ctl, (inum + MDSS_MDP_INTF0)); return -EBUSY; } - pr_debug("video Intf #%d base=%p", ctx->intf_num, ctx->base); + pr_debug("video Intf #%d base=%pK", ctx->intf_num, ctx->base); ctx->ref_cnt++; } else { pr_err("Invalid intf number: %d\n", (inum + MDSS_MDP_INTF0)); diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c index b74767078ae2b..d8d01afb4e059 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pipe.c +++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c @@ -1739,7 +1739,7 @@ int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe, } if (src_data == NULL) { - pr_debug("src_data=%p pipe num=%dx\n", + pr_debug("src_data=%pK pipe num=%dx\n", src_data, pipe->num); goto update_nobuf; } diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c index 3cfa92624ce85..5065bc8da1627 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pp.c +++ b/drivers/video/msm/mdss/mdss_mdp_pp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2224,7 +2224,7 @@ static int pp_ad_calc_bl(struct msm_fb_data_type *mfd, int bl_in, int *bl_out, pr_debug("AD not supported on device.\n"); return ret; } else if (ret || !ad) { - pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", + pr_err("Failed to get ad info: ret = %d, ad = 0x%pK.\n", ret, ad); return ret; } @@ -2240,7 +2240,7 @@ static int pp_ad_calc_bl(struct msm_fb_data_type *mfd, int bl_in, int *bl_out, if (!ad->bl_mfd || !ad->bl_mfd->panel_info || !ad->bl_att_lut) { - pr_err("Invalid ad info: bl_mfd = 0x%p, ad->bl_mfd->panel_info = 0x%p, bl_att_lut = 0x%p\n", + pr_err("Invalid ad info: bl_mfd = 0x%pK, ad->bl_mfd->panel_info = 0x%pK, bl_att_lut = 0x%pK\n", ad->bl_mfd, (!ad->bl_mfd) ? NULL : ad->bl_mfd->panel_info, ad->bl_att_lut); @@ -3507,7 +3507,7 @@ static int pp_hist_enable(struct pp_hist_col_info *hist_info, spin_lock_irqsave(&hist_info->hist_lock, flag); if (hist_info->col_en) { spin_unlock_irqrestore(&hist_info->hist_lock, flag); - pr_info("%s Hist collection has already been enabled %p\n", + pr_info("%s Hist collection has already been enabled %pK\n", __func__, hist_info->base); goto exit; } @@ -3644,7 +3644,7 @@ static int pp_hist_disable(struct pp_hist_col_info *hist_info) spin_lock_irqsave(&hist_info->hist_lock, flag); if (hist_info->col_en == false) { spin_unlock_irqrestore(&hist_info->hist_lock, flag); - pr_debug("Histogram already disabled (%p)\n", hist_info->base); + pr_debug("Histogram already disabled (%pK)\n", hist_info->base); ret = -EINVAL; goto exit; } @@ -3758,7 +3758,7 @@ int mdss_mdp_hist_intr_req(struct mdss_intr *intr, u32 bits, bool en) unsigned long flag; int ret = 0; if (!intr) { - pr_err("NULL addr passed, %p\n", intr); + pr_err("NULL addr passed, %pK\n", intr); return -EINVAL; } @@ -4512,7 +4512,7 @@ static int pp_ad_invalidate_input(struct msm_fb_data_type *mfd) ret = mdss_mdp_get_ad(mfd, &ad); if (ret || !ad) { - pr_err("Fail to get ad: ret = %d, ad = 0x%p\n", ret, ad); + pr_err("Fail to get ad: ret = %d, ad = 0x%pK\n", ret, ad); return -EINVAL; } pr_debug("AD backlight level changed (%d), trigger update to AD\n", diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c index c62acf3db78b0..926dfdef15851 100644 --- a/drivers/video/msm/mdss/mdss_mdp_util.c +++ b/drivers/video/msm/mdss/mdss_mdp_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -507,7 +507,7 @@ static int mdss_mdp_put_img(struct mdss_mdp_img_data *data) pr_debug("pmem buf=0x%pa\n", &data->addr); data->srcp_file = NULL; } else if (!IS_ERR_OR_NULL(data->srcp_ihdl)) { - pr_debug("ion hdl=%p buf=0x%pa\n", data->srcp_ihdl, + pr_debug("ion hdl=%pK buf=0x%pa\n", data->srcp_ihdl, &data->addr); if (!iclient) { pr_err("invalid ion client\n"); @@ -599,7 +599,7 @@ static int mdss_mdp_get_img(struct msmfb_data *img, data->addr += data->offset; data->len -= data->offset; - pr_debug("mem=%d ihdl=%p buf=0x%pa len=0x%lu\n", img->memory_id, + pr_debug("mem=%d ihdl=%pK buf=0x%pa len=0x%lu\n", img->memory_id, data->srcp_ihdl, &data->addr, data->len); } else { mdss_mdp_put_img(data); @@ -653,7 +653,7 @@ static int mdss_mdp_map_buffer(struct mdss_mdp_img_data *data) data->addr += data->offset; data->len -= data->offset; - pr_debug("ihdl=%p buf=0x%pa len=0x%lu\n", + pr_debug("ihdl=%pK buf=0x%pa len=0x%lu\n", data->srcp_ihdl, &data->addr, data->len); } else { mdss_mdp_put_img(data); diff --git a/drivers/video/msm/mdss/mdss_mdp_wb.c b/drivers/video/msm/mdss/mdss_mdp_wb.c index def90ebb39490..da6587ef6a54f 100644 --- a/drivers/video/msm/mdss/mdss_mdp_wb.c +++ b/drivers/video/msm/mdss/mdss_mdp_wb.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -95,7 +95,7 @@ struct mdss_mdp_data *mdss_mdp_wb_debug_buffer(struct msm_fb_data_type *mfd) ihdl = ion_alloc(iclient, img_size, SZ_4K, ION_HEAP(ION_SF_HEAP_ID), 0); if (IS_ERR_OR_NULL(ihdl)) { - pr_err("unable to alloc fbmem from ion (%p)\n", ihdl); + pr_err("unable to alloc fbmem from ion (%pK)\n", ihdl); return NULL; } @@ -122,7 +122,7 @@ struct mdss_mdp_data *mdss_mdp_wb_debug_buffer(struct msm_fb_data_type *mfd) img->len = img_size; } - pr_debug("ihdl=%p virt=%p phys=0x%pa iova=0x%pa size=%u\n", + pr_debug("ihdl=%pK virt=%pK phys=0x%pa iova=0x%pa size=%u\n", ihdl, videomemory, &mdss_wb_mem, &img->addr, img_size); } return &mdss_wb_buffer; @@ -435,7 +435,7 @@ static struct mdss_mdp_wb_data *get_user_node(struct msm_fb_data_type *mfd, list_for_each_entry(node, &wb->register_queue, registered_entry) if ((node->buf_data.p[0].srcp_ihdl == ihdl) && (node->buf_info.offset == data->offset)) { - pr_debug("found fd=%d hdl=%p off=%x addr=%pa\n", + pr_debug("found fd=%d hdl=%pK off=%x addr=%pa\n", data->memory_id, ihdl, data->offset, &node->buf_data.p[0].addr); @@ -501,7 +501,7 @@ static void mdss_mdp_wb_free_node(struct mdss_mdp_wb_data *node) if (node->user_alloc) { buf = &node->buf_data.p[0]; - pr_debug("free user mem_id=%d ihdl=%p, offset=%u addr=0x%pa\n", + pr_debug("free user mem_id=%d ihdl=%pK, offset=%u addr=0x%pa\n", node->buf_info.memory_id, buf->srcp_ihdl, node->buf_info.offset, diff --git a/drivers/video/msm/mdss/mdss_util.c b/drivers/video/msm/mdss/mdss_util.c index 587db41a9d105..345b0927bc58e 100644 --- a/drivers/video/msm/mdss/mdss_util.c +++ b/drivers/video/msm/mdss/mdss_util.c @@ -1,5 +1,4 @@ - -/* Copyright (c) 2007-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2007-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -33,7 +32,7 @@ int mdss_register_irq(struct mdss_hw *hw) if (!mdss_irq_handlers[hw->hw_ndx]) mdss_irq_handlers[hw->hw_ndx] = hw; else - pr_err("panel %d's irq at %p is already registered\n", + pr_err("panel %d's irq at %pK is already registered\n", hw->hw_ndx, hw->irq_handler); spin_unlock_irqrestore(&mdss_lock, irq_flags); From 6b514a40f90f1828af3e3c1cf17b7d48aa26e356 Mon Sep 17 00:00:00 2001 From: Gaurav Singhal Date: Fri, 8 Jul 2016 19:20:33 +0530 Subject: [PATCH 241/320] NFC: IRQ gpio usage modification in nfc_read Modified condition to ensure data is read only after interrupt has occurred. Spurious interrupt handling is done in nfc_read instead of irq handler. Change-Id: Ie2362610fe922e792e6358b4386c828fdd754fa8 Signed-off-by: Gaurav Singhal --- drivers/nfc/nq-nci.c | 48 ++++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c index 04d72420cf773..c4257c08c160e 100644 --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -107,36 +107,14 @@ static void nqx_disable_irq(struct nqx_dev *nqx_dev) spin_unlock_irqrestore(&nqx_dev->irq_enabled_lock, flags); } -static void nqx_enable_irq(struct nqx_dev *nqx_dev) -{ - unsigned long flags; - - spin_lock_irqsave(&nqx_dev->irq_enabled_lock, flags); - if (!nqx_dev->irq_enabled) { - nqx_dev->irq_enabled = true; - enable_irq(nqx_dev->client->irq); - } - spin_unlock_irqrestore(&nqx_dev->irq_enabled_lock, flags); -} - static irqreturn_t nqx_dev_irq_handler(int irq, void *dev_id) { struct nqx_dev *nqx_dev = dev_id; unsigned long flags; - int ret; if (device_may_wakeup(&nqx_dev->client->dev)) pm_wakeup_event(&nqx_dev->client->dev, WAKEUP_SRC_TIMEOUT); - ret = gpio_get_value(nqx_dev->irq_gpio); - if (!ret) { -#ifdef NFC_KERNEL_BU - dev_info(&nqx_dev->client->dev, - "nqx nfc : nqx_dev_irq_handler error = %d\n", ret); -#endif - return IRQ_HANDLED; - } - nqx_disable_irq(nqx_dev); spin_lock_irqsave(&nqx_dev->irq_enabled_lock, flags); nqx_dev->count_irq++; @@ -175,15 +153,24 @@ static ssize_t nfc_read(struct file *filp, char __user *buf, ret = -EAGAIN; goto err; } - if (!nqx_dev->irq_enabled) { - enable_irq(nqx_dev->client->irq); - nqx_dev->irq_enabled = true; + while (1) { + ret = 0; + if (!nqx_dev->irq_enabled) { + nqx_dev->irq_enabled = true; + enable_irq(nqx_dev->client->irq); + } + if (!gpio_get_value(nqx_dev->irq_gpio)) { + ret = wait_event_interruptible(nqx_dev->read_wq, + !nqx_dev->irq_enabled); + } + if (ret) + goto err; + nqx_disable_irq(nqx_dev); + + if (gpio_get_value(nqx_dev->irq_gpio)) + break; + dev_err_ratelimited(&nqx_dev->client->dev, "gpio is low, no need to read data\n"); } - ret = wait_event_interruptible(nqx_dev->read_wq, - gpio_get_value(nqx_dev->irq_gpio)); - if (ret) - goto err; - nqx_disable_irq(nqx_dev); } tmp = nqx_dev->kbuf; @@ -391,7 +378,6 @@ int nfc_ioctl_power_states(struct file *filp, unsigned long arg) /* hardware dependent delay */ msleep(100); } else if (arg == 1) { - nqx_enable_irq(nqx_dev); dev_dbg(&nqx_dev->client->dev, "gpio_set_value enable: %s: info: %p\n", __func__, nqx_dev); From 9e24756af7691ca32a683acacdffa8cc4873e1a7 Mon Sep 17 00:00:00 2001 From: Gaurav Singhal Date: Thu, 11 Aug 2016 12:40:41 +0530 Subject: [PATCH 242/320] NFC: Fix unbalanced irq warning stack trace When NFC is not enabled, IRQ will be disabled and then if we do suspend/resume wake up functionality won't be enabled at suspend but we try to disable the same at resume and cause irq warning. Fix warning trace in below cases: 1) NFC enabled in makefile, but manually turned off in settings menu (NFC driver is enabled and hw is present). 2) NFC is not enabled in makefile (NFC driver is enabled and hw is present). Change-Id: I0fd76809cd949d88ae7b820c37f0a9f349abb090 Signed-off-by: Gaurav Singhal --- drivers/nfc/nq-nci.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c index 04d72420cf773..c11344a1bdddb 100644 --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -63,6 +63,8 @@ struct nqx_dev { bool nfc_ven_enabled; /* NFC_IRQ state */ bool irq_enabled; + /* NFC_IRQ wake-up state */ + bool irq_wake_up; spinlock_t irq_enabled_lock; unsigned int count_irq; /* Initial CORE RESET notification */ @@ -897,6 +899,7 @@ static int nqx_probe(struct i2c_client *client, device_init_wakeup(&client->dev, true); device_set_wakeup_capable(&client->dev, true); i2c_set_clientdata(client, nqx_dev); + nqx_dev->irq_wake_up = false; dev_err(&client->dev, "%s: probing NFCC NQxxx exited successfully\n", @@ -977,17 +980,22 @@ static int nqx_suspend(struct device *device) struct i2c_client *client = to_i2c_client(device); struct nqx_dev *nqx_dev = i2c_get_clientdata(client); - if (device_may_wakeup(&client->dev) && nqx_dev->irq_enabled) - enable_irq_wake(client->irq); + if (device_may_wakeup(&client->dev) && nqx_dev->irq_enabled) { + if (!enable_irq_wake(client->irq)) + nqx_dev->irq_wake_up = true; + } return 0; } static int nqx_resume(struct device *device) { struct i2c_client *client = to_i2c_client(device); + struct nqx_dev *nqx_dev = i2c_get_clientdata(client); - if (device_may_wakeup(&client->dev)) - disable_irq_wake(client->irq); + if (device_may_wakeup(&client->dev) && nqx_dev->irq_wake_up) { + if (!disable_irq_wake(client->irq)) + nqx_dev->irq_wake_up = false; + } return 0; } From 309d334cb3d95f98bb73aceddd09bb3296ffd669 Mon Sep 17 00:00:00 2001 From: Gaurav Singhal Date: Fri, 5 Aug 2016 13:16:22 +0530 Subject: [PATCH 243/320] NFC: Set enable gpio to low If ese gpio is not present on target, and we disable NFC then enable gpio should be set to LOW. Negative gpio value is invalid case, we should avoid gpio free for error scenario. Change-Id: I87c890bbb66ee683129f062a2aa4c8d95d5c93ee Signed-off-by: Gaurav Singhal --- drivers/nfc/nq-nci.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c index 04d72420cf773..beced72cd460c 100644 --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -383,6 +383,9 @@ int nfc_ioctl_power_states(struct file *filp, unsigned long arg) } else { dev_dbg(&nqx_dev->client->dev, "keeping en_gpio high\n"); } + } else { + dev_dbg(&nqx_dev->client->dev, "ese_gpio invalid, set en_gpio to low\n"); + gpio_set_value(nqx_dev->en_gpio, 0); } r = nqx_clock_deselect(nqx_dev); if (r < 0) @@ -787,21 +790,28 @@ static int nqx_probe(struct i2c_client *client, r = gpio_request(platform_data->ese_gpio, "nfc-ese_pwr"); if (r) { + nqx_dev->ese_gpio = -EINVAL; dev_err(&client->dev, "%s: unable to request nfc ese gpio [%d]\n", __func__, platform_data->ese_gpio); /* ese gpio optional so we should continue */ } else { nqx_dev->ese_gpio = platform_data->ese_gpio; - } - r = gpio_direction_output(platform_data->ese_gpio, 0); - if (r) { - dev_err(&client->dev, - "%s: cannot set direction for nfc ese gpio [%d]\n", - __func__, platform_data->ese_gpio); - /* ese gpio optional so we should continue */ + r = gpio_direction_output(platform_data->ese_gpio, 0); + if (r) { + /* free ese gpio and set invalid + to avoid further use + */ + gpio_free(platform_data->ese_gpio); + nqx_dev->ese_gpio = -EINVAL; + dev_err(&client->dev, + "%s: cannot set direction for nfc ese gpio [%d]\n", + __func__, platform_data->ese_gpio); + /* ese gpio optional so we should continue */ + } } } else { + nqx_dev->ese_gpio = -EINVAL; dev_err(&client->dev, "%s: ese gpio not provided\n", __func__); /* ese gpio optional so we should continue */ @@ -831,7 +841,6 @@ static int nqx_probe(struct i2c_client *client, nqx_dev->en_gpio = platform_data->en_gpio; nqx_dev->irq_gpio = platform_data->irq_gpio; nqx_dev->firm_gpio = platform_data->firm_gpio; - nqx_dev->ese_gpio = platform_data->ese_gpio; nqx_dev->clkreq_gpio = platform_data->clkreq_gpio; nqx_dev->pdata = platform_data; @@ -917,7 +926,7 @@ static int nqx_probe(struct i2c_client *client, gpio_free(platform_data->clkreq_gpio); err_ese_gpio: /* optional gpio, not sure was configured in probe */ - if (nqx_dev->ese_gpio) + if (nqx_dev->ese_gpio > 0) gpio_free(platform_data->ese_gpio); err_firm_gpio: gpio_free(platform_data->firm_gpio); @@ -958,7 +967,7 @@ static int nqx_remove(struct i2c_client *client) mutex_destroy(&nqx_dev->read_mutex); gpio_free(nqx_dev->clkreq_gpio); /* optional gpio, not sure was configured in probe */ - if (nqx_dev->ese_gpio) + if (nqx_dev->ese_gpio > 0) gpio_free(nqx_dev->ese_gpio); gpio_free(nqx_dev->firm_gpio); gpio_free(nqx_dev->irq_gpio); From c1d7f34241a5922c52d211d257e1d20340806729 Mon Sep 17 00:00:00 2001 From: Charan Teja Reddy Date: Thu, 8 Sep 2016 20:47:55 +0530 Subject: [PATCH 244/320] coresight: fix the dangling pointer issues on coresight Fix the dangling pointer issues on CoreSight that can cause kernel panic. Change-Id: If3abe89bf0326230c29a49d293ab22ebcec93076 Signed-off-by: Charan Teja Reddy --- drivers/coresight/coresight-csr.c | 7 ++++--- drivers/coresight/coresight-fuse.c | 7 ++++--- drivers/soc/qcom/jtag-fuse.c | 6 +++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/coresight/coresight-csr.c b/drivers/coresight/coresight-csr.c index 19e44b9c5d3be..7ad40f16d303c 100644 --- a/drivers/coresight/coresight-csr.c +++ b/drivers/coresight/coresight-csr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2013,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -195,8 +195,6 @@ static int csr_probe(struct platform_device *pdev) drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; - /* Store the driver data pointer for use in exported functions */ - csrdrvdata = drvdata; drvdata->dev = &pdev->dev; platform_set_drvdata(pdev, drvdata); @@ -227,6 +225,9 @@ static int csr_probe(struct platform_device *pdev) if (IS_ERR(drvdata->csdev)) return PTR_ERR(drvdata->csdev); + /* Store the driver data pointer for use in exported functions */ + csrdrvdata = drvdata; + dev_info(dev, "CSR initialized\n"); return 0; } diff --git a/drivers/coresight/coresight-fuse.c b/drivers/coresight/coresight-fuse.c index 94689285d8d86..cdbfc7a2ac13c 100644 --- a/drivers/coresight/coresight-fuse.c +++ b/drivers/coresight/coresight-fuse.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -252,8 +252,6 @@ static int fuse_probe(struct platform_device *pdev) drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; - /* Store the driver data pointer for use in exported functions */ - fusedrvdata = drvdata; drvdata->dev = &pdev->dev; platform_set_drvdata(pdev, drvdata); @@ -315,6 +313,9 @@ static int fuse_probe(struct platform_device *pdev) if (IS_ERR(drvdata->csdev)) return PTR_ERR(drvdata->csdev); + /* Store the driver data pointer for use in exported functions */ + fusedrvdata = drvdata; + dev_info(dev, "Fuse initialized\n"); return 0; } diff --git a/drivers/soc/qcom/jtag-fuse.c b/drivers/soc/qcom/jtag-fuse.c index 46de4e5f2026e..d7389f397b9ce 100644 --- a/drivers/soc/qcom/jtag-fuse.c +++ b/drivers/soc/qcom/jtag-fuse.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -152,8 +152,6 @@ static int jtag_fuse_probe(struct platform_device *pdev) drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; - /* Store the driver data pointer for use in exported functions */ - fusedrvdata = drvdata; drvdata->dev = &pdev->dev; platform_set_drvdata(pdev, drvdata); @@ -174,6 +172,8 @@ static int jtag_fuse_probe(struct platform_device *pdev) if (!drvdata->base) return -ENOMEM; + /* Store the driver data pointer for use in exported functions */ + fusedrvdata = drvdata; dev_info(dev, "JTag Fuse initialized\n"); return 0; } From 65978306d512f7fbffcb0b8d562ba7d58e3f13a0 Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Tue, 28 Jan 2014 14:45:41 -0500 Subject: [PATCH 245/320] selinux: add SOCK_DIAG_BY_FAMILY to the list of netlink message types commit 6a96e15096da6e7491107321cfa660c7c2aa119d upstream. The SELinux AF_NETLINK/NETLINK_SOCK_DIAG socket class was missing the SOCK_DIAG_BY_FAMILY definition which caused SELINUX_ERR messages when the ss tool was run. # ss Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port u_str ESTAB 0 0 * 14189 * 14190 u_str ESTAB 0 0 * 14145 * 14144 u_str ESTAB 0 0 * 14151 * 14150 {...} # ausearch -m SELINUX_ERR ---- time->Thu Jan 23 11:11:16 2014 type=SYSCALL msg=audit(1390493476.445:374): arch=c000003e syscall=44 success=yes exit=40 a0=3 a1=7fff03aa11f0 a2=28 a3=0 items=0 ppid=1852 pid=1895 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="ss" exe="/usr/sbin/ss" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null) type=SELINUX_ERR msg=audit(1390493476.445:374): SELinux: unrecognized netlink message type=20 for sclass=32 Change-Id: I771870cdf7de6a55c161fda65ef8681040495a18 Signed-off-by: Paul Moore Git-commit: 53be74a0138bc0e8be644b445321210b1d77217d Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: Ashwanth Goli --- security/selinux/nlmsgtab.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c index 855e464e92efb..c478eab7c4dd3 100644 --- a/security/selinux/nlmsgtab.c +++ b/security/selinux/nlmsgtab.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "flask.h" #include "av_permissions.h" @@ -78,6 +79,7 @@ static struct nlmsg_perm nlmsg_tcpdiag_perms[] = { { TCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, { DCCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, + { SOCK_DIAG_BY_FAMILY, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, }; static struct nlmsg_perm nlmsg_xfrm_perms[] = From 0e8706c71c66dd65a2f245eca73316208e8947fa Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 4 Feb 2016 00:52:15 +0900 Subject: [PATCH 246/320] selinux: nlmsgtab: add SOCK_DESTROY to the netlink mapping tables Without this, using SOCK_DESTROY in enforcing mode results in: SELinux: unrecognized netlink message type=21 for sclass=32 Change-Id: I7862bb0fc83573567243ffa9549a2c7405b5986c Git-commit: 2c332426b5af4edf921d064b183da76c1ae2fda6 Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: Ashwanth Goli --- security/selinux/nlmsgtab.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c index c478eab7c4dd3..a619a235a3ebd 100644 --- a/security/selinux/nlmsgtab.c +++ b/security/selinux/nlmsgtab.c @@ -77,9 +77,10 @@ static struct nlmsg_perm nlmsg_route_perms[] = static struct nlmsg_perm nlmsg_tcpdiag_perms[] = { - { TCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, - { DCCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, - { SOCK_DIAG_BY_FAMILY, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, + { TCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, + { DCCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, + { SOCK_DIAG_BY_FAMILY, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, + { SOCK_DESTROY_BACKPORT, NETLINK_TCPDIAG_SOCKET__NLMSG_WRITE }, }; static struct nlmsg_perm nlmsg_xfrm_perms[] = From 263a71b7b23b1b72cb1981409145d7379347e44f Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 29 Aug 2016 21:58:32 +0530 Subject: [PATCH 247/320] misc: qcom: qdsp6v2: initialize config_32 Not all memebers of config_32 are set before they are used which might lead to invalid values being passed and used. To fix this issue initialize all member variables of struct config_32 to 0 before assigning specific values individually. CRs-Fixed: 1058826 Change-Id: Ifea3a6e8bf45481c65a4455ee64318304798fee2 Signed-off-by: Laxminath Kasam --- drivers/misc/qcom/qdsp6v2/aac_in.c | 4 +++- drivers/misc/qcom/qdsp6v2/amrnb_in.c | 5 ++++- drivers/misc/qcom/qdsp6v2/amrwb_in.c | 2 ++ drivers/misc/qcom/qdsp6v2/audio_alac.c | 4 +++- drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c | 6 +++++- drivers/misc/qcom/qdsp6v2/audio_ape.c | 4 +++- drivers/misc/qcom/qdsp6v2/audio_multi_aac.c | 4 +++- drivers/misc/qcom/qdsp6v2/audio_utils_aio.c | 1 + drivers/misc/qcom/qdsp6v2/audio_wmapro.c | 4 +++- drivers/misc/qcom/qdsp6v2/evrc_in.c | 4 +++- drivers/misc/qcom/qdsp6v2/qcelp_in.c | 4 +++- 11 files changed, 33 insertions(+), 9 deletions(-) diff --git a/drivers/misc/qcom/qdsp6v2/aac_in.c b/drivers/misc/qcom/qdsp6v2/aac_in.c index 38db0381c50e8..a5ad927345f60 100644 --- a/drivers/misc/qcom/qdsp6v2/aac_in.c +++ b/drivers/misc/qcom/qdsp6v2/aac_in.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -425,6 +425,8 @@ static long aac_in_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_aac_enc_config cfg; struct msm_audio_aac_enc_config32 cfg_32; + memset(&cfg_32, 0, sizeof(cfg_32)); + cmd = AUDIO_GET_AAC_ENC_CONFIG; rc = aac_in_ioctl_shared(file, cmd, &cfg); if (rc) { diff --git a/drivers/misc/qcom/qdsp6v2/amrnb_in.c b/drivers/misc/qcom/qdsp6v2/amrnb_in.c index eb92137f06717..1bb441bd2ff48 100644 --- a/drivers/misc/qcom/qdsp6v2/amrnb_in.c +++ b/drivers/misc/qcom/qdsp6v2/amrnb_in.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2010-2012, 2014 The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2012, 2014, 2016 The Linux Foundation. + * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -221,6 +222,8 @@ static long amrnb_in_compat_ioctl(struct file *file, struct msm_audio_amrnb_enc_config_v2 *amrnb_config; struct msm_audio_amrnb_enc_config_v2_32 amrnb_config_32; + memset(&amrnb_config_32, 0, sizeof(amrnb_config_32)); + amrnb_config = (struct msm_audio_amrnb_enc_config_v2 *)audio->enc_cfg; amrnb_config_32.band_mode = amrnb_config->band_mode; diff --git a/drivers/misc/qcom/qdsp6v2/amrwb_in.c b/drivers/misc/qcom/qdsp6v2/amrwb_in.c index 4cea3dc63389f..71adbce0e257c 100644 --- a/drivers/misc/qcom/qdsp6v2/amrwb_in.c +++ b/drivers/misc/qcom/qdsp6v2/amrwb_in.c @@ -216,6 +216,8 @@ static long amrwb_in_compat_ioctl(struct file *file, struct msm_audio_amrwb_enc_config *amrwb_config; struct msm_audio_amrwb_enc_config_32 amrwb_config_32; + memset(&amrwb_config_32, 0, sizeof(amrwb_config_32)); + amrwb_config = (struct msm_audio_amrwb_enc_config *)audio->enc_cfg; amrwb_config_32.band_mode = amrwb_config->band_mode; diff --git a/drivers/misc/qcom/qdsp6v2/audio_alac.c b/drivers/misc/qcom/qdsp6v2/audio_alac.c index d6ca657c22e3b..94a1843040e64 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_alac.c +++ b/drivers/misc/qcom/qdsp6v2/audio_alac.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -176,6 +176,8 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_alac_config *alac_config; struct msm_audio_alac_config_32 alac_config_32; + memset(&alac_config_32, 0, sizeof(alac_config_32)); + alac_config = (struct msm_audio_alac_config *)audio->codec_cfg; alac_config_32.frameLength = alac_config->frameLength; alac_config_32.compatVersion = diff --git a/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c b/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c index bd2b5e31dc5ca..295193c901126 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c +++ b/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c @@ -2,7 +2,7 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2014,2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -202,6 +202,10 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_amrwbplus_config_v2 *amrwbplus_config; struct msm_audio_amrwbplus_config_v2_32 amrwbplus_config_32; + + memset(&amrwbplus_config_32, 0, + sizeof(amrwbplus_config_32)); + amrwbplus_config = (struct msm_audio_amrwbplus_config_v2 *) audio->codec_cfg; diff --git a/drivers/misc/qcom/qdsp6v2/audio_ape.c b/drivers/misc/qcom/qdsp6v2/audio_ape.c index 983835524e90c..ab3ddb58388f3 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_ape.c +++ b/drivers/misc/qcom/qdsp6v2/audio_ape.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -177,6 +177,8 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_ape_config *ape_config; struct msm_audio_ape_config_32 ape_config_32; + memset(&ape_config_32, 0, sizeof(ape_config_32)); + ape_config = (struct msm_audio_ape_config *)audio->codec_cfg; ape_config_32.compatibleVersion = ape_config->compatibleVersion; ape_config_32.compressionLevel = diff --git a/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c b/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c index 28c1d361fee1b..f4f669a043c95 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c +++ b/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c @@ -2,7 +2,7 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2014,2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -302,6 +302,8 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_aac_config *aac_config; struct msm_audio_aac_config32 aac_config_32; + memset(&aac_config_32, 0, sizeof(aac_config_32)); + aac_config = (struct msm_audio_aac_config *)audio->codec_cfg; aac_config_32.format = aac_config->format; aac_config_32.audio_object = aac_config->audio_object; diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c index a1d5e461a7c42..80411116dedc1 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c @@ -1972,6 +1972,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, audio->buf_cfg.frames_per_buf); mutex_lock(&audio->lock); + memset(&cfg_32, 0, sizeof(cfg_32)); cfg_32.meta_info_enable = audio->buf_cfg.meta_info_enable; cfg_32.frames_per_buf = audio->buf_cfg.frames_per_buf; if (copy_to_user((void *)arg, &cfg_32, diff --git a/drivers/misc/qcom/qdsp6v2/audio_wmapro.c b/drivers/misc/qcom/qdsp6v2/audio_wmapro.c index 54c05062703e3..1a97daeffef82 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_wmapro.c +++ b/drivers/misc/qcom/qdsp6v2/audio_wmapro.c @@ -2,7 +2,7 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2009-2014,2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -220,6 +220,8 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_wmapro_config *wmapro_config; struct msm_audio_wmapro_config32 wmapro_config_32; + memset(&wmapro_config_32, 0, sizeof(wmapro_config_32)); + wmapro_config = (struct msm_audio_wmapro_config *)audio->codec_cfg; wmapro_config_32.armdatareqthr = wmapro_config->armdatareqthr; diff --git a/drivers/misc/qcom/qdsp6v2/evrc_in.c b/drivers/misc/qcom/qdsp6v2/evrc_in.c index 1b8f8ad451db6..d7d67dec46061 100644 --- a/drivers/misc/qcom/qdsp6v2/evrc_in.c +++ b/drivers/misc/qcom/qdsp6v2/evrc_in.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -224,6 +224,8 @@ static long evrc_in_compat_ioctl(struct file *file, struct msm_audio_evrc_enc_config32 cfg_32; struct msm_audio_evrc_enc_config *enc_cfg; + memset(&cfg_32, 0, sizeof(cfg_32)); + enc_cfg = audio->enc_cfg; cfg_32.cdma_rate = enc_cfg->cdma_rate; cfg_32.min_bit_rate = enc_cfg->min_bit_rate; diff --git a/drivers/misc/qcom/qdsp6v2/qcelp_in.c b/drivers/misc/qcom/qdsp6v2/qcelp_in.c index 6dbb90d2a24e6..d1a8a8e5bcf78 100644 --- a/drivers/misc/qcom/qdsp6v2/qcelp_in.c +++ b/drivers/misc/qcom/qdsp6v2/qcelp_in.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -225,6 +225,8 @@ static long qcelp_in_compat_ioctl(struct file *file, struct msm_audio_qcelp_enc_config32 cfg_32; struct msm_audio_qcelp_enc_config *enc_cfg; + memset(&cfg_32, 0, sizeof(cfg_32)); + enc_cfg = (struct msm_audio_qcelp_enc_config *)audio->enc_cfg; cfg_32.cdma_rate = enc_cfg->cdma_rate; cfg_32.min_bit_rate = enc_cfg->min_bit_rate; From 460de4da8e14238369613c3ae88e76360f02fac5 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Wed, 16 Dec 2015 15:42:39 -0800 Subject: [PATCH 248/320] ASoC: msm-lsm-client: free lsm client data in msm_lsm_close Currently lsm client data is deallocated when q6lsm_open() fails which can cause memory corruption if lsm client data is accessed after freed. Fix this issue by deallocating the client data only in msm_lsm_close(). Change-Id: If048c26a0ffd8a346a28622183cbf2ba1e7e5ff3 Signed-off-by: Vidyakumar Athota --- include/sound/q6lsm.h | 1 + sound/soc/msm/qdsp6v2/msm-lsm-client.c | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/sound/q6lsm.h b/include/sound/q6lsm.h index db64e37b81e07..19f20c5abfb66 100644 --- a/include/sound/q6lsm.h +++ b/include/sound/q6lsm.h @@ -73,6 +73,7 @@ struct lsm_client { uint16_t connect_to_port; uint8_t num_confidence_levels; uint8_t *confidence_levels; + bool opened; bool started; dma_addr_t lsm_cal_phy_addr; uint32_t lsm_cal_size; diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/sound/soc/msm/qdsp6v2/msm-lsm-client.c index dc7ce933064ee..f7cecd5396cd7 100644 --- a/sound/soc/msm/qdsp6v2/msm-lsm-client.c +++ b/sound/soc/msm/qdsp6v2/msm-lsm-client.c @@ -753,10 +753,9 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: lsm open failed, %d\n", __func__, ret); - q6lsm_client_free(prtd->lsm_client); - kfree(prtd); return ret; } + prtd->lsm_client->opened = true; dev_dbg(rtd->dev, "%s: Session_ID = %d, APP ID = %d\n", __func__, prtd->lsm_client->session, @@ -1730,7 +1729,7 @@ static int msm_lsm_open(struct snd_pcm_substream *substream) prtd->lsm_client->session_state = IDLE; prtd->lsm_client->poll_enable = true; prtd->lsm_client->perf_mode = 0; - + prtd->lsm_client->opened = false; return 0; } @@ -1820,7 +1819,10 @@ static int msm_lsm_close(struct snd_pcm_substream *substream) msm_pcm_routing_dereg_phy_stream(rtd->dai_link->be_id, SNDRV_PCM_STREAM_CAPTURE); - q6lsm_close(prtd->lsm_client); + if (prtd->lsm_client->opened) { + q6lsm_close(prtd->lsm_client); + prtd->lsm_client->opened = false; + } q6lsm_client_free(prtd->lsm_client); spin_lock_irqsave(&prtd->event_lock, flags); @@ -1828,6 +1830,7 @@ static int msm_lsm_close(struct snd_pcm_substream *substream) prtd->event_status = NULL; spin_unlock_irqrestore(&prtd->event_lock, flags); kfree(prtd); + runtime->private_data = NULL; return 0; } From 675f35a754ad972c1e1c0615a95e4d314d8ff1f5 Mon Sep 17 00:00:00 2001 From: Sunil Khatri Date: Tue, 13 Sep 2016 15:46:35 +0530 Subject: [PATCH 249/320] msm: kgsl: Validate the input parameter len against zero Validate the len against zero and return with valid error values. Change-Id: I8596c3a6558827d40a6764d0dfddaeb359c2794d Signed-off-by: Sunil Khatri --- drivers/gpu/msm/kgsl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index ecfe64061ccd9..cc0f06c63c798 100755 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -2902,7 +2902,8 @@ static int kgsl_setup_useraddr(struct kgsl_mem_entry *entry, struct vm_area_struct *vma = NULL; int ret; - if (param->offset != 0 || param->hostptr == 0 + if (param->len == 0 || param->offset != 0 + || param->hostptr == 0 || !KGSL_IS_PAGE_ALIGNED(param->hostptr) || !KGSL_IS_PAGE_ALIGNED(param->len)) return -EINVAL; From cd99d3bbdb16899a425716e672485e0cdc283245 Mon Sep 17 00:00:00 2001 From: Abhijit Kulkarni Date: Wed, 15 Jun 2016 10:30:50 -0700 Subject: [PATCH 250/320] msm: mdss: hide kernel addresses from unprevileged users for printing kernel pointers which should be hidden from unprivileged users, use %pK which evaluates whether kptr_restrict is set. CRs-Fixed: 987021 Change-Id: Ie49eee9478f4657cfb2a994ba60da1ec4c356339 Signed-off-by: Abhijit Kulkarni Signed-off-by: Nirmal Abraham --- drivers/video/msm/mdss/mdp3.c | 16 ++++++++-------- drivers/video/msm/mdss/mdp3_ppp_hwio.c | 8 +++++--- drivers/video/msm/mdss/mdss_debug.c | 8 ++++---- drivers/video/msm/mdss/mdss_dsi.c | 14 +++++++------- drivers/video/msm/mdss/mdss_dsi_host.c | 2 +- drivers/video/msm/mdss/mdss_dsi_panel.c | 12 ++++++------ drivers/video/msm/mdss/mdss_fb.c | 6 +++--- drivers/video/msm/mdss/mdss_hdmi_tx.c | 6 +++--- drivers/video/msm/mdss/mdss_hdmi_util.c | 4 ++-- drivers/video/msm/mdss/mdss_mdp.c | 4 ++-- drivers/video/msm/mdss/mdss_mdp_debug.c | 6 +++--- drivers/video/msm/mdss/mdss_mdp_intf_cmd.c | 6 +++--- drivers/video/msm/mdss/mdss_mdp_intf_video.c | 6 +++--- drivers/video/msm/mdss/mdss_mdp_pipe.c | 2 +- drivers/video/msm/mdss/mdss_mdp_pp.c | 14 +++++++------- drivers/video/msm/mdss/mdss_mdp_util.c | 8 ++++---- drivers/video/msm/mdss/mdss_mdp_wb.c | 10 +++++----- drivers/video/msm/mdss/mdss_util.c | 5 ++--- 18 files changed, 69 insertions(+), 68 deletions(-) diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c index 2a9c9156ac5e1..521eb7e59e9f2 100644 --- a/drivers/video/msm/mdss/mdp3.c +++ b/drivers/video/msm/mdss/mdp3.c @@ -1096,7 +1096,7 @@ static int mdp3_res_init(void) mdp3_res->ion_client = msm_ion_client_create(mdp3_res->pdev->name); if (IS_ERR_OR_NULL(mdp3_res->ion_client)) { - pr_err("msm_ion_client_create() return error (%p)\n", + pr_err("msm_ion_client_create() return error (%pK)\n", mdp3_res->ion_client); mdp3_res->ion_client = NULL; return -EINVAL; @@ -1528,7 +1528,7 @@ void mdp3_unmap_iommu(struct ion_client *client, struct ion_handle *handle) mutex_lock(&mdp3_res->iommu_lock); meta = mdp3_iommu_meta_lookup(table); if (!meta) { - WARN(1, "%s: buffer was never mapped for %p\n", __func__, + WARN(1, "%s: buffer was never mapped for %pK\n", __func__, handle); mutex_unlock(&mdp3_res->iommu_lock); goto out; @@ -1556,7 +1556,7 @@ static void mdp3_iommu_meta_add(struct mdp3_iommu_meta *meta) } else if (meta->table > entry->table) { p = &(*p)->rb_right; } else { - pr_err("%s: handle %p already exists\n", __func__, + pr_err("%s: handle %pK already exists\n", __func__, entry->handle); BUG(); } @@ -1618,7 +1618,7 @@ static int mdp3_iommu_map_iommu(struct mdp3_iommu_meta *meta, ret = iommu_map_range(domain, meta->iova_addr + padding, table->sgl, size, prot); if (ret) { - pr_err("%s: could not map %pa in domain %p\n", + pr_err("%s: could not map %pa in domain %pK\n", __func__, &meta->iova_addr, domain); unmap_size = padding; goto out2; @@ -1741,12 +1741,12 @@ int mdp3_self_map_iommu(struct ion_client *client, struct ion_handle *handle, } } else { if (iommu_meta->flags != iommu_flags) { - pr_err("%s: handle %p is already mapped with diff flag\n", + pr_err("%s: handle %pK is already mapped with diff flag\n", __func__, handle); ret = -EINVAL; goto out_unlock; } else if (iommu_meta->mapped_size != iova_length) { - pr_err("%s: handle %p is already mapped with diff len\n", + pr_err("%s: handle %pK is already mapped with diff len\n", __func__, handle); ret = -EINVAL; goto out_unlock; @@ -1868,7 +1868,7 @@ int mdp3_get_img(struct msmfb_data *img, struct mdp3_img_data *data, int client) data->addr += img->offset; data->len -= img->offset; - pr_debug("mem=%d ihdl=%p buf=0x%pa len=0x%x\n", img->memory_id, + pr_debug("mem=%d ihdl=%pK buf=0x%pa len=0x%x\n", img->memory_id, data->srcp_ihdl, &data->addr, data->len); } else { mdp3_put_img(data, client); @@ -2101,7 +2101,7 @@ static int mdp3_alloc(struct msm_fb_data_type *mfd) return ret; } - pr_info("allocating %u bytes at %p (%lx phys) for fb %d\n", + pr_info("allocating %u bytes at %pK (%lx phys) for fb %d\n", size, virt, phys, mfd->index); mfd->fbi->screen_base = virt; diff --git a/drivers/video/msm/mdss/mdp3_ppp_hwio.c b/drivers/video/msm/mdss/mdp3_ppp_hwio.c index d8c4168e5ead1..43177262fc4b8 100644 --- a/drivers/video/msm/mdss/mdp3_ppp_hwio.c +++ b/drivers/video/msm/mdss/mdp3_ppp_hwio.c @@ -1291,7 +1291,8 @@ int config_ppp_op_mode(struct ppp_blit_op *blit_op) bg_mdp_ops = 0; } pr_debug("BLIT FG Param Fmt %d (x %d,y %d,w %d,h %d), ROI(x %d,y %d, w\ - %d, h %d) Addr_P0 %p, Stride S0 %d Addr_P1 %p, Stride S1 %d\n", + %d, h %d) Addr_P0 %pK, Stride S0 %d Addr_P1 %pK,\ + Stride S1 %d\n", blit_op->src.color_fmt, blit_op->src.prop.x, blit_op->src.prop.y, blit_op->src.prop.width, blit_op->src.prop.height, blit_op->src.roi.x, blit_op->src.roi.y, blit_op->src.roi.width, @@ -1299,14 +1300,15 @@ int config_ppp_op_mode(struct ppp_blit_op *blit_op) blit_op->src.p1, blit_op->src.stride1); if (blit_op->bg.p0 != blit_op->dst.p0) pr_debug("BLIT BG Param Fmt %d (x %d,y %d,w %d,h %d), ROI(x %d,y %d, w\ - %d, h %d) Addr %p, Stride S0 %d Addr_P1 %p, Stride S1 %d\n", + %d, h %d) Addr %pK, Stride S0 %d Addr_P1 %pK,\ + Stride S1 %d\n", blit_op->bg.color_fmt, blit_op->bg.prop.x, blit_op->bg.prop.y, blit_op->bg.prop.width, blit_op->bg.prop.height, blit_op->bg.roi.x, blit_op->bg.roi.y, blit_op->bg.roi.width, blit_op->bg.roi.height, blit_op->bg.p0, blit_op->bg.stride0, blit_op->bg.p1, blit_op->bg.stride1); pr_debug("BLIT FB Param Fmt %d (x %d,y %d,w %d,h %d), ROI(x %d,y %d, w\ - %d, h %d) Addr %p, Stride S0 %d Addr_P1 %p, Stride S1 %d\n", + %d, h %d) Addr %pK, Stride S0 %d Addr_P1 %pK, Stride S1 %d\n", blit_op->dst.color_fmt, blit_op->dst.prop.x, blit_op->dst.prop.y, blit_op->dst.prop.width, blit_op->dst.prop.height, blit_op->dst.roi.x, blit_op->dst.roi.y, blit_op->dst.roi.width, diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c index 3513540f0ae4b..15d7dea14558b 100644 --- a/drivers/video/msm/mdss/mdss_debug.c +++ b/drivers/video/msm/mdss/mdss_debug.c @@ -178,7 +178,7 @@ static ssize_t panel_debug_base_reg_write(struct file *file, for (i = 0; i < len; i++) { p = buf + i * 3; p[2] = 0; - pr_debug("p[%d] = %p:%s\n", i, p, p); + pr_debug("p[%d] = %pK:%s\n", i, p, p); cnt = sscanf(p, "%x", &tmp); reg[i] = tmp; pr_debug("reg[%d] = %x\n", i, (int)reg[i]); @@ -1072,7 +1072,7 @@ void mdss_dump_reg(char __iomem *base, int len) x4 = readl_relaxed(addr+0x4); x8 = readl_relaxed(addr+0x8); xc = readl_relaxed(addr+0xc); - pr_info("%p : %08x %08x %08x %08x\n", addr, x0, x4, x8, xc); + pr_info("%pK : %08x %08x %08x %08x\n", addr, x0, x4, x8, xc); addr += 16; } mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); @@ -1192,7 +1192,7 @@ static inline struct mdss_mdp_misr_map *mdss_misr_get_map(u32 block_id, return NULL; } - pr_debug("MISR Module(%d) CTRL(0x%x) SIG(0x%x) intf_base(0x%p)\n", + pr_debug("MISR Module(%d) CTRL(0x%x) SIG(0x%x) intf_base(0x%pK)\n", block_id, map->ctrl_reg, map->value_reg, intf_base); return map; } @@ -1235,7 +1235,7 @@ int mdss_misr_set(struct mdss_data_type *mdata, bool use_mdp_up_misr = false; if (!mdata || !req || !ctl) { - pr_err("Invalid input params: mdata = %p req = %p ctl = %p", + pr_err("Invalid input params: mdata = %pK req = %pK ctl = %pK", mdata, req, ctl); return -EINVAL; } diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c index 9d12dfb457d92..62c6f120b24f7 100644 --- a/drivers/video/msm/mdss/mdss_dsi.c +++ b/drivers/video/msm/mdss/mdss_dsi.c @@ -471,7 +471,7 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata, int power_state) panel_info = &ctrl_pdata->panel_data.panel_info; - pr_debug("%s+: ctrl=%p ndx=%d power_state=%d\n", + pr_debug("%s+: ctrl=%pK ndx=%d power_state=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx, power_state); if (power_state == panel_info->panel_power_state) { @@ -559,7 +559,7 @@ int mdss_dsi_on(struct mdss_panel_data *pdata) panel_data); cur_power_state = pdata->panel_info.panel_power_state; - pr_debug("%s+: ctrl=%p ndx=%d cur_power_state=%d\n", __func__, + pr_debug("%s+: ctrl=%pK ndx=%d cur_power_state=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx, cur_power_state); pinfo = &pdata->panel_info; @@ -703,7 +703,7 @@ static int mdss_dsi_unblank(struct mdss_panel_data *pdata) panel_data); mipi = &pdata->panel_info.mipi; - pr_debug("%s+: ctrl=%p ndx=%d cur_blank_state=%d\n", __func__, + pr_debug("%s+: ctrl=%pK ndx=%d cur_blank_state=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx, pdata->panel_info.blank_state); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); @@ -756,7 +756,7 @@ static int mdss_dsi_blank(struct mdss_panel_data *pdata, int power_state) panel_data); mipi = &pdata->panel_info.mipi; - pr_debug("%s+: ctrl=%p ndx=%d power_state=%d\n", + pr_debug("%s+: ctrl=%pK ndx=%d power_state=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx, power_state); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); @@ -826,7 +826,7 @@ static int mdss_dsi_post_panel_on(struct mdss_panel_data *pdata) ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s+: ctrl=%p ndx=%d\n", __func__, + pr_debug("%s+: ctrl=%pK ndx=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); @@ -858,7 +858,7 @@ int mdss_dsi_cont_splash_on(struct mdss_panel_data *pdata) ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s+: ctrl=%p ndx=%d\n", __func__, + pr_debug("%s+: ctrl=%pK ndx=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx); WARN((ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT), @@ -1700,7 +1700,7 @@ int mdss_dsi_retrieve_ctrl_resources(struct platform_device *pdev, int mode, return rc; } - pr_info("%s: ctrl_base=%p ctrl_size=%x phy_base=%p phy_size=%x\n", + pr_info("%s: ctrl_base=%pK ctrl_size=%x phy_base=%pK phy_size=%x\n", __func__, ctrl->ctrl_base, ctrl->reg_size, ctrl->phy_io.base, ctrl->phy_io.len); diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c index ace2895d48f94..762cb55f5de33 100644 --- a/drivers/video/msm/mdss/mdss_dsi_host.c +++ b/drivers/video/msm/mdss/mdss_dsi_host.c @@ -97,7 +97,7 @@ void mdss_dsi_ctrl_init(struct device *ctrl_dev, if (ctrl->mdss_util->register_irq(ctrl->dsi_hw)) pr_err("%s: mdss_register_irq failed.\n", __func__); - pr_debug("%s: ndx=%d base=%p\n", __func__, ctrl->ndx, ctrl->ctrl_base); + pr_debug("%s: ndx=%d base=%pK\n", __func__, ctrl->ndx, ctrl->ctrl_base); init_completion(&ctrl->dma_comp); init_completion(&ctrl->mdp_comp); diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c index 8c57c9b8902ab..b1687692357cb 100644 --- a/drivers/video/msm/mdss/mdss_dsi_panel.c +++ b/drivers/video/msm/mdss/mdss_dsi_panel.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -611,7 +611,7 @@ static int mdss_dsi_panel_on(struct mdss_panel_data *pdata) ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx); + pr_debug("%s: ctrl=%pK ndx=%d\n", __func__, ctrl, ctrl->ndx); if (pinfo->dcs_cmd_by_left) { if (ctrl->ndx != DSI_CTRL_LEFT) @@ -641,7 +641,7 @@ static int mdss_dsi_post_panel_on(struct mdss_panel_data *pdata) ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx); + pr_debug("%s: ctrl=%pK ndx=%d\n", __func__, ctrl, ctrl->ndx); pinfo = &pdata->panel_info; if (pinfo->dcs_cmd_by_left) { @@ -651,7 +651,7 @@ static int mdss_dsi_post_panel_on(struct mdss_panel_data *pdata) on_cmds = &ctrl->post_panel_on_cmds; - pr_debug("%s: ctrl=%p cmd_cnt=%d\n", __func__, ctrl, on_cmds->cmd_cnt); + pr_debug("%s: ctrl=%pK cmd_cnt=%d\n", __func__, ctrl, on_cmds->cmd_cnt); if (on_cmds->cmd_cnt) { msleep(50); /* wait for 3 vsync passed */ @@ -677,7 +677,7 @@ static int mdss_dsi_panel_off(struct mdss_panel_data *pdata) ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx); + pr_debug("%s: ctrl=%pK ndx=%d\n", __func__, ctrl, ctrl->ndx); if (pinfo->dcs_cmd_by_left) { if (ctrl->ndx != DSI_CTRL_LEFT) @@ -708,7 +708,7 @@ static int mdss_dsi_panel_low_power_config(struct mdss_panel_data *pdata, ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s: ctrl=%p ndx=%d enable=%d\n", __func__, ctrl, ctrl->ndx, + pr_debug("%s: ctrl=%pK ndx=%d enable=%d\n", __func__, ctrl, ctrl->ndx, enable); /* Any panel specific low power commands/config */ diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c index c06abd3d95167..6f09747da6c05 100644 --- a/drivers/video/msm/mdss/mdss_fb.c +++ b/drivers/video/msm/mdss/mdss_fb.c @@ -1642,7 +1642,7 @@ int mdss_fb_alloc_fb_ion_memory(struct msm_fb_data_type *mfd, size_t fb_size) goto fb_mmap_failed; } - pr_debug("alloc 0x%zuB vaddr = %p (%pa iova) for fb%d\n", fb_size, + pr_debug("alloc 0x%zuB vaddr = %pK (%pa iova) for fb%d\n", fb_size, vaddr, &mfd->iova, mfd->index); mfd->fbi->screen_base = (char *) vaddr; @@ -1735,7 +1735,7 @@ static int mdss_fb_fbmem_ion_mmap(struct fb_info *info, vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); - pr_debug("vma=%p, addr=%x len=%ld\n", + pr_debug("vma=%pK, addr=%x len=%ld\n", vma, (unsigned int)addr, len); pr_debug("vm_start=%x vm_end=%x vm_page_prot=%ld\n", (unsigned int)vma->vm_start, @@ -1905,7 +1905,7 @@ static int mdss_fb_alloc_fbmem_iommu(struct msm_fb_data_type *mfd, int dom) if (rc) pr_warn("Cannot map fb_mem %pa to IOMMU. rc=%d\n", &phys, rc); - pr_debug("alloc 0x%zxB @ (%pa phys) (0x%p virt) (%pa iova) for fb%d\n", + pr_debug("alloc 0x%zxB @ (%pa phys) (0x%pK virt) (%pa iova) for fb%d\n", size, &phys, virt, &mfd->iova, mfd->index); mfd->fbi->screen_base = virt; diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c index 90f92678948c7..140a460b2acb7 100644 --- a/drivers/video/msm/mdss/mdss_hdmi_tx.c +++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1035,7 +1035,7 @@ static int hdmi_tx_sysfs_create(struct hdmi_tx_ctrl *hdmi_ctrl, return rc; } hdmi_ctrl->kobj = &fbi->dev->kobj; - DEV_DBG("%s: sysfs group %p\n", __func__, hdmi_ctrl->kobj); + DEV_DBG("%s: sysfs group %pK\n", __func__, hdmi_ctrl->kobj); return 0; } /* hdmi_tx_sysfs_create */ @@ -3556,7 +3556,7 @@ static int hdmi_tx_init_resource(struct hdmi_tx_ctrl *hdmi_ctrl) DEV_DBG("%s: '%s' remap failed or not available\n", __func__, hdmi_tx_io_name(i)); } - DEV_INFO("%s: '%s': start = 0x%p, len=0x%x\n", __func__, + DEV_INFO("%s: '%s': start = 0x%pK, len=0x%x\n", __func__, hdmi_tx_io_name(i), pdata->io[i].base, pdata->io[i].len); } diff --git a/drivers/video/msm/mdss/mdss_hdmi_util.c b/drivers/video/msm/mdss/mdss_hdmi_util.c index b40ff288551c4..b50aee3483284 100644 --- a/drivers/video/msm/mdss/mdss_hdmi_util.c +++ b/drivers/video/msm/mdss/mdss_hdmi_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -178,7 +178,7 @@ static void hdmi_ddc_print_data(struct hdmi_tx_ddc_data *ddc_data, return; } - DEV_DBG("%s: buf=%p, d_len=0x%x, d_addr=0x%x, no_align=%d\n", + DEV_DBG("%s: buf=%pK, d_len=0x%x, d_addr=0x%x, no_align=%d\n", caller, ddc_data->data_buf, ddc_data->data_len, ddc_data->dev_addr, ddc_data->no_align); DEV_DBG("%s: offset=0x%x, req_len=0x%x, retry=%d, what=%s\n", diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c index 14514f32ee82a..3a53359acb717 100644 --- a/drivers/video/msm/mdss/mdss_mdp.c +++ b/drivers/video/msm/mdss/mdss_mdp.c @@ -1207,7 +1207,7 @@ static u32 mdss_mdp_res_init(struct mdss_data_type *mdata) mdata->iclient = msm_ion_client_create(mdata->pdev->name); if (IS_ERR_OR_NULL(mdata->iclient)) { - pr_err("msm_ion_client_create() return error (%p)\n", + pr_err("msm_ion_client_create() return error (%pK)\n", mdata->iclient); mdata->iclient = NULL; } @@ -1526,7 +1526,7 @@ static int mdss_mdp_probe(struct platform_device *pdev) if (rc) pr_debug("unable to map MDSS VBIF non-realtime base\n"); else - pr_debug("MDSS VBIF NRT HW Base addr=%p len=0x%x\n", + pr_debug("MDSS VBIF NRT HW Base addr=%pK len=0x%x\n", mdata->vbif_nrt_io.base, mdata->vbif_nrt_io.len); res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); diff --git a/drivers/video/msm/mdss/mdss_mdp_debug.c b/drivers/video/msm/mdss/mdss_mdp_debug.c index 39230d1968421..9b1ab8d9ab269 100644 --- a/drivers/video/msm/mdss/mdss_mdp_debug.c +++ b/drivers/video/msm/mdss/mdss_mdp_debug.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -57,13 +57,13 @@ static void __dump_pipe(struct seq_file *s, struct mdss_mdp_pipe *pipe) seq_puts(s, "Data:\n"); if (pipe->front_buf.num_planes) { buf = pipe->front_buf.p; - seq_printf(s, "\tfront_buf ihdl=0x%p addr=%pa size=%lu\n", + seq_printf(s, "\tfront_buf ihdl=0x%pK addr=%pa size=%lu\n", buf->srcp_ihdl, &buf->addr, buf->len); } if (pipe->back_buf.num_planes) { buf = pipe->back_buf.p; - seq_printf(s, "\tback_buf ihdl=0x%p addr=%pa size=%lu\n", + seq_printf(s, "\tback_buf ihdl=0x%pK addr=%pa size=%lu\n", buf->srcp_ihdl, &buf->addr, buf->len); } } diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c index 6f6fc91b16b85..b07b3c523e5e1 100644 --- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -581,7 +581,7 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg) ctx->rdptr_enabled, ctl->roi_bkup.w, ctl->roi_bkup.h); - pr_debug("%s: intf_num=%d ctx=%p koff_cnt=%d\n", __func__, + pr_debug("%s: intf_num=%d ctx=%pK koff_cnt=%d\n", __func__, ctl->intf_num, ctx, atomic_read(&ctx->koff_cnt)); rc = wait_event_timeout(ctx->pp_waitq, @@ -1164,7 +1164,7 @@ static int mdss_mdp_cmd_intfs_setup(struct mdss_mdp_ctl *ctl, ctx->intf_stopped = 0; - pr_debug("%s: ctx=%p num=%d mixer=%d\n", __func__, + pr_debug("%s: ctx=%pK num=%d mixer=%d\n", __func__, ctx, ctx->pp_num, mixer->num); MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), ctx->clk_enabled, ctx->rdptr_enabled); diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c index 2bc8a1db0b109..9ce6885af7544 100644 --- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c +++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c @@ -116,7 +116,7 @@ int mdss_mdp_video_addr_setup(struct mdss_data_type *mdata, for (i = 0; i < count; i++) { head[i].base = mdata->mdss_io.base + offsets[i]; - pr_debug("adding Video Intf #%d offset=0x%x virt=%p\n", i, + pr_debug("adding Video Intf #%d offset=0x%x virt=%pK\n", i, offsets[i], head[i].base); head[i].ref_cnt = 0; head[i].intf_num = i + MDSS_MDP_INTF0; @@ -442,7 +442,7 @@ static int mdss_mdp_video_intfs_stop(struct mdss_mdp_ctl *ctl, pr_err("Intf %d not in use\n", (inum + MDSS_MDP_INTF0)); return -ENODEV; } - pr_debug("stop ctl=%d video Intf #%d base=%p", ctl->num, + pr_debug("stop ctl=%d video Intf #%d base=%pK", ctl->num, ctx->intf_num, ctx->base); } else { pr_err("Invalid intf number: %d\n", (inum + MDSS_MDP_INTF0)); @@ -1158,7 +1158,7 @@ static int mdss_mdp_video_intfs_setup(struct mdss_mdp_ctl *ctl, (inum + MDSS_MDP_INTF0)); return -EBUSY; } - pr_debug("video Intf #%d base=%p", ctx->intf_num, ctx->base); + pr_debug("video Intf #%d base=%pK", ctx->intf_num, ctx->base); ctx->ref_cnt++; } else { pr_err("Invalid intf number: %d\n", (inum + MDSS_MDP_INTF0)); diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c index b74767078ae2b..d8d01afb4e059 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pipe.c +++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c @@ -1739,7 +1739,7 @@ int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe, } if (src_data == NULL) { - pr_debug("src_data=%p pipe num=%dx\n", + pr_debug("src_data=%pK pipe num=%dx\n", src_data, pipe->num); goto update_nobuf; } diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c index 3cfa92624ce85..5065bc8da1627 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pp.c +++ b/drivers/video/msm/mdss/mdss_mdp_pp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2224,7 +2224,7 @@ static int pp_ad_calc_bl(struct msm_fb_data_type *mfd, int bl_in, int *bl_out, pr_debug("AD not supported on device.\n"); return ret; } else if (ret || !ad) { - pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", + pr_err("Failed to get ad info: ret = %d, ad = 0x%pK.\n", ret, ad); return ret; } @@ -2240,7 +2240,7 @@ static int pp_ad_calc_bl(struct msm_fb_data_type *mfd, int bl_in, int *bl_out, if (!ad->bl_mfd || !ad->bl_mfd->panel_info || !ad->bl_att_lut) { - pr_err("Invalid ad info: bl_mfd = 0x%p, ad->bl_mfd->panel_info = 0x%p, bl_att_lut = 0x%p\n", + pr_err("Invalid ad info: bl_mfd = 0x%pK, ad->bl_mfd->panel_info = 0x%pK, bl_att_lut = 0x%pK\n", ad->bl_mfd, (!ad->bl_mfd) ? NULL : ad->bl_mfd->panel_info, ad->bl_att_lut); @@ -3507,7 +3507,7 @@ static int pp_hist_enable(struct pp_hist_col_info *hist_info, spin_lock_irqsave(&hist_info->hist_lock, flag); if (hist_info->col_en) { spin_unlock_irqrestore(&hist_info->hist_lock, flag); - pr_info("%s Hist collection has already been enabled %p\n", + pr_info("%s Hist collection has already been enabled %pK\n", __func__, hist_info->base); goto exit; } @@ -3644,7 +3644,7 @@ static int pp_hist_disable(struct pp_hist_col_info *hist_info) spin_lock_irqsave(&hist_info->hist_lock, flag); if (hist_info->col_en == false) { spin_unlock_irqrestore(&hist_info->hist_lock, flag); - pr_debug("Histogram already disabled (%p)\n", hist_info->base); + pr_debug("Histogram already disabled (%pK)\n", hist_info->base); ret = -EINVAL; goto exit; } @@ -3758,7 +3758,7 @@ int mdss_mdp_hist_intr_req(struct mdss_intr *intr, u32 bits, bool en) unsigned long flag; int ret = 0; if (!intr) { - pr_err("NULL addr passed, %p\n", intr); + pr_err("NULL addr passed, %pK\n", intr); return -EINVAL; } @@ -4512,7 +4512,7 @@ static int pp_ad_invalidate_input(struct msm_fb_data_type *mfd) ret = mdss_mdp_get_ad(mfd, &ad); if (ret || !ad) { - pr_err("Fail to get ad: ret = %d, ad = 0x%p\n", ret, ad); + pr_err("Fail to get ad: ret = %d, ad = 0x%pK\n", ret, ad); return -EINVAL; } pr_debug("AD backlight level changed (%d), trigger update to AD\n", diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c index c62acf3db78b0..926dfdef15851 100644 --- a/drivers/video/msm/mdss/mdss_mdp_util.c +++ b/drivers/video/msm/mdss/mdss_mdp_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -507,7 +507,7 @@ static int mdss_mdp_put_img(struct mdss_mdp_img_data *data) pr_debug("pmem buf=0x%pa\n", &data->addr); data->srcp_file = NULL; } else if (!IS_ERR_OR_NULL(data->srcp_ihdl)) { - pr_debug("ion hdl=%p buf=0x%pa\n", data->srcp_ihdl, + pr_debug("ion hdl=%pK buf=0x%pa\n", data->srcp_ihdl, &data->addr); if (!iclient) { pr_err("invalid ion client\n"); @@ -599,7 +599,7 @@ static int mdss_mdp_get_img(struct msmfb_data *img, data->addr += data->offset; data->len -= data->offset; - pr_debug("mem=%d ihdl=%p buf=0x%pa len=0x%lu\n", img->memory_id, + pr_debug("mem=%d ihdl=%pK buf=0x%pa len=0x%lu\n", img->memory_id, data->srcp_ihdl, &data->addr, data->len); } else { mdss_mdp_put_img(data); @@ -653,7 +653,7 @@ static int mdss_mdp_map_buffer(struct mdss_mdp_img_data *data) data->addr += data->offset; data->len -= data->offset; - pr_debug("ihdl=%p buf=0x%pa len=0x%lu\n", + pr_debug("ihdl=%pK buf=0x%pa len=0x%lu\n", data->srcp_ihdl, &data->addr, data->len); } else { mdss_mdp_put_img(data); diff --git a/drivers/video/msm/mdss/mdss_mdp_wb.c b/drivers/video/msm/mdss/mdss_mdp_wb.c index def90ebb39490..da6587ef6a54f 100644 --- a/drivers/video/msm/mdss/mdss_mdp_wb.c +++ b/drivers/video/msm/mdss/mdss_mdp_wb.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -95,7 +95,7 @@ struct mdss_mdp_data *mdss_mdp_wb_debug_buffer(struct msm_fb_data_type *mfd) ihdl = ion_alloc(iclient, img_size, SZ_4K, ION_HEAP(ION_SF_HEAP_ID), 0); if (IS_ERR_OR_NULL(ihdl)) { - pr_err("unable to alloc fbmem from ion (%p)\n", ihdl); + pr_err("unable to alloc fbmem from ion (%pK)\n", ihdl); return NULL; } @@ -122,7 +122,7 @@ struct mdss_mdp_data *mdss_mdp_wb_debug_buffer(struct msm_fb_data_type *mfd) img->len = img_size; } - pr_debug("ihdl=%p virt=%p phys=0x%pa iova=0x%pa size=%u\n", + pr_debug("ihdl=%pK virt=%pK phys=0x%pa iova=0x%pa size=%u\n", ihdl, videomemory, &mdss_wb_mem, &img->addr, img_size); } return &mdss_wb_buffer; @@ -435,7 +435,7 @@ static struct mdss_mdp_wb_data *get_user_node(struct msm_fb_data_type *mfd, list_for_each_entry(node, &wb->register_queue, registered_entry) if ((node->buf_data.p[0].srcp_ihdl == ihdl) && (node->buf_info.offset == data->offset)) { - pr_debug("found fd=%d hdl=%p off=%x addr=%pa\n", + pr_debug("found fd=%d hdl=%pK off=%x addr=%pa\n", data->memory_id, ihdl, data->offset, &node->buf_data.p[0].addr); @@ -501,7 +501,7 @@ static void mdss_mdp_wb_free_node(struct mdss_mdp_wb_data *node) if (node->user_alloc) { buf = &node->buf_data.p[0]; - pr_debug("free user mem_id=%d ihdl=%p, offset=%u addr=0x%pa\n", + pr_debug("free user mem_id=%d ihdl=%pK, offset=%u addr=0x%pa\n", node->buf_info.memory_id, buf->srcp_ihdl, node->buf_info.offset, diff --git a/drivers/video/msm/mdss/mdss_util.c b/drivers/video/msm/mdss/mdss_util.c index 587db41a9d105..345b0927bc58e 100644 --- a/drivers/video/msm/mdss/mdss_util.c +++ b/drivers/video/msm/mdss/mdss_util.c @@ -1,5 +1,4 @@ - -/* Copyright (c) 2007-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2007-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -33,7 +32,7 @@ int mdss_register_irq(struct mdss_hw *hw) if (!mdss_irq_handlers[hw->hw_ndx]) mdss_irq_handlers[hw->hw_ndx] = hw; else - pr_err("panel %d's irq at %p is already registered\n", + pr_err("panel %d's irq at %pK is already registered\n", hw->hw_ndx, hw->irq_handler); spin_unlock_irqrestore(&mdss_lock, irq_flags); From 5efdee55f45f8d4ab99958f4b7215911c9634adb Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 29 Aug 2016 21:58:32 +0530 Subject: [PATCH 251/320] misc: qcom: qdsp6v2: initialize config_32 Not all memebers of config_32 are set before they are used which might lead to invalid values being passed and used. To fix this issue initialize all member variables of struct config_32 to 0 before assigning specific values individually. CRs-Fixed: 1058826 Change-Id: Ifea3a6e8bf45481c65a4455ee64318304798fee2 Signed-off-by: Laxminath Kasam --- drivers/misc/qcom/qdsp6v2/aac_in.c | 4 +++- drivers/misc/qcom/qdsp6v2/amrnb_in.c | 5 ++++- drivers/misc/qcom/qdsp6v2/amrwb_in.c | 2 ++ drivers/misc/qcom/qdsp6v2/audio_alac.c | 4 +++- drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c | 6 +++++- drivers/misc/qcom/qdsp6v2/audio_ape.c | 4 +++- drivers/misc/qcom/qdsp6v2/audio_multi_aac.c | 4 +++- drivers/misc/qcom/qdsp6v2/audio_utils_aio.c | 1 + drivers/misc/qcom/qdsp6v2/audio_wmapro.c | 4 +++- drivers/misc/qcom/qdsp6v2/evrc_in.c | 4 +++- drivers/misc/qcom/qdsp6v2/qcelp_in.c | 4 +++- 11 files changed, 33 insertions(+), 9 deletions(-) diff --git a/drivers/misc/qcom/qdsp6v2/aac_in.c b/drivers/misc/qcom/qdsp6v2/aac_in.c index 38db0381c50e8..a5ad927345f60 100644 --- a/drivers/misc/qcom/qdsp6v2/aac_in.c +++ b/drivers/misc/qcom/qdsp6v2/aac_in.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -425,6 +425,8 @@ static long aac_in_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_aac_enc_config cfg; struct msm_audio_aac_enc_config32 cfg_32; + memset(&cfg_32, 0, sizeof(cfg_32)); + cmd = AUDIO_GET_AAC_ENC_CONFIG; rc = aac_in_ioctl_shared(file, cmd, &cfg); if (rc) { diff --git a/drivers/misc/qcom/qdsp6v2/amrnb_in.c b/drivers/misc/qcom/qdsp6v2/amrnb_in.c index eb92137f06717..1bb441bd2ff48 100644 --- a/drivers/misc/qcom/qdsp6v2/amrnb_in.c +++ b/drivers/misc/qcom/qdsp6v2/amrnb_in.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2010-2012, 2014 The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2012, 2014, 2016 The Linux Foundation. + * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -221,6 +222,8 @@ static long amrnb_in_compat_ioctl(struct file *file, struct msm_audio_amrnb_enc_config_v2 *amrnb_config; struct msm_audio_amrnb_enc_config_v2_32 amrnb_config_32; + memset(&amrnb_config_32, 0, sizeof(amrnb_config_32)); + amrnb_config = (struct msm_audio_amrnb_enc_config_v2 *)audio->enc_cfg; amrnb_config_32.band_mode = amrnb_config->band_mode; diff --git a/drivers/misc/qcom/qdsp6v2/amrwb_in.c b/drivers/misc/qcom/qdsp6v2/amrwb_in.c index 4cea3dc63389f..71adbce0e257c 100644 --- a/drivers/misc/qcom/qdsp6v2/amrwb_in.c +++ b/drivers/misc/qcom/qdsp6v2/amrwb_in.c @@ -216,6 +216,8 @@ static long amrwb_in_compat_ioctl(struct file *file, struct msm_audio_amrwb_enc_config *amrwb_config; struct msm_audio_amrwb_enc_config_32 amrwb_config_32; + memset(&amrwb_config_32, 0, sizeof(amrwb_config_32)); + amrwb_config = (struct msm_audio_amrwb_enc_config *)audio->enc_cfg; amrwb_config_32.band_mode = amrwb_config->band_mode; diff --git a/drivers/misc/qcom/qdsp6v2/audio_alac.c b/drivers/misc/qcom/qdsp6v2/audio_alac.c index d6ca657c22e3b..94a1843040e64 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_alac.c +++ b/drivers/misc/qcom/qdsp6v2/audio_alac.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -176,6 +176,8 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_alac_config *alac_config; struct msm_audio_alac_config_32 alac_config_32; + memset(&alac_config_32, 0, sizeof(alac_config_32)); + alac_config = (struct msm_audio_alac_config *)audio->codec_cfg; alac_config_32.frameLength = alac_config->frameLength; alac_config_32.compatVersion = diff --git a/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c b/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c index bd2b5e31dc5ca..295193c901126 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c +++ b/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c @@ -2,7 +2,7 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2014,2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -202,6 +202,10 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_amrwbplus_config_v2 *amrwbplus_config; struct msm_audio_amrwbplus_config_v2_32 amrwbplus_config_32; + + memset(&amrwbplus_config_32, 0, + sizeof(amrwbplus_config_32)); + amrwbplus_config = (struct msm_audio_amrwbplus_config_v2 *) audio->codec_cfg; diff --git a/drivers/misc/qcom/qdsp6v2/audio_ape.c b/drivers/misc/qcom/qdsp6v2/audio_ape.c index 983835524e90c..ab3ddb58388f3 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_ape.c +++ b/drivers/misc/qcom/qdsp6v2/audio_ape.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -177,6 +177,8 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_ape_config *ape_config; struct msm_audio_ape_config_32 ape_config_32; + memset(&ape_config_32, 0, sizeof(ape_config_32)); + ape_config = (struct msm_audio_ape_config *)audio->codec_cfg; ape_config_32.compatibleVersion = ape_config->compatibleVersion; ape_config_32.compressionLevel = diff --git a/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c b/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c index 28c1d361fee1b..f4f669a043c95 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c +++ b/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c @@ -2,7 +2,7 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2014,2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -302,6 +302,8 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_aac_config *aac_config; struct msm_audio_aac_config32 aac_config_32; + memset(&aac_config_32, 0, sizeof(aac_config_32)); + aac_config = (struct msm_audio_aac_config *)audio->codec_cfg; aac_config_32.format = aac_config->format; aac_config_32.audio_object = aac_config->audio_object; diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c index a1d5e461a7c42..80411116dedc1 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c @@ -1972,6 +1972,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, audio->buf_cfg.frames_per_buf); mutex_lock(&audio->lock); + memset(&cfg_32, 0, sizeof(cfg_32)); cfg_32.meta_info_enable = audio->buf_cfg.meta_info_enable; cfg_32.frames_per_buf = audio->buf_cfg.frames_per_buf; if (copy_to_user((void *)arg, &cfg_32, diff --git a/drivers/misc/qcom/qdsp6v2/audio_wmapro.c b/drivers/misc/qcom/qdsp6v2/audio_wmapro.c index 54c05062703e3..1a97daeffef82 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_wmapro.c +++ b/drivers/misc/qcom/qdsp6v2/audio_wmapro.c @@ -2,7 +2,7 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2009-2014,2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -220,6 +220,8 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_wmapro_config *wmapro_config; struct msm_audio_wmapro_config32 wmapro_config_32; + memset(&wmapro_config_32, 0, sizeof(wmapro_config_32)); + wmapro_config = (struct msm_audio_wmapro_config *)audio->codec_cfg; wmapro_config_32.armdatareqthr = wmapro_config->armdatareqthr; diff --git a/drivers/misc/qcom/qdsp6v2/evrc_in.c b/drivers/misc/qcom/qdsp6v2/evrc_in.c index 1b8f8ad451db6..d7d67dec46061 100644 --- a/drivers/misc/qcom/qdsp6v2/evrc_in.c +++ b/drivers/misc/qcom/qdsp6v2/evrc_in.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -224,6 +224,8 @@ static long evrc_in_compat_ioctl(struct file *file, struct msm_audio_evrc_enc_config32 cfg_32; struct msm_audio_evrc_enc_config *enc_cfg; + memset(&cfg_32, 0, sizeof(cfg_32)); + enc_cfg = audio->enc_cfg; cfg_32.cdma_rate = enc_cfg->cdma_rate; cfg_32.min_bit_rate = enc_cfg->min_bit_rate; diff --git a/drivers/misc/qcom/qdsp6v2/qcelp_in.c b/drivers/misc/qcom/qdsp6v2/qcelp_in.c index 6dbb90d2a24e6..d1a8a8e5bcf78 100644 --- a/drivers/misc/qcom/qdsp6v2/qcelp_in.c +++ b/drivers/misc/qcom/qdsp6v2/qcelp_in.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -225,6 +225,8 @@ static long qcelp_in_compat_ioctl(struct file *file, struct msm_audio_qcelp_enc_config32 cfg_32; struct msm_audio_qcelp_enc_config *enc_cfg; + memset(&cfg_32, 0, sizeof(cfg_32)); + enc_cfg = (struct msm_audio_qcelp_enc_config *)audio->enc_cfg; cfg_32.cdma_rate = enc_cfg->cdma_rate; cfg_32.min_bit_rate = enc_cfg->min_bit_rate; From ec7efbb2e884af58e59277e432b9f1e3ef2d9ac1 Mon Sep 17 00:00:00 2001 From: Charan Teja Reddy Date: Thu, 8 Sep 2016 20:47:55 +0530 Subject: [PATCH 252/320] coresight: fix the dangling pointer issues on coresight Fix the dangling pointer issues on CoreSight that can cause kernel panic. Change-Id: If3abe89bf0326230c29a49d293ab22ebcec93076 Signed-off-by: Charan Teja Reddy --- drivers/coresight/coresight-csr.c | 7 ++++--- drivers/coresight/coresight-fuse.c | 7 ++++--- drivers/soc/qcom/jtag-fuse.c | 6 +++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/coresight/coresight-csr.c b/drivers/coresight/coresight-csr.c index 19e44b9c5d3be..7ad40f16d303c 100644 --- a/drivers/coresight/coresight-csr.c +++ b/drivers/coresight/coresight-csr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2013,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -195,8 +195,6 @@ static int csr_probe(struct platform_device *pdev) drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; - /* Store the driver data pointer for use in exported functions */ - csrdrvdata = drvdata; drvdata->dev = &pdev->dev; platform_set_drvdata(pdev, drvdata); @@ -227,6 +225,9 @@ static int csr_probe(struct platform_device *pdev) if (IS_ERR(drvdata->csdev)) return PTR_ERR(drvdata->csdev); + /* Store the driver data pointer for use in exported functions */ + csrdrvdata = drvdata; + dev_info(dev, "CSR initialized\n"); return 0; } diff --git a/drivers/coresight/coresight-fuse.c b/drivers/coresight/coresight-fuse.c index 94689285d8d86..cdbfc7a2ac13c 100644 --- a/drivers/coresight/coresight-fuse.c +++ b/drivers/coresight/coresight-fuse.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -252,8 +252,6 @@ static int fuse_probe(struct platform_device *pdev) drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; - /* Store the driver data pointer for use in exported functions */ - fusedrvdata = drvdata; drvdata->dev = &pdev->dev; platform_set_drvdata(pdev, drvdata); @@ -315,6 +313,9 @@ static int fuse_probe(struct platform_device *pdev) if (IS_ERR(drvdata->csdev)) return PTR_ERR(drvdata->csdev); + /* Store the driver data pointer for use in exported functions */ + fusedrvdata = drvdata; + dev_info(dev, "Fuse initialized\n"); return 0; } diff --git a/drivers/soc/qcom/jtag-fuse.c b/drivers/soc/qcom/jtag-fuse.c index 46de4e5f2026e..d7389f397b9ce 100644 --- a/drivers/soc/qcom/jtag-fuse.c +++ b/drivers/soc/qcom/jtag-fuse.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -152,8 +152,6 @@ static int jtag_fuse_probe(struct platform_device *pdev) drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; - /* Store the driver data pointer for use in exported functions */ - fusedrvdata = drvdata; drvdata->dev = &pdev->dev; platform_set_drvdata(pdev, drvdata); @@ -174,6 +172,8 @@ static int jtag_fuse_probe(struct platform_device *pdev) if (!drvdata->base) return -ENOMEM; + /* Store the driver data pointer for use in exported functions */ + fusedrvdata = drvdata; dev_info(dev, "JTag Fuse initialized\n"); return 0; } From e9784ffa858f91f87acb2d599d2b9b30ba5464e7 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Wed, 16 Dec 2015 15:42:39 -0800 Subject: [PATCH 253/320] ASoC: msm-lsm-client: free lsm client data in msm_lsm_close Currently lsm client data is deallocated when q6lsm_open() fails which can cause memory corruption if lsm client data is accessed after freed. Fix this issue by deallocating the client data only in msm_lsm_close(). Change-Id: If048c26a0ffd8a346a28622183cbf2ba1e7e5ff3 Signed-off-by: Vidyakumar Athota --- include/sound/q6lsm.h | 1 + sound/soc/msm/qdsp6v2/msm-lsm-client.c | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/sound/q6lsm.h b/include/sound/q6lsm.h index db64e37b81e07..19f20c5abfb66 100644 --- a/include/sound/q6lsm.h +++ b/include/sound/q6lsm.h @@ -73,6 +73,7 @@ struct lsm_client { uint16_t connect_to_port; uint8_t num_confidence_levels; uint8_t *confidence_levels; + bool opened; bool started; dma_addr_t lsm_cal_phy_addr; uint32_t lsm_cal_size; diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/sound/soc/msm/qdsp6v2/msm-lsm-client.c index dc7ce933064ee..f7cecd5396cd7 100644 --- a/sound/soc/msm/qdsp6v2/msm-lsm-client.c +++ b/sound/soc/msm/qdsp6v2/msm-lsm-client.c @@ -753,10 +753,9 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: lsm open failed, %d\n", __func__, ret); - q6lsm_client_free(prtd->lsm_client); - kfree(prtd); return ret; } + prtd->lsm_client->opened = true; dev_dbg(rtd->dev, "%s: Session_ID = %d, APP ID = %d\n", __func__, prtd->lsm_client->session, @@ -1730,7 +1729,7 @@ static int msm_lsm_open(struct snd_pcm_substream *substream) prtd->lsm_client->session_state = IDLE; prtd->lsm_client->poll_enable = true; prtd->lsm_client->perf_mode = 0; - + prtd->lsm_client->opened = false; return 0; } @@ -1820,7 +1819,10 @@ static int msm_lsm_close(struct snd_pcm_substream *substream) msm_pcm_routing_dereg_phy_stream(rtd->dai_link->be_id, SNDRV_PCM_STREAM_CAPTURE); - q6lsm_close(prtd->lsm_client); + if (prtd->lsm_client->opened) { + q6lsm_close(prtd->lsm_client); + prtd->lsm_client->opened = false; + } q6lsm_client_free(prtd->lsm_client); spin_lock_irqsave(&prtd->event_lock, flags); @@ -1828,6 +1830,7 @@ static int msm_lsm_close(struct snd_pcm_substream *substream) prtd->event_status = NULL; spin_unlock_irqrestore(&prtd->event_lock, flags); kfree(prtd); + runtime->private_data = NULL; return 0; } From 7e100ec9e96e34a7cdff53dfae988a457ce4d88c Mon Sep 17 00:00:00 2001 From: VijayaKumar T M Date: Wed, 7 Sep 2016 12:53:43 +0530 Subject: [PATCH 254/320] msm: camera: Restructure data handling to be more robust Use dynamic array allocation instead of static array to prevent stack overflow. User-supplied number of bytes may result in integer overflow. To fix this we check that the num_byte isn't above 8K size. CRs-Fixed: 1060554 Change-Id: I9b05b846e5cc3a62b1a0a67be529f09abc764796 Signed-off-by: VijayaKumar T M --- .../camera_v2/sensor/io/msm_camera_cci_i2c.c | 6 +++ .../camera_v2/sensor/io/msm_camera_qup_i2c.c | 39 ++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c index edc40c95ee6e6..448cea0d4cd86 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c @@ -71,6 +71,12 @@ int32_t msm_camera_cci_i2c_read_seq(struct msm_camera_i2c_client *client, || num_byte == 0) return rc; + if (num_byte > I2C_REG_DATA_MAX) { + pr_err("%s: Error num_byte:0x%x exceeds 8K max supported:0x%x\n", + __func__, num_byte, I2C_REG_DATA_MAX); + return rc; + } + buf = kzalloc(num_byte, GFP_KERNEL); if (!buf) { pr_err("%s:%d no memory\n", __func__, __LINE__); diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c index a40c84eb53dea..f8e74a9a5cc59 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c @@ -102,7 +102,7 @@ int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client, enum msm_camera_i2c_data_type data_type) { int32_t rc = -EFAULT; - unsigned char buf[client->addr_type+data_type]; + unsigned char *buf = NULL; if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR && client->addr_type != MSM_CAMERA_I2C_WORD_ADDR) @@ -110,6 +110,17 @@ int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client, && data_type != MSM_CAMERA_I2C_WORD_DATA)) return rc; + if (client->addr_type > UINT_MAX - data_type) { + pr_err("%s: integer overflow prevented\n", __func__); + return rc; + } + + buf = kzalloc(client->addr_type+data_type, GFP_KERNEL); + if (!buf) { + pr_err("%s:%d no memory\n", __func__, __LINE__); + return -ENOMEM; + } + if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) { buf[0] = addr; } else if (client->addr_type == MSM_CAMERA_I2C_WORD_ADDR) { @@ -119,6 +130,8 @@ int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client, rc = msm_camera_qup_i2c_rxdata(client, buf, data_type); if (rc < 0) { S_I2C_DBG("%s fail\n", __func__); + kfree(buf); + buf = NULL; return rc; } @@ -128,6 +141,8 @@ int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client, *data = buf[0] << 8 | buf[1]; S_I2C_DBG("%s addr = 0x%x data: 0x%x\n", __func__, addr, *data); + kfree(buf); + buf = NULL; return rc; } @@ -135,7 +150,7 @@ int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client, uint32_t addr, uint8_t *data, uint32_t num_byte) { int32_t rc = -EFAULT; - unsigned char buf[client->addr_type+num_byte]; + unsigned char *buf = NULL; int i; if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR @@ -143,6 +158,22 @@ int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client, || num_byte == 0) return rc; + if (num_byte > I2C_REG_DATA_MAX) { + pr_err("%s: Error num_byte:0x%x exceeds 8K max supported:0x%x\n", + __func__, num_byte, I2C_REG_DATA_MAX); + return rc; + } + if (client->addr_type > UINT_MAX - num_byte) { + pr_err("%s: integer overflow prevented\n", __func__); + return rc; + } + + buf = kzalloc(client->addr_type+num_byte, GFP_KERNEL); + if (!buf) { + pr_err("%s:%d no memory\n", __func__, __LINE__); + return -ENOMEM; + } + if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) { buf[0] = addr; } else if (client->addr_type == MSM_CAMERA_I2C_WORD_ADDR) { @@ -152,6 +183,8 @@ int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client, rc = msm_camera_qup_i2c_rxdata(client, buf, num_byte); if (rc < 0) { S_I2C_DBG("%s fail\n", __func__); + kfree(buf); + buf = NULL; return rc; } @@ -161,6 +194,8 @@ int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client, S_I2C_DBG("Byte %d: 0x%x\n", i, buf[i]); S_I2C_DBG("Data: 0x%x\n", data[i]); } + kfree(buf); + buf = NULL; return rc; } From 633b51cd36200ea8501ff41ba703e9063caa56f9 Mon Sep 17 00:00:00 2001 From: Raghavendra Ambadas Date: Wed, 14 Sep 2016 12:04:46 +0530 Subject: [PATCH 255/320] msm: mdss: Disable histogram interrupt in ISR Histogram INTR done msg are seen when there is a sync issue between histogram disable and histogram ISR call. To avoid error logging, check the HIST status and disable the histogram interrupt in ISR. Change-Id: Ib24251a00903d9f3f20034be3d12fb1e321b4aba Signed-off-by: Raghavendra Ambadas --- drivers/video/msm/mdss/mdss_mdp_pp.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c index 5065bc8da1627..421fd18f0d2a3 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pp.c +++ b/drivers/video/msm/mdss/mdss_mdp_pp.c @@ -4318,6 +4318,7 @@ void mdss_mdp_hist_intr_done(u32 isr) bool need_complete = false; u32 isr_mask = (is_hist_v2) ? HIST_V2_INTR_BIT_MASK : HIST_V1_INTR_BIT_MASK; + u32 intr_mask = is_hist_v2 ? 1 : 3; isr &= isr_mask; while (isr != 0) { @@ -4352,7 +4353,16 @@ void mdss_mdp_hist_intr_done(u32 isr) * Histogram collection is disabled yet we got an * interrupt somehow. */ - pr_err("hist Done interrupt, col_en=false!\n"); + if (mdata->mdp_hist_irq_mask == + (intr_mask << hist_info->intr_shift)) { + mdss_mdp_hist_intr_req(&mdata->hist_intr, + intr_mask << hist_info->intr_shift, + false); + pr_err("Disable hist interrupt, irq mask=%x\n", + mdata->mdp_hist_irq_mask); + } else { + pr_err("hist Done interrupt, col_en=false!\n"); + } } /* Histogram Reset Done Interrupt */ if (hist_info && is_hist_reset_done && (hist_info->col_en)) { From c4fb3de631ee9baae8eb7057731e602cbc1c4c90 Mon Sep 17 00:00:00 2001 From: Mohamad Ayyash Date: Wed, 11 May 2016 13:18:35 -0700 Subject: [PATCH 256/320] Don't show empty tag stats for unprivileged uids BUG: 27577101 BUG: 27532522 Change-Id: If0c03fa24270cd3683db482a599fc39e9fec1ac9 Signed-off-by: Mohamad Ayyash Git-commit: d85e322ff3bc8d7aa872ad12df6427dd236e540a Git-repo: https://android.googlesource.com/kernel/common Signed-off-by: Ravi Kumar Siddojigari --- net/netfilter/xt_qtaguid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c index c690e0f19b454..9ce62282edb07 100644 --- a/net/netfilter/xt_qtaguid.c +++ b/net/netfilter/xt_qtaguid.c @@ -2521,7 +2521,7 @@ static int pp_stats_line(struct seq_file *m, struct tag_stat *ts_entry, uid_t stat_uid = get_uid_from_tag(tag); struct proc_print_info *ppi = m->private; /* Detailed tags are not available to everybody */ - if (get_atag_from_tag(tag) && !can_read_other_uid_stats(stat_uid)) { + if (!can_read_other_uid_stats(stat_uid)) { CT_DEBUG("qtaguid: stats line: " "%s 0x%llx %u: insufficient priv " "from pid=%u tgid=%u uid=%u stats.gid=%u\n", From afec2e4d3e888b9f548c49626e755626350b61e5 Mon Sep 17 00:00:00 2001 From: Mallikarjuna Reddy Amireddy Date: Wed, 15 Oct 2014 19:03:11 +0530 Subject: [PATCH 257/320] qcedev: msm: Remove gating of zero length packets for authentication Crypto drivers has zero length checks during the parameters validation, which results in failures for zero length input. This patch update the checks in crypto drivers to support SHA1/SHA256/HMAC/CMAC zero length input data. Change-Id: Ic58385d78b7bc5839674f118e1935361d8e5563d Signed-off-by: Mallikarjuna Reddy Amireddy --- drivers/crypto/msm/qcedev.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c index 2313d927c53ad..a85f6fd468b91 100644 --- a/drivers/crypto/msm/qcedev.c +++ b/drivers/crypto/msm/qcedev.c @@ -832,11 +832,6 @@ static int qcedev_sha_final(struct qcedev_async_req *qcedev_areq, return -EINVAL; } - if (handle->sha_ctxt.trailing_buf_len == 0) { - pr_err("%s Incorrect trailng buffer %d\n", __func__, - handle->sha_ctxt.trailing_buf_len); - return -EINVAL; - } handle->sha_ctxt.last_blk = 1; total = handle->sha_ctxt.trailing_buf_len; @@ -1606,10 +1601,9 @@ static int qcedev_check_sha_params(struct qcedev_sha_op_req *req, pr_err("%s: CMAC not supported\n", __func__); goto sha_error; } - if ((req->entries == 0) || (req->data_len == 0) || - (req->entries > QCEDEV_MAX_BUFFERS)) { - pr_err("%s: Invalid data length (%d)/ num entries (%d)\n", - __func__, req->data_len, req->entries); + if ((!req->entries) || (req->entries > QCEDEV_MAX_BUFFERS)) { + pr_err("%s: Invalid num entries (%d)\n", + __func__, req->entries); goto sha_error; } From 031a745f923b081c3e0fc411385d58decb6c1612 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Wed, 23 Mar 2016 16:38:55 +0100 Subject: [PATCH 258/320] ppp: take reference on channels netns Let channels hold a reference on their network namespace. Some channel types, like ppp_async and ppp_synctty, can have their userspace controller running in a different namespace. Therefore they can't rely on them to preclude their netns from being removed from under them. ================================================================== BUG: KASAN: use-after-free in ppp_unregister_channel+0x372/0x3a0 at addr ffff880064e217e0 Read of size 8 by task syz-executor/11581 ============================================================================= BUG net_namespace (Not tainted): kasan: bad access detected ----------------------------------------------------------------------------- Disabling lock debugging due to kernel taint INFO: Allocated in copy_net_ns+0x6b/0x1a0 age=92569 cpu=3 pid=6906 [< none >] ___slab_alloc+0x4c7/0x500 kernel/mm/slub.c:2440 [< none >] __slab_alloc+0x4c/0x90 kernel/mm/slub.c:2469 [< inline >] slab_alloc_node kernel/mm/slub.c:2532 [< inline >] slab_alloc kernel/mm/slub.c:2574 [< none >] kmem_cache_alloc+0x23a/0x2b0 kernel/mm/slub.c:2579 [< inline >] kmem_cache_zalloc kernel/include/linux/slab.h:597 [< inline >] net_alloc kernel/net/core/net_namespace.c:325 [< none >] copy_net_ns+0x6b/0x1a0 kernel/net/core/net_namespace.c:360 [< none >] create_new_namespaces+0x2f6/0x610 kernel/kernel/nsproxy.c:95 [< none >] copy_namespaces+0x297/0x320 kernel/kernel/nsproxy.c:150 [< none >] copy_process.part.35+0x1bf4/0x5760 kernel/kernel/fork.c:1451 [< inline >] copy_process kernel/kernel/fork.c:1274 [< none >] _do_fork+0x1bc/0xcb0 kernel/kernel/fork.c:1723 [< inline >] SYSC_clone kernel/kernel/fork.c:1832 [< none >] SyS_clone+0x37/0x50 kernel/kernel/fork.c:1826 [< none >] entry_SYSCALL_64_fastpath+0x16/0x7a kernel/arch/x86/entry/entry_64.S:185 INFO: Freed in net_drop_ns+0x67/0x80 age=575 cpu=2 pid=2631 [< none >] __slab_free+0x1fc/0x320 kernel/mm/slub.c:2650 [< inline >] slab_free kernel/mm/slub.c:2805 [< none >] kmem_cache_free+0x2a0/0x330 kernel/mm/slub.c:2814 [< inline >] net_free kernel/net/core/net_namespace.c:341 [< none >] net_drop_ns+0x67/0x80 kernel/net/core/net_namespace.c:348 [< none >] cleanup_net+0x4e5/0x600 kernel/net/core/net_namespace.c:448 [< none >] process_one_work+0x794/0x1440 kernel/kernel/workqueue.c:2036 [< none >] worker_thread+0xdb/0xfc0 kernel/kernel/workqueue.c:2170 [< none >] kthread+0x23f/0x2d0 kernel/drivers/block/aoe/aoecmd.c:1303 [< none >] ret_from_fork+0x3f/0x70 kernel/arch/x86/entry/entry_64.S:468 INFO: Slab 0xffffea0001938800 objects=3 used=0 fp=0xffff880064e20000 flags=0x5fffc0000004080 INFO: Object 0xffff880064e20000 @offset=0 fp=0xffff880064e24200 CPU: 1 PID: 11581 Comm: syz-executor Tainted: G B 4.4.0+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014 00000000ffffffff ffff8800662c7790 ffffffff8292049d ffff88003e36a300 ffff880064e20000 ffff880064e20000 ffff8800662c77c0 ffffffff816f2054 ffff88003e36a300 ffffea0001938800 ffff880064e20000 0000000000000000 Call Trace: [< inline >] __dump_stack kernel/lib/dump_stack.c:15 [] dump_stack+0x6f/0xa2 kernel/lib/dump_stack.c:50 [] print_trailer+0xf4/0x150 kernel/mm/slub.c:654 [] object_err+0x2f/0x40 kernel/mm/slub.c:661 [< inline >] print_address_description kernel/mm/kasan/report.c:138 [] kasan_report_error+0x215/0x530 kernel/mm/kasan/report.c:236 [< inline >] kasan_report kernel/mm/kasan/report.c:259 [] __asan_report_load8_noabort+0x3e/0x40 kernel/mm/kasan/report.c:280 [< inline >] ? ppp_pernet kernel/include/linux/compiler.h:218 [] ? ppp_unregister_channel+0x372/0x3a0 kernel/drivers/net/ppp/ppp_generic.c:2392 [< inline >] ppp_pernet kernel/include/linux/compiler.h:218 [] ppp_unregister_channel+0x372/0x3a0 kernel/drivers/net/ppp/ppp_generic.c:2392 [< inline >] ? ppp_pernet kernel/drivers/net/ppp/ppp_generic.c:293 [] ? ppp_unregister_channel+0xe6/0x3a0 kernel/drivers/net/ppp/ppp_generic.c:2392 [] ppp_asynctty_close+0xa3/0x130 kernel/drivers/net/ppp/ppp_async.c:241 [] ? async_lcp_peek+0x5b0/0x5b0 kernel/drivers/net/ppp/ppp_async.c:1000 [] tty_ldisc_close.isra.1+0x99/0xe0 kernel/drivers/tty/tty_ldisc.c:478 [] tty_ldisc_kill+0x40/0x170 kernel/drivers/tty/tty_ldisc.c:744 [] tty_ldisc_release+0x1b3/0x260 kernel/drivers/tty/tty_ldisc.c:772 [] tty_release+0xac1/0x13e0 kernel/drivers/tty/tty_io.c:1901 [] ? release_tty+0x320/0x320 kernel/drivers/tty/tty_io.c:1688 [] __fput+0x236/0x780 kernel/fs/file_table.c:208 [] ____fput+0x15/0x20 kernel/fs/file_table.c:244 [] task_work_run+0x16b/0x200 kernel/kernel/task_work.c:115 [< inline >] exit_task_work kernel/include/linux/task_work.h:21 [] do_exit+0x8b5/0x2c60 kernel/kernel/exit.c:750 [] ? debug_check_no_locks_freed+0x290/0x290 kernel/kernel/locking/lockdep.c:4123 [] ? mm_update_next_owner+0x6f0/0x6f0 kernel/kernel/exit.c:357 [] ? __dequeue_signal+0x136/0x470 kernel/kernel/signal.c:550 [] ? recalc_sigpending_tsk+0x13b/0x180 kernel/kernel/signal.c:145 [] do_group_exit+0x108/0x330 kernel/kernel/exit.c:880 [] get_signal+0x5e4/0x14f0 kernel/kernel/signal.c:2307 [< inline >] ? kretprobe_table_lock kernel/kernel/kprobes.c:1113 [] ? kprobe_flush_task+0xb5/0x450 kernel/kernel/kprobes.c:1158 [] do_signal+0x83/0x1c90 kernel/arch/x86/kernel/signal.c:712 [] ? recycle_rp_inst+0x310/0x310 kernel/include/linux/list.h:655 [] ? setup_sigcontext+0x780/0x780 kernel/arch/x86/kernel/signal.c:165 [] ? finish_task_switch+0x424/0x5f0 kernel/kernel/sched/core.c:2692 [< inline >] ? finish_lock_switch kernel/kernel/sched/sched.h:1099 [] ? finish_task_switch+0x120/0x5f0 kernel/kernel/sched/core.c:2678 [< inline >] ? context_switch kernel/kernel/sched/core.c:2807 [] ? __schedule+0x919/0x1bd0 kernel/kernel/sched/core.c:3283 [] exit_to_usermode_loop+0xf1/0x1a0 kernel/arch/x86/entry/common.c:247 [< inline >] prepare_exit_to_usermode kernel/arch/x86/entry/common.c:282 [] syscall_return_slowpath+0x19f/0x210 kernel/arch/x86/entry/common.c:344 [] int_ret_from_sys_call+0x25/0x9f kernel/arch/x86/entry/entry_64.S:281 Memory state around the buggy address: ffff880064e21680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff880064e21700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb >ffff880064e21780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ ffff880064e21800: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff880064e21880: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ================================================================== Change-Id: I0f07a51358271a42ec6e1f0d3b2de8913575dfae Fixes: 273ec51dd7ce ("net: ppp_generic - introduce net-namespace functionality v2") Reported-by: Baozeng Ding Signed-off-by: Guillaume Nault Reviewed-by: Cyrill Gorcunov Signed-off-by: David S. Miller Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Git-commit: 1f461dcdd296eecedaffffc6bae2bfa90bd7eb89 Signed-off-by: Ravi Kumar Siddojigari --- drivers/net/ppp/ppp_generic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 72ff14b811c62..eaef679e29107 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -2222,7 +2222,7 @@ int ppp_register_net_channel(struct net *net, struct ppp_channel *chan) pch->ppp = NULL; pch->chan = chan; - pch->chan_net = net; + pch->chan_net = get_net(net); chan->ppp = pch; init_ppp_file(&pch->file, CHANNEL); pch->file.hdrlen = chan->hdrlen; @@ -2319,6 +2319,8 @@ ppp_unregister_channel(struct ppp_channel *chan) spin_lock_bh(&pn->all_channels_lock); list_del(&pch->list); spin_unlock_bh(&pn->all_channels_lock); + put_net(pch->chan_net); + pch->chan_net = NULL; pch->file.dead = 1; wake_up_interruptible(&pch->file.rwait); From b12969cd2c210baf984e6742247c8cc7aafcf141 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 7 Sep 2016 20:49:19 +0530 Subject: [PATCH 259/320] ASN.1: Fix non-match detection failure on data overrun If the ASN.1 decoder is asked to parse a sequence of objects, non-optional matches get skipped if there's no more data to be had rather than a data-overrun error being reported. This is due to the code segment that decides whether to skip optional matches (ie. matches that could get ignored because an element is marked OPTIONAL in the grammar) due to a lack of data also skips non-optional elements if the data pointer has reached the end of the buffer. This can be tested with the data decoder for the new RSA akcipher algorithm that takes three non-optional integers. Currently, it skips the last integer if there is insufficient data. Without the fix, #defining DEBUG in asn1_decoder.c will show something like: next_op: pc=0/13 dp=0/270 C=0 J=0 - match? 30 30 00 - TAG: 30 266 CONS next_op: pc=2/13 dp=4/270 C=1 J=0 - match? 02 02 00 - TAG: 02 257 - LEAF: 257 next_op: pc=5/13 dp=265/270 C=1 J=0 - match? 02 02 00 - TAG: 02 3 - LEAF: 3 next_op: pc=8/13 dp=270/270 C=1 J=0 next_op: pc=11/13 dp=270/270 C=1 J=0 - end cons t=4 dp=270 l=270/270 The next_op line for pc=8/13 should be followed by a match line. This is not exploitable for X.509 certificates by means of shortening the message and fixing up the ASN.1 CONS tags because: (1) The relevant records being built up are cleared before use. (2) If the message is shortened sufficiently to remove the public key, the ASN.1 parse of the RSA key will fail quickly due to a lack of data. (3) Extracted signature data is either turned into MPIs (which cope with a 0 length) or is simpler integers specifying algoritms and suchlike (which can validly be 0); and (4) The AKID and SKID extensions are optional and their removal is handled without risking passing a NULL to asymmetric_key_generate_id(). (5) If the certificate is truncated sufficiently to remove the subject, issuer or serialNumber then the ASN.1 decoder will fail with a 'Cons stack underflow' return. This is not exploitable for PKCS#7 messages by means of removal of elements from such a message from the tail end of a sequence: (1) Any shortened X.509 certs embedded in the PKCS#7 message are survivable as detailed above. (2) The message digest content isn't used if it shows a NULL pointer, similarly, the authattrs aren't used if that shows a NULL pointer. (3) A missing signature results in a NULL MPI - which the MPI routines deal with. (4) If data is NULL, it is expected that the message has detached content and that is handled appropriately. (5) If the serialNumber is excised, the unconditional action associated with it will pick up the containing SEQUENCE instead, so no NULL pointer will be seen here. If both the issuer and the serialNumber are excised, the ASN.1 decode will fail with an 'Unexpected tag' return. In either case, there's no way to get to asymmetric_key_generate_id() with a NULL pointer. (6) Other fields are decoded to simple integers. Shortening the message to omit an algorithm ID field will cause checks on this to fail early in the verification process. This can also be tested by snipping objects off of the end of the ASN.1 stream such that mandatory tags are removed - or even from the end of internal SEQUENCEs. If any mandatory tag is missing, the error EBADMSG *should* be produced. Without this patch ERANGE or ENOPKG might be produced or the parse may apparently succeed, perhaps with ENOKEY or EKEYREJECTED being produced later, depending on what gets snipped. Just snipping off the final BIT_STRING or OCTET_STRING from either sample should be a start since both are mandatory and neither will cause an EBADMSG without the patches Change-Id: Id39d78ad9b108fcec06e082bc154756b53c63c0e Reported-by: Marcel Holtmann Signed-off-by: David Howells Tested-by: Marcel Holtmann Reviewed-by: David Woodhouse Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Git-commit: 0d62e9dd6da45bbf0f33a8617afc5fe774c8f45f Signed-off-by: Ravi Kumar Siddojigari --- lib/asn1_decoder.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/asn1_decoder.c b/lib/asn1_decoder.c index 11b9b01fda6b6..3787d02e2c49e 100644 --- a/lib/asn1_decoder.c +++ b/lib/asn1_decoder.c @@ -208,9 +208,8 @@ int asn1_ber_decoder(const struct asn1_decoder *decoder, unsigned char tmp; /* Skip conditional matches if possible */ - if ((op & ASN1_OP_MATCH__COND && - flags & FLAG_MATCHED) || - dp == datalen) { + if ((op & ASN1_OP_MATCH__COND && flags & FLAG_MATCHED) || + (op & ASN1_OP_MATCH__SKIP && dp == datalen)) { pc += asn1_op_lengths[op]; goto next_op; } From e53e03a51f648524162f1c7f0cfe8bd96e6ad5f7 Mon Sep 17 00:00:00 2001 From: AnilKumar Chimata Date: Wed, 31 Aug 2016 14:08:16 +0530 Subject: [PATCH 260/320] qcedev: Validate Source and Destination addresses Source and Destination addresses passed by user space apps/clients are validated independent of type of operation to mitigate kernel address space exploitation. Change-Id: I9ecb0103d7a73eedb2e0d1db1d5613b18dd77e59 Signed-off-by: AnilKumar Chimata --- drivers/crypto/msm/qcedev.c | 68 ++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 38 deletions(-) diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c index 2313d927c53ad..f757dc79da92f 100644 --- a/drivers/crypto/msm/qcedev.c +++ b/drivers/crypto/msm/qcedev.c @@ -1254,44 +1254,6 @@ static int qcedev_vbuf_ablk_cipher(struct qcedev_async_req *areq, struct qcedev_cipher_op_req *saved_req; struct qcedev_cipher_op_req *creq = &areq->cipher_op_req; - /* Verify Source Address's */ - for (i = 0; i < areq->cipher_op_req.entries; i++) - if (!access_ok(VERIFY_READ, - (void __user *)areq->cipher_op_req.vbuf.src[i].vaddr, - areq->cipher_op_req.vbuf.src[i].len)) - return -EFAULT; - - /* Verify Destination Address's */ - if (creq->in_place_op != 1) { - for (i = 0, total = 0; i < QCEDEV_MAX_BUFFERS; i++) { - if ((areq->cipher_op_req.vbuf.dst[i].vaddr != 0) && - (total < creq->data_len)) { - if (!access_ok(VERIFY_WRITE, - (void __user *)creq->vbuf.dst[i].vaddr, - creq->vbuf.dst[i].len)) { - pr_err("%s:DST WR_VERIFY err %d=0x%lx\n", - __func__, i, (uintptr_t) - creq->vbuf.dst[i].vaddr); - return -EFAULT; - } - total += creq->vbuf.dst[i].len; - } - } - } else { - for (i = 0, total = 0; i < creq->entries; i++) { - if (total < creq->data_len) { - if (!access_ok(VERIFY_WRITE, - (void __user *)creq->vbuf.src[i].vaddr, - creq->vbuf.src[i].len)) { - pr_err("%s:SRC WR_VERIFY err %d=0x%lx\n", - __func__, i, (uintptr_t) - creq->vbuf.src[i].vaddr); - return -EFAULT; - } - total += creq->vbuf.src[i].len; - } - } - } total = 0; if (areq->cipher_op_req.mode == QCEDEV_AES_MODE_CTR) @@ -1589,6 +1551,36 @@ static int qcedev_check_cipher_params(struct qcedev_cipher_op_req *req, __func__, total, req->data_len); goto error; } + /* Verify Source Address's */ + for (i = 0, total = 0; i < req->entries; i++) { + if (total < req->data_len) { + if (!access_ok(VERIFY_READ, + (void __user *)req->vbuf.src[i].vaddr, + req->vbuf.src[i].len)) { + pr_err("%s:SRC RD_VERIFY err %d=0x%lx\n", + __func__, i, (uintptr_t) + req->vbuf.src[i].vaddr); + goto error; + } + total += req->vbuf.src[i].len; + } + } + + /* Verify Destination Address's */ + for (i = 0, total = 0; i < QCEDEV_MAX_BUFFERS; i++) { + if ((req->vbuf.dst[i].vaddr != 0) && + (total < req->data_len)) { + if (!access_ok(VERIFY_WRITE, + (void __user *)req->vbuf.dst[i].vaddr, + req->vbuf.dst[i].len)) { + pr_err("%s:DST WR_VERIFY err %d=0x%lx\n", + __func__, i, (uintptr_t) + req->vbuf.dst[i].vaddr); + goto error; + } + total += req->vbuf.dst[i].len; + } + } return 0; error: return -EINVAL; From a49d48d6e3cbdbf68e331e82a6d45d31b0599a5e Mon Sep 17 00:00:00 2001 From: Mark Grondona Date: Wed, 11 Sep 2013 14:24:31 -0700 Subject: [PATCH 261/320] __ptrace_may_access() should not deny sub-threads __ptrace_may_access() checks get_dumpable/ptrace_has_cap/etc if task != current, this can can lead to surprising results. For example, a sub-thread can't readlink("/proc/self/exe") if the executable is not readable. setup_new_exec()->would_dump() notices that inode_permission(MAY_READ) fails and then it does set_dumpable(suid_dumpable). After that get_dumpable() fails. (It is not clear why proc_pid_readlink() checks get_dumpable(), perhaps we could add PTRACE_MODE_NODUMPABLE) Change __ptrace_may_access() to use same_thread_group() instead of "task == current". Any security check is pointless when the tasks share the same ->mm. Change-Id: If3e58d9a7cc9f42028eec006ac0c69a312c58e3e Signed-off-by: Mark Grondona Signed-off-by: Ben Woodard Signed-off-by: Oleg Nesterov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Git-commit: 73af963f9f3036dffed55c3a2898598186db1045 Signed-off-by: Srinivasarao P --- kernel/ptrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/ptrace.c b/kernel/ptrace.c index afadcf7b4a22d..4c71777aa2ad4 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -236,7 +236,7 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode) */ int dumpable = 0; /* Don't let security modules deny introspection */ - if (task == current) + if (same_thread_group(task, current)) return 0; rcu_read_lock(); tcred = __task_cred(task); From 0753d3572b6f03f05a2b4f508448a894661c62a0 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 11 Sep 2013 14:24:37 -0700 Subject: [PATCH 262/320] proc: make proc_fd_permission() thread-friendly proc_fd_permission() says "process can still access /proc/self/fd after it has executed a setuid()", but the "task_pid() = proc_pid() check only helps if the task is group leader, /proc/self points to /proc/. Change this check to use task_tgid() so that the whole thread group can access its /proc/self/fd or /proc//fd. Notes: - CLONE_THREAD does not require CLONE_FILES so task->files can differ, but I don't think this can lead to any security problem. And this matches same_thread_group() in __ptrace_may_access(). - /proc/self should probably point to /proc/, but it is too late to change the rules. Perhaps it makes sense to add /proc/thread though. Test-case: void *tfunc(void *arg) { assert(opendir("/proc/self/fd")); return NULL; } int main(void) { pthread_t t; pthread_create(&t, NULL, tfunc, NULL); pthread_join(t, NULL); return 0; } fails if, say, this executable is not readable and suid_dumpable = 0. Change-Id: I8a120c803a5a74c6f92fad07e766f73df3b70b46 Signed-off-by: Oleg Nesterov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Git-commit: 96d0df79f2644fc823f26c06491e182d87a90c2a Signed-off-by: Srinivasarao P --- fs/proc/fd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/proc/fd.c b/fs/proc/fd.c index d7a4a28ef6302..50ac26b3182f7 100644 --- a/fs/proc/fd.c +++ b/fs/proc/fd.c @@ -305,7 +305,7 @@ int proc_fd_permission(struct inode *inode, int mask) int rv = generic_permission(inode, mask); if (rv == 0) return 0; - if (task_pid(current) == proc_pid(inode)) + if (task_tgid(current) == proc_pid(inode)) rv = 0; return rv; } From 27d813dc4e130b567b28692f4df22c770645ffc5 Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Wed, 7 Sep 2016 21:36:57 +0530 Subject: [PATCH 263/320] ecryptfs: forbid opening files without mmap handler This prevents users from triggering a stack overflow through a recursive invocation of pagefault handling that involves mapping procfs files into virtual memory. Change-Id: I91f0a2b4fecaa7deaef9d5b062dca1b88a083703 Signed-off-by: Jann Horn Acked-by: Tyler Hicks Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Git-commit: 2f36db71009304b3f0b95afacd8eba1f9f046b87 Signed-off-by: Ravi Kumar Siddojigari --- fs/ecryptfs/kthread.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c index f1ea610362c6c..84e7d54799eea 100644 --- a/fs/ecryptfs/kthread.c +++ b/fs/ecryptfs/kthread.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "ecryptfs_kernel.h" struct ecryptfs_open_req { @@ -147,7 +148,7 @@ int ecryptfs_privileged_open(struct file **lower_file, flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR; (*lower_file) = dentry_open(&req.path, flags, cred); if (!IS_ERR(*lower_file)) - goto out; + goto have_file; if ((flags & O_ACCMODE) == O_RDONLY) { rc = PTR_ERR((*lower_file)); goto out; @@ -165,8 +166,17 @@ int ecryptfs_privileged_open(struct file **lower_file, mutex_unlock(&ecryptfs_kthread_ctl.mux); wake_up(&ecryptfs_kthread_ctl.wait); wait_for_completion(&req.done); - if (IS_ERR(*lower_file)) + if (IS_ERR(*lower_file)) { rc = PTR_ERR(*lower_file); + goto out; + } + +have_file: + if ((*lower_file)->f_op->mmap == NULL) { + fput(*lower_file); + *lower_file = NULL; + rc = -EMEDIUMTYPE; + } out: return rc; } From 67347fcbad4e89b087790f644eac626b65d2e052 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 22 Mar 2016 18:02:50 +0100 Subject: [PATCH 264/320] netfilter: x_tables: make sure e->next_offset covers remaining blob size Otherwise this function may read data beyond the ruleset blob. Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Git-commit: 6e94e0cfb0887e4013b3b930fa6ab1fe6bb6ba91 Change-Id: I78ac6043166c21e47b83a3742e3bd95c6710c953 Signed-off-by: Ravi Kumar Siddojigari --- net/ipv4/netfilter/arp_tables.c | 6 ++++-- net/ipv4/netfilter/ip_tables.c | 6 ++++-- net/ipv6/netfilter/ip6_tables.c | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index f95b6f93814b9..d0d178004d8c0 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -568,7 +568,8 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, unsigned int h; if ((unsigned long)e % __alignof__(struct arpt_entry) != 0 || - (unsigned char *)e + sizeof(struct arpt_entry) >= limit) { + (unsigned char *)e + sizeof(struct arpt_entry) >= limit || + (unsigned char *)e + e->next_offset > limit) { duprintf("Bad offset %p\n", e); return -EINVAL; } @@ -1224,7 +1225,8 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, duprintf("check_compat_entry_size_and_hooks %p\n", e); if ((unsigned long)e % __alignof__(struct compat_arpt_entry) != 0 || - (unsigned char *)e + sizeof(struct compat_arpt_entry) >= limit) { + (unsigned char *)e + sizeof(struct compat_arpt_entry) >= limit || + (unsigned char *)e + e->next_offset > limit) { duprintf("Bad offset %p, limit = %p\n", e, limit); return -EINVAL; } diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 99e810f84671b..c11351116ff9a 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -731,7 +731,8 @@ check_entry_size_and_hooks(struct ipt_entry *e, unsigned int h; if ((unsigned long)e % __alignof__(struct ipt_entry) != 0 || - (unsigned char *)e + sizeof(struct ipt_entry) >= limit) { + (unsigned char *)e + sizeof(struct ipt_entry) >= limit || + (unsigned char *)e + e->next_offset > limit) { duprintf("Bad offset %p\n", e); return -EINVAL; } @@ -1490,7 +1491,8 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, duprintf("check_compat_entry_size_and_hooks %p\n", e); if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 || - (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit) { + (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit || + (unsigned char *)e + e->next_offset > limit) { duprintf("Bad offset %p, limit = %p\n", e, limit); return -EINVAL; } diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index e080fbbbc0e5c..9bc3ed55ed07d 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -742,7 +742,8 @@ check_entry_size_and_hooks(struct ip6t_entry *e, unsigned int h; if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 || - (unsigned char *)e + sizeof(struct ip6t_entry) >= limit) { + (unsigned char *)e + sizeof(struct ip6t_entry) >= limit || + (unsigned char *)e + e->next_offset > limit) { duprintf("Bad offset %p\n", e); return -EINVAL; } @@ -1502,7 +1503,8 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, duprintf("check_compat_entry_size_and_hooks %p\n", e); if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 || - (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit) { + (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit || + (unsigned char *)e + e->next_offset > limit) { duprintf("Bad offset %p, limit = %p\n", e, limit); return -EINVAL; } From e2af0de0d0ab3facde9423f7f02dfdd1e6585af0 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 22 Mar 2016 18:02:52 +0100 Subject: [PATCH 265/320] netfilter: x_tables: fix unconditional helper Ben Hawkes says: In the mark_source_chains function (net/ipv4/netfilter/ip_tables.c) it is possible for a user-supplied ipt_entry structure to have a large next_offset field. This field is not bounds checked prior to writing a counter value at the supplied offset. Problem is that mark_source_chains should not have been called -- the rule doesn't have a next entry, so its supposed to return an absolute verdict of either ACCEPT or DROP. However, the function conditional() doesn't work as the name implies. It only checks that the rule is using wildcard address matching. However, an unconditional rule must also not be using any matches (no -m args). The underflow validator only checked the addresses, therefore passing the 'unconditional absolute verdict' test, while mark_source_chains also tested for presence of matches, and thus proceeeded to the next (not-existent) rule. Unify this so that all the callers have same idea of 'unconditional rule'. Change-Id: Icbca80abeff1811180e61195802664220b30853f Reported-by: Ben Hawkes Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Git-commit: 54d83fc74aa9ec72794373cb47432c5f7fb1a309 Git-repo:http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Signed-off-by: Ravi Kumar Siddojigari --- net/ipv4/netfilter/arp_tables.c | 18 +++++++++--------- net/ipv4/netfilter/ip_tables.c | 23 +++++++++++------------ net/ipv6/netfilter/ip6_tables.c | 23 +++++++++++------------ 3 files changed, 31 insertions(+), 33 deletions(-) diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index f95b6f93814b9..a12e24856cc7d 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -355,11 +355,12 @@ unsigned int arpt_do_table(struct sk_buff *skb, } /* All zeroes == unconditional rule. */ -static inline bool unconditional(const struct arpt_arp *arp) +static inline bool unconditional(const struct arpt_entry *e) { static const struct arpt_arp uncond; - return memcmp(arp, &uncond, sizeof(uncond)) == 0; + return e->target_offset == sizeof(struct arpt_entry) && + memcmp(&e->arp, &uncond, sizeof(uncond)) == 0; } /* Figures out from what hook each rule can be called: returns 0 if @@ -398,11 +399,10 @@ static int mark_source_chains(const struct xt_table_info *newinfo, |= ((1 << hook) | (1 << NF_ARP_NUMHOOKS)); /* Unconditional return/END. */ - if ((e->target_offset == sizeof(struct arpt_entry) && + if ((unconditional(e) && (strcmp(t->target.u.user.name, XT_STANDARD_TARGET) == 0) && - t->verdict < 0 && unconditional(&e->arp)) || - visited) { + t->verdict < 0) || visited) { unsigned int oldpos, size; if ((strcmp(t->target.u.user.name, @@ -547,7 +547,7 @@ static bool check_underflow(const struct arpt_entry *e) const struct xt_entry_target *t; unsigned int verdict; - if (!unconditional(&e->arp)) + if (!unconditional(e)) return false; t = arpt_get_target_c(e); if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) @@ -588,9 +588,9 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, newinfo->hook_entry[h] = hook_entries[h]; if ((unsigned char *)e - base == underflows[h]) { if (!check_underflow(e)) { - pr_err("Underflows must be unconditional and " - "use the STANDARD target with " - "ACCEPT/DROP\n"); + pr_debug("Underflows must be unconditional and " + "use the STANDARD target with " + "ACCEPT/DROP\n"); return -EINVAL; } newinfo->underflow[h] = underflows[h]; diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 99e810f84671b..4636fd3ff49f0 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -168,11 +168,12 @@ get_entry(const void *base, unsigned int offset) /* All zeroes == unconditional rule. */ /* Mildly perf critical (only if packet tracing is on) */ -static inline bool unconditional(const struct ipt_ip *ip) +static inline bool unconditional(const struct ipt_entry *e) { static const struct ipt_ip uncond; - return memcmp(ip, &uncond, sizeof(uncond)) == 0; + return e->target_offset == sizeof(struct ipt_entry) && + memcmp(&e->ip, &uncond, sizeof(uncond)) == 0; #undef FWINV } @@ -229,11 +230,10 @@ get_chainname_rulenum(const struct ipt_entry *s, const struct ipt_entry *e, } else if (s == e) { (*rulenum)++; - if (s->target_offset == sizeof(struct ipt_entry) && + if (unconditional(s) && strcmp(t->target.u.kernel.target->name, XT_STANDARD_TARGET) == 0 && - t->verdict < 0 && - unconditional(&s->ip)) { + t->verdict < 0) { /* Tail of chains: STANDARD target (return/policy) */ *comment = *chainname == hookname ? comments[NF_IP_TRACE_COMMENT_POLICY] @@ -472,11 +472,10 @@ mark_source_chains(const struct xt_table_info *newinfo, e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); /* Unconditional return/END. */ - if ((e->target_offset == sizeof(struct ipt_entry) && + if ((unconditional(e) && (strcmp(t->target.u.user.name, XT_STANDARD_TARGET) == 0) && - t->verdict < 0 && unconditional(&e->ip)) || - visited) { + t->verdict < 0) || visited) { unsigned int oldpos, size; if ((strcmp(t->target.u.user.name, @@ -709,7 +708,7 @@ static bool check_underflow(const struct ipt_entry *e) const struct xt_entry_target *t; unsigned int verdict; - if (!unconditional(&e->ip)) + if (!unconditional(e)) return false; t = ipt_get_target_c(e); if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) @@ -751,9 +750,9 @@ check_entry_size_and_hooks(struct ipt_entry *e, newinfo->hook_entry[h] = hook_entries[h]; if ((unsigned char *)e - base == underflows[h]) { if (!check_underflow(e)) { - pr_err("Underflows must be unconditional and " - "use the STANDARD target with " - "ACCEPT/DROP\n"); + pr_debug("Underflows must be unconditional and " + "use the STANDARD target with " + "ACCEPT/DROP\n"); return -EINVAL; } newinfo->underflow[h] = underflows[h]; diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index e080fbbbc0e5c..415f1f027374a 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -195,11 +195,12 @@ get_entry(const void *base, unsigned int offset) /* All zeroes == unconditional rule. */ /* Mildly perf critical (only if packet tracing is on) */ -static inline bool unconditional(const struct ip6t_ip6 *ipv6) +static inline bool unconditional(const struct ip6t_entry *e) { static const struct ip6t_ip6 uncond; - return memcmp(ipv6, &uncond, sizeof(uncond)) == 0; + return e->target_offset == sizeof(struct ip6t_entry) && + memcmp(&e->ipv6, &uncond, sizeof(uncond)) == 0; } static inline const struct xt_entry_target * @@ -255,11 +256,10 @@ get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e, } else if (s == e) { (*rulenum)++; - if (s->target_offset == sizeof(struct ip6t_entry) && + if (unconditional(s) && strcmp(t->target.u.kernel.target->name, XT_STANDARD_TARGET) == 0 && - t->verdict < 0 && - unconditional(&s->ipv6)) { + t->verdict < 0) { /* Tail of chains: STANDARD target (return/policy) */ *comment = *chainname == hookname ? comments[NF_IP6_TRACE_COMMENT_POLICY] @@ -482,11 +482,10 @@ mark_source_chains(const struct xt_table_info *newinfo, e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); /* Unconditional return/END. */ - if ((e->target_offset == sizeof(struct ip6t_entry) && + if ((unconditional(e) && (strcmp(t->target.u.user.name, XT_STANDARD_TARGET) == 0) && - t->verdict < 0 && - unconditional(&e->ipv6)) || visited) { + t->verdict < 0) || visited) { unsigned int oldpos, size; if ((strcmp(t->target.u.user.name, @@ -720,7 +719,7 @@ static bool check_underflow(const struct ip6t_entry *e) const struct xt_entry_target *t; unsigned int verdict; - if (!unconditional(&e->ipv6)) + if (!unconditional(e)) return false; t = ip6t_get_target_c(e); if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) @@ -762,9 +761,9 @@ check_entry_size_and_hooks(struct ip6t_entry *e, newinfo->hook_entry[h] = hook_entries[h]; if ((unsigned char *)e - base == underflows[h]) { if (!check_underflow(e)) { - pr_err("Underflows must be unconditional and " - "use the STANDARD target with " - "ACCEPT/DROP\n"); + pr_debug("Underflows must be unconditional and " + "use the STANDARD target with " + "ACCEPT/DROP\n"); return -EINVAL; } newinfo->underflow[h] = underflows[h]; From 0af37437726130c61df30f8510a40253bbcee487 Mon Sep 17 00:00:00 2001 From: Rainer Weikusat Date: Fri, 20 Nov 2015 22:07:23 +0000 Subject: [PATCH 266/320] unix: avoid use-after-free in ep_remove_wait_queue Rainer Weikusat writes: An AF_UNIX datagram socket being the client in an n:1 association with some server socket is only allowed to send messages to the server if the receive queue of this socket contains at most sk_max_ack_backlog datagrams. This implies that prospective writers might be forced to go to sleep despite none of the message presently enqueued on the server receive queue were sent by them. In order to ensure that these will be woken up once space becomes again available, the present unix_dgram_poll routine does a second sock_poll_wait call with the peer_wait wait queue of the server socket as queue argument (unix_dgram_recvmsg does a wake up on this queue after a datagram was received). This is inherently problematic because the server socket is only guaranteed to remain alive for as long as the client still holds a reference to it. In case the connection is dissolved via connect or by the dead peer detection logic in unix_dgram_sendmsg, the server socket may be freed despite "the polling mechanism" (in particular, epoll) still has a pointer to the corresponding peer_wait queue. There's no way to forcibly deregister a wait queue with epoll. Based on an idea by Jason Baron, the patch below changes the code such that a wait_queue_t belonging to the client socket is enqueued on the peer_wait queue of the server whenever the peer receive queue full condition is detected by either a sendmsg or a poll. A wake up on the peer queue is then relayed to the ordinary wait queue of the client socket via wake function. The connection to the peer wait queue is again dissolved if either a wake up is about to be relayed or the client socket reconnects or a dead peer is detected or the client socket is itself closed. This enables removing the second sock_poll_wait from unix_dgram_poll, thus avoiding the use-after-free, while still ensuring that no blocked writer sleeps forever. Signed-off-by: Rainer Weikusat Fixes: ec0d215f9420 ("af_unix: fix 'poll for write'/connected DGRAM sockets") Reviewed-by: Jason Baron Signed-off-by: David S. Miller Git-repo: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git Git-commit: 7d267278a9ece963d77eefec61630223fce08c6c Change-Id: Id2214d152329fc282c11167b6bbfaa71d9c639ef Signed-off-by: Ravi Kumar Siddojigari --- include/net/af_unix.h | 1 + net/unix/af_unix.c | 185 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 166 insertions(+), 20 deletions(-) diff --git a/include/net/af_unix.h b/include/net/af_unix.h index dbdfd2b0f3b3d..9120783132e71 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -62,6 +62,7 @@ struct unix_sock { #define UNIX_GC_CANDIDATE 0 #define UNIX_GC_MAYBE_CYCLE 1 struct socket_wq peer_wq; + wait_queue_t peer_wake; }; #define unix_sk(__sk) ((struct unix_sock *)__sk) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 254e09611da19..78627098941af 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -314,7 +314,119 @@ static struct sock *unix_find_socket_byinode(struct inode *i) return s; } -static inline int unix_writable(struct sock *sk) +/* Support code for asymmetrically connected dgram sockets + * + * If a datagram socket is connected to a socket not itself connected + * to the first socket (eg, /dev/log), clients may only enqueue more + * messages if the present receive queue of the server socket is not + * "too large". This means there's a second writeability condition + * poll and sendmsg need to test. The dgram recv code will do a wake + * up on the peer_wait wait queue of a socket upon reception of a + * datagram which needs to be propagated to sleeping would-be writers + * since these might not have sent anything so far. This can't be + * accomplished via poll_wait because the lifetime of the server + * socket might be less than that of its clients if these break their + * association with it or if the server socket is closed while clients + * are still connected to it and there's no way to inform "a polling + * implementation" that it should let go of a certain wait queue + * + * In order to propagate a wake up, a wait_queue_t of the client + * socket is enqueued on the peer_wait queue of the server socket + * whose wake function does a wake_up on the ordinary client socket + * wait queue. This connection is established whenever a write (or + * poll for write) hit the flow control condition and broken when the + * association to the server socket is dissolved or after a wake up + * was relayed. + */ + +static int unix_dgram_peer_wake_relay(wait_queue_t *q, unsigned mode, int flags, + void *key) +{ + struct unix_sock *u; + wait_queue_head_t *u_sleep; + + u = container_of(q, struct unix_sock, peer_wake); + + __remove_wait_queue(&unix_sk(u->peer_wake.private)->peer_wait, + q); + u->peer_wake.private = NULL; + + /* relaying can only happen while the wq still exists */ + u_sleep = sk_sleep(&u->sk); + if (u_sleep) + wake_up_interruptible_poll(u_sleep, key); + + return 0; +} + +static int unix_dgram_peer_wake_connect(struct sock *sk, struct sock *other) +{ + struct unix_sock *u, *u_other; + int rc; + + u = unix_sk(sk); + u_other = unix_sk(other); + rc = 0; + spin_lock(&u_other->peer_wait.lock); + + if (!u->peer_wake.private) { + u->peer_wake.private = other; + __add_wait_queue(&u_other->peer_wait, &u->peer_wake); + + rc = 1; + } + + spin_unlock(&u_other->peer_wait.lock); + return rc; +} + +static void unix_dgram_peer_wake_disconnect(struct sock *sk, + struct sock *other) +{ + struct unix_sock *u, *u_other; + + u = unix_sk(sk); + u_other = unix_sk(other); + spin_lock(&u_other->peer_wait.lock); + + if (u->peer_wake.private == other) { + __remove_wait_queue(&u_other->peer_wait, &u->peer_wake); + u->peer_wake.private = NULL; + } + + spin_unlock(&u_other->peer_wait.lock); +} + +static void unix_dgram_peer_wake_disconnect_wakeup(struct sock *sk, + struct sock *other) +{ + unix_dgram_peer_wake_disconnect(sk, other); + wake_up_interruptible_poll(sk_sleep(sk), + POLLOUT | + POLLWRNORM | + POLLWRBAND); +} + +/* preconditions: + * - unix_peer(sk) == other + * - association is stable + */ +static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other) +{ + int connected; + + connected = unix_dgram_peer_wake_connect(sk, other); + + if (unix_recvq_full(other)) + return 1; + + if (connected) + unix_dgram_peer_wake_disconnect(sk, other); + + return 0; +} + +static int unix_writable(const struct sock *sk) { return (atomic_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf; } @@ -418,6 +530,8 @@ static void unix_release_sock(struct sock *sk, int embrion) skpair->sk_state_change(skpair); sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP); } + + unix_dgram_peer_wake_disconnect(sk, skpair); sock_put(skpair); /* It may now die */ unix_peer(sk) = NULL; } @@ -651,6 +765,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock) INIT_LIST_HEAD(&u->link); mutex_init(&u->readlock); /* single task reading lock */ init_waitqueue_head(&u->peer_wait); + init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay); unix_insert_socket(unix_sockets_unbound(sk), sk); out: if (sk == NULL) @@ -1018,6 +1133,8 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr, if (unix_peer(sk)) { struct sock *old_peer = unix_peer(sk); unix_peer(sk) = other; + unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer); + unix_state_double_unlock(sk, other); if (other != old_peer) @@ -1457,6 +1574,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, struct scm_cookie tmp_scm; int max_level; int data_len = 0; + int sk_locked; if (NULL == siocb->scm) siocb->scm = &tmp_scm; @@ -1533,12 +1651,14 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, goto out_free; } + sk_locked = 0; unix_state_lock(other); +restart_locked: err = -EPERM; if (!unix_may_send(sk, other)) goto out_unlock; - if (sock_flag(other, SOCK_DEAD)) { + if (unlikely(sock_flag(other, SOCK_DEAD))) { /* * Check with 1003.1g - what should * datagram error @@ -1546,10 +1666,14 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, unix_state_unlock(other); sock_put(other); + if (!sk_locked) + unix_state_lock(sk); + err = 0; - unix_state_lock(sk); if (unix_peer(sk) == other) { unix_peer(sk) = NULL; + unix_dgram_peer_wake_disconnect_wakeup(sk, other); + unix_state_unlock(sk); unix_dgram_disconnected(sk, other); @@ -1575,21 +1699,38 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, goto out_unlock; } - if (unix_peer(other) != sk && unix_recvq_full(other)) { - if (!timeo) { - err = -EAGAIN; - goto out_unlock; + if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) { + if (timeo) { + timeo = unix_wait_for_peer(other, timeo); + + err = sock_intr_errno(timeo); + if (signal_pending(current)) + goto out_free; + + goto restart; } - timeo = unix_wait_for_peer(other, timeo); + if (!sk_locked) { + unix_state_unlock(other); + unix_state_double_lock(sk, other); + } - err = sock_intr_errno(timeo); - if (signal_pending(current)) - goto out_free; + if (unix_peer(sk) != other || + unix_dgram_peer_wake_me(sk, other)) { + err = -EAGAIN; + sk_locked = 1; + goto out_unlock; + } - goto restart; + if (!sk_locked) { + sk_locked = 1; + goto restart_locked; + } } + if (unlikely(sk_locked)) + unix_state_unlock(sk); + if (sock_flag(other, SOCK_RCVTSTAMP)) __net_timestamp(skb); maybe_add_creds(skb, sock, other); @@ -1603,6 +1744,8 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, return len; out_unlock: + if (sk_locked) + unix_state_unlock(sk); unix_state_unlock(other); out_free: kfree_skb(skb); @@ -2241,14 +2384,16 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, return mask; writable = unix_writable(sk); - other = unix_peer_get(sk); - if (other) { - if (unix_peer(other) != sk) { - sock_poll_wait(file, &unix_sk(other)->peer_wait, wait); - if (unix_recvq_full(other)) - writable = 0; - } - sock_put(other); + if (writable) { + unix_state_lock(sk); + + other = unix_peer(sk); + if (other && unix_peer(other) != sk && + unix_recvq_full(other) && + unix_dgram_peer_wake_me(sk, other)) + writable = 0; + + unix_state_unlock(sk); } if (writable) From 615fbe10df7414c39e1eeccd86b92d53c1067784 Mon Sep 17 00:00:00 2001 From: Dhaval Patel Date: Wed, 21 Oct 2015 10:55:51 -0700 Subject: [PATCH 267/320] msm: mdss: fix backlight update between unblank and kickoff The backlight update between unblank and kickoff call may result in garbage/snow screen on panel based on panel ram initialized status. For ex: -> Unblank the panel - black frame transfer start, panel is on but ram is still uninitialized. -> backlight update - turn on the backlight. It will show data from uninitialized ram because frame transfer is not complete yet. This can be avoided by blocking the backlight update request between unblank and first frame kickoff. This gives guarantee that panel has valid data to display when backlight was turned on. Change-Id: I09c707cd10acd53bd6aa0935885269ffc5aec649 Signed-off-by: Dhaval Patel --- drivers/video/msm/mdss/mdss_fb.c | 21 ++++++++++++------- drivers/video/msm/mdss/mdss_fb.h | 2 +- drivers/video/msm/mdss/mdss_mdp_splash_logo.c | 2 +- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c index 6f09747da6c05..a9ba912f6036a 100644 --- a/drivers/video/msm/mdss/mdss_fb.c +++ b/drivers/video/msm/mdss/mdss_fb.c @@ -617,7 +617,7 @@ static int mdss_fb_lpm_enable(struct msm_fb_data_type *mfd, int mode) unlock_fb_info(mfd->fbi); mutex_lock(&mfd->bl_lock); - mfd->bl_updated = true; + mfd->allow_bl_update = true; mdss_fb_set_backlight(mfd, bl_lvl); mutex_unlock(&mfd->bl_lock); @@ -1174,7 +1174,7 @@ void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl) } if ((((mdss_fb_is_power_off(mfd) && mfd->dcm_state != DCM_ENTER) - || !mfd->bl_updated) && !IS_CALIB_MODE_BL(mfd)) || + || !mfd->allow_bl_update) && !IS_CALIB_MODE_BL(mfd)) || mfd->panel_info->cont_splash_enabled) { mfd->unset_bl_level = bkl_lvl; return; @@ -1221,7 +1221,7 @@ void mdss_fb_update_backlight(struct msm_fb_data_type *mfd) if (!mfd->unset_bl_level) return; mutex_lock(&mfd->bl_lock); - if (!mfd->bl_updated) { + if (!mfd->allow_bl_update) { pdata = dev_get_platdata(&mfd->pdev->dev); if ((pdata) && (pdata->set_backlight)) { mfd->bl_level = mfd->unset_bl_level; @@ -1233,8 +1233,8 @@ void mdss_fb_update_backlight(struct msm_fb_data_type *mfd) mdss_fb_scale_bl(mfd, &temp); pdata->set_backlight(pdata, temp); mfd->bl_level_scaled = mfd->unset_bl_level; - mfd->bl_updated = 1; mdss_fb_bl_update_notify(mfd); + mfd->allow_bl_update = true; } } mutex_unlock(&mfd->bl_lock); @@ -1339,7 +1339,7 @@ static int mdss_fb_blank_blank(struct msm_fb_data_type *mfd, mdss_fb_stop_disp_thread(mfd); mutex_lock(&mfd->bl_lock); mdss_fb_set_backlight(mfd, 0); - mfd->bl_updated = 0; + mfd->allow_bl_update = false; mfd->unset_bl_level = current_bl; mutex_unlock(&mfd->bl_lock); } @@ -1406,8 +1406,8 @@ static int mdss_fb_blank_unblank(struct msm_fb_data_type *mfd) /* Reset the backlight only if the panel was off */ if (mdss_panel_is_power_off(cur_power_state)) { mutex_lock(&mfd->bl_lock); - if (!mfd->bl_updated) { - mfd->bl_updated = 1; + if (!mfd->allow_bl_update) { + mfd->allow_bl_update = true; /* * If in AD calibration mode then frameworks would not * be allowed to update backlight hence post unblank @@ -1418,6 +1418,13 @@ static int mdss_fb_blank_unblank(struct msm_fb_data_type *mfd) mdss_fb_set_backlight(mfd, mfd->calib_mode_bl); else if (!mfd->panel_info->mipi.post_init_delay) mdss_fb_set_backlight(mfd, mfd->unset_bl_level); + + /* + * it blocks the backlight update between unblank and + * first kickoff to avoid backlight turn on before black + * frame is transferred to panel through unblank call. + */ + mfd->allow_bl_update = false; } mutex_unlock(&mfd->bl_lock); } diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h index 3327f1fbd90cc..c3f5811f2fc99 100644 --- a/drivers/video/msm/mdss/mdss_fb.h +++ b/drivers/video/msm/mdss/mdss_fb.h @@ -245,7 +245,7 @@ struct msm_fb_data_type { u32 bl_scale; u32 bl_min_lvl; u32 unset_bl_level; - u32 bl_updated; + bool allow_bl_update; u32 bl_level_scaled; struct mutex bl_lock; diff --git a/drivers/video/msm/mdss/mdss_mdp_splash_logo.c b/drivers/video/msm/mdss/mdss_mdp_splash_logo.c index 681771a2884c6..2e3e048e6b50a 100644 --- a/drivers/video/msm/mdss/mdss_mdp_splash_logo.c +++ b/drivers/video/msm/mdss/mdss_mdp_splash_logo.c @@ -558,7 +558,7 @@ static int mdss_mdp_splash_thread(void *data) unlock_fb_info(mfd->fbi); mutex_lock(&mfd->bl_lock); - mfd->bl_updated = true; + mfd->allow_bl_update = true; mdss_fb_set_backlight(mfd, mfd->panel_info->bl_max >> 1); mutex_unlock(&mfd->bl_lock); From 00b0a7715ffd9bf450f2b15b822cac68ca0698cf Mon Sep 17 00:00:00 2001 From: Arun Kumar Neelakantam Date: Wed, 21 Sep 2016 18:34:01 +0530 Subject: [PATCH 268/320] net: ipc_router: fix NULL pointer de-reference issue Fail cases of accept() system call on AF_MSM_IPC socket family causes NULL pointer de-reference of sock structure variable in release operation. Validate the sock structure pointer before using it in release operation. CRs-Fixed: 1068888 Change-Id: I5637e52be59ea9504ea6ae317394bef0c28c7865 Signed-off-by: Arun Kumar Neelakantam --- net/ipc_router/ipc_router_socket.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/net/ipc_router/ipc_router_socket.c b/net/ipc_router/ipc_router_socket.c index f74448eccbb71..8ba511b5d77dc 100644 --- a/net/ipc_router/ipc_router_socket.c +++ b/net/ipc_router/ipc_router_socket.c @@ -629,10 +629,18 @@ static unsigned int msm_ipc_router_poll(struct file *file, static int msm_ipc_router_close(struct socket *sock) { struct sock *sk = sock->sk; - struct msm_ipc_port *port_ptr = msm_ipc_sk_port(sk); + struct msm_ipc_port *port_ptr; int ret; + if (!sk) + return -EINVAL; + lock_sock(sk); + port_ptr = msm_ipc_sk_port(sk); + if (!port_ptr) { + release_sock(sk); + return -EINVAL; + } ret = msm_ipc_router_close_port(port_ptr); msm_ipc_unload_default_node(msm_ipc_sk(sk)->default_node_vote_info); release_sock(sk); From 763e64adfc1d1a6c1b205ac1bb7ae68e0cc4438e Mon Sep 17 00:00:00 2001 From: Karthik Reddy Katta Date: Wed, 7 Sep 2016 18:02:23 +0530 Subject: [PATCH 269/320] ASoC: msm: Add Buffer overflow check The overflow check is required to ensure that user space data in kernel may not go beyond buffer boundary. CRs-Fixed: 1064411 Change-Id: I54c28a8942cf1a6a47a4e8272f3159b35d753ead Signed-off-by: Karthik Reddy Katta --- drivers/misc/qcom/qdsp6v2/audio_utils.c | 13 +++++++++++++ include/sound/q6asm-v2.h | 2 +- sound/soc/msm/qdsp6v2/q6asm.c | 5 +++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils.c b/drivers/misc/qcom/qdsp6v2/audio_utils.c index 9dd52b6391816..172790c3082a1 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils.c @@ -24,6 +24,15 @@ #include #include "audio_utils.h" +/* + * Define maximum buffer size. Below values are chosen considering the higher + * values used among all native drivers. + */ +#define MAX_FRAME_SIZE 1536 +#define MAX_FRAMES 5 +#define META_SIZE (sizeof(struct meta_out_dsp)) +#define MAX_BUFFER_SIZE (1 + ((MAX_FRAME_SIZE + META_SIZE) * MAX_FRAMES)) + static int audio_in_pause(struct q6audio_in *audio) { int rc; @@ -329,6 +338,10 @@ long audio_in_ioctl(struct file *file, rc = -EINVAL; break; } + if (cfg.buffer_size > MAX_BUFFER_SIZE) { + rc = -EINVAL; + break; + } audio->str_cfg.buffer_size = cfg.buffer_size; audio->str_cfg.buffer_count = cfg.buffer_count; if (audio->opened) { diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h index d1252913b7327..3bbbb82e5d466 100644 --- a/include/sound/q6asm-v2.h +++ b/include/sound/q6asm-v2.h @@ -205,7 +205,7 @@ struct audio_client *q6asm_get_audio_client(int session_id); int q6asm_audio_client_buf_alloc(unsigned int dir/* 1:Out,0:In */, struct audio_client *ac, unsigned int bufsz, - unsigned int bufcnt); + uint32_t bufcnt); int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir /* 1:Out,0:In */, struct audio_client *ac, diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index 209b857686e58..99890cf14ac02 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -45,6 +45,7 @@ #define FALSE 0x00 #define CMD_GET_HDR_SZ 16 +#define U32_MAX ((u32)~0U) enum { ASM_TOPOLOGY_CAL = 0, @@ -1074,7 +1075,7 @@ struct audio_client *q6asm_get_audio_client(int session_id) int q6asm_audio_client_buf_alloc(unsigned int dir, struct audio_client *ac, unsigned int bufsz, - unsigned int bufcnt) + uint32_t bufcnt) { int cnt = 0; int rc = 0; @@ -1101,7 +1102,7 @@ int q6asm_audio_client_buf_alloc(unsigned int dir, return 0; } mutex_lock(&ac->cmd_lock); - if (bufcnt > (LONG_MAX/sizeof(struct audio_buffer))) { + if (bufcnt > (U32_MAX/sizeof(struct audio_buffer))) { pr_err("%s: Buffer size overflows", __func__); mutex_unlock(&ac->cmd_lock); goto fail; From 76287a32451c15fa7ebea1a27eec1d7ade6dbd84 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 22 Mar 2016 18:02:49 +0100 Subject: [PATCH 270/320] netfilter: x_tables: validate e->target_offset early We should check that e->target_offset is sane before mark_source_chains gets called since it will fetch the target entry for loop detection. Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Dennis Cagle Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Git-commit: bdf533de6968e9686df777dc178486f600c6e617 (cherry picked from commit bdf533de6968e9686df777dc178486f600c6e617) Change-Id: Id3ec56cdc333990d62c99d6c2e59dbcce633bcc1 --- net/ipv4/netfilter/arp_tables.c | 17 ++++++++--------- net/ipv4/netfilter/ip_tables.c | 17 ++++++++--------- net/ipv6/netfilter/ip6_tables.c | 17 ++++++++--------- 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index c6a8e98dbe123..738e62d548ce7 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -470,14 +470,12 @@ static int mark_source_chains(const struct xt_table_info *newinfo, return 1; } -static inline int check_entry(const struct arpt_entry *e, const char *name) +static inline int check_entry(const struct arpt_entry *e) { const struct xt_entry_target *t; - if (!arp_checkentry(&e->arp)) { - duprintf("arp_tables: arp check failed %p %s.\n", e, name); + if (!arp_checkentry(&e->arp)) return -EINVAL; - } if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) return -EINVAL; @@ -518,10 +516,6 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size) struct xt_target *target; int ret; - ret = check_entry(e, name); - if (ret) - return ret; - t = arpt_get_target(e); target = xt_request_find_target(NFPROTO_ARP, t->u.user.name, t->u.user.revision); @@ -566,6 +560,7 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, unsigned int valid_hooks) { unsigned int h; + int err; if ((unsigned long)e % __alignof__(struct arpt_entry) != 0 || (unsigned char *)e + sizeof(struct arpt_entry) >= limit || @@ -581,6 +576,10 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, return -EINVAL; } + err = check_entry(e); + if (err) + return err; + /* Check hooks & underflows */ for (h = 0; h < NF_ARP_NUMHOOKS; h++) { if (!(valid_hooks & (1 << h))) @@ -1239,7 +1238,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, } /* For purposes of check_entry casting the compat entry is fine */ - ret = check_entry((struct arpt_entry *)e, name); + ret = check_entry((struct arpt_entry *)e); if (ret) return ret; diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 9bb6ca7cf5761..2c8fb724dde5d 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -564,14 +564,12 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net) } static int -check_entry(const struct ipt_entry *e, const char *name) +check_entry(const struct ipt_entry *e) { const struct xt_entry_target *t; - if (!ip_checkentry(&e->ip)) { - duprintf("ip check failed %p %s.\n", e, name); + if (!ip_checkentry(&e->ip)) return -EINVAL; - } if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) @@ -661,10 +659,6 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name, struct xt_mtchk_param mtpar; struct xt_entry_match *ematch; - ret = check_entry(e, name); - if (ret) - return ret; - j = 0; mtpar.net = net; mtpar.table = name; @@ -728,6 +722,7 @@ check_entry_size_and_hooks(struct ipt_entry *e, unsigned int valid_hooks) { unsigned int h; + int err; if ((unsigned long)e % __alignof__(struct ipt_entry) != 0 || (unsigned char *)e + sizeof(struct ipt_entry) >= limit || @@ -743,6 +738,10 @@ check_entry_size_and_hooks(struct ipt_entry *e, return -EINVAL; } + err = check_entry(e); + if (err) + return err; + /* Check hooks & underflows */ for (h = 0; h < NF_INET_NUMHOOKS; h++) { if (!(valid_hooks & (1 << h))) @@ -1504,7 +1503,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, } /* For purposes of check_entry casting the compat entry is fine */ - ret = check_entry((struct ipt_entry *)e, name); + ret = check_entry((struct ipt_entry *)e); if (ret) return ret; diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 2a0c4819e277a..bc0615b1cf63e 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -574,14 +574,12 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net) } static int -check_entry(const struct ip6t_entry *e, const char *name) +check_entry(const struct ip6t_entry *e) { const struct xt_entry_target *t; - if (!ip6_checkentry(&e->ipv6)) { - duprintf("ip_tables: ip check failed %p %s.\n", e, name); + if (!ip6_checkentry(&e->ipv6)) return -EINVAL; - } if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) @@ -672,10 +670,6 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, struct xt_mtchk_param mtpar; struct xt_entry_match *ematch; - ret = check_entry(e, name); - if (ret) - return ret; - j = 0; mtpar.net = net; mtpar.table = name; @@ -739,6 +733,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e, unsigned int valid_hooks) { unsigned int h; + int err; if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 || (unsigned char *)e + sizeof(struct ip6t_entry) >= limit || @@ -754,6 +749,10 @@ check_entry_size_and_hooks(struct ip6t_entry *e, return -EINVAL; } + err = check_entry(e); + if (err) + return err; + /* Check hooks & underflows */ for (h = 0; h < NF_INET_NUMHOOKS; h++) { if (!(valid_hooks & (1 << h))) @@ -1516,7 +1515,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, } /* For purposes of check_entry casting the compat entry is fine */ - ret = check_entry((struct ip6t_entry *)e, name); + ret = check_entry((struct ip6t_entry *)e); if (ret) return ret; From 5b23c6e1a0b176cad76c4e2c9541cfc348e879d8 Mon Sep 17 00:00:00 2001 From: dcashman Date: Thu, 29 Sep 2016 12:45:55 +0530 Subject: [PATCH 271/320] FROMLIST: mm: mmap: Add new /proc tunable for mmap_base ASLR. (cherry picked from commit https://lkml.org/lkml/2015/12/21/337) ASLR only uses as few as 8 bits to generate the random offset for the mmap base address on 32 bit architectures. This value was chosen to prevent a poorly chosen value from dividing the address space in such a way as to prevent large allocations. This may not be an issue on all platforms. Allow the specification of a minimum number of bits so that platforms desiring greater ASLR protection may determine where to place the trade-off. Bug: 24047224 Signed-off-by: Daniel Cashman Signed-off-by: Daniel Cashman Git-commit: 00ead9ddada26be1726539b1ead14abf974d235d Git-repo: https://android.googlesource.com/kernel/common.git [schikk@codeaurora.org conflict resolved] CRs-Fixed: 1066871 Change-Id: Iecbfb9abfe8f3f27d83a85989145d7fee05806a0 Signed-off-by: Swetha Chikkaboraiah --- Documentation/sysctl/vm.txt | 29 ++++++++++++++++ arch/Kconfig | 68 +++++++++++++++++++++++++++++++++++++ include/linux/mm.h | 11 ++++++ kernel/sysctl.c | 22 ++++++++++++ mm/mmap.c | 12 +++++++ 5 files changed, 142 insertions(+) diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index b81fca90f7fe4..c7539eced6263 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -42,6 +42,8 @@ Currently, these files are in /proc/sys/vm: - min_slab_ratio - min_unmapped_ratio - mmap_min_addr +- mmap_rnd_bits +- mmap_rnd_compat_bits - nr_hugepages - nr_overcommit_hugepages - nr_trim_pages (only if CONFIG_MMU=n) @@ -455,6 +457,33 @@ against future potential kernel bugs. ============================================================== +mmap_rnd_bits: + +This value can be used to select the number of bits to use to +determine the random offset to the base address of vma regions +resulting from mmap allocations on architectures which support +tuning address space randomization. This value will be bounded +by the architecture's minimum and maximum supported values. + +This value can be changed after boot using the +/proc/sys/vm/mmap_rnd_bits tunable + +============================================================== + +mmap_rnd_compat_bits: + +This value can be used to select the number of bits to use to +determine the random offset to the base address of vma regions +resulting from mmap allocations for applications run in +compatibility mode on architectures which support tuning address +space randomization. This value will be bounded by the +architecture's minimum and maximum supported values. + +This value can be changed after boot using the +/proc/sys/vm/mmap_rnd_compat_bits tunable + +============================================================== + nr_hugepages Change the minimum size of the hugepage pool. diff --git a/arch/Kconfig b/arch/Kconfig index 1ee888b66806b..69fcfae907781 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -455,6 +455,74 @@ config HAVE_UNDERSCORE_SYMBOL_PREFIX Some architectures generate an _ in front of C symbols; things like module loading and assembly files need to know about this. +config HAVE_ARCH_MMAP_RND_BITS + bool + help + An arch should select this symbol if it supports setting a variable + number of bits for use in establishing the base address for mmap + allocations, has MMU enabled and provides values for both: + - ARCH_MMAP_RND_BITS_MIN + - ARCH_MMAP_RND_BITS_MAX + +config ARCH_MMAP_RND_BITS_MIN + int + +config ARCH_MMAP_RND_BITS_MAX + int + +config ARCH_MMAP_RND_BITS_DEFAULT + int + +config ARCH_MMAP_RND_BITS + int "Number of bits to use for ASLR of mmap base address" if EXPERT + range ARCH_MMAP_RND_BITS_MIN ARCH_MMAP_RND_BITS_MAX + default ARCH_MMAP_RND_BITS_DEFAULT if ARCH_MMAP_RND_BITS_DEFAULT + default ARCH_MMAP_RND_BITS_MIN + depends on HAVE_ARCH_MMAP_RND_BITS + help + This value can be used to select the number of bits to use to + determine the random offset to the base address of vma regions + resulting from mmap allocations. This value will be bounded + by the architecture's minimum and maximum supported values. + + This value can be changed after boot using the + /proc/sys/vm/mmap_rnd_bits tunable + +config HAVE_ARCH_MMAP_RND_COMPAT_BITS + bool + help + An arch should select this symbol if it supports running applications + in compatibility mode, supports setting a variable number of bits for + use in establishing the base address for mmap allocations, has MMU + enabled and provides values for both: + - ARCH_MMAP_RND_COMPAT_BITS_MIN + - ARCH_MMAP_RND_COMPAT_BITS_MAX + +config ARCH_MMAP_RND_COMPAT_BITS_MIN + int + +config ARCH_MMAP_RND_COMPAT_BITS_MAX + int + +config ARCH_MMAP_RND_COMPAT_BITS_DEFAULT + int + +config ARCH_MMAP_RND_COMPAT_BITS + int "Number of bits to use for ASLR of mmap base address for compatible applications" if EXPERT + range ARCH_MMAP_RND_COMPAT_BITS_MIN ARCH_MMAP_RND_COMPAT_BITS_MAX + default ARCH_MMAP_RND_COMPAT_BITS_DEFAULT if ARCH_MMAP_RND_COMPAT_BITS_DEFAULT + default ARCH_MMAP_RND_COMPAT_BITS_MIN + depends on HAVE_ARCH_MMAP_RND_COMPAT_BITS + help + This value can be used to select the number of bits to use to + determine the random offset to the base address of vma regions + resulting from mmap allocations for compatible applications This + value will be bounded by the architecture's minimum and maximum + supported values. + + This value can be changed after boot using the + /proc/sys/vm/mmap_rnd_compat_bits tunable + # # ABI hall of shame # diff --git a/include/linux/mm.h b/include/linux/mm.h index 5ee09340acef2..269e3eddc0fd5 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -47,6 +47,17 @@ extern int sysctl_legacy_va_layout; #define sysctl_legacy_va_layout 0 #endif +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_BITS +extern const int mmap_rnd_bits_min; +extern const int mmap_rnd_bits_max; +extern int mmap_rnd_bits __read_mostly; +#endif +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS +extern const int mmap_rnd_compat_bits_min; +extern const int mmap_rnd_compat_bits_max; +extern int mmap_rnd_compat_bits __read_mostly; +#endif + #include #include #include diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 855cc380d35da..a1d1acab8cd9c 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1658,6 +1658,28 @@ static struct ctl_table vm_table[] = { .mode = 0644, .proc_handler = proc_doulongvec_minmax, }, +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_BITS + { + .procname = "mmap_rnd_bits", + .data = &mmap_rnd_bits, + .maxlen = sizeof(mmap_rnd_bits), + .mode = 0600, + .proc_handler = proc_dointvec_minmax, + .extra1 = (void *)&mmap_rnd_bits_min, + .extra2 = (void *)&mmap_rnd_bits_max, + }, +#endif +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS + { + .procname = "mmap_rnd_compat_bits", + .data = &mmap_rnd_compat_bits, + .maxlen = sizeof(mmap_rnd_compat_bits), + .mode = 0600, + .proc_handler = proc_dointvec_minmax, + .extra1 = (void *)&mmap_rnd_compat_bits_min, + .extra2 = (void *)&mmap_rnd_compat_bits_max, + }, +#endif { } }; diff --git a/mm/mmap.c b/mm/mmap.c index 37528a3597ce0..641dd3d2c3dc9 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -52,6 +52,18 @@ #define arch_rebalance_pgtables(addr, len) (addr) #endif +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_BITS +const int mmap_rnd_bits_min = CONFIG_ARCH_MMAP_RND_BITS_MIN; +const int mmap_rnd_bits_max = CONFIG_ARCH_MMAP_RND_BITS_MAX; +int mmap_rnd_bits __read_mostly = CONFIG_ARCH_MMAP_RND_BITS; +#endif +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS +const int mmap_rnd_compat_bits_min = CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN; +const int mmap_rnd_compat_bits_max = CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX; +int mmap_rnd_compat_bits __read_mostly = CONFIG_ARCH_MMAP_RND_COMPAT_BITS; +#endif + + static void unmap_region(struct mm_struct *mm, struct vm_area_struct *vma, struct vm_area_struct *prev, unsigned long start, unsigned long end); From 7707691eb38c8cd5ff6613942b766d87b8cacd6d Mon Sep 17 00:00:00 2001 From: dcashman Date: Thu, 29 Sep 2016 12:54:37 +0530 Subject: [PATCH 272/320] FROMLIST: arm: mm: support ARCH_MMAP_RND_BITS. (cherry picked from commit https://lkml.org/lkml/2015/12/21/341) arm: arch_mmap_rnd() uses a hard-code value of 8 to generate the random offset for the mmap base address. This value represents a compromise between increased ASLR effectiveness and avoiding address-space fragmentation. Replace it with a Kconfig option, which is sensibly bounded, so that platform developers may choose where to place this compromise. Keep 8 as the minimum acceptable value. Bug: 24047224 Signed-off-by: Daniel Cashman Signed-off-by: Daniel Cashman Git-commit: 983bb4778143ef60deaeaffba320d316b8b3d263 Git-repo: https://android.googlesource.com/kernel/common.git [schikk@codeaurora.org conflict resolved] CRs-Fixed: 1066871 Change-Id: If5ae03b7db3742ff7ec607ae5e9b44c7a540e79c Signed-off-by: Swetha Chikkaboraiah --- arch/arm/Kconfig | 9 +++++++++ arch/arm/mm/mmap.c | 3 +-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 27fe6a93395cd..1c47c172439c8 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -23,6 +23,7 @@ config ARM select HARDIRQS_SW_RESEND select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL select HAVE_ARCH_KGDB + select HAVE_ARCH_MMAP_RND_BITS if MMU select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK select HAVE_BPF_JIT @@ -301,6 +302,14 @@ config MMU Select if you want MMU-based virtualised addressing space support by paged memory management. If unsure, say 'Y'. +config ARCH_MMAP_RND_BITS_MIN + default 8 + +config ARCH_MMAP_RND_BITS_MAX + default 14 if PAGE_OFFSET=0x40000000 + default 15 if PAGE_OFFSET=0x80000000 + default 16 + # # The "ARM system type" choice list is ordered alphabetically by option # text. Please add new entries in the option alphabetic order. diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index 5e85ed371364c..655aa70aa1017 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -173,10 +173,9 @@ void arch_pick_mmap_layout(struct mm_struct *mm) { unsigned long random_factor = 0UL; - /* 8 bits of randomness in 20 address space bits */ if ((current->flags & PF_RANDOMIZE) && !(current->personality & ADDR_NO_RANDOMIZE)) - random_factor = (get_random_int() % (1 << 8)) << PAGE_SHIFT; + random_factor = (get_random_int() & ((1 << mmap_rnd_bits) - 1)) << PAGE_SHIFT; if (mmap_is_legacy()) { mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; From ea06198d567ee1711c1613d437925ee80ff3eeda Mon Sep 17 00:00:00 2001 From: dcashman Date: Thu, 29 Sep 2016 11:02:18 +0530 Subject: [PATCH 273/320] BACKPORT: FROMLIST: arm64: mm: support ARCH_MMAP_RND_BITS. (cherry picked from commit https://lkml.org/lkml/2015/12/21/340) arm64: arch_mmap_rnd() uses STACK_RND_MASK to generate the random offset for the mmap base address. This value represents a compromise between increased ASLR effectiveness and avoiding address-space fragmentation. Replace it with a Kconfig option, which is sensibly bounded, so that platform developers may choose where to place this compromise. Keep default values as new minimums. Bug: 24047224 Signed-off-by: Daniel Cashman Signed-off-by: Daniel Cashman Git-commit: 0896a27b57016186a34b634198d52fe61e007355 Git-repo: https://android.googlesource.com/kernel/common.git [schikk@codeaurora.org iconflict resolved] CRs-Fixed: 1066871 Change-Id: Id49b6a5cc1a71ace4bde321f487237e68ff81c24 Signed-off-by: Swetha Chikkaboraiah --- arch/arm64/Kconfig | 19 +++++++++++++++++++ arch/arm64/mm/mmap.c | 21 +++++++++------------ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 69efe1d33c817..62e957b9be898 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -33,6 +33,8 @@ config ARM64 select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_JUMP_LABEL select HAVE_ARCH_KGDB + select HAVE_ARCH_MMAP_RND_BITS + select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK select HAVE_C_RECORDMCOUNT @@ -82,6 +84,23 @@ config MMU config NO_IOPORT_MAP def_bool y +config ARCH_MMAP_RND_BITS_MIN + default 14 if ARM64_64K_PAGES + default 18 + +# max bits determined by the following formula: +# VA_BITS - PAGE_SHIFT - 3 +# VA_BITS is always 39 +config ARCH_MMAP_RND_BITS_MAX + default 20 if ARM64_64K_PAGES + default 24 + +config ARCH_MMAP_RND_COMPAT_BITS_MIN + default 11 + +config ARCH_MMAP_RND_COMPAT_BITS_MAX + default 16 + config STACKTRACE_SUPPORT def_bool y diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c index 8ed6cb1a900f2..5c4cb6b899a37 100644 --- a/arch/arm64/mm/mmap.c +++ b/arch/arm64/mm/mmap.c @@ -47,22 +47,19 @@ static int mmap_is_legacy(void) return sysctl_legacy_va_layout; } -/* - * Since get_random_int() returns the same value within a 1 jiffy window, we - * will almost always get the same randomisation for the stack and mmap - * region. This will mean the relative distance between stack and mmap will be - * the same. - * - * To avoid this we can shift the randomness by 1 bit. - */ static unsigned long mmap_rnd(void) { unsigned long rnd = 0; - if (current->flags & PF_RANDOMIZE) - rnd = (long)get_random_int() & (STACK_RND_MASK >> 1); - - return rnd << (PAGE_SHIFT + 1); + if (current->flags & PF_RANDOMIZE) { +#ifdef CONFIG_COMPAT + if (test_thread_flag(TIF_32BIT)) + rnd = (unsigned long)get_random_int() & ((1 << mmap_rnd_compat_bits) - 1); + else +#endif + rnd = (unsigned long)get_random_int() & ((1 << mmap_rnd_bits) - 1); + } + return rnd << PAGE_SHIFT; } static unsigned long mmap_base(void) From 0a32e5eb93b0791a5979c6b54ee9e9f76a6222fc Mon Sep 17 00:00:00 2001 From: dcashman Date: Thu, 29 Sep 2016 11:05:47 +0530 Subject: [PATCH 274/320] FROMLIST: drivers: char: random: add get_random_long() (cherry picked from commit https://lkml.org/lkml/2016/2/4/831) d07e22597d1d355 ("mm: mmap: add new /proc tunable for mmap_base ASLR") added the ability to choose from a range of values to use for entropy count in generating the random offset to the mmap_base address. The maximum value on this range was set to 32 bits for 64-bit x86 systems, but this value could be increased further, requiring more than the 32 bits of randomness provided by get_random_int(), as is already possible for arm64. Add a new function: get_random_long() which more naturally fits with the mmap usage of get_random_int() but operates exactly the same as get_random_int(). Also, fix the shifting constant in mmap_rnd() to be an unsigned long so that values greater than 31 bits generate an appropriate mask without overflow. This is especially important on x86, as its shift instruction uses a 5-bit mask for the shift operand, which meant that any value for mmap_rnd_bits over 31 acts as a no-op and effectively disables mmap_base randomization. Finally, replace calls to get_random_int() with get_random_long() where appropriate. Bug: 26963541 Signed-off-by: Daniel Cashman Signed-off-by: Daniel Cashman Git-commit: 166c8af3630e1dbe6074a9b5907855ec57c428ab Git-repo: https://android.googlesource.com/kernel/common.git [schikk@codeaurora.org conflict resolved] CRs-Fixed: 1066871 Change-Id: I849e70e22ae66d1fe70d9332ef82e117337d0578 Signed-off-by: Swetha Chikkaboraiah --- drivers/char/random.c | 22 ++++++++++++++++++++++ include/linux/random.h | 1 + 2 files changed, 23 insertions(+) diff --git a/drivers/char/random.c b/drivers/char/random.c index d9e24b59fcbfe..1c24ed59207d7 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1502,6 +1502,28 @@ unsigned int get_random_int(void) } EXPORT_SYMBOL(get_random_int); +/* + * Same as get_random_int(), but returns unsigned long. + */ +unsigned long get_random_long(void) +{ + __u32 *hash; + unsigned long ret; + + if (arch_get_random_long(&ret)) + return ret; + + hash = get_cpu_var(get_random_int_hash); + + hash[0] += current->pid + jiffies + get_cycles(); + md5_transform(hash, random_int_secret); + ret = *(unsigned long *)hash; + put_cpu_var(get_random_int_hash); + + return ret; +} +EXPORT_SYMBOL(get_random_long); + /* * randomize_range() returns a start address such that * diff --git a/include/linux/random.h b/include/linux/random.h index bf9085e89fb5d..1b91d7d186e71 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -24,6 +24,7 @@ extern const struct file_operations random_fops, urandom_fops; #endif unsigned int get_random_int(void); +unsigned long get_random_long(void); unsigned long randomize_range(unsigned long start, unsigned long end, unsigned long len); u32 prandom_u32(void); From 3fb3eb5cc9fb50c74eeb287da1f3886bf1e20eba Mon Sep 17 00:00:00 2001 From: dcashman Date: Thu, 29 Sep 2016 13:39:34 +0530 Subject: [PATCH 275/320] BACKPORT: FROMLIST: mm: ASLR: use get_random_long() (cherry picked from commit https://lkml.org/lkml/2016/2/4/833) Replace calls to get_random_int() followed by a cast to (unsigned long) with calls to get_random_long(). Also address shifting bug which, in case of x86 removed entropy mask for mmap_rnd_bits values > 31 bits. Bug: 26963541 Signed-off-by: Daniel Cashman Signed-off-by: Daniel Cashman Git-commit: 000d53cb73049f5539762e33d44437c8df99fe38 Git-repo: https://android.googlesource.com/kernel/common.git [schikk@codeaurora.org conflict resolved] CRs-Fixed: 1066871 Change-Id: I9c77b70f386531b0c609ea31f7290002e5484896 Signed-off-by: Swetha Chikkaboraiah --- arch/arm/mm/mmap.c | 2 +- arch/arm64/mm/mmap.c | 4 ++-- arch/mips/mm/mmap.c | 4 ++-- arch/powerpc/kernel/process.c | 6 +++--- arch/powerpc/mm/mmap_64.c | 4 ++-- arch/sparc/kernel/sys_sparc_64.c | 2 +- arch/x86/mm/mmap.c | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index 655aa70aa1017..2d689d1f88fef 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -175,7 +175,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm) if ((current->flags & PF_RANDOMIZE) && !(current->personality & ADDR_NO_RANDOMIZE)) - random_factor = (get_random_int() & ((1 << mmap_rnd_bits) - 1)) << PAGE_SHIFT; + random_factor = (get_random_long() & ((1UL << mmap_rnd_bits) - 1)) << PAGE_SHIFT; if (mmap_is_legacy()) { mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c index 5c4cb6b899a37..cdc2b985e4117 100644 --- a/arch/arm64/mm/mmap.c +++ b/arch/arm64/mm/mmap.c @@ -54,10 +54,10 @@ static unsigned long mmap_rnd(void) if (current->flags & PF_RANDOMIZE) { #ifdef CONFIG_COMPAT if (test_thread_flag(TIF_32BIT)) - rnd = (unsigned long)get_random_int() & ((1 << mmap_rnd_compat_bits) - 1); + rnd = get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1); else #endif - rnd = (unsigned long)get_random_int() & ((1 << mmap_rnd_bits) - 1); + rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1); } return rnd << PAGE_SHIFT; } diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c index f1baadd56e82e..5ab9e96d52252 100644 --- a/arch/mips/mm/mmap.c +++ b/arch/mips/mm/mmap.c @@ -147,7 +147,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm) unsigned long random_factor = 0UL; if (current->flags & PF_RANDOMIZE) { - random_factor = get_random_int(); + random_factor = get_random_long(); random_factor = random_factor << PAGE_SHIFT; if (TASK_IS_32BIT_ADDR) random_factor &= 0xfffffful; @@ -166,7 +166,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm) static inline unsigned long brk_rnd(void) { - unsigned long rnd = get_random_int(); + unsigned long rnd = get_random_long(); rnd = rnd << PAGE_SHIFT; /* 8MB for 32bit, 256MB for 64bit */ diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index d55357ee90283..bce0fe7acd445 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1440,7 +1440,7 @@ void notrace __ppc64_runlatch_off(void) unsigned long arch_align_stack(unsigned long sp) { if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) - sp -= get_random_int() & ~PAGE_MASK; + sp -= get_random_long() & ~PAGE_MASK; return sp & ~0xf; } @@ -1450,9 +1450,9 @@ static inline unsigned long brk_rnd(void) /* 8MB for 32bit, 1GB for 64bit */ if (is_32bit_task()) - rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT))); + rnd = (get_random_long() % (1UL<<(23-PAGE_SHIFT))); else - rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT))); + rnd = (get_random_long() % (1UL<<(30-PAGE_SHIFT))); return rnd << PAGE_SHIFT; } diff --git a/arch/powerpc/mm/mmap_64.c b/arch/powerpc/mm/mmap_64.c index cb8bdbe4972fa..2575510873dd0 100644 --- a/arch/powerpc/mm/mmap_64.c +++ b/arch/powerpc/mm/mmap_64.c @@ -60,9 +60,9 @@ static unsigned long mmap_rnd(void) if (current->flags & PF_RANDOMIZE) { /* 8MB for 32bit, 1GB for 64bit */ if (is_32bit_task()) - rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT))); + rnd = get_random_long() % (1UL<<(23-PAGE_SHIFT)); else - rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT))); + rnd = get_random_long() % (1UL<<(30-PAGE_SHIFT)); } return rnd << PAGE_SHIFT; } diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 51561b8b15baf..56b4959069c76 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -265,7 +265,7 @@ static unsigned long mmap_rnd(void) unsigned long rnd = 0UL; if (current->flags & PF_RANDOMIZE) { - unsigned long val = get_random_int(); + unsigned long val = get_random_long(); if (test_thread_flag(TIF_32BIT)) rnd = (val % (1UL << (23UL-PAGE_SHIFT))); else diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c index 25e7e1372bb26..65ba1a7d0c7c9 100644 --- a/arch/x86/mm/mmap.c +++ b/arch/x86/mm/mmap.c @@ -75,9 +75,9 @@ static unsigned long mmap_rnd(void) */ if (current->flags & PF_RANDOMIZE) { if (mmap_is_ia32()) - rnd = get_random_int() % (1<<8); + rnd = get_random_long() % (1UL<<8); else - rnd = get_random_int() % (1<<28); + rnd = get_random_long() % (1UL<<28); } return rnd << PAGE_SHIFT; } From a5b7446c7c0eae9a64ee554a904c10c0c9f332c4 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 30 Aug 2016 10:35:49 +0800 Subject: [PATCH 276/320] ASoC: utils: initialize dummy_codec before use dummy_codec is not initialized before use, which could cause kernel panic. Initialize dummy_codec before use. Change-Id: Iedf7a3accbd14138ab7ed9e4e36a98fd7ca9a839 Signed-off-by: Meng Wang --- sound/soc/soc-utils.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 4b3be6c3c91e2..6305074255f1e 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c @@ -123,6 +123,9 @@ static int snd_soc_dummy_probe(struct platform_device *pdev) { int ret; + memset(&dummy_codec, 0, + sizeof(struct snd_soc_codec_driver)); + ret = snd_soc_register_codec(&pdev->dev, &dummy_codec, &dummy_dai, 1); if (ret < 0) return ret; From d6a065464af790f8b35c11a03eff1cc0b0eb5ace Mon Sep 17 00:00:00 2001 From: Surendar karka Date: Wed, 29 Jun 2016 14:23:25 +0530 Subject: [PATCH 277/320] ASoC: msm: qdsp6v2: check param length for EAC3 format Initialize param length with user space argument and check the condition for maximum length in SND_AUDIOCODEC_EAC3 format. CRs-Fixed: 1032820 Change-Id: I710c1f743d7502e93989e8cc487078366570e723 Signed-off-by: Surendar karka --- sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c index 931f473bc84f2..4910132a70a6b 100644 --- a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1082,6 +1082,7 @@ static int msm_compr_ioctl_shared(struct snd_pcm_substream *substream, __func__, ddp->params_length); return -EINVAL; } + params_length = ddp->params_length*sizeof(int); if (params_length > MAX_AC3_PARAM_SIZE) { /*MAX is 36*sizeof(int) this should not happen*/ pr_err("%s: params_length(%d) is greater than %zd\n", From 11dfd47cc8b84d23e649769c14235e768f277b0a Mon Sep 17 00:00:00 2001 From: Walter Yang Date: Wed, 7 Sep 2016 16:28:50 +0800 Subject: [PATCH 278/320] ASoC: msm: initialize the params array before using it The params array is used without initialization, which may cause security issues. Initialize it as all zero after the definition. CRs-Fixed: 1062271 Change-Id: If462fe3d82f139d72547f82dc7eb564f83cb35bf Signed-off-by: Walter Yang --- sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c index 931f473bc84f2..5dae8365c3107 100644 --- a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c @@ -1036,6 +1036,7 @@ static int msm_compr_ioctl_shared(struct snd_pcm_substream *substream, struct snd_dec_ddp *ddp = &compr->info.codec_param.codec.options.ddp; uint32_t params_length = 0; + memset(params_value, 0, MAX_AC3_PARAM_SIZE); /* check integer overflow */ if (ddp->params_length > UINT_MAX/sizeof(int)) { pr_err("%s: Integer overflow ddp->params_length %d\n", @@ -1076,6 +1077,7 @@ static int msm_compr_ioctl_shared(struct snd_pcm_substream *substream, struct snd_dec_ddp *ddp = &compr->info.codec_param.codec.options.ddp; uint32_t params_length = 0; + memset(params_value, 0, MAX_AC3_PARAM_SIZE); /* check integer overflow */ if (ddp->params_length > UINT_MAX/sizeof(int)) { pr_err("%s: Integer overflow ddp->params_length %d\n", From b72986473c2fd447d07f2ec47a324ccfb6ccb054 Mon Sep 17 00:00:00 2001 From: Srinivasarao P Date: Mon, 3 Oct 2016 12:09:52 +0530 Subject: [PATCH 279/320] ion: use %pk instead of %p which respects kptr_restrict sysctl Hide kernel pointers from unprivileged users by using %pk format-specifier instead of %p. This respects the kptr_restrict sysctl setting which is by default on. So by default %pk will print zeroes as address. echo 1 to kptr_restrict to print proper kernel address. Change-Id: Ia300e3e38b8662afac15edda28959564b05c9367 Signed-off-by: Satyajit Desai Signed-off-by: Srinivasarao P --- drivers/staging/android/ion/ion.c | 4 ++-- drivers/staging/android/ion/ion_cma_heap.c | 6 +++--- drivers/staging/android/ion/ion_cma_secure_heap.c | 10 +++++----- drivers/staging/android/ion/msm/msm_ion.c | 8 ++++---- drivers/staging/android/ion/msm/secure_buffer.c | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 253bb2f6bd713..b6380bf87f916 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -1133,7 +1133,7 @@ static void ion_vm_open(struct vm_area_struct *vma) mutex_lock(&buffer->lock); list_add(&vma_list->list, &buffer->vmas); mutex_unlock(&buffer->lock); - pr_debug("%s: adding %p\n", __func__, vma); + pr_debug("%s: adding %pK\n", __func__, vma); } static void ion_vm_close(struct vm_area_struct *vma) @@ -1148,7 +1148,7 @@ static void ion_vm_close(struct vm_area_struct *vma) continue; list_del(&vma_list->list); kfree(vma_list); - pr_debug("%s: deleting %p\n", __func__, vma); + pr_debug("%s: deleting %pK\n", __func__, vma); break; } mutex_unlock(&buffer->lock); diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c index 3fb6078e8c3fc..6d21aecce8ea1 100644 --- a/drivers/staging/android/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -97,7 +97,7 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, /* keep this for memory release */ buffer->priv_virt = info; - dev_dbg(dev, "Allocate buffer %p\n", buffer); + dev_dbg(dev, "Allocate buffer %pK\n", buffer); return 0; err: @@ -110,7 +110,7 @@ static void ion_cma_free(struct ion_buffer *buffer) struct device *dev = buffer->heap->priv; struct ion_cma_buffer_info *info = buffer->priv_virt; - dev_dbg(dev, "Release buffer %p\n", buffer); + dev_dbg(dev, "Release buffer %pK\n", buffer); /* release memory */ dma_free_coherent(dev, buffer->size, info->cpu_addr, info->handle); sg_free_table(info->table); @@ -126,7 +126,7 @@ static int ion_cma_phys(struct ion_heap *heap, struct ion_buffer *buffer, struct device *dev = heap->priv; struct ion_cma_buffer_info *info = buffer->priv_virt; - dev_dbg(dev, "Return buffer %p physical address 0x%pa\n", buffer, + dev_dbg(dev, "Return buffer %pK physical address 0x%pa\n", buffer, &info->handle); *addr = info->handle; diff --git a/drivers/staging/android/ion/ion_cma_secure_heap.c b/drivers/staging/android/ion/ion_cma_secure_heap.c index 73299d67668de..ebd98e6d3bec3 100644 --- a/drivers/staging/android/ion/ion_cma_secure_heap.c +++ b/drivers/staging/android/ion/ion_cma_secure_heap.c @@ -3,7 +3,7 @@ * * Copyright (C) Linaro 2012 * Author: for ST-Ericsson. - * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014,2016 The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -487,7 +487,7 @@ static struct ion_secure_cma_buffer_info *__ion_secure_cma_allocate( /* keep this for memory release */ buffer->priv_virt = info; - dev_dbg(sheap->dev, "Allocate buffer %p\n", buffer); + dev_dbg(sheap->dev, "Allocate buffer %pK\n", buffer); return info; err: @@ -571,7 +571,7 @@ static void ion_secure_cma_free(struct ion_buffer *buffer) struct ion_secure_cma_buffer_info *info = buffer->priv_virt; int ret = 0; - dev_dbg(sheap->dev, "Release buffer %p\n", buffer); + dev_dbg(sheap->dev, "Release buffer %pK\n", buffer); if (msm_secure_v2_is_supported()) ret = msm_ion_unsecure_table(info->table); atomic_sub(buffer->size, &sheap->total_allocated); @@ -593,8 +593,8 @@ static int ion_secure_cma_phys(struct ion_heap *heap, struct ion_buffer *buffer, container_of(heap, struct ion_cma_secure_heap, heap); struct ion_secure_cma_buffer_info *info = buffer->priv_virt; - dev_dbg(sheap->dev, "Return buffer %p physical address 0x%pa\n", buffer, - &info->phys); + dev_dbg(sheap->dev, "Return buffer %pK physical address 0x%pa\n", + buffer, &info->phys); *addr = info->phys; *len = buffer->size; diff --git a/drivers/staging/android/ion/msm/msm_ion.c b/drivers/staging/android/ion/msm/msm_ion.c index 9f8c1413e6824..9ec2d983ae8d4 100644 --- a/drivers/staging/android/ion/msm/msm_ion.c +++ b/drivers/staging/android/ion/msm/msm_ion.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -714,7 +714,7 @@ long msm_ion_custom_ioctl(struct ion_client *client, } else { handle = ion_import_dma_buf(client, data.flush_data.fd); if (IS_ERR(handle)) { - pr_info("%s: Could not import handle: %p\n", + pr_info("%s: Could not import handle: %pK\n", __func__, handle); return -EINVAL; } @@ -727,8 +727,8 @@ long msm_ion_custom_ioctl(struct ion_client *client, + data.flush_data.length; if (start && check_vaddr_bounds(start, end)) { - pr_err("%s: virtual address %p is out of bounds\n", - __func__, data.flush_data.vaddr); + pr_err("%s: virtual address %pK is out of bounds\n", + __func__, data.flush_data.vaddr); ret = -EINVAL; } else { ret = ion_do_cache_op( diff --git a/drivers/staging/android/ion/msm/secure_buffer.c b/drivers/staging/android/ion/msm/secure_buffer.c index c9f2523eaa40e..d09efdda13072 100644 --- a/drivers/staging/android/ion/msm/secure_buffer.c +++ b/drivers/staging/android/ion/msm/secure_buffer.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2011 Google, Inc - * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -99,7 +99,7 @@ static int secure_buffer_change_table(struct sg_table *table, int lock) u32 base; u64 tmp = sg_dma_address(sg); WARN((tmp >> 32) & 0xffffffff, - "%s: there are ones in the upper 32 bits of the sg at %p! They will be truncated! Address: 0x%llx\n", + "%s: there are ones in the upper 32 bits of the sg at %pK! They will be truncated! Address: 0x%llx\n", __func__, sg, tmp); if (unlikely(!size || (size % V2_CHUNK_SIZE))) { WARN(1, From 7e8fde7c3d20347a63e2d47795afae37c261abba Mon Sep 17 00:00:00 2001 From: raghavendra ambadas Date: Wed, 28 Sep 2016 10:48:50 +0530 Subject: [PATCH 280/320] msm: mdss: Reset the col_en flag after disabling the Hist Intr Race condition occured between Hist Disable and Hist ISR function becasue of below change ID, hence make sure that the 'col_en' is set to false only after hist isr is disabled. change ID: Ib24251a00903d9f3f20034be3d12fb1e321b4aba Change-Id: I0600b9b0c3435c6ed749f7753b9b8defd31d994a Signed-off-by: Raghavendra Ambadas --- drivers/video/msm/mdss/mdss_mdp_pp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c index 421fd18f0d2a3..c08ed10abacb2 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pp.c +++ b/drivers/video/msm/mdss/mdss_mdp_pp.c @@ -3648,11 +3648,13 @@ static int pp_hist_disable(struct pp_hist_col_info *hist_info) ret = -EINVAL; goto exit; } - hist_info->col_en = false; - hist_info->col_state = HIST_UNKNOWN; spin_unlock_irqrestore(&hist_info->hist_lock, flag); mdss_mdp_hist_intr_req(&mdata->hist_intr, intr_mask << hist_info->intr_shift, false); + spin_lock_irqsave(&hist_info->hist_lock, flag); + hist_info->col_en = false; + hist_info->col_state = HIST_UNKNOWN; + spin_unlock_irqrestore(&hist_info->hist_lock, flag); complete_all(&hist_info->first_kick); complete_all(&hist_info->comp); /* if hist v2, make sure HW is unlocked */ From 5526c23720665c61780f4dbc53ffc9c74d24be01 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Tue, 4 Oct 2016 09:52:27 +0530 Subject: [PATCH 281/320] UPSTREAM: kernel.h: define u8, s8, u32, etc. limits (cherry pick from commit 89a0714106aac7309c7dfa0f004b39e1e89d2942) Create constants that define the maximum and minimum values representable by the kernel types u8, s8, u16, s16, and so on. Change-Id: I5b3f021c30454e6a6f188c74910d5758ccccccc9 Signed-off-by: Alex Elder Cc: Sage Weil Cc: David Miller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman Bug: 27299111 Bug: 27297988 Git-commit: 89a0714106aac7309c7dfa0f004b39e1e89d2942 Git-repo: https://android.googlesource.com/kernel/common [schikk@codeaurora.org fixed compilation errors] Signed-off-by: Swetha Chikkaboraiah --- include/linux/kernel.h | 13 +++++++++++++ lib/qmi_encdec.c | 1 - 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 3d0723d93ec3c..1bd97aa78ce18 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -29,6 +29,19 @@ #define ULLONG_MAX (~0ULL) #define SIZE_MAX (~(size_t)0) +#define U8_MAX ((u8)~0U) +#define S8_MAX ((s8)(U8_MAX>>1)) +#define S8_MIN ((s8)(-S8_MAX - 1)) +#define U16_MAX ((u16)~0U) +#define S16_MAX ((s16)(U16_MAX>>1)) +#define S16_MIN ((s16)(-S16_MAX - 1)) +#define U32_MAX ((u32)~0U) +#define S32_MAX ((s32)(U32_MAX>>1)) +#define S32_MIN ((s32)(-S32_MAX - 1)) +#define U64_MAX ((u64)~0ULL) +#define S64_MAX ((s64)(U64_MAX>>1)) +#define S64_MIN ((s64)(-S64_MAX - 1)) + #define STACK_MAGIC 0xdeadbeef #define REPEAT_BYTE(x) ((~0ul / 0xff) * (x)) diff --git a/lib/qmi_encdec.c b/lib/qmi_encdec.c index a205a5b719bbb..d930aae18e352 100644 --- a/lib/qmi_encdec.c +++ b/lib/qmi_encdec.c @@ -24,7 +24,6 @@ #define TLV_LEN_SIZE sizeof(uint16_t) #define TLV_TYPE_SIZE sizeof(uint8_t) -#define U8_MAX 255 #ifdef CONFIG_QMI_ENCDEC_DEBUG From 8af2db7f2786c14e2b9e195fb9e0c16ca00027a6 Mon Sep 17 00:00:00 2001 From: Swetha Chikkaboraiah Date: Mon, 3 Oct 2016 13:27:57 +0530 Subject: [PATCH 282/320] defconfig: arm: setting mmap_rnd_bits Update mmap_rnd_bits to max value. Change-Id: Ibba0cdddddae76d9e1106907dbb5f96135726d85 Git-commit: 98437587fbd2f9c407125872ef5798ee04ad12c0 Git-repo: https://android.googlesource.com/kernel/msm.git [schikk@codeaurora.org similar change added for 64-bit defconfig] CRs-Fixed: 1058121 Signed-off-by: Swetha Chikkaboraiah --- arch/arm/configs/msm8909-1gb-perf_defconfig | 1 + arch/arm/configs/msm8909-1gb_defconfig | 1 + arch/arm/configs/msm8916-perf_defconfig | 1 + arch/arm/configs/msm8916_defconfig | 1 + arch/arm64/configs/msm-perf_defconfig | 1 + arch/arm64/configs/msm_defconfig | 1 + 6 files changed, 6 insertions(+) diff --git a/arch/arm/configs/msm8909-1gb-perf_defconfig b/arch/arm/configs/msm8909-1gb-perf_defconfig index 98ba6997241b0..0200db769e7c2 100644 --- a/arch/arm/configs/msm8909-1gb-perf_defconfig +++ b/arch/arm/configs/msm8909-1gb-perf_defconfig @@ -279,6 +279,7 @@ CONFIG_DUMMY=y CONFIG_TUN=y CONFIG_KS8851=y CONFIG_MSM_RMNET_BAM=y +CONFIG_ARCH_MMAP_RND_BITS=16 CONFIG_PPP=y CONFIG_PPP_BSDCOMP=y CONFIG_PPP_DEFLATE=y diff --git a/arch/arm/configs/msm8909-1gb_defconfig b/arch/arm/configs/msm8909-1gb_defconfig index 5b24a7001ed32..021f7333cc76d 100644 --- a/arch/arm/configs/msm8909-1gb_defconfig +++ b/arch/arm/configs/msm8909-1gb_defconfig @@ -286,6 +286,7 @@ CONFIG_DUMMY=y CONFIG_TUN=y CONFIG_KS8851=y CONFIG_MSM_RMNET_BAM=y +CONFIG_ARCH_MMAP_RND_BITS=16 CONFIG_PPP=y CONFIG_PPP_BSDCOMP=y CONFIG_PPP_DEFLATE=y diff --git a/arch/arm/configs/msm8916-perf_defconfig b/arch/arm/configs/msm8916-perf_defconfig index b549b9f827301..50bd944134cb7 100644 --- a/arch/arm/configs/msm8916-perf_defconfig +++ b/arch/arm/configs/msm8916-perf_defconfig @@ -254,6 +254,7 @@ CONFIG_DUMMY=y CONFIG_TUN=y CONFIG_KS8851=y CONFIG_MSM_RMNET_BAM=y +CONFIG_ARCH_MMAP_RND_BITS=16 CONFIG_PPP=y CONFIG_PPP_BSDCOMP=y CONFIG_PPP_DEFLATE=y diff --git a/arch/arm/configs/msm8916_defconfig b/arch/arm/configs/msm8916_defconfig index de7df33681eb6..9367648788d31 100755 --- a/arch/arm/configs/msm8916_defconfig +++ b/arch/arm/configs/msm8916_defconfig @@ -257,6 +257,7 @@ CONFIG_DUMMY=y CONFIG_TUN=y CONFIG_KS8851=y CONFIG_MSM_RMNET_BAM=y +CONFIG_ARCH_MMAP_RND_BITS=16 CONFIG_PPP=y CONFIG_PPP_BSDCOMP=y CONFIG_PPP_DEFLATE=y diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig index 28cc8e3af565e..a754983660f4a 100644 --- a/arch/arm64/configs/msm-perf_defconfig +++ b/arch/arm64/configs/msm-perf_defconfig @@ -234,6 +234,7 @@ CONFIG_DUMMY=y CONFIG_MII=y CONFIG_TUN=y CONFIG_MSM_RMNET_BAM=y +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16 CONFIG_PHYLIB=y CONFIG_PPP=y CONFIG_PPP_BSDCOMP=y diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig index 8557337cfadd5..320462994ed77 100644 --- a/arch/arm64/configs/msm_defconfig +++ b/arch/arm64/configs/msm_defconfig @@ -239,6 +239,7 @@ CONFIG_DUMMY=y CONFIG_MII=y CONFIG_TUN=y CONFIG_MSM_RMNET_BAM=y +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16 CONFIG_PHYLIB=y CONFIG_PPP=y CONFIG_PPP_BSDCOMP=y From 3e88b66e9f4756e4eae174c8167cfbd80073caf4 Mon Sep 17 00:00:00 2001 From: raghavendra ambadas Date: Wed, 28 Sep 2016 10:48:50 +0530 Subject: [PATCH 283/320] msm: mdss: Reset the col_en flag after disabling the Hist Intr Race condition occured between Hist Disable and Hist ISR function becasue of below change ID, hence make sure that the 'col_en' is set to false only after hist isr is disabled. change ID: Ib24251a00903d9f3f20034be3d12fb1e321b4aba Change-Id: I0600b9b0c3435c6ed749f7753b9b8defd31d994a Signed-off-by: Raghavendra Ambadas --- drivers/video/msm/mdss/mdss_mdp_pp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c index 421fd18f0d2a3..c08ed10abacb2 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pp.c +++ b/drivers/video/msm/mdss/mdss_mdp_pp.c @@ -3648,11 +3648,13 @@ static int pp_hist_disable(struct pp_hist_col_info *hist_info) ret = -EINVAL; goto exit; } - hist_info->col_en = false; - hist_info->col_state = HIST_UNKNOWN; spin_unlock_irqrestore(&hist_info->hist_lock, flag); mdss_mdp_hist_intr_req(&mdata->hist_intr, intr_mask << hist_info->intr_shift, false); + spin_lock_irqsave(&hist_info->hist_lock, flag); + hist_info->col_en = false; + hist_info->col_state = HIST_UNKNOWN; + spin_unlock_irqrestore(&hist_info->hist_lock, flag); complete_all(&hist_info->first_kick); complete_all(&hist_info->comp); /* if hist v2, make sure HW is unlocked */ From 1f5bfc0c9ea0b096da18fda2162c993886809d3a Mon Sep 17 00:00:00 2001 From: Ravi Kumar Siddojigari Date: Tue, 20 Sep 2016 14:27:36 +0530 Subject: [PATCH 284/320] input: synaptics_dsx: allocate heap memory for temp buf There is a possible stack overflow vulnerability in the rmidev_write function because the stack array size is from user space. changes to allocate heap memory for the temporary buffer instead of stack memory to prevent the stack overflow vulnerability. As discussed under CVE-2016-3865 and ANDROID-28799389. Change-Id: I20f639e09aaf3c533c98a12a2413570feae3d6d0 Signed-off-by: Ravi Kumar Siddojigari Signed-off-by: Shantanu Jain --- .../synaptics_dsx/synaptics_dsx_rmi_dev.c | 21 +++++++++++++------ drivers/input/touchscreen/synaptics_rmi_dev.c | 20 +++++++++++++----- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_rmi_dev.c b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_rmi_dev.c index 4c341ffb60940..9d61eb110e2f1 100644 --- a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_rmi_dev.c +++ b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_rmi_dev.c @@ -347,7 +347,7 @@ static ssize_t rmidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { ssize_t retval; - unsigned char tmpbuf[count + 1]; + unsigned char *tmpbuf; struct rmidev_data *dev_data = filp->private_data; if (IS_ERR(dev_data)) { @@ -361,6 +361,10 @@ static ssize_t rmidev_read(struct file *filp, char __user *buf, if (count > (REG_ADDR_LIMIT - *f_pos)) count = REG_ADDR_LIMIT - *f_pos; + tmpbuf = kzalloc(count + 1, GFP_KERNEL); + if (!tmpbuf) + return -ENOMEM; + mutex_lock(&(dev_data->file_mutex)); retval = synaptics_rmi4_reg_read(rmidev->rmi4_data, @@ -377,7 +381,7 @@ static ssize_t rmidev_read(struct file *filp, char __user *buf, clean_up: mutex_unlock(&(dev_data->file_mutex)); - + kfree(tmpbuf); return retval; } @@ -393,7 +397,7 @@ static ssize_t rmidev_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { ssize_t retval; - unsigned char tmpbuf[count + 1]; + unsigned char *tmpbuf; struct rmidev_data *dev_data = filp->private_data; if (IS_ERR(dev_data)) { @@ -407,9 +411,14 @@ static ssize_t rmidev_write(struct file *filp, const char __user *buf, if (count > (REG_ADDR_LIMIT - *f_pos)) count = REG_ADDR_LIMIT - *f_pos; - if (copy_from_user(tmpbuf, buf, count)) - return -EFAULT; + tmpbuf = kzalloc(count + 1, GFP_KERNEL); + if (!tmpbuf) + return -ENOMEM; + if (copy_from_user(tmpbuf, buf, count)) { + kfree(tmpbuf); + return -EFAULT; + } mutex_lock(&(dev_data->file_mutex)); retval = synaptics_rmi4_reg_write(rmidev->rmi4_data, @@ -420,7 +429,7 @@ static ssize_t rmidev_write(struct file *filp, const char __user *buf, *f_pos += retval; mutex_unlock(&(dev_data->file_mutex)); - + kfree(tmpbuf); return retval; } diff --git a/drivers/input/touchscreen/synaptics_rmi_dev.c b/drivers/input/touchscreen/synaptics_rmi_dev.c index 88595582579e0..ff4f426df7d55 100644 --- a/drivers/input/touchscreen/synaptics_rmi_dev.c +++ b/drivers/input/touchscreen/synaptics_rmi_dev.c @@ -291,7 +291,7 @@ static ssize_t rmidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { ssize_t retval; - unsigned char tmpbuf[count + 1]; + unsigned char *tmpbuf; struct rmidev_data *dev_data = filp->private_data; if (IS_ERR(dev_data)) { @@ -305,6 +305,10 @@ static ssize_t rmidev_read(struct file *filp, char __user *buf, if (count > (REG_ADDR_LIMIT - *f_pos)) count = REG_ADDR_LIMIT - *f_pos; + tmpbuf = kzalloc(count + 1, GFP_KERNEL); + if (!tmpbuf) + return -ENOMEM; + mutex_lock(&(dev_data->file_mutex)); retval = rmidev->fn_ptr->read(rmidev->rmi4_data, @@ -321,7 +325,7 @@ static ssize_t rmidev_read(struct file *filp, char __user *buf, clean_up: mutex_unlock(&(dev_data->file_mutex)); - + kfree(tmpbuf); return retval; } @@ -337,7 +341,7 @@ static ssize_t rmidev_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { ssize_t retval; - unsigned char tmpbuf[count + 1]; + unsigned char *tmpbuf; struct rmidev_data *dev_data = filp->private_data; if (IS_ERR(dev_data)) { @@ -351,8 +355,14 @@ static ssize_t rmidev_write(struct file *filp, const char __user *buf, if (count > (REG_ADDR_LIMIT - *f_pos)) count = REG_ADDR_LIMIT - *f_pos; - if (copy_from_user(tmpbuf, buf, count)) + tmpbuf = kzalloc(count + 1, GFP_KERNEL); + if (!tmpbuf) + return -ENOMEM; + + if (copy_from_user(tmpbuf, buf, count)) { + kfree(tmpbuf); return -EFAULT; + } mutex_lock(&(dev_data->file_mutex)); @@ -364,7 +374,7 @@ static ssize_t rmidev_write(struct file *filp, const char __user *buf, *f_pos += retval; mutex_unlock(&(dev_data->file_mutex)); - + kfree(tmpbuf); return retval; } From 6337c8477b1230e3021a425a41e41f66ad2430b6 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 15 Sep 2016 10:01:23 -0700 Subject: [PATCH 285/320] perf: Tighten (and fix) the grouping condition The fix from 9fc81d87420d ("perf: Fix events installation during moving group") was incomplete in that it failed to recognise that creating a group with events for different CPUs is semantically broken -- they cannot be co-scheduled. Furthermore, it leads to real breakage where, when we create an event for CPU Y and then migrate it to form a group on CPU X, the code gets confused where the counter is programmed -- triggered in practice as well by me via the perf fuzzer. Fix this by tightening the rules for creating groups. Only allow grouping of counters that can be co-scheduled in the same context. This means for the same task and/or the same cpu. Change-Id: I01d7b24b44fff039e72c80cca7f70158fa354470 Fixes: 9fc81d87420d ("perf: Fix events installation during moving group") Signed-off-by: Peter Zijlstra (Intel) Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Link: http://lkml.kernel.org/r/20150123125834.090683288@infradead.org Signed-off-by: Ingo Molnar Signed-off-by: Kamal Mostafa Git-commit: c3c87e770458aa004bd7ed3f29945ff436fd6511 Git-repo: http://git.kernel.org/cgit/linux/kernel/git/tip/tip.git Signed-off-by: Patrick Fay --- include/linux/perf_event.h | 6 ------ kernel/events/core.c | 15 +++++++++++++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index d3ac528a935bd..f1213e198fa4c 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -433,11 +433,6 @@ struct perf_event { #endif /* CONFIG_PERF_EVENTS */ }; -enum perf_event_context_type { - task_context, - cpu_context, -}; - /** * struct perf_event_context - event context structure * @@ -445,7 +440,6 @@ enum perf_event_context_type { */ struct perf_event_context { struct pmu *pmu; - enum perf_event_context_type type; /* * Protect the states of the events in the list, * nr_active, and the list: diff --git a/kernel/events/core.c b/kernel/events/core.c index 5bd52c9c8c252..3500e9d1d8e2f 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6214,7 +6214,6 @@ int perf_pmu_register(struct pmu *pmu, char *name, int type) __perf_event_init_context(&cpuctx->ctx); lockdep_set_class(&cpuctx->ctx.mutex, &cpuctx_mutex); lockdep_set_class(&cpuctx->ctx.lock, &cpuctx_lock); - cpuctx->ctx.type = cpu_context; cpuctx->ctx.pmu = pmu; cpuctx->jiffies_interval = 1; INIT_LIST_HEAD(&cpuctx->rotation_list); @@ -6827,7 +6826,19 @@ SYSCALL_DEFINE5(perf_event_open, * task or CPU context: */ if (move_group) { - if (group_leader->ctx->type != ctx->type) + /* + * Make sure we're both on the same task, or both + * per-cpu events. + */ + if (group_leader->ctx->task != ctx->task) + goto err_context; + + /* + * Make sure we're both events for the same CPU; + * grouping events for different CPUs is broken; since + * you can never concurrently schedule them anyhow. + */ + if (group_leader->cpu != event->cpu) goto err_context; } else { if (group_leader->ctx != ctx) From 51b498242672d701f35c3f532362210c6b35dac6 Mon Sep 17 00:00:00 2001 From: Suman Mukherjee Date: Thu, 22 Sep 2016 09:06:48 +0530 Subject: [PATCH 286/320] msm: sensor: validate the i2c table index before use Verifying the i2c table index value before accessing the i2c table to avoid memory corruption issues. CRs-Fixed: 1065916 Change-Id: I0e31c22f90006f27a77cd420288334b8355cee95 Signed-off-by: Sureshnaidu Laveti Signed-off-by: Suman Mukherjee --- .../msm/camera_v2/sensor/actuator/msm_actuator.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c index 3e329ada3ee23..73334a7955c70 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c +++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c @@ -85,11 +85,6 @@ static void msm_actuator_parse_i2c_params(struct msm_actuator_ctrl_t *a_ctrl, struct msm_camera_i2c_reg_array *i2c_tbl = a_ctrl->i2c_reg_tbl; CDBG("Enter\n"); for (i = 0; i < size; i++) { - /* check that the index into i2c_tbl cannot grow larger that - the allocated size of i2c_tbl */ - if ((a_ctrl->total_steps + 1) < (a_ctrl->i2c_tbl_index)) - break; - if (write_arr[i].reg_write_type == MSM_ACTUATOR_WRITE_DAC) { value = (next_lens_position << write_arr[i].data_shift) | @@ -103,6 +98,11 @@ static void msm_actuator_parse_i2c_params(struct msm_actuator_ctrl_t *a_ctrl, i2c_byte2 = value & 0xFF; CDBG("byte1:0x%x, byte2:0x%x\n", i2c_byte1, i2c_byte2); + if (a_ctrl->i2c_tbl_index > + a_ctrl->total_steps) { + pr_err("failed:i2c table index out of bound\n"); + break; + } i2c_tbl[a_ctrl->i2c_tbl_index]. reg_addr = i2c_byte1; i2c_tbl[a_ctrl->i2c_tbl_index]. @@ -123,6 +123,10 @@ static void msm_actuator_parse_i2c_params(struct msm_actuator_ctrl_t *a_ctrl, i2c_byte2 = (hw_dword & write_arr[i].hw_mask) >> write_arr[i].hw_shift; } + if (a_ctrl->i2c_tbl_index > a_ctrl->total_steps) { + pr_err("failed: i2c table index out of bound\n"); + break; + } CDBG("i2c_byte1:0x%x, i2c_byte2:0x%x\n", i2c_byte1, i2c_byte2); i2c_tbl[a_ctrl->i2c_tbl_index].reg_addr = i2c_byte1; i2c_tbl[a_ctrl->i2c_tbl_index].reg_data = i2c_byte2; From e8f0df3bc87ba79167d7f7fc4691f173018d9421 Mon Sep 17 00:00:00 2001 From: Nikhilesh Reddy Date: Wed, 24 Feb 2016 14:29:47 -0800 Subject: [PATCH 287/320] fs:fuse: Disable shortcircuit when mmap is called on a file When some data is written to a file both mmap and regular io there can be race conditions that can cause incorrect data to be saved. Disable shortcircuit on the specific files on which mmap is called until we add mmap support to shortcircuit. Change-Id: Ic24219ab22d3130aa7e9e998a9e6798648a7321c Signed-off-by: Nikhilesh Reddy Signed-off-by: Srinivasarao P --- fs/fuse/file.c | 14 ++++++++++++-- fs/fuse/fuse_i.h | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index c1a4eb8052ff3..1a975ec2b46cc 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -65,6 +65,9 @@ struct fuse_file *fuse_file_alloc(struct fuse_conn *fc) return NULL; ff->rw_lower_file = NULL; + ff->shortcircuit_enabled = 0; + if (fc->shortcircuit_io) + ff->shortcircuit_enabled = 1; ff->fc = fc; ff->reserved_req = fuse_request_alloc(0); if (unlikely(!ff->reserved_req)) { @@ -987,7 +990,7 @@ static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov, return err; } - if (ff && ff->rw_lower_file) + if (ff && ff->shortcircuit_enabled && ff->rw_lower_file) ret_val = fuse_shortcircuit_aio_read(iocb, iov, nr_segs, pos); else ret_val = generic_file_aio_read(iocb, iov, nr_segs, pos); @@ -1277,7 +1280,7 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, if (err) goto out; - if (ff && ff->rw_lower_file) { + if (ff && ff->shortcircuit_enabled && ff->rw_lower_file) { /* Use iocb->ki_pos instead of pos to handle the cases of files * that are opened with O_APPEND. For example if multiple * processes open the same file with O_APPEND then the @@ -1875,6 +1878,9 @@ static const struct vm_operations_struct fuse_file_vm_ops = { static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma) { + struct fuse_file *ff = file->private_data; + + ff->shortcircuit_enabled = 0; if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) fuse_link_write_file(file); @@ -1885,6 +1891,10 @@ static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma) static int fuse_direct_mmap(struct file *file, struct vm_area_struct *vma) { + struct fuse_file *ff = file->private_data; + + ff->shortcircuit_enabled = 0; + /* Can't provide the coherency needed for MAP_SHARED */ if (vma->vm_flags & VM_MAYSHARE) return -ENODEV; diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index e4457b68c58a4..f04a3e35781a8 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -160,6 +160,7 @@ struct fuse_file { /* the read write file */ struct file *rw_lower_file; + bool shortcircuit_enabled; }; /** One input argument of a request */ From f2b907ce62fd5f2e0334466aea25182b73248dd3 Mon Sep 17 00:00:00 2001 From: Alexy Joseph Date: Tue, 4 Nov 2014 11:11:03 -0800 Subject: [PATCH 288/320] ASoC: msm: qdsp6v2: Add support for setting channel map per mask Add api to enable setting the input stream's channel map based on its channel mask Change-Id: I19cff5bf8aed9d35b3d2e6a65e4ab37ad627dc40 Signed-off-by: Alexy Joseph --- include/sound/q6asm-v2.h | 5 ++-- sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c | 6 +++- sound/soc/msm/qdsp6v2/q6asm.c | 35 +++++++++++++++------- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h index 3bbbb82e5d466..1b7ea08584489 100644 --- a/include/sound/q6asm-v2.h +++ b/include/sound/q6asm-v2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -353,7 +353,8 @@ int q6asm_media_format_block_pcm_format_support(struct audio_client *ac, int q6asm_media_format_block_pcm_format_support_v2(struct audio_client *ac, uint32_t rate, uint32_t channels, - uint16_t bits_per_sample, int stream_id); + uint16_t bits_per_sample, int stream_id, + bool use_default_chmap, char *channel_map); int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac, uint32_t rate, uint32_t channels, diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c index 2f5ff04efd30c..6bb18095eccc8 100644 --- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c @@ -624,6 +624,8 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream, int ret = 0; uint16_t bit_width = 16; + bool use_default_chmap = true; + char *chmap = NULL; pr_debug("%s: use_gapless_codec_options %d\n", __func__, use_gapless_codec_options); @@ -647,7 +649,9 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream, prtd->audio_client, prtd->sample_rate, prtd->num_channels, - bit_width, stream_id); + bit_width, stream_id, + use_default_chmap, + chmap); if (ret < 0) pr_err("%s: CMD Format block failed\n", __func__); diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index 99890cf14ac02..347f224d9c12d 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * Author: Brian Swetland * * This software is licensed under the terms of the GNU General Public @@ -2929,7 +2929,6 @@ static int q6asm_map_channels(u8 *channel_mapping, uint32_t channels) return -EINVAL; } return 0; - } int q6asm_enable_sbrps(struct audio_client *ac, @@ -3255,7 +3254,8 @@ int q6asm_enc_cfg_blk_amrwb(struct audio_client *ac, uint32_t frames_per_buf, static int __q6asm_media_format_block_pcm(struct audio_client *ac, uint32_t rate, uint32_t channels, - uint16_t bits_per_sample, int stream_id) + uint16_t bits_per_sample, int stream_id, + bool use_default_chmap, char *channel_map) { struct asm_multi_channel_pcm_fmt_blk_v2 fmt; u8 *channel_mapping; @@ -3290,9 +3290,15 @@ static int __q6asm_media_format_block_pcm(struct audio_client *ac, memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); - if (q6asm_map_channels(channel_mapping, channels)) { - pr_err("%s: map channels failed %d\n", __func__, channels); - return -EINVAL; + if (use_default_chmap) { + if (q6asm_map_channels(channel_mapping, channels)) { + pr_err("%s: map channels failed %d\n", + __func__, channels); + return -EINVAL; + } + } else { + memcpy(channel_mapping, channel_map, + PCM_FORMAT_MAX_NUM_CHANNEL); } rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); @@ -3320,7 +3326,8 @@ int q6asm_media_format_block_pcm(struct audio_client *ac, uint32_t rate, uint32_t channels) { return __q6asm_media_format_block_pcm(ac, rate, - channels, 16, ac->stream_id); + channels, 16, ac->stream_id, + true, NULL); } int q6asm_media_format_block_pcm_format_support(struct audio_client *ac, @@ -3328,15 +3335,23 @@ int q6asm_media_format_block_pcm_format_support(struct audio_client *ac, uint16_t bits_per_sample) { return __q6asm_media_format_block_pcm(ac, rate, - channels, bits_per_sample, ac->stream_id); + channels, bits_per_sample, ac->stream_id, + true, NULL); } int q6asm_media_format_block_pcm_format_support_v2(struct audio_client *ac, uint32_t rate, uint32_t channels, - uint16_t bits_per_sample, int stream_id) + uint16_t bits_per_sample, int stream_id, + bool use_default_chmap, char *channel_map) { + if (!use_default_chmap && (channel_map == NULL)) { + pr_err("%s: No valid chan map and can't use default\n", + __func__); + return -EINVAL; + } return __q6asm_media_format_block_pcm(ac, rate, - channels, bits_per_sample, stream_id); + channels, bits_per_sample, stream_id, + use_default_chmap, channel_map); } static int __q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac, From caaffe57823de1d4784c4bb8bf8ed9bd333514e1 Mon Sep 17 00:00:00 2001 From: Alexy Joseph Date: Thu, 30 Oct 2014 19:06:12 -0700 Subject: [PATCH 289/320] ASoC: msm: qdsp6v2: Fix input and output channel mapping For multichannel playback, fix default input and output channel map to the ch mixer and add compressed driver mixer ctl to receive the input stream channel map Change-Id: I56d4da70274625304ba21a10b588d2f0869ca667 Signed-off-by: Alexy Joseph --- sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c | 151 ++++++++++++++++++++- sound/soc/msm/qdsp6v2/q6adm.c | 16 +-- sound/soc/msm/qdsp6v2/q6asm.c | 12 +- 3 files changed, 164 insertions(+), 15 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c index 6bb18095eccc8..0b04e4776b78b 100644 --- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c @@ -99,6 +99,7 @@ struct msm_compr_pdata { struct msm_compr_audio_effects *audio_effects[MSM_FRONTEND_DAI_MAX]; bool use_dsp_gapless_mode; struct msm_compr_dec_params *dec_params[MSM_FRONTEND_DAI_MAX]; + struct msm_compr_ch_map *ch_map[MSM_FRONTEND_DAI_MAX]; }; struct msm_compr_audio { @@ -181,6 +182,11 @@ struct msm_compr_dec_params { struct snd_dec_ddp ddp_params; }; +struct msm_compr_ch_map { + bool set_ch_map; + char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL]; +}; + static int msm_compr_send_dec_params(struct snd_compr_stream *cstream, struct msm_compr_dec_params *dec_params, int stream_id); @@ -613,6 +619,9 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream, { struct snd_compr_runtime *runtime = cstream->runtime; struct msm_compr_audio *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = cstream->private_data; + struct msm_compr_pdata *pdata = + snd_soc_platform_get_drvdata(rtd->platform); struct asm_aac_cfg aac_cfg; struct asm_wma_cfg wma_cfg; struct asm_wmapro_cfg wma_pro_cfg; @@ -643,6 +652,12 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream, switch (prtd->codec) { case FORMAT_LINEAR_PCM: pr_debug("SND_AUDIOCODEC_PCM\n"); + if (pdata->ch_map[rtd->dai_link->be_id]) { + use_default_chmap = + !(pdata->ch_map[rtd->dai_link->be_id]->set_ch_map); + chmap = + pdata->ch_map[rtd->dai_link->be_id]->channel_map; + } if (prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S24_LE) bit_width = 24; ret = q6asm_media_format_block_pcm_format_support_v2( @@ -1175,7 +1190,9 @@ static int msm_compr_free(struct snd_compr_stream *cstream) q6asm_audio_client_free(ac); kfree(pdata->audio_effects[soc_prtd->dai_link->be_id]); + pdata->audio_effects[soc_prtd->dai_link->be_id] = NULL; kfree(pdata->dec_params[soc_prtd->dai_link->be_id]); + pdata->dec_params[soc_prtd->dai_link->be_id] = NULL; kfree(prtd); return 0; @@ -2459,6 +2476,64 @@ static int msm_compr_app_type_cfg_get(struct snd_kcontrol *kcontrol, return 0; } +static int msm_compr_channel_map_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol); + u64 fe_id = kcontrol->private_value; + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_platform_get_drvdata(platform); + int rc = 0, i; + + pr_debug("%s: fe_id- %llu\n", __func__, fe_id); + + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received out of bounds fe_id %llu\n", + __func__, fe_id); + rc = -EINVAL; + goto end; + } + + if (pdata->ch_map[fe_id]) { + pdata->ch_map[fe_id]->set_ch_map = true; + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + pdata->ch_map[fe_id]->channel_map[i] = + (char)(ucontrol->value.integer.value[i]); + } else { + pr_debug("%s: no memory for ch_map, default will be set\n", + __func__); + } +end: + pr_debug("%s: ret %d\n", __func__, rc); + return rc; +} + +static int msm_compr_channel_map_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol); + u64 fe_id = kcontrol->private_value; + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_platform_get_drvdata(platform); + int rc = 0, i; + + pr_debug("%s: fe_id- %llu\n", __func__, fe_id); + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s: Received out of bounds fe_id %llu\n", + __func__, fe_id); + rc = -EINVAL; + goto end; + } + if (pdata->ch_map[fe_id]) { + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + ucontrol->value.integer.value[i] = + pdata->ch_map[fe_id]->channel_map[i]; + } +end: + pr_debug("%s: ret %d\n", __func__, rc); + return rc; +} + static int msm_compr_probe(struct snd_soc_platform *platform) { struct msm_compr_pdata *pdata; @@ -2480,6 +2555,7 @@ static int msm_compr_probe(struct snd_soc_platform *platform) pdata->audio_effects[i] = NULL; pdata->dec_params[i] = NULL; pdata->cstream[i] = NULL; + pdata->ch_map[i] = NULL; } /* @@ -2532,6 +2608,16 @@ static int msm_compr_app_type_cfg_info(struct snd_kcontrol *kcontrol, return 0; } +static int msm_compr_channel_map_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 8; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 0xFFFFFFFF; + return 0; +} + static int msm_compr_add_volume_control(struct snd_soc_pcm_runtime *rtd) { const char *mixer_ctl_name = "Compress Playback"; @@ -2758,6 +2844,65 @@ static int msm_compr_add_app_type_cfg_control(struct snd_soc_pcm_runtime *rtd) return 0; } +static int msm_compr_add_channel_map_control(struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = "Playback Channel Map"; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + struct msm_compr_pdata *pdata = NULL; + int ctl_len; + struct snd_kcontrol_new fe_channel_map_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_compr_channel_map_info, + .get = msm_compr_channel_map_get, + .put = msm_compr_channel_map_put, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s: NULL rtd\n", __func__); + return -EINVAL; + } + + pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n", + __func__, rtd->dai_link->name, rtd->dai_link->be_id, + rtd->dai_link->cpu_dai_name, rtd->pcm->device); + + ctl_len = strlen(mixer_ctl_name) + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + + if (!mixer_str) { + pr_err("%s: failed to allocate mixer ctrl str of len %d\n", + __func__, ctl_len); + return -ENOMEM; + } + + snprintf(mixer_str, ctl_len, "%s%d", mixer_ctl_name, rtd->pcm->device); + + fe_channel_map_control[0].name = mixer_str; + fe_channel_map_control[0].private_value = rtd->dai_link->be_id; + pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); + snd_soc_add_platform_controls(rtd->platform, + fe_channel_map_control, + ARRAY_SIZE(fe_channel_map_control)); + + pdata = snd_soc_platform_get_drvdata(rtd->platform); + pdata->ch_map[rtd->dai_link->be_id] = + kzalloc(sizeof(struct msm_compr_ch_map), GFP_KERNEL); + if (!pdata->ch_map[rtd->dai_link->be_id]) { + pr_err("%s: Could not allocate memory for channel map\n", + __func__); + kfree(mixer_str); + return -ENOMEM; + } + kfree(mixer_str); + return 0; +} + static int msm_compr_new(struct snd_soc_pcm_runtime *rtd) { int rc; @@ -2775,7 +2920,11 @@ static int msm_compr_new(struct snd_soc_pcm_runtime *rtd) __func__); rc = msm_compr_add_app_type_cfg_control(rtd); if (rc) - pr_err("%s: Could not add Compr Dec runtime params Control\n", + pr_err("%s: Could not add Compr App Type Cfg Control\n", + __func__); + rc = msm_compr_add_channel_map_control(rtd); + if (rc) + pr_err("%s: Could not add Compr Channel Map Control\n", __func__); return 0; } diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c index 55b646451c7fd..ef051c1114c5d 100644 --- a/sound/soc/msm/qdsp6v2/q6adm.c +++ b/sound/soc/msm/qdsp6v2/q6adm.c @@ -2097,14 +2097,14 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, } else if (channel_mode == 4) { open.dev_channel_mapping[0] = PCM_CHANNEL_FL; open.dev_channel_mapping[1] = PCM_CHANNEL_FR; - open.dev_channel_mapping[2] = PCM_CHANNEL_RB; - open.dev_channel_mapping[3] = PCM_CHANNEL_LB; + open.dev_channel_mapping[2] = PCM_CHANNEL_LS; + open.dev_channel_mapping[3] = PCM_CHANNEL_RS; } else if (channel_mode == 5) { open.dev_channel_mapping[0] = PCM_CHANNEL_FL; open.dev_channel_mapping[1] = PCM_CHANNEL_FR; open.dev_channel_mapping[2] = PCM_CHANNEL_FC; - open.dev_channel_mapping[3] = PCM_CHANNEL_LB; - open.dev_channel_mapping[4] = PCM_CHANNEL_RB; + open.dev_channel_mapping[3] = PCM_CHANNEL_LS; + open.dev_channel_mapping[4] = PCM_CHANNEL_RS; } else if (channel_mode == 6) { open.dev_channel_mapping[0] = PCM_CHANNEL_FL; open.dev_channel_mapping[1] = PCM_CHANNEL_FR; @@ -2117,10 +2117,10 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, open.dev_channel_mapping[1] = PCM_CHANNEL_FR; open.dev_channel_mapping[2] = PCM_CHANNEL_LFE; open.dev_channel_mapping[3] = PCM_CHANNEL_FC; - open.dev_channel_mapping[4] = PCM_CHANNEL_LB; - open.dev_channel_mapping[5] = PCM_CHANNEL_RB; - open.dev_channel_mapping[6] = PCM_CHANNEL_FLC; - open.dev_channel_mapping[7] = PCM_CHANNEL_FRC; + open.dev_channel_mapping[4] = PCM_CHANNEL_LS; + open.dev_channel_mapping[5] = PCM_CHANNEL_RS; + open.dev_channel_mapping[6] = PCM_CHANNEL_LB; + open.dev_channel_mapping[7] = PCM_CHANNEL_RB; } else { pr_err("%s: invalid num_chan %d\n", __func__, channel_mode); diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index 347f224d9c12d..681b41a8fe910 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -2899,14 +2899,14 @@ static int q6asm_map_channels(u8 *channel_mapping, uint32_t channels) } else if (channels == 4) { lchannel_mapping[0] = PCM_CHANNEL_FL; lchannel_mapping[1] = PCM_CHANNEL_FR; - lchannel_mapping[2] = PCM_CHANNEL_RB; - lchannel_mapping[3] = PCM_CHANNEL_LB; + lchannel_mapping[2] = PCM_CHANNEL_LS; + lchannel_mapping[3] = PCM_CHANNEL_RS; } else if (channels == 5) { lchannel_mapping[0] = PCM_CHANNEL_FL; lchannel_mapping[1] = PCM_CHANNEL_FR; lchannel_mapping[2] = PCM_CHANNEL_FC; - lchannel_mapping[3] = PCM_CHANNEL_LB; - lchannel_mapping[4] = PCM_CHANNEL_RB; + lchannel_mapping[3] = PCM_CHANNEL_LS; + lchannel_mapping[4] = PCM_CHANNEL_RS; } else if (channels == 6) { lchannel_mapping[0] = PCM_CHANNEL_FL; lchannel_mapping[1] = PCM_CHANNEL_FR; @@ -2921,8 +2921,8 @@ static int q6asm_map_channels(u8 *channel_mapping, uint32_t channels) lchannel_mapping[3] = PCM_CHANNEL_LFE; lchannel_mapping[4] = PCM_CHANNEL_LB; lchannel_mapping[5] = PCM_CHANNEL_RB; - lchannel_mapping[6] = PCM_CHANNEL_FLC; - lchannel_mapping[7] = PCM_CHANNEL_FRC; + lchannel_mapping[6] = PCM_CHANNEL_LS; + lchannel_mapping[7] = PCM_CHANNEL_RS; } else { pr_err("%s: ERROR.unsupported num_ch = %u\n", __func__, channels); From c549c2a322d31ce9b7da5a350d76ad3703f93907 Mon Sep 17 00:00:00 2001 From: Ramlal Karra Date: Thu, 19 May 2016 17:07:34 +0530 Subject: [PATCH 290/320] ASoC: msm: qdsp6v2: Add support to query adsp version Q6 core service provides API to query ADSP version. Update the apr with get()/set() to use this adsp version by platform/machine drivers. Change-Id: Icf480991b4b7847cd872ab7286ed1132facff0a4 Signed-off-by: Laxminath Kasam Signed-off-by: Surendar karka --- include/sound/q6core.h | 19 +++++++- sound/soc/msm/qdsp6v2/q6core.c | 88 ++++++++++++++++++++++++++++++++-- 2 files changed, 103 insertions(+), 4 deletions(-) diff --git a/include/sound/q6core.h b/include/sound/q6core.h index 146fc1a6cfcd2..70a7b9a7639ca 100644 --- a/include/sound/q6core.h +++ b/include/sound/q6core.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -155,4 +155,21 @@ struct avcs_cmdrsp_get_license_validation_result { int32_t core_set_license(uint32_t key, uint32_t module_id); int32_t core_get_license_status(uint32_t module_id); +#define AVCS_GET_VERSIONS 0x00012905 +struct avcs_cmd_get_version_result { + struct apr_hdr hdr; + uint32_t id; +}; +#define AVCS_GET_VERSIONS_RSP 0x00012906 + +#define AVCS_CMDRSP_Q6_ID_2_6 0x00040000 +#define AVCS_CMDRSP_Q6_ID_2_7 0x00040001 + +enum q6_subsys_image { + Q6_SUBSYS_AVS2_6 = 1, + Q6_SUBSYS_AVS2_7, + Q6_SUBSYS_INVALID, +}; +enum q6_subsys_image q6core_get_avs_version(void); +int core_get_adsp_ver(void); #endif /* __Q6CORE_H__ */ diff --git a/sound/soc/msm/qdsp6v2/q6core.c b/sound/soc/msm/qdsp6v2/q6core.c index 2a28b47e02018..c636d0b878ad8 100644 --- a/sound/soc/msm/qdsp6v2/q6core.c +++ b/sound/soc/msm/qdsp6v2/q6core.c @@ -40,7 +40,8 @@ struct q6core_str { u32 bus_bw_resp_received; enum cmd_flags { FLAG_NONE, - FLAG_CMDRSP_LICENSE_RESULT + FLAG_CMDRSP_LICENSE_RESULT, + FLAG_AVCS_GET_VERSIONS_RESULT, } cmd_resp_received_flag; struct mutex cmd_lock; union { @@ -50,6 +51,7 @@ struct q6core_str { struct avcs_cmd_rsp_get_low_power_segments_info_t lp_ocm_payload; u32 param; struct cal_type_data *cal_data; + u32 q6_core_avs_version; }; static struct q6core_str q6core_lcl; @@ -147,7 +149,29 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) q6core_lcl.bus_bw_resp_received = 1; wake_up(&q6core_lcl.bus_bw_req_wait); break; - case AVCS_CMDRSP_GET_LICENSE_VALIDATION_RESULT: + case AVCS_GET_VERSIONS_RSP: + payload1 = data->payload; + pr_debug("%s: Received ADSP version response[3]0x%x\n", + __func__, payload1[3]); + q6core_lcl.cmd_resp_received_flag = + FLAG_AVCS_GET_VERSIONS_RESULT; + if (AVCS_CMDRSP_Q6_ID_2_6 == payload1[3]) { + q6core_lcl.q6_core_avs_version = Q6_SUBSYS_AVS2_6; + pr_debug("%s: Received ADSP version as 2.6\n", + __func__); + } else if (AVCS_CMDRSP_Q6_ID_2_7 == payload1[3]) { + q6core_lcl.q6_core_avs_version = Q6_SUBSYS_AVS2_7; + pr_debug("%s: Received ADSP version as 2.7\n", + __func__); + } else { + pr_err("%s: ADSP version is neither 2.6 nor 2.7\n", + __func__); + q6core_lcl.q6_core_avs_version = Q6_SUBSYS_INVALID; + } + wake_up(&q6core_lcl.cmd_req_wait); + break; + + case AVCS_CMDRSP_GET_LICENSE_VALIDATION_RESULT: payload1 = data->payload; pr_debug("%s: cmd = LICENSE_VALIDATION_RESULT, result = 0x%x\n", __func__, payload1[0]); @@ -173,7 +197,6 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) } break; } - return 0; } @@ -282,6 +305,65 @@ int32_t core_set_license(uint32_t key, uint32_t module_id) return rc; } +int core_get_adsp_ver(void) +{ + struct avcs_cmd_get_version_result get_aver_cmd; + int ret = 0; + + mutex_lock(&(q6core_lcl.cmd_lock)); + ocm_core_open(); + if (q6core_lcl.core_handle_q == NULL) { + pr_err("%s: apr registration for CORE failed\n", __func__); + ret = -ENODEV; + goto fail_cmd; + } + + get_aver_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + get_aver_cmd.hdr.pkt_size = sizeof(get_aver_cmd); + get_aver_cmd.hdr.src_port = 0; + get_aver_cmd.hdr.dest_port = 0; + get_aver_cmd.hdr.token = 0; + get_aver_cmd.hdr.opcode = AVCS_GET_VERSIONS; + + ret = apr_send_pkt(q6core_lcl.core_handle_q, + (uint32_t *) &get_aver_cmd); + if (ret < 0) { + pr_err("%s: Core get DSP version request failed, err %d\n", + __func__, ret); + ret = -EREMOTE; + goto fail_cmd; + } + + q6core_lcl.cmd_resp_received_flag &= ~(FLAG_AVCS_GET_VERSIONS_RESULT); + mutex_unlock(&(q6core_lcl.cmd_lock)); + ret = wait_event_timeout(q6core_lcl.cmd_req_wait, + (q6core_lcl.cmd_resp_received_flag == + FLAG_AVCS_GET_VERSIONS_RESULT), + msecs_to_jiffies(TIMEOUT_MS)); + mutex_lock(&(q6core_lcl.cmd_lock)); + if (!ret) { + pr_err("%s: wait_event timeout for AVCS_GET_VERSIONS_RESULT\n", + __func__); + ret = -ETIMEDOUT; + goto fail_cmd; + } + q6core_lcl.cmd_resp_received_flag &= ~(FLAG_AVCS_GET_VERSIONS_RESULT); + +fail_cmd: + if (ret < 0) + q6core_lcl.q6_core_avs_version = Q6_SUBSYS_INVALID; + mutex_unlock(&(q6core_lcl.cmd_lock)); + return ret; +} + +enum q6_subsys_image q6core_get_avs_version(void) +{ + if (q6core_lcl.q6_core_avs_version == 0) + core_get_adsp_ver(); + return q6core_lcl.q6_core_avs_version; +} + int32_t core_get_license_status(uint32_t module_id) { struct avcs_cmd_get_license_validation_result get_lvr_cmd; From c3c3616b5417b3b2e738ee04db7bb5de783e7c96 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Sat, 14 May 2016 15:16:05 +0530 Subject: [PATCH 291/320] ASoC: msm: add support for AVS 2.7 in native drivers In Q6 asm and afe drivers, add API support for AVS 2.7. Update compress driver to use ASM volume gain compatible to verion used. Change-Id: I152a3410c99cfa37dca0eadb30b97f121f5d0a89 Signed-off-by: Laxminath Kasam Signed-off-by: Surendar karka --- drivers/misc/qcom/qdsp6v2/audio_utils_aio.c | 45 ++- include/sound/apr_audio-v2.h | 344 +++++++++++++++++++- include/sound/q6afe-v2.h | 4 +- include/sound/q6asm-v2.h | 5 + sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c | 139 ++++++-- sound/soc/msm/qdsp6v2/q6afe.c | 107 ++++++ sound/soc/msm/qdsp6v2/q6asm.c | 282 +++++++++++++++- 7 files changed, 876 insertions(+), 50 deletions(-) diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c index 80411116dedc1..2b4ea85d395db 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c @@ -1,6 +1,6 @@ /* Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2009-2014, 2016 The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -26,6 +26,7 @@ #include #include #include +#include #include "audio_utils_aio.h" #ifdef CONFIG_USE_DEV_CTRL_VOLUME #include @@ -1499,7 +1500,26 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, memset(&stats, 0, sizeof(struct msm_audio_stats)); stats.byte_count = atomic_read(&audio->in_bytes); stats.sample_count = atomic_read(&audio->in_samples); - rc = q6asm_get_session_time(audio->ac, ×tamp); + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_7): + { + rc = q6asm_get_session_time(audio->ac, ×tamp); + break; + } + case (Q6_SUBSYS_AVS2_6): + { + rc = q6asm_get_session_time_legacy(audio->ac, + ×tamp); + break; + } + case (Q6_SUBSYS_INVALID): + default: + { + pr_err("%s: UNKNOWN AVS IMAGE VERSION\n", __func__); + rc = -EINVAL; + break; + } + } if (rc >= 0) memcpy(&stats.unused[0], ×tamp, sizeof(timestamp)); else @@ -1787,7 +1807,26 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, memset(&stats, 0, sizeof(struct msm_audio_stats32)); stats.byte_count = atomic_read(&audio->in_bytes); stats.sample_count = atomic_read(&audio->in_samples); - rc = q6asm_get_session_time(audio->ac, ×tamp); + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_7): + { + rc = q6asm_get_session_time(audio->ac, ×tamp); + break; + } + case (Q6_SUBSYS_AVS2_6): + { + rc = q6asm_get_session_time_legacy(audio->ac, + ×tamp); + break; + } + case (Q6_SUBSYS_INVALID): + default: + { + pr_err("%s: UNKNOWN AVS IMAGE VERSION\n", __func__); + rc = -EINVAL; + break; + } + } if (rc >= 0) memcpy(&stats.unused[0], ×tamp, sizeof(timestamp)); else diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h index 59d7ee1a2ac44..f6bd71f70abcc 100644 --- a/include/sound/apr_audio-v2.h +++ b/include/sound/apr_audio-v2.h @@ -2894,7 +2894,8 @@ struct asm_dec_ddp_endp_param_v2 { } __packed; /* @brief Multichannel PCM encoder configuration structure used - * in the #ASM_STREAM_CMD_OPEN_READ_V2 command. + * in the #ASM_STREAM_CMD_OPEN_READ_V2(for AVS2.6 image) OR + * ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2(FOR AVS2.7 image) command. */ struct asm_multi_channel_pcm_enc_cfg_v2 { @@ -3374,7 +3375,8 @@ struct asm_v13k_enc_cfg { #define ASM_MEDIA_FMT_EVRC_FS 0x00010BEE /* EVRC encoder configuration structure used in the - * #ASM_STREAM_CMD_OPEN_READ_V2 command. + * #ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2(for AVS2.6 image) + * #ASM_STREAM_CMD_OPEN_READ_V2(for AVS2.7 image) command. */ struct asm_evrc_enc_cfg { struct apr_hdr hdr; @@ -3583,6 +3585,8 @@ struct asm_amrwbplus_fmt_blk_v2 { } __packed; +#define ASM_MEDIA_FMT_AC3 0x00010DEE +#define ASM_MEDIA_FMT_EAC3 0x00010DEF #define ASM_MEDIA_FMT_AC3_DEC 0x00010BF6 #define ASM_MEDIA_FMT_EAC3_DEC 0x00010C3C #define ASM_MEDIA_FMT_DTS 0x00010D88 @@ -4329,6 +4333,8 @@ struct asm_stream_cmd_open_write_v3 { * - #ASM_MEDIA_FMT_SBC * - #ASM_MEDIA_FMT_WMA_V10PRO_V2 * - #ASM_MEDIA_FMT_WMA_V9_V2 + * - #ASM_MEDIA_FMT_AC3 + * - #ASM_MEDIA_FMT_EAC3 * - #ASM_MEDIA_FMT_AC3_DEC * - #ASM_MEDIA_FMT_EAC3_DEC * - #ASM_MEDIA_FMT_G711_ALAW_FS @@ -4501,6 +4507,7 @@ struct asm_stream_cmd_open_readwrite_v2 { * - #ASM_MEDIA_FMT_WMA_V10PRO_V2 * - #ASM_MEDIA_FMT_WMA_V9_V2 * - #ASM_MEDIA_FMT_AMR_WB_PLUS_V2 + * - #ASM_MEDIA_FMT_AC3 * - #ASM_MEDIA_FMT_AC3_DEC * - #ASM_MEDIA_FMT_G711_ALAW_FS * - #ASM_MEDIA_FMT_G711_MLAW_FS @@ -5117,6 +5124,8 @@ struct asm_stream_cmd_open_write_compressed { * Supported values: * - #ASM_MEDIA_FMT_AC3_DEC * - #ASM_MEDIA_FMT_EAC3_DEC + * - #ASM_MEDIA_FMT_AC3 + * - #ASM_MEDIA_FMT_EAC3 * - #ASM_MEDIA_FMT_DTS * - #ASM_MEDIA_FMT_ATRAC * - #ASM_MEDIA_FMT_MAT @@ -5935,6 +5944,7 @@ struct audproc_topology_module_id_info_t { * This module supports the following parameter IDs: * - #ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN * - #ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN + * - #ASM_PARAM_ID_MULTICHANNEL_GAIN * - #ASM_PARAM_ID_VOL_CTRL_MUTE_CONFIG * - #ASM_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS * - #ASM_PARAM_ID_SOFT_PAUSE_PARAMETERS @@ -5961,6 +5971,7 @@ struct audproc_topology_module_id_info_t { * @messagepayload * @structure{asm_volume_ctrl_lr_chan_gain} * @tablespace + * @inputtable{Audio_Postproc_ASM_PARAM_ID_MULTICHANNEL_GAIN.tex} * @inputtable{Audio_Postproc_ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN.tex} */ #define ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN 0x00010C00 @@ -6165,12 +6176,10 @@ struct asm_soft_pause_params { */ -struct asm_volume_ctrl_channelype_gain_pair { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; - uint8_t channelype; -/*< Channel type for which the gain setting is to be applied. +struct asm_volume_ctrl_channeltype_gain_pair { + uint8_t channeltype; +/* + *< Channel type for which the gain setting is to be applied. * Supported values: * - #PCM_CHANNEL_L * - #PCM_CHANNEL_R @@ -6200,7 +6209,8 @@ struct asm_volume_ctrl_channelype_gain_pair { /*< Clients must set this field to zero. */ uint32_t gain; -/*< Gain value for this channel in Q28 format. +/* + *< Gain value for this channel in Q28 format. * Supported values: Any */ } __packed; @@ -6219,14 +6229,14 @@ struct asm_volume_ctrl_multichannel_gain { struct asm_stream_cmd_set_pp_params_v2 param; struct asm_stream_param_data_v2 data; uint32_t num_channels; -/*< Number of channels for which gain values are provided. Any +/* + *< Number of channels for which gain values are provided. Any * channels present in the data for which gain is not provided are * set to unity gain. * Supported values: 1 to 8 */ - - struct asm_volume_ctrl_channelype_gain_pair + struct asm_volume_ctrl_channeltype_gain_pair gain_data[VOLUME_CONTROL_MAX_CHANNELS]; /*< Array of channel type/gain pairs.*/ } __packed; @@ -7459,6 +7469,154 @@ enum afe_lpass_clk_mode { Q6AFE_LPASS_MODE_BOTH_VALID, } __packed; +/* Clock ID Enumeration Define. */ +/* Clock ID for Primary I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT 0x100 +/* Clock ID for Primary I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT 0x101 +/* Clock ID for Secondary I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT 0x102 +/* Clock ID for Secondary I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT 0x103 +/* Clock ID for Tertiary I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT 0x104 +/* Clock ID for Tertiary I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT 0x105 +/* Clock ID for Quartnery I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT 0x106 +/* Clock ID for Quartnery I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT 0x107 +/* Clock ID for Speaker I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_IBIT 0x108 +/* Clock ID for Speaker I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_EBIT 0x109 +/* Clock ID for Speaker I2S OSR */ +#define Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_OSR 0x10A + +/* Clock ID for QUINARY I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT 0x10B +/* Clock ID for QUINARY I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT 0x10C +/* Clock ID for SENARY I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEN_MI2S_IBIT 0x10D +/* Clock ID for SENARY I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEN_MI2S_EBIT 0x10E + +/* Clock ID for Primary PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT 0x200 +/* Clock ID for Primary PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_PCM_EBIT 0x201 +/* Clock ID for Secondary PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_PCM_IBIT 0x202 +/* Clock ID for Secondary PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_PCM_EBIT 0x203 +/* Clock ID for Tertiary PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_PCM_IBIT 0x204 +/* Clock ID for Tertiary PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_PCM_EBIT 0x205 +/* Clock ID for Quartery PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_PCM_IBIT 0x206 +/* Clock ID for Quartery PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_PCM_EBIT 0x207 + +/** Clock ID for Primary TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT 0x200 +/** Clock ID for Primary TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_TDM_EBIT 0x201 +/** Clock ID for Secondary TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_TDM_IBIT 0x202 +/** Clock ID for Secondary TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_TDM_EBIT 0x203 +/** Clock ID for Tertiary TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT 0x204 +/** Clock ID for Tertiary TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_TDM_EBIT 0x205 +/** Clock ID for Quartery TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT 0x206 +/** Clock ID for Quartery TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_TDM_EBIT 0x207 + +/* Clock ID for MCLK1 */ +#define Q6AFE_LPASS_CLK_ID_MCLK_1 0x300 +/* Clock ID for MCLK2 */ +#define Q6AFE_LPASS_CLK_ID_MCLK_2 0x301 +/* Clock ID for MCLK3 */ +#define Q6AFE_LPASS_CLK_ID_MCLK_3 0x302 +/* Clock ID for Internal Digital Codec Core */ +#define Q6AFE_LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE 0x303 + +/* Clock ID for AHB HDMI input */ +#define Q6AFE_LPASS_CLK_ID_AHB_HDMI_INPUT 0x400 + +/* Clock ID for SPDIF core */ +#define Q6AFE_LPASS_CLK_ID_SPDIF_CORE 0x500 + + +/* Clock attribute for invalid use (reserved for internal usage) */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_INVALID 0x0 +/* Clock attribute for no couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO 0x1 +/* Clock attribute for dividend couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVIDEND 0x2 +/* Clock attribute for divisor couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR 0x3 +/* Clock attribute for invert and no couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_INVERT_COUPLE_NO 0x4 +/* Clock set API version */ +#define Q6AFE_LPASS_CLK_CONFIG_API_VERSION 0x1 + +struct afe_clk_set { + /* + * Minor version used for tracking clock set. + * @values #AFE_API_VERSION_CLOCK_SET + */ + uint32_t clk_set_minor_version; + + /* + * Clock ID + * @values + * - 0x100 to 0x10A - MSM8996 + * - 0x200 to 0x207 - MSM8996 + * - 0x300 to 0x302 - MSM8996 @tablebulletend + */ + uint32_t clk_id; + + /* + * Clock frequency (in Hertz) to be set. + * @values + * - >= 0 for clock frequency to set @tablebulletend + */ + uint32_t clk_freq_in_hz; + + /* Use to specific divider for two clocks if needed. + * Set to Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO for no divider + * relation clocks + * @values + * - #Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO + * - #Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVIDEND + * - #Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR @tablebulletend + */ + uint16_t clk_attri; + + /* + * Specifies the root clock source. + * Currently, only Q6AFE_LPASS_CLK_ROOT_DEFAULT is valid + * @values + * - 0 @tablebulletend + */ + uint16_t clk_root; + + /* + * for enable and disable clock. + * "clk_freq_in_hz", "clk_attri", and "clk_root" + * are ignored in disable clock case. + * @values + * - 0 -- Disabled + * - 1 -- Enabled @tablebulletend + */ + uint32_t enable; +}; + struct afe_clk_cfg { /* Minor version used for tracking the version of the I2S * configuration interface. @@ -7496,7 +7654,8 @@ struct afe_clk_cfg { /* This param id is used to configure I2S clk */ #define AFE_PARAM_ID_LPAIF_CLK_CONFIG 0x00010238 - +#define AFE_MODULE_CLOCK_SET 0x0001028F +#define AFE_PARAM_ID_CLOCK_SET 0x00010290 struct afe_lpass_clk_config_command { struct apr_hdr hdr; @@ -7663,6 +7822,13 @@ struct afe_svc_cmd_set_param { uint32_t mem_map_handle; } __packed; +struct afe_svc_param_data { + uint32_t module_id; + uint32_t param_id; + uint16_t param_size; + uint16_t reserved; +} __packed; + struct afe_param_hw_mad_ctrl { uint32_t minor_version; uint16_t mad_type; @@ -7694,6 +7860,13 @@ struct afe_param_cdc_reg_cfg_payload { struct afe_param_cdc_reg_cfg reg_cfg; } __packed; +struct afe_lpass_clk_config_command_v2 { + struct apr_hdr hdr; + struct afe_svc_cmd_set_param param; + struct afe_svc_param_data pdata; + struct afe_clk_set clk_cfg; +} __packed; + /* * reg_data's size can be up to AFE_MAX_CDC_REGISTERS_TO_CONFIG */ @@ -7905,6 +8078,151 @@ struct asm_mtmx_strtr_params { u32 window_lsw; u32 window_msw; } __packed; + + + +/* Command for Matrix or Stream Router */ +#define ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2 0x00010DCE +/* Module for AVSYNC */ +#define ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC 0x00010DC6 + +/* Parameter used by #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC to specify the + * render window start value. This parameter is supported only for a Set + * command (not a Get command) in the Rx direction + * (#ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2). + * Render window start is a value (session time minus timestamp, or ST-TS) + * below which frames are held, and after which frames are immediately + * rendered. + */ +#define ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_START_V2 0x00010DD1 + +/* Parameter used by #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC to specify the + * render window end value. This parameter is supported only for a Set + * command (not a Get command) in the Rx direction + * (#ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2). Render window end is a value + * (session time minus timestamp) above which frames are dropped, and below + * which frames are immediately rendered. + */ +#define ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_END_V2 0x00010DD2 + +/* Generic payload of the window parameters in the + * #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC module. + * This payload is supported only for a Set command + * (not a Get command) on the Rx path. + */ + +#define ASM_SESSION_CMD_GET_MTMX_STRTR_PARAMS_V2 0x00010DCF +#define ASM_SESSION_CMDRSP_GET_MTMX_STRTR_PARAMS_V2 0x00010DD0 + +#define ASM_SESSION_MTMX_STRTR_PARAM_SESSION_TIME_V3 0x00012F0B +#define ASM_SESSION_MTMX_STRTR_PARAM_STIME_TSTMP_FLG_BMASK (0x80000000UL) + +struct asm_session_cmd_get_mtmx_strstr_params_v2 { + uint32_t data_payload_addr_lsw; + /* Lower 32 bits of the 64-bit data payload address. */ + + uint32_t data_payload_addr_msw; + /* + * Upper 32 bits of the 64-bit data payload address. + * If the address is not sent (NULL), the message is in the payload. + * If the address is sent (non-NULL), the parameter data payloads + * begin at the specified address. + */ + + uint32_t mem_map_handle; + /* + * Unique identifier for an address. This memory map handle is returned + * by the aDSP through the #ASM_CMD_SHARED_MEM_MAP_REGIONS command. + * values + * - NULL -- Parameter data payloads are within the message payload + * (in-band). + * - Non-NULL -- Parameter data payloads begin at the address specified + * in the data_payload_addr_lsw and data_payload_addr_msw fields + * (out-of-band). + */ + uint32_t direction; + /* + * Direction of the entity (matrix mixer or stream router) on which + * the parameter is to be set. + * values + * - 0 -- Rx (for Rx stream router or Rx matrix mixer) + * - 1 -- Tx (for Tx stream router or Tx matrix mixer) + */ + uint32_t module_id; + /* Unique module ID. */ + + uint32_t param_id; + /* Unique parameter ID. */ + + uint32_t param_max_size; +}; + +struct asm_session_mtmx_strtr_param_session_time_v3_t { + uint32_t session_time_lsw; + /* Lower 32 bits of the current session time in microseconds */ + + uint32_t session_time_msw; + /* + * Upper 32 bits of the current session time in microseconds. + * The 64-bit number formed by session_time_lsw and session_time_msw + * is treated as signed. + */ + + uint32_t absolute_time_lsw; + /* + * Lower 32 bits of the 64-bit absolute time in microseconds. + * This is the time when the sample corresponding to the + * session_time_lsw is rendered to the hardware. This absolute + * time can be slightly in the future or past. + */ + + uint32_t absolute_time_msw; + /* + * Upper 32 bits of the 64-bit absolute time in microseconds. + * This is the time when the sample corresponding to the + * session_time_msw is rendered to hardware. This absolute + * time can be slightly in the future or past. The 64-bit number + * formed by absolute_time_lsw and absolute_time_msw is treated as + * unsigned. + */ + + uint32_t time_stamp_lsw; + /* Lower 32 bits of the last processed timestamp in microseconds */ + + uint32_t time_stamp_msw; + /* + * Upper 32 bits of the last processed timestamp in microseconds. + * The 64-bit number formed by time_stamp_lsw and time_stamp_lsw + * is treated as unsigned. + */ + + uint32_t flags; + /* + * Keeps track of any additional flags needed. + * @values{for bit 31} + * - 0 -- Uninitialized/invalid + * - 1 -- Valid + * All other bits are reserved; clients must set them to zero. + */ +}; + +union asm_session_mtmx_strtr_data_type { + struct asm_session_mtmx_strtr_param_session_time_v3_t session_time; +}; + +struct asm_mtmx_strtr_get_params { + struct apr_hdr hdr; + struct asm_session_cmd_get_mtmx_strstr_params_v2 param_info; +} __packed; + +struct asm_mtmx_strtr_get_params_cmdrsp { + uint32_t err_code; + struct asm_stream_param_data_v2 param_info; + union asm_session_mtmx_strtr_data_type param_data; +} __packed; + + + #define AUDPROC_MODULE_ID_RESAMPLER 0x00010719 enum { diff --git a/include/sound/q6afe-v2.h b/include/sound/q6afe-v2.h index f965bc2fd0e38..46da0660919cd 100644 --- a/include/sound/q6afe-v2.h +++ b/include/sound/q6afe-v2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -38,7 +38,6 @@ #define RT_PROXY_DAI_002_RX 0xF1 #define RT_PROXY_DAI_002_TX 0xE1 #define VIRTUAL_ID_TO_PORTID(val) ((val & 0xF) | 0x2000) - enum { IDX_PRIMARY_I2S_RX = 0, IDX_PRIMARY_I2S_TX = 1, @@ -198,6 +197,7 @@ int afe_convert_virtual_to_portid(u16 port_id); int afe_pseudo_port_start_nowait(u16 port_id); int afe_pseudo_port_stop_nowait(u16 port_id); int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg); +int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg); int afe_set_digital_codec_core_clock(u16 port_id, struct afe_digital_clk_cfg *cfg); int afe_set_lpass_internal_digital_codec_clock(u16 port_id, diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h index 1b7ea08584489..3c6a456e9ae14 100644 --- a/include/sound/q6asm-v2.h +++ b/include/sound/q6asm-v2.h @@ -431,10 +431,15 @@ int q6asm_set_softvolume_v2(struct audio_client *ac, /* Send left-right channel gain */ int q6asm_set_lrgain(struct audio_client *ac, int left_gain, int right_gain); +/* Send multi channel gain */ +int q6asm_set_multich_gain(struct audio_client *ac, uint32_t channels, + uint32_t *gains, uint8_t *ch_map, bool use_default); + /* Enable Mute/unmute flag */ int q6asm_set_mute(struct audio_client *ac, int muteflag); int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp); +int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp); int q6asm_send_audio_effects_params(struct audio_client *ac, char *params, uint32_t params_length); diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c index 0b04e4776b78b..31fcedc7f34f9 100644 --- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -195,8 +196,13 @@ static int msm_compr_set_volume(struct snd_compr_stream *cstream, uint32_t volume_l, uint32_t volume_r) { struct msm_compr_audio *prtd; - int rc = 0; - uint32_t avg_vol; + int i, rc = -1; + uint32_t avg_vol, gain_list[VOLUME_CONTROL_MAX_CHANNELS]; + uint32_t num_channels; + struct snd_soc_pcm_runtime *rtd; + struct msm_compr_pdata *pdata; + bool use_default = true; + u8 *chmap = NULL; pr_debug("%s: volume_l %d volume_r %d\n", __func__, volume_l, volume_r); @@ -204,18 +210,30 @@ static int msm_compr_set_volume(struct snd_compr_stream *cstream, pr_err("%s: session not active\n", __func__); return -EPERM; } + rtd = cstream->private_data; prtd = cstream->runtime->private_data; if (!prtd || !prtd->audio_client) { - pr_err("%s: invalid session prtd or no audio client", __func__); + pr_err("%s: invalid session/rtd, prtd or no audio client", + __func__); return rc; } + pdata = snd_soc_platform_get_drvdata(rtd->platform); if (prtd->compr_passthr != LEGACY_PCM) { pr_debug("%s: No volume config for passthrough %d\n", __func__, prtd->compr_passthr); return rc; } + + use_default = !(pdata->ch_map[rtd->dai_link->be_id]->set_ch_map); + chmap = pdata->ch_map[rtd->dai_link->be_id]->channel_map; + num_channels = prtd->num_channels; + pr_debug("%s: call q6asm_set_volume volume_l(%d)volume_r(%d)num of channels(%d)\n", + __func__, volume_l, volume_r, prtd->num_channels); + pr_debug("%s: AVS version(%d): 0 for AVS2.6, 1 for AVS2.7\n", + __func__, q6core_get_avs_version()); + if (prtd->num_channels > 2) { /* * Currently the left and right gains are averaged an applied @@ -226,28 +244,62 @@ static int msm_compr_set_volume(struct snd_compr_stream *cstream, * channel gains. * */ - pr_debug("%s: call q6asm_set_volume for multichannel\n", - __func__); - avg_vol = (volume_l + volume_r) / 2; - rc = q6asm_set_volume(prtd->audio_client, avg_vol); + switch (q6core_get_avs_version()) { + case Q6_SUBSYS_AVS2_7: + avg_vol = (volume_l + volume_r) / 2; + for (i = 0; i < prtd->num_channels; i++) + gain_list[i] = avg_vol; + rc = q6asm_set_multich_gain(prtd->audio_client, + num_channels, gain_list, chmap, use_default); + break; + case Q6_SUBSYS_AVS2_6: + avg_vol = (volume_l + volume_r) / 2; + rc = q6asm_set_volume(prtd->audio_client, avg_vol); + break; + case Q6_SUBSYS_INVALID: + default: + pr_err("%s: UNKNOWN AVS IMAGE\n", __func__); + return rc; + } } else { - pr_debug("%s: call q6asm_set_lrgain\n", __func__); - rc = q6asm_set_lrgain(prtd->audio_client, volume_l, volume_r); - if (rc < 0) { - pr_err("%s: Send LR gain command failed rc=%d\n", - __func__, rc); - } else { - pr_debug("%s: now calling msm_dts_eagle_set_volume\n", - __func__); - rc = msm_dts_eagle_set_volume(prtd->audio_client, - volume_l, volume_r); - if (rc < 0) { - pr_err("%s: Send Volume command failed (DTS_EAGLE) rc=%d\n", + switch (q6core_get_avs_version()) { + case Q6_SUBSYS_AVS2_7: + gain_list[0] = volume_l; + gain_list[1] = volume_r; + /* force sending FR/FL/FC volume for mono */ + if (prtd->num_channels == 1) { + gain_list[2] = volume_l; + num_channels = 3; + use_default = true; + } + rc = q6asm_set_multich_gain(prtd->audio_client, + num_channels, gain_list, chmap, use_default); + break; + case Q6_SUBSYS_AVS2_6: + pr_debug("%s: call q6asm_set_lrgain\n", __func__); + rc = q6asm_set_lrgain(prtd->audio_client, + volume_l, volume_r); + if (rc < 0) + pr_err("%s: Send LR gain command failed rc=%d\n", + __func__, rc); + else { + pr_debug("%s: now calling msm_dts_eagle_set_volume\n", + __func__); + rc = msm_dts_eagle_set_volume( + prtd->audio_client, + volume_l, volume_r); + if (rc < 0) { + pr_err("%s: Send Volume command failed (DTS_EAGLE) rc=%d\n", __func__, rc); + } } + break; + case Q6_SUBSYS_INVALID: + default: + pr_err("%s: UNKNOWN AVS IMAGE\n", __func__); + return rc; } } - if (rc < 0) pr_err("%s: Send vol gain command failed rc=%d\n", __func__, rc); @@ -1709,9 +1761,30 @@ static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd) /* * Cache this time as last known time */ - q6asm_get_session_time(prtd->audio_client, - &prtd->marker_timestamp); + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_7): + { + q6asm_get_session_time(prtd->audio_client, + &prtd->marker_timestamp); + break; + } + case (Q6_SUBSYS_AVS2_6): + { + q6asm_get_session_time_legacy( + prtd->audio_client, + &prtd->marker_timestamp); + break; + } + case (Q6_SUBSYS_INVALID): + default: + { + pr_err("%s: UNKNOWN AVS IMAGE VERSION\n", + __func__); + break; + } + } spin_lock_irqsave(&prtd->lock, flags); + /* * Don't reset these as these vars map to * total_bytes_transferred and total_bytes_available. @@ -1868,7 +1941,27 @@ static int msm_compr_pointer(struct snd_compr_stream *cstream, pr_debug("%s session time in gapless transition", __func__); - rc = q6asm_get_session_time(prtd->audio_client, ×tamp); + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_7): + { + rc = q6asm_get_session_time(prtd->audio_client, + ×tamp); + break; + } + case (Q6_SUBSYS_AVS2_6): + { + rc = q6asm_get_session_time_legacy( + prtd->audio_client, ×tamp); + break; + } + case (Q6_SUBSYS_INVALID): + default: + { + pr_err("%s: UNKNOWN AVS IMAGE VERSION\n", __func__); + rc = -EINVAL; + break; + } + } if (rc < 0) { pr_err("%s: Get Session Time return value =%lld\n", __func__, timestamp); diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c index ae720468ff89d..5e6da527d97d1 100644 --- a/sound/soc/msm/qdsp6v2/q6afe.c +++ b/sound/soc/msm/qdsp6v2/q6afe.c @@ -3785,6 +3785,113 @@ int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg) return ret; } +int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg) +{ + struct afe_lpass_clk_config_command_v2 clk_cfg; + int ret = 0; + + if (!cfg) { + pr_err("%s: clock cfg is NULL\n", __func__); + ret = -EINVAL; + return ret; + } + + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: index[%d] invalid!\n", __func__, index); + return -EINVAL; + } + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + mutex_lock(&this_afe.afe_cmd_lock); + clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + clk_cfg.hdr.pkt_size = sizeof(clk_cfg); + clk_cfg.hdr.src_port = 0; + clk_cfg.hdr.dest_port = 0; + clk_cfg.hdr.token = index; + + clk_cfg.hdr.opcode = AFE_SVC_CMD_SET_PARAM; + clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) + - sizeof(clk_cfg.param); + clk_cfg.param.payload_address_lsw = 0x00; + clk_cfg.param.payload_address_msw = 0x00; + clk_cfg.param.mem_map_handle = 0x00; + clk_cfg.pdata.module_id = AFE_MODULE_CLOCK_SET; + clk_cfg.pdata.param_id = AFE_PARAM_ID_CLOCK_SET; + clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); + clk_cfg.clk_cfg = *cfg; + + + pr_debug("%s: Minor version =0x%x clk id = %d\n" + "clk freq (Hz) = %d, clk attri = 0x%x\n" + "clk root = 0x%x clk enable = 0x%x\n", + __func__, cfg->clk_set_minor_version, + cfg->clk_id, cfg->clk_freq_in_hz, cfg->clk_attri, + cfg->clk_root, cfg->enable); + + atomic_set(&this_afe.state, 1); + atomic_set(&this_afe.status, 0); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); + if (ret < 0) { + pr_err("%s: AFE clk cfg failed with ret %d\n", + __func__, ret); + ret = -EINVAL; + goto fail_cmd; + } + + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } else { + /* set ret to 0 as no timeout happened */ + ret = 0; + } + if (atomic_read(&this_afe.status) != 0) { + pr_err("%s: config cmd failed\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + +fail_cmd: + mutex_unlock(&this_afe.afe_cmd_lock); + return ret; +} + +int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg) +{ + int index = 0; + int ret = 0; + + index = q6audio_get_port_index(port_id); + if (index < 0 || index > AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_is_digital_pcm_interface(port_id); + if (ret < 0) { + pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n", + __func__, ret); + return -EINVAL; + } + + ret = afe_set_lpass_clk_cfg(index, cfg); + if (ret) + pr_err("%s: afe_set_lpass_clk_cfg_v2 failed %d\n", + __func__, ret); + + return ret; +} + int afe_set_lpass_internal_digital_codec_clock(u16 port_id, struct afe_digital_clk_cfg *cfg) { diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index 681b41a8fe910..e2c2d7b94bb7d 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -1431,6 +1432,57 @@ static int32_t is_no_wait_cmd_rsp(uint32_t opcode, uint32_t *cmd_type) return 0; } +static void q6asm_process_mtmx_get_param_rsp(struct audio_client *ac, + struct asm_mtmx_strtr_get_params_cmdrsp *cmdrsp) +{ + struct asm_session_mtmx_strtr_param_session_time_v3_t *time; + + if (cmdrsp->err_code) { + dev_err_ratelimited(ac->dev, + "%s: err=%x, mod_id=%x, param_id=%x\n", + __func__, cmdrsp->err_code, + cmdrsp->param_info.module_id, + cmdrsp->param_info.param_id); + return; + } + dev_dbg_ratelimited(ac->dev, + "%s: mod_id=%x, param_id=%x\n", __func__, + cmdrsp->param_info.module_id, + cmdrsp->param_info.param_id); + + switch (cmdrsp->param_info.module_id) { + case ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC: + switch (cmdrsp->param_info.param_id) { + case ASM_SESSION_MTMX_STRTR_PARAM_SESSION_TIME_V3: + time = &cmdrsp->param_data.session_time; + dev_vdbg(ac->dev, "%s: GET_TIME_V3, time_lsw=%x, time_msw=%x\n", + __func__, time->session_time_lsw, + time->session_time_msw); + ac->time_stamp = (uint64_t)(((uint64_t) + time->session_time_msw << 32) | + time->session_time_lsw); + if (time->flags & + ASM_SESSION_MTMX_STRTR_PARAM_STIME_TSTMP_FLG_BMASK) + dev_warn_ratelimited(ac->dev, + "%s: recv inval tstmp\n", + __func__); + if (atomic_cmpxchg(&ac->time_flag, 1, 0)) + wake_up(&ac->time_wait); + + break; + default: + dev_err(ac->dev, "%s: unexpected param_id %x\n", + __func__, cmdrsp->param_info.param_id); + break; + } + break; + default: + dev_err(ac->dev, "%s: unexpected mod_id %x\n", __func__, + cmdrsp->param_info.module_id); + break; + } +} + static int32_t q6asm_callback(struct apr_client_data *data, void *priv) { int i = 0; @@ -1750,6 +1802,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) payload[0], payload[1], payload[2], payload[3]); break; + case ASM_SESSION_CMDRSP_GET_MTMX_STRTR_PARAMS_V2: + q6asm_process_mtmx_get_param_rsp(ac, (void *) payload); + break; } if (ac->cb) ac->cb(data->opcode, data->token, @@ -2149,14 +2204,35 @@ int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format, switch (format) { case FORMAT_AC3: - open.fmt_id = ASM_MEDIA_FMT_AC3_DEC; - break; + switch (q6core_get_avs_version()) { + case Q6_SUBSYS_AVS2_7: + open.fmt_id = ASM_MEDIA_FMT_AC3; + break; + case Q6_SUBSYS_AVS2_6: + open.fmt_id = ASM_MEDIA_FMT_AC3_DEC; + break; + case Q6_SUBSYS_INVALID: + default: + pr_err("%s: Invalid format[%d]\n", + __func__, format); + rc = -EINVAL; + goto fail_cmd; + } case FORMAT_EAC3: - open.fmt_id = ASM_MEDIA_FMT_EAC3_DEC; - break; - default: - pr_err("%s: Invalid format[%d]\n", __func__, format); - goto fail_cmd; + switch (q6core_get_avs_version()) { + case Q6_SUBSYS_AVS2_7: + open.fmt_id = ASM_MEDIA_FMT_EAC3; + break; + case Q6_SUBSYS_AVS2_6: + open.fmt_id = ASM_MEDIA_FMT_EAC3_DEC; + break; + case Q6_SUBSYS_INVALID: + default: + pr_err("%s: Invalid format[%d]\n", + __func__, format); + rc = -EINVAL; + goto fail_cmd; + } } /*Below flag indicates the DSP that Compressed audio input stream is not IEC 61937 or IEC 60958 packetizied*/ @@ -2197,6 +2273,7 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format, bool is_gapless_mode) { int rc = 0x00; + struct asm_stream_cmd_open_write_v3 open; if (ac == NULL) { @@ -2272,10 +2349,36 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format, open.dec_fmt_id = ASM_MEDIA_FMT_MP3; break; case FORMAT_AC3: - open.dec_fmt_id = ASM_MEDIA_FMT_EAC3_DEC; + switch (q6core_get_avs_version()) { + case Q6_SUBSYS_AVS2_7: + open.dec_fmt_id = ASM_MEDIA_FMT_AC3; + break; + case Q6_SUBSYS_AVS2_6: + open.dec_fmt_id = ASM_MEDIA_FMT_AC3_DEC; + break; + case Q6_SUBSYS_INVALID: + default: + pr_err("%s: Invalid format[%d]\n", + __func__, format); + rc = -EINVAL; + goto fail_cmd; + } break; case FORMAT_EAC3: - open.dec_fmt_id = ASM_MEDIA_FMT_EAC3_DEC; + switch (q6core_get_avs_version()) { + case Q6_SUBSYS_AVS2_7: + open.dec_fmt_id = ASM_MEDIA_FMT_EAC3; + break; + case Q6_SUBSYS_AVS2_6: + open.dec_fmt_id = ASM_MEDIA_FMT_EAC3_DEC; + break; + case Q6_SUBSYS_INVALID: + default: + pr_err("%s: Invalid format[%d]\n", + __func__, format); + rc = -EINVAL; + goto fail_cmd; + } break; case FORMAT_MP2: open.dec_fmt_id = ASM_MEDIA_FMT_MP2; @@ -4348,6 +4451,110 @@ int q6asm_set_lrgain(struct audio_client *ac, int left_gain, int right_gain) return rc; } +/* + * q6asm_set_multich_gain: set multiple channel gains on an ASM session + * @ac: audio client handle + * @channels: number of channels caller intends to set gains + * @gains: list of gains of audio channels + * @ch_map: list of channel mapping. Only valid if use_default is false + * @use_default: flag to indicate whether to use default mapping + */ +int q6asm_set_multich_gain(struct audio_client *ac, uint32_t channels, + uint32_t *gains, uint8_t *ch_map, bool use_default) +{ + struct asm_volume_ctrl_multichannel_gain multich_gain; + int sz = 0; + int rc = 0; + int i; + u8 default_chmap[VOLUME_CONTROL_MAX_CHANNELS]; + + if (ac == NULL) { + pr_err("%s: ac is NULL\n", __func__); + rc = -EINVAL; + goto done; + } + if (ac->apr == NULL) { + dev_err(ac->dev, "%s: AC APR handle NULL\n", __func__); + rc = -EINVAL; + goto done; + } + if (gains == NULL) { + dev_err(ac->dev, "%s: gain_list is NULL\n", __func__); + rc = -EINVAL; + goto done; + } + if (channels > VOLUME_CONTROL_MAX_CHANNELS) { + dev_err(ac->dev, "%s: Invalid channel count %d\n", + __func__, channels); + rc = -EINVAL; + goto done; + } + if (!use_default && ch_map == NULL) { + dev_err(ac->dev, "%s: NULL channel map\n", __func__); + rc = -EINVAL; + goto done; + } + + memset(&multich_gain, 0, sizeof(multich_gain)); + sz = sizeof(struct asm_volume_ctrl_multichannel_gain); + q6asm_add_hdr_async(ac, &multich_gain.hdr, sz, TRUE); + atomic_set(&ac->cmd_state, 1); + multich_gain.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; + multich_gain.param.data_payload_addr_lsw = 0; + multich_gain.param.data_payload_addr_msw = 0; + multich_gain.param.mem_map_handle = 0; + multich_gain.param.data_payload_size = sizeof(multich_gain) - + sizeof(multich_gain.hdr) - sizeof(multich_gain.param); + multich_gain.data.module_id = ASM_MODULE_ID_VOL_CTRL; + multich_gain.data.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN; + multich_gain.data.param_size = multich_gain.param.data_payload_size - + sizeof(multich_gain.data); + multich_gain.data.reserved = 0; + + if (use_default) { + rc = q6asm_map_channels(default_chmap, channels); + if (rc < 0) + goto done; + for (i = 0; i < channels; i++) { + multich_gain.gain_data[i].channeltype = + default_chmap[i]; + multich_gain.gain_data[i].gain = gains[i] << 15; + } + } else { + for (i = 0; i < channels; i++) { + multich_gain.gain_data[i].channeltype = ch_map[i]; + multich_gain.gain_data[i].gain = gains[i] << 15; + } + } + multich_gain.num_channels = channels; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &multich_gain); + if (rc < 0) { + pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", + __func__, multich_gain.data.param_id, rc); + goto done; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) <= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, + multich_gain.data.param_id); + rc = -EINVAL; + goto done; + } + if (atomic_read(&ac->cmd_state) < 0) { + pr_err("%s: DSP returned error[%d] , set-params paramid[0x%x]\n", + __func__, atomic_read(&ac->cmd_state), + multich_gain.data.param_id); + rc = -EINVAL; + goto done; + } + rc = 0; +done: + return rc; +} + int q6asm_set_mute(struct audio_client *ac, int muteflag) { struct asm_volume_ctrl_mute_config mute; @@ -5304,6 +5511,63 @@ int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts, } int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) +{ + struct asm_mtmx_strtr_get_params mtmx_params; + int rc; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + if (tstamp == NULL) { + pr_err("%s: tstamp NULL\n", __func__); + return -EINVAL; + } + + q6asm_add_hdr(ac, &mtmx_params.hdr, sizeof(mtmx_params), TRUE); + mtmx_params.hdr.opcode = ASM_SESSION_CMD_GET_MTMX_STRTR_PARAMS_V2; + mtmx_params.param_info.data_payload_addr_lsw = 0; + mtmx_params.param_info.data_payload_addr_msw = 0; + mtmx_params.param_info.mem_map_handle = 0; + mtmx_params.param_info.direction = (ac->io_mode & TUN_READ_IO_MODE + ? 1 : 0); + mtmx_params.param_info.module_id = + ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; + mtmx_params.param_info.param_id = + ASM_SESSION_MTMX_STRTR_PARAM_SESSION_TIME_V3; + mtmx_params.param_info.param_max_size = + sizeof(struct asm_stream_param_data_v2) + + sizeof(struct asm_session_mtmx_strtr_param_session_time_v3_t); + atomic_set(&ac->time_flag, 1); + + dev_vdbg(ac->dev, "%s: session[%d]opcode[0x%x]\n", __func__, + ac->session, mtmx_params.hdr.opcode); + rc = apr_send_pkt(ac->apr, (uint32_t *) &mtmx_params); + if (rc < 0) { + pr_err("%s: Commmand 0x%x failed %d\n", __func__, + mtmx_params.hdr.opcode, rc); + goto fail_cmd; + } + rc = wait_event_timeout(ac->time_wait, + (atomic_read(&ac->time_flag) == 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout in getting session time from DSP\n", + __func__); + goto fail_cmd; + } + + *tstamp = ac->time_stamp; + return 0; + +fail_cmd: + return -EINVAL; +} + +int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp) { struct apr_hdr hdr; int rc; From 67632e735ea2dd76bdda5a5e0625cb9e13689314 Mon Sep 17 00:00:00 2001 From: Surendar karka Date: Tue, 27 Sep 2016 14:25:43 +0530 Subject: [PATCH 292/320] ASoC: msm: update machine driver with AVS 2.7 support Update machine driver AFE API calls compatible with adsp version AVS 2.6 and AVS 2.7. Change-Id: Ieda8563891b2892b04f18bb7de952a91014caedf Signed-off-by: Surendar karka --- sound/soc/codecs/audio-ext-clk.c | 76 +++++-- sound/soc/msm/msm8x16.c | 353 ++++++++++++++++++++----------- 2 files changed, 284 insertions(+), 145 deletions(-) diff --git a/sound/soc/codecs/audio-ext-clk.c b/sound/soc/codecs/audio-ext-clk.c index 672ab43dc558b..636c310d35e48 100644 --- a/sound/soc/codecs/audio-ext-clk.c +++ b/sound/soc/codecs/audio-ext-clk.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "../msm/msm-audio-pinctrl.h" @@ -48,6 +49,14 @@ struct audio_ext_pmi_clk { struct clk c; }; +static struct afe_clk_set digital_cdc_core_clk = { + Q6AFE_LPASS_CLK_CONFIG_API_VERSION, + Q6AFE_LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, +}; + static int audio_ext_clk_prepare(struct clk *clk); static void audio_ext_clk_unprepare(struct clk *clk); @@ -113,12 +122,6 @@ static int audio_ext_clk_prepare(struct clk *clk) goto err; } - tasha_digital_cdc_clk.i2s_cfg_minor_version = - AFE_API_VERSION_I2S_CONFIG; - tasha_digital_cdc_clk.clk_val = 9600000; - tasha_digital_cdc_clk.clk_root = 5; - tasha_digital_cdc_clk.reserved = 0; - vaddr = ioremap(LPASS_CSR_GP_IO_MUX_SPKR_CTL , 4); val = ioread32(vaddr); val = val | 0x00000002; @@ -129,13 +132,33 @@ static int audio_ext_clk_prepare(struct clk *clk) val = val | 0x00000002; iowrite32(val, vaddr); - ret = afe_set_digital_codec_core_clock( - AFE_PORT_ID_PRIMARY_MI2S_RX , &tasha_digital_cdc_clk); - - if (ret < 0) { - pr_err("%s afe_set_digital_codec_core_clock failed\n", - __func__); - return ret; + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_6): + tasha_digital_cdc_clk.i2s_cfg_minor_version = + AFE_API_VERSION_I2S_CONFIG; + tasha_digital_cdc_clk.clk_val = 9600000; + tasha_digital_cdc_clk.clk_root = 5; + tasha_digital_cdc_clk.reserved = 0; + ret = afe_set_digital_codec_core_clock( + AFE_PORT_ID_PRIMARY_MI2S_RX, + &tasha_digital_cdc_clk); + if (ret < 0) { + pr_err("%s afe_set_digital_codec_core_clock failed\n", + __func__); + return ret; + } + break; + case (Q6_SUBSYS_AVS2_7): + digital_cdc_core_clk.enable = 1; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_PRIMARY_MI2S_RX, + &digital_cdc_core_clk); + break; + case (Q6_SUBSYS_INVALID): + default: + ret = -EINVAL; + pr_err("%s: INVALID AVS IMAGE\n", __func__); + break; } } else { pr_err("%s: gpio: %d\n", __func__, audio_clk->gpio); @@ -159,14 +182,29 @@ static void audio_ext_clk_unprepare(struct clk *clk) __func__, ret); ret = -EIO; } - tasha_digital_cdc_clk.clk_val = 0; + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_6): + tasha_digital_cdc_clk.clk_val = 0; - ret = afe_set_digital_codec_core_clock( - AFE_PORT_ID_PRIMARY_MI2S_RX, &tasha_digital_cdc_clk); + ret = afe_set_digital_codec_core_clock( + AFE_PORT_ID_PRIMARY_MI2S_RX, + &tasha_digital_cdc_clk); - if (ret < 0) { - pr_err("%s afe_set_digital_codec_core_clock failed\n", - __func__); + if (ret < 0) { + pr_err("%s afe_set_digital_codec_core_clock failed\n", + __func__); + } + case (Q6_SUBSYS_AVS2_7): + digital_cdc_core_clk.enable = 0; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_PRIMARY_MI2S_RX, + &digital_cdc_core_clk); + break; + case (Q6_SUBSYS_INVALID): + default: + ret = -EINVAL; + pr_err("%s: INVALID AVS IMAGE\n", __func__); + break; } } else { pr_debug("%s: gpio: %d\n", __func__, audio_clk->gpio); diff --git a/sound/soc/msm/msm8x16.c b/sound/soc/msm/msm8x16.c index 52f34e9c97848..f366e095822a2 100644 --- a/sound/soc/msm/msm8x16.c +++ b/sound/soc/msm/msm8x16.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "qdsp6v2/msm-pcm-routing-v2.h" #include "../codecs/msm8x16-wcd.h" @@ -239,7 +240,7 @@ void *def_tapan_mbhc_cal(void) return tapan_cal; } -static struct afe_clk_cfg mi2s_rx_clk = { +static struct afe_clk_cfg mi2s_rx_clk_v1 = { AFE_API_VERSION_I2S_CONFIG, Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, Q6AFE_LPASS_OSR_CLK_12_P288_MHZ, @@ -249,7 +250,7 @@ static struct afe_clk_cfg mi2s_rx_clk = { 0, }; -static struct afe_clk_cfg mi2s_tx_clk = { +static struct afe_clk_cfg mi2s_tx_clk_v1 = { AFE_API_VERSION_I2S_CONFIG, Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, Q6AFE_LPASS_OSR_CLK_12_P288_MHZ, @@ -259,6 +260,24 @@ static struct afe_clk_cfg mi2s_tx_clk = { 0, }; +static struct afe_clk_set mi2s_tx_clk = { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, +}; + +static struct afe_clk_set mi2s_rx_clk = { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, +}; + struct cdc_pdm_pinctrl_info { struct pinctrl *pinctrl; struct pinctrl_state *cdc_lines_sus; @@ -368,7 +387,7 @@ static int msm8x16_mclk_event(struct snd_soc_dapm_widget *w, static const struct snd_soc_dapm_widget msm8x16_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY_S("MCLK", -1, SND_SOC_NOPM, 0, 0, - msm8x16_mclk_event, SND_SOC_DAPM_POST_PMD), + msm8x16_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MIC("Handset Mic", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_MIC("Secondary Mic", NULL), @@ -378,6 +397,13 @@ static const struct snd_soc_dapm_widget msm8x16_dapm_widgets[] = { SND_SOC_DAPM_MIC("Digital Mic3", NULL), }; +static struct snd_soc_dapm_route wcd9335_audio_paths[] = { + {"MIC BIAS1", NULL, "MCLK"}, + {"MIC BIAS2", NULL, "MCLK"}, + {"MIC BIAS3", NULL, "MCLK"}, + {"MIC BIAS4", NULL, "MCLK"}, +}; + static char const *rx_bit_format_text[] = {"S16_LE", "S24_LE"}; static const char *const mi2s_tx_ch_text[] = {"One", "Two", "Three", "Four"}; static const char *const loopback_mclk_text[] = {"DISABLE", "ENABLE"}; @@ -400,6 +426,43 @@ static int msm_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } +static int msm8x16_get_clk_id(int port_id) +{ + switch (port_id) { + case AFE_PORT_ID_PRIMARY_MI2S_RX: + return Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT; + case AFE_PORT_ID_SECONDARY_MI2S_RX: + return Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT; + case AFE_PORT_ID_TERTIARY_MI2S_TX: + return Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT; + case AFE_PORT_ID_QUATERNARY_MI2S_RX: + case AFE_PORT_ID_QUATERNARY_MI2S_TX: + return Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT; + default: + pr_err("%s: invalid port_id: 0x%x\n", __func__, port_id); + return -EINVAL; + } +} + +static int msm8x16_get_port_id(int be_id) +{ + switch (be_id) { + case MSM_BACKEND_DAI_PRI_MI2S_RX: + return AFE_PORT_ID_PRIMARY_MI2S_RX; + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + return AFE_PORT_ID_SECONDARY_MI2S_RX; + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + return AFE_PORT_ID_TERTIARY_MI2S_TX; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + return AFE_PORT_ID_QUATERNARY_MI2S_RX; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + return AFE_PORT_ID_QUATERNARY_MI2S_TX; + default: + pr_err("%s: Invalid be_id: %d\n", __func__, be_id); + return -EINVAL; + } +} + static int enable_spk_ext_pa(struct snd_soc_codec *codec, int enable) { struct snd_soc_card *card = codec->card; @@ -768,19 +831,20 @@ static int quat_mi2s_sclk_ctl(struct snd_pcm_substream *substream, bool enable) if (enable) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (mi2s_rx_bit_format == SNDRV_PCM_FORMAT_S24_LE) - mi2s_rx_clk.clk_val1 = + mi2s_rx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_3_P072_MHZ; else - mi2s_rx_clk.clk_val1 = + mi2s_rx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; ret = afe_set_lpass_clock( AFE_PORT_ID_QUATERNARY_MI2S_RX, - &mi2s_rx_clk); + &mi2s_rx_clk_v1); } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - mi2s_tx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; + mi2s_tx_clk_v1.clk_val1 = + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; ret = afe_set_lpass_clock( AFE_PORT_ID_QUATERNARY_MI2S_TX, - &mi2s_tx_clk); + &mi2s_tx_clk_v1); } else { pr_err("%s:Not valid substream.\n", __func__); } @@ -790,10 +854,10 @@ static int quat_mi2s_sclk_ctl(struct snd_pcm_substream *substream, bool enable) } else { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; + mi2s_rx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; ret = afe_set_lpass_clock( AFE_PORT_ID_QUATERNARY_MI2S_RX, - &mi2s_rx_clk); + &mi2s_rx_clk_v1); } else { pr_err("%s:Not valid substream.\n", __func__); } @@ -811,13 +875,13 @@ static int sec_mi2s_sclk_ctl(struct snd_pcm_substream *substream, bool enable) if (enable) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (mi2s_rx_bit_format == SNDRV_PCM_FORMAT_S24_LE) - mi2s_rx_clk.clk_val1 = + mi2s_rx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_3_P072_MHZ; else - mi2s_rx_clk.clk_val1 = + mi2s_rx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_RX, - &mi2s_rx_clk); + &mi2s_rx_clk_v1); } else pr_err("%s:Not valid substream.\n", __func__); @@ -826,9 +890,9 @@ static int sec_mi2s_sclk_ctl(struct snd_pcm_substream *substream, bool enable) } else { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; + mi2s_rx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_RX, - &mi2s_rx_clk); + &mi2s_rx_clk_v1); } else pr_err("%s:Not valid substream.\n", __func__); @@ -844,17 +908,18 @@ static int mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) if (enable) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (mi2s_rx_bit_format == SNDRV_PCM_FORMAT_S24_LE) - mi2s_rx_clk.clk_val1 = + mi2s_rx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_3_P072_MHZ; else - mi2s_rx_clk.clk_val1 = + mi2s_rx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; ret = afe_set_lpass_clock(AFE_PORT_ID_PRIMARY_MI2S_RX, - &mi2s_rx_clk); + &mi2s_rx_clk_v1); } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - mi2s_tx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; + mi2s_tx_clk_v1.clk_val1 = + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; ret = afe_set_lpass_clock(AFE_PORT_ID_TERTIARY_MI2S_TX, - &mi2s_tx_clk); + &mi2s_tx_clk_v1); } else pr_err("%s:Not valid substream.\n", __func__); @@ -863,13 +928,13 @@ static int mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) } else { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; + mi2s_rx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; ret = afe_set_lpass_clock(AFE_PORT_ID_PRIMARY_MI2S_RX, - &mi2s_rx_clk); + &mi2s_rx_clk_v1); } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - mi2s_tx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; + mi2s_tx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; ret = afe_set_lpass_clock(AFE_PORT_ID_TERTIARY_MI2S_TX, - &mi2s_tx_clk); + &mi2s_tx_clk_v1); } else pr_err("%s:Not valid substream.\n", __func__); @@ -880,23 +945,75 @@ static int mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) return ret; } -static int ext_mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable, - u16 port_id) +static uint32_t get_mi2s_rx_clk_val(void) +{ + uint32_t clk_val; + + clk_val = pri_rx_sample_rate * bits_per_sample * 2; + + return clk_val; +} + +static int ext_mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) { int ret = 0; + int port_id = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + + port_id = msm8x16_get_port_id(rtd->dai_link->be_id); + if (port_id < 0) { + pr_err("%s: Invalid port_id\n", __func__); + return -EINVAL; + } if (enable) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - u32 clk_val = pri_rx_sample_rate * bits_per_sample * 2; - mi2s_rx_clk.clk_val1 = clk_val; - ret = afe_set_lpass_clock( - port_id, + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_6): + mi2s_rx_clk_v1.clk_val1 = get_mi2s_rx_clk_val(); + ret = afe_set_lpass_clock( + port_id, + &mi2s_rx_clk_v1); + break; + case (Q6_SUBSYS_AVS2_7): + mi2s_rx_clk.enable = enable; + mi2s_rx_clk.clk_id = + msm8x16_get_clk_id(port_id); + mi2s_rx_clk.clk_freq_in_hz = + get_mi2s_rx_clk_val(); + ret = afe_set_lpass_clock_v2(port_id, &mi2s_rx_clk); + break; + case (Q6_SUBSYS_INVALID): + default: + ret = -EINVAL; + pr_err("%s: INVALID AVS IMAGE\n", __func__); + break; + } } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - mi2s_tx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; - ret = afe_set_lpass_clock( - port_id, + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_6): + mi2s_tx_clk_v1.clk_val1 = + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; + ret = afe_set_lpass_clock( + port_id, + &mi2s_tx_clk_v1); + break; + case (Q6_SUBSYS_AVS2_7): + mi2s_tx_clk.enable = enable; + mi2s_tx_clk.clk_id = + msm8x16_get_clk_id(port_id); + mi2s_tx_clk.clk_freq_in_hz = + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; + ret = afe_set_lpass_clock_v2(port_id, &mi2s_tx_clk); + break; + case (Q6_SUBSYS_INVALID): + default: + ret = -EINVAL; + pr_err("%s: INVALID AVS IMAGE\n", __func__); + break; + } } else pr_err("%s:Not valid substream.\n", __func__); @@ -905,15 +1022,51 @@ static int ext_mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable, __func__, ret); } else { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; - ret = afe_set_lpass_clock( - port_id, - &mi2s_rx_clk); + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_6): + mi2s_rx_clk_v1.clk_val1 = + Q6AFE_LPASS_IBIT_CLK_DISABLE; + ret = afe_set_lpass_clock( + port_id, + &mi2s_rx_clk_v1); + break; + case (Q6_SUBSYS_AVS2_7): + mi2s_rx_clk.enable = enable; + mi2s_rx_clk.clk_id = + msm8x16_get_clk_id(port_id); + mi2s_rx_clk.clk_freq_in_hz = 0; + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_rx_clk); + break; + case (Q6_SUBSYS_INVALID): + default: + ret = -EINVAL; + pr_err("%s: INVALID AVS IMAGE\n", __func__); + break; + } } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - mi2s_tx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; - ret = afe_set_lpass_clock( - port_id, - &mi2s_tx_clk); + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_6): + mi2s_tx_clk_v1.clk_val1 = + Q6AFE_LPASS_IBIT_CLK_DISABLE; + ret = afe_set_lpass_clock( + port_id, + &mi2s_tx_clk_v1); + break; + case (Q6_SUBSYS_AVS2_7): + mi2s_tx_clk.enable = enable; + mi2s_tx_clk.clk_id = + msm8x16_get_clk_id(port_id); + mi2s_tx_clk.clk_freq_in_hz = 0; + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_tx_clk); + break; + case (Q6_SUBSYS_INVALID): + default: + ret = -EINVAL; + pr_err("%s: INVALID AVS IMAGE\n", __func__); + break; + } } else pr_err("%s:Not valid substream %d\n", __func__, substream->stream); @@ -978,44 +1131,8 @@ static int msm8x16_enable_codec_ext_clk(struct snd_soc_codec *codec, static int msm8x16_enable_extcodec_ext_clk(struct snd_soc_codec *codec, int enable, bool dapm) { - int ret = 0; - struct msm8916_asoc_mach_data *pdata = NULL; - - pdata = snd_soc_card_get_drvdata(codec->card); - - pr_debug("%s: enable = %d codec name %s enable %d mclk ref counter %d\n", - __func__, enable, codec->name, enable, - atomic_read(&pdata->mclk_rsc_ref)); - if (enable) { - if (atomic_inc_return(&pdata->mclk_rsc_ref) == 1) { - mutex_lock(&pdata->cdc_mclk_mutex); - pdata->digital_cdc_clk.clk_val = 9600000; - afe_set_digital_codec_core_clock( - AFE_PORT_ID_PRIMARY_MI2S_RX, - &pdata->digital_cdc_clk); - pdata->digital_cdc_clk.clk_val = 9600000; - afe_set_digital_codec_core_clock( - AFE_PORT_ID_QUATERNARY_MI2S_RX, - &pdata->digital_cdc_clk); - mutex_unlock(&pdata->cdc_mclk_mutex); - tasha_cdc_mclk_enable(codec, 1, dapm); - } - } else { - if (atomic_dec_return(&pdata->mclk_rsc_ref) == 0) { - mutex_lock(&pdata->cdc_mclk_mutex); - pdata->digital_cdc_clk.clk_val = 0; - afe_set_digital_codec_core_clock( - AFE_PORT_ID_PRIMARY_MI2S_RX, - &pdata->digital_cdc_clk); - pdata->digital_cdc_clk.clk_val = 0; - afe_set_digital_codec_core_clock( - AFE_PORT_ID_QUATERNARY_MI2S_RX, - &pdata->digital_cdc_clk); - mutex_unlock(&pdata->cdc_mclk_mutex); - tasha_cdc_mclk_enable(codec, 0, dapm); - } - } - return ret; + tasha_cdc_mclk_enable(codec, enable, dapm); + return 0; } static int msm_btsco_rate_get(struct snd_kcontrol *kcontrol, @@ -1082,6 +1199,10 @@ static int msm8x16_mclk_event(struct snd_soc_dapm_widget *w, pdata = snd_soc_card_get_drvdata(w->codec->card); pr_debug("%s: event = %d\n", __func__, event); switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (pdata->codec_type) + msm8x16_enable_extcodec_ext_clk(w->codec, 1, true); + break; case SND_SOC_DAPM_POST_PMD: pr_debug("%s: mclk_res_ref = %d\n", __func__, atomic_read(&pdata->mclk_rsc_ref)); @@ -1097,6 +1218,8 @@ static int msm8x16_mclk_event(struct snd_soc_dapm_widget *w, pr_err("%s: error during pinctrl state select\n", __func__); } + } else { + msm8x16_enable_extcodec_ext_clk(w->codec, 0, true); } break; default: @@ -1111,7 +1234,6 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) int ret; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_card *card = rtd->card; - struct snd_soc_codec *codec = rtd->codec; struct msm8916_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); pr_debug("%s(): substream = %s stream = %d\n", __func__, @@ -1129,24 +1251,15 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) atomic_read(&pdata->mclk_rsc_ref)); } } else { - ret = msm_gpioset_suspend(CLIENT_WCD_EXT, "pri_i2s"); - if (ret < 0) { - pr_err("%s: gpio set cannot be de-activated %sd", - __func__, "quin_i2s"); - return; - } - ret = msm8x16_enable_extcodec_ext_clk(codec, 0, false); + ret = msm_gpioset_suspend(CLIENT_WCD_EXT, "pri_i2s"); if (ret < 0) { - pr_err("%s: failed to enable mclk; ret=%d\n", - __func__, ret); + pr_err("%s: gpio set cannot be de-activated %sd", + __func__, "quin_i2s"); return; } - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - ret = ext_mi2s_clk_ctl(substream, false, - AFE_PORT_ID_PRIMARY_MI2S_RX); - else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ret = ext_mi2s_clk_ctl(substream, false, - AFE_PORT_ID_PRIMARY_MI2S_TX); + ret = ext_mi2s_clk_ctl(substream, false); + if (ret < 0) + pr_err("%s: failed to enable sclk\n", __func__); } } @@ -1392,19 +1505,11 @@ static int msm_quat_mi2s_snd_startup(struct snd_pcm_substream *substream) __func__); return ret; } - ret = msm8x16_enable_extcodec_ext_clk(codec, 1, true); + ret = ext_mi2s_clk_ctl(substream, true); if (ret < 0) { - pr_err("%s: failed to enable mclk; ret=%d\n", - __func__, ret); + pr_err("%s: failed to enable sclk\n", __func__); return ret; } - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = ext_mi2s_clk_ctl(substream, true, - AFE_PORT_ID_QUATERNARY_MI2S_RX); - } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - ret = ext_mi2s_clk_ctl(substream, true, - AFE_PORT_ID_QUATERNARY_MI2S_TX); - } } if (atomic_inc_return(&quat_mi2s_clk_ref) == 1) { ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); @@ -1463,18 +1568,9 @@ static void msm_quat_mi2s_snd_shutdown(struct snd_pcm_substream *substream) __func__, "quin_i2s"); } - ret = msm8x16_enable_extcodec_ext_clk(codec, 0, false); - if (ret < 0) { - pr_err("%s: failed to enable mclk; ret=%d\n", - __func__, ret); - return; - } - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - ret = ext_mi2s_clk_ctl(substream, false, - AFE_PORT_ID_QUATERNARY_MI2S_RX); - else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ret = ext_mi2s_clk_ctl(substream, false, - AFE_PORT_ID_QUATERNARY_MI2S_TX); + ret = ext_mi2s_clk_ctl(substream, false); + if (ret < 0) + pr_err("%s: failed to disable sclk\n", __func__); if (atomic_read(&quat_mi2s_clk_ref) > 0) atomic_dec(&quat_mi2s_clk_ref); @@ -1566,18 +1662,11 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) return ret; } - ret = msm8x16_enable_extcodec_ext_clk(codec, 1, true); + ret = ext_mi2s_clk_ctl(substream, true); if (ret < 0) { - pr_err("%s: failed to enable mclk; ret=%d\n", - __func__, ret); + pr_err("%s: failed to enable sclk\n", __func__); return ret; } - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - ret = ext_mi2s_clk_ctl(substream, true, - AFE_PORT_ID_PRIMARY_MI2S_RX); - else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ret = ext_mi2s_clk_ctl(substream, true, - AFE_PORT_ID_PRIMARY_MI2S_TX); } ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) @@ -1703,6 +1792,9 @@ static int msm_audrx_init_wcd(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_new_controls(dapm, msm8x16_dapm_widgets, ARRAY_SIZE(msm8x16_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, wcd9335_audio_paths, + ARRAY_SIZE(wcd9335_audio_paths)); + snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); @@ -3170,6 +3262,15 @@ static int msm8x16_asoc_machine_probe(struct platform_device *pdev) ret); goto err; } + + ret = core_get_adsp_ver(); + if (ret < 0) { + ret = -EPROBE_DEFER; + dev_info(&pdev->dev, "%s: Get adsp version failed (%d)\n", + __func__, ret); + goto err; + } + return 0; err: if (pdata->vaddr_gpio_mux_spkr_ctl) From 729c9e6ca0fdea82460f98cf195590613cac0074 Mon Sep 17 00:00:00 2001 From: Surendar karka Date: Sat, 1 Oct 2016 15:00:23 +0530 Subject: [PATCH 293/320] ASoC: msm: qdsp6v2: add AVS 2.8 support in native drivers Add AVS 2.8 support in compress driver and Q6 core driver. Change-Id: Ifb8208e44400475213321529cb1dd060a5b92e93 Signed-off-by: Surendar karka --- drivers/misc/qcom/qdsp6v2/audio_utils_aio.c | 2 ++ include/sound/q6core.h | 2 ++ sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c | 4 ++++ sound/soc/msm/qdsp6v2/q6core.c | 4 ++++ 4 files changed, 12 insertions(+) diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c index 2b4ea85d395db..725e912265fb5 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c @@ -1502,6 +1502,7 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, stats.sample_count = atomic_read(&audio->in_samples); switch (q6core_get_avs_version()) { case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): { rc = q6asm_get_session_time(audio->ac, ×tamp); break; @@ -1809,6 +1810,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, stats.sample_count = atomic_read(&audio->in_samples); switch (q6core_get_avs_version()) { case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): { rc = q6asm_get_session_time(audio->ac, ×tamp); break; diff --git a/include/sound/q6core.h b/include/sound/q6core.h index 70a7b9a7639ca..83ae16760bd1a 100644 --- a/include/sound/q6core.h +++ b/include/sound/q6core.h @@ -164,10 +164,12 @@ struct avcs_cmd_get_version_result { #define AVCS_CMDRSP_Q6_ID_2_6 0x00040000 #define AVCS_CMDRSP_Q6_ID_2_7 0x00040001 +#define AVCS_CMDRSP_Q6_ID_2_8 0x00040002 enum q6_subsys_image { Q6_SUBSYS_AVS2_6 = 1, Q6_SUBSYS_AVS2_7, + Q6_SUBSYS_AVS2_8, Q6_SUBSYS_INVALID, }; enum q6_subsys_image q6core_get_avs_version(void); diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c index 31fcedc7f34f9..d89a19a733625 100644 --- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c @@ -246,6 +246,7 @@ static int msm_compr_set_volume(struct snd_compr_stream *cstream, */ switch (q6core_get_avs_version()) { case Q6_SUBSYS_AVS2_7: + case Q6_SUBSYS_AVS2_8: avg_vol = (volume_l + volume_r) / 2; for (i = 0; i < prtd->num_channels; i++) gain_list[i] = avg_vol; @@ -264,6 +265,7 @@ static int msm_compr_set_volume(struct snd_compr_stream *cstream, } else { switch (q6core_get_avs_version()) { case Q6_SUBSYS_AVS2_7: + case Q6_SUBSYS_AVS2_8: gain_list[0] = volume_l; gain_list[1] = volume_r; /* force sending FR/FL/FC volume for mono */ @@ -1763,6 +1765,7 @@ static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd) */ switch (q6core_get_avs_version()) { case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): { q6asm_get_session_time(prtd->audio_client, &prtd->marker_timestamp); @@ -1943,6 +1946,7 @@ static int msm_compr_pointer(struct snd_compr_stream *cstream, switch (q6core_get_avs_version()) { case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): { rc = q6asm_get_session_time(prtd->audio_client, ×tamp); diff --git a/sound/soc/msm/qdsp6v2/q6core.c b/sound/soc/msm/qdsp6v2/q6core.c index c636d0b878ad8..a9ff7e6fe06ec 100644 --- a/sound/soc/msm/qdsp6v2/q6core.c +++ b/sound/soc/msm/qdsp6v2/q6core.c @@ -163,6 +163,10 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) q6core_lcl.q6_core_avs_version = Q6_SUBSYS_AVS2_7; pr_debug("%s: Received ADSP version as 2.7\n", __func__); + } else if (AVCS_CMDRSP_Q6_ID_2_8 == payload1[3]) { + q6core_lcl.q6_core_avs_version = Q6_SUBSYS_AVS2_8; + pr_info("%s: Received ADSP version as 2.8\n", + __func__); } else { pr_err("%s: ADSP version is neither 2.6 nor 2.7\n", __func__); From 226c1b6764a5f6ae29b0d4b122f8e7291764ca17 Mon Sep 17 00:00:00 2001 From: Surendar karka Date: Sat, 1 Oct 2016 15:01:40 +0530 Subject: [PATCH 294/320] ASoC: msm: add AVS 2.8 support in machine driver Update machine driver and codec driver with AVS 2.8 support. Change-Id: Ia905a2c784058cdff280deee3681d99ab1c00be2 Signed-off-by: Surendar karka --- sound/soc/codecs/audio-ext-clk.c | 2 ++ sound/soc/msm/msm8x16.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/sound/soc/codecs/audio-ext-clk.c b/sound/soc/codecs/audio-ext-clk.c index 636c310d35e48..eed1c0e8b590c 100644 --- a/sound/soc/codecs/audio-ext-clk.c +++ b/sound/soc/codecs/audio-ext-clk.c @@ -149,6 +149,7 @@ static int audio_ext_clk_prepare(struct clk *clk) } break; case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): digital_cdc_core_clk.enable = 1; ret = afe_set_lpass_clock_v2( AFE_PORT_ID_PRIMARY_MI2S_RX, @@ -195,6 +196,7 @@ static void audio_ext_clk_unprepare(struct clk *clk) __func__); } case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): digital_cdc_core_clk.enable = 0; ret = afe_set_lpass_clock_v2( AFE_PORT_ID_PRIMARY_MI2S_RX, diff --git a/sound/soc/msm/msm8x16.c b/sound/soc/msm/msm8x16.c index f366e095822a2..99d0d5a22ece8 100644 --- a/sound/soc/msm/msm8x16.c +++ b/sound/soc/msm/msm8x16.c @@ -976,6 +976,7 @@ static int ext_mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) &mi2s_rx_clk_v1); break; case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): mi2s_rx_clk.enable = enable; mi2s_rx_clk.clk_id = msm8x16_get_clk_id(port_id); @@ -1000,6 +1001,7 @@ static int ext_mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) &mi2s_tx_clk_v1); break; case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): mi2s_tx_clk.enable = enable; mi2s_tx_clk.clk_id = msm8x16_get_clk_id(port_id); @@ -1031,6 +1033,7 @@ static int ext_mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) &mi2s_rx_clk_v1); break; case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): mi2s_rx_clk.enable = enable; mi2s_rx_clk.clk_id = msm8x16_get_clk_id(port_id); @@ -1054,6 +1057,7 @@ static int ext_mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) &mi2s_tx_clk_v1); break; case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): mi2s_tx_clk.enable = enable; mi2s_tx_clk.clk_id = msm8x16_get_clk_id(port_id); From 99942fec122e05fb41321acac51e8b71ea489d67 Mon Sep 17 00:00:00 2001 From: Patrick Daly Date: Mon, 22 Feb 2016 18:55:12 -0800 Subject: [PATCH 295/320] defconfig: msm: Enable MODULE_RONX Set the appropriate permissions on module text and read-only sections. Change-Id: Iab9e733040ffd6d048258b94e05537884bc8fc4a Signed-off-by: Patrick Daly Signed-off-by: Prakash Gupta Signed-off-by: Srinivasarao P --- arch/arm64/configs/msm-perf_defconfig | 1 + arch/arm64/configs/msm_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig index a754983660f4a..bb010558c74be 100644 --- a/arch/arm64/configs/msm-perf_defconfig +++ b/arch/arm64/configs/msm-perf_defconfig @@ -512,6 +512,7 @@ CONFIG_TIMER_STATS=y CONFIG_DEBUG_INFO=y CONFIG_IPC_LOGGING=y CONFIG_KEYS=y +CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig index 320462994ed77..7442575a767b2 100644 --- a/arch/arm64/configs/msm_defconfig +++ b/arch/arm64/configs/msm_defconfig @@ -560,6 +560,7 @@ CONFIG_MSM_RTB_SEPARATE_CPUS=y CONFIG_IPC_LOGGING=y CONFIG_DYNAMIC_DEBUG=y CONFIG_PANIC_ON_DATA_CORRUPTION=y +CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y From 4b510b25bae10f39c965bfc09c5a48d5a3583927 Mon Sep 17 00:00:00 2001 From: Divya Narayanan Poojary Date: Wed, 12 Oct 2016 17:39:07 +0530 Subject: [PATCH 296/320] ASoC: soc: change audio drivers to use %pK Change all audio driver to use %pK instead of %p. %pK hides addresses when the users doesn't have kernel permissions. If address information is needed echo 0 > /proc/sys/kernel/kptr_restrict. CRs-Fixed: 1052832 Change-Id: I9ff5cf06b019c566973eb609bf5d37969b98d31d Signed-off-by: Xiaojun Sang Signed-off-by: Divya Narayanan Poojary --- sound/soc/codecs/msm8x16-wcd.c | 2 +- sound/soc/codecs/wcd-mbhc-v2.c | 2 +- sound/soc/codecs/wcd9306.c | 4 ++-- sound/soc/codecs/wcd9320.c | 2 +- sound/soc/codecs/wcd9330.c | 10 +++++----- sound/soc/codecs/wcd9335.c | 6 +++--- sound/soc/codecs/wcd9xxx-mbhc.c | 4 ++-- sound/soc/codecs/wcd_cpe_core.c | 2 +- sound/soc/codecs/wm8994.c | 2 +- sound/soc/codecs/wsa881x.c | 2 +- 10 files changed, 18 insertions(+), 18 deletions(-) diff --git a/sound/soc/codecs/msm8x16-wcd.c b/sound/soc/codecs/msm8x16-wcd.c index 3106ed3f69abe..040bd4702b6cf 100644 --- a/sound/soc/codecs/msm8x16-wcd.c +++ b/sound/soc/codecs/msm8x16-wcd.c @@ -5779,7 +5779,7 @@ static int msm8x16_wcd_spmi_probe(struct spmi_device *spmi) } - dev_dbg(&spmi->dev, "%s(%d):start addr = 0x%pa\n", + dev_dbg(&spmi->dev, "%s(%d):start addr = 0x%pK\n", __func__, __LINE__, &wcd_resource->start); if (wcd_resource->start != TOMBAK_CORE_0_SPMI_ADDR) diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c index 47e9521bb34e5..61b110437c2ce 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.c +++ b/sound/soc/codecs/wcd-mbhc-v2.c @@ -2032,7 +2032,7 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, schedule_delayed_work(&mbhc->mbhc_firmware_dwork, usecs_to_jiffies(FW_READ_TIMEOUT)); else - pr_err("%s: Skipping to read mbhc fw, 0x%p %p\n", + pr_err("%s: Skipping to read mbhc fw, 0x%pK %pK\n", __func__, mbhc->mbhc_fw, mbhc->mbhc_cal); } pr_debug("%s: leave %d\n", __func__, rc); diff --git a/sound/soc/codecs/wcd9306.c b/sound/soc/codecs/wcd9306.c index 1d2f2884a6c72..46111855ffa95 100644 --- a/sound/soc/codecs/wcd9306.c +++ b/sound/soc/codecs/wcd9306.c @@ -3800,7 +3800,7 @@ static int tapan_get_channel_map(struct snd_soc_dai *dai, case AIF2_PB: case AIF3_PB: if (!rx_slot || !rx_num) { - pr_err("%s: Invalid rx_slot %p or rx_num %p\n", + pr_err("%s: Invalid rx_slot %pK or rx_num %pK\n", __func__, rx_slot, rx_num); return -EINVAL; } @@ -3817,7 +3817,7 @@ static int tapan_get_channel_map(struct snd_soc_dai *dai, case AIF2_CAP: case AIF3_CAP: if (!tx_slot || !tx_num) { - pr_err("%s: Invalid tx_slot %p or tx_num %p\n", + pr_err("%s: Invalid tx_slot %pK or tx_num %pK\n", __func__, tx_slot, tx_num); return -EINVAL; } diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c index 0334a74b02e29..697a1b63098b1 100644 --- a/sound/soc/codecs/wcd9320.c +++ b/sound/soc/codecs/wcd9320.c @@ -4716,7 +4716,7 @@ static int taiko_set_channel_map(struct snd_soc_dai *dai, struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec); struct wcd9xxx *core = dev_get_drvdata(dai->codec->dev->parent); if (!tx_slot || !rx_slot) { - pr_err("%s: Invalid tx_slot=%p, rx_slot=%p\n", __func__, + pr_err("%s: Invalid tx_slot=%pK, rx_slot=%pK\n", __func__, tx_slot, rx_slot); return -EINVAL; } diff --git a/sound/soc/codecs/wcd9330.c b/sound/soc/codecs/wcd9330.c index 7e9c009abd6a4..05e88895d3d0a 100644 --- a/sound/soc/codecs/wcd9330.c +++ b/sound/soc/codecs/wcd9330.c @@ -5362,7 +5362,7 @@ static int tomtom_set_channel_map(struct snd_soc_dai *dai, struct tomtom_priv *tomtom = snd_soc_codec_get_drvdata(dai->codec); struct wcd9xxx *core = dev_get_drvdata(dai->codec->dev->parent); if (!tx_slot || !rx_slot) { - pr_err("%s: Invalid tx_slot=%p, rx_slot=%p\n", + pr_err("%s: Invalid tx_slot=%pK, rx_slot=%pK\n", __func__, tx_slot, rx_slot); return -EINVAL; } @@ -5398,7 +5398,7 @@ static int tomtom_get_channel_map(struct snd_soc_dai *dai, case AIF2_PB: case AIF3_PB: if (!rx_slot || !rx_num) { - pr_err("%s: Invalid rx_slot %p or rx_num %p\n", + pr_err("%s: Invalid rx_slot %pK or rx_num %pK\n", __func__, rx_slot, rx_num); return -EINVAL; } @@ -5417,7 +5417,7 @@ static int tomtom_get_channel_map(struct snd_soc_dai *dai, case AIF4_VIFEED: case AIF4_MAD_TX: if (!tx_slot || !tx_num) { - pr_err("%s: Invalid tx_slot %p or tx_num %p\n", + pr_err("%s: Invalid tx_slot %pK or tx_num %pK\n", __func__, tx_slot, tx_num); return -EINVAL; } @@ -8036,7 +8036,7 @@ static void tomtom_compute_impedance(struct wcd9xxx_mbhc *mbhc, s16 *l, s16 *r, struct tomtom_priv *tomtom; if (!mbhc) { - pr_err("%s: Invalid parameters mbhc = %p\n", + pr_err("%s: Invalid parameters mbhc = %pK\n", __func__, mbhc); return; } @@ -8095,7 +8095,7 @@ static void tomtom_zdet_error_approx(struct wcd9xxx_mbhc *mbhc, uint32_t *zl, const int shift = TOMTOM_ZDET_ERROR_APPROX_SHIFT; if (!zl || !zr || !mbhc) { - pr_err("%s: Invalid parameters zl = %p zr = %p, mbhc = %p\n", + pr_err("%s: Invalid parameters zl = %pK zr = %pK, mbhc = %pK\n", __func__, zl, zr, mbhc); return; } diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 8cd5825244411..3fa5346a0cbe5 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -9465,7 +9465,7 @@ static int tasha_get_channel_map(struct snd_soc_dai *dai, case AIF3_PB: case AIF_MIX1_PB: if (!rx_slot || !rx_num) { - pr_err("%s: Invalid rx_slot %p or rx_num %p\n", + pr_err("%s: Invalid rx_slot %pK or rx_num %pK\n", __func__, rx_slot, rx_num); return -EINVAL; } @@ -9484,7 +9484,7 @@ static int tasha_get_channel_map(struct snd_soc_dai *dai, case AIF4_MAD_TX: case AIF4_VIFEED: if (!tx_slot || !tx_num) { - pr_err("%s: Invalid tx_slot %p or tx_num %p\n", + pr_err("%s: Invalid tx_slot %pK or tx_num %pK\n", __func__, tx_slot, tx_num); return -EINVAL; } @@ -9522,7 +9522,7 @@ static int tasha_set_channel_map(struct snd_soc_dai *dai, core = dev_get_drvdata(dai->codec->dev->parent); if (!tx_slot || !rx_slot) { - pr_err("%s: Invalid tx_slot=%p, rx_slot=%p\n", + pr_err("%s: Invalid tx_slot=%pK, rx_slot=%pK\n", __func__, tx_slot, rx_slot); return -EINVAL; } diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c index 407b0e2515e99..e187b39c6184b 100644 --- a/sound/soc/codecs/wcd9xxx-mbhc.c +++ b/sound/soc/codecs/wcd9xxx-mbhc.c @@ -4631,7 +4631,7 @@ int wcd9xxx_mbhc_start(struct wcd9xxx_mbhc *mbhc, schedule_delayed_work(&mbhc->mbhc_firmware_dwork, usecs_to_jiffies(FW_READ_TIMEOUT)); else - pr_debug("%s: Skipping to read mbhc fw, 0x%p %p\n", + pr_debug("%s: Skipping to read mbhc fw, 0x%pK %pK\n", __func__, mbhc->mbhc_fw, mbhc->mbhc_cal); } @@ -5024,7 +5024,7 @@ static int wcd9xxx_remeasure_z_values(struct wcd9xxx_mbhc *mbhc, right = !!(r); dev_dbg(codec->dev, "%s: Remeasuring impedance values\n", __func__); - dev_dbg(codec->dev, "%s: l: %p, r: %p, left=%d, right=%d\n", __func__, + dev_dbg(codec->dev, "%s: l: %pK, r: %pK, left=%d, right=%d\n", __func__, l, r, left, right); /* Remeasure V2 values */ diff --git a/sound/soc/codecs/wcd_cpe_core.c b/sound/soc/codecs/wcd_cpe_core.c index beebcebfdb40a..235d0670fcb05 100644 --- a/sound/soc/codecs/wcd_cpe_core.c +++ b/sound/soc/codecs/wcd_cpe_core.c @@ -429,7 +429,7 @@ static int wcd_cpe_load_fw(struct wcd_cpe_core *core, bool load_segment; if (!core || !core->cpe_handle) { - pr_err("%s: Error CPE core %p\n", __func__, + pr_err("%s: Error CPE core %pK\n", __func__, core); return -EINVAL; } diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 29e95f93d4822..223b5b327cff8 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3340,7 +3340,7 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, dev_warn(codec->dev, "Failed to configure MICBIAS%d: %d\n", micbias, ret); - dev_dbg(codec->dev, "Configuring microphone detection on %d %p\n", + dev_dbg(codec->dev, "Configuring microphone detection on %d %pK\n", micbias, jack); /* Store the configuration */ diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c index db22ec4ecef73..ea9e5f0d40bd2 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/sound/soc/codecs/wsa881x.c @@ -888,7 +888,7 @@ int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port, u8 num_port, if (!port || !ch_mask || !ch_rate || (num_port > WSA881X_MAX_SWR_PORTS)) { dev_err(codec->dev, - "%s: Invalid port=%p, ch_mask=%p, ch_rate=%p\n", + "%s: Invalid port=%pK, ch_mask=%pK, ch_rate=%pK\n", __func__, port, ch_mask, ch_rate); return -EINVAL; } From 4c0fea4df1ad2f3e735ba47e4a0fc214da0f020f Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Tue, 30 Aug 2016 15:31:56 +0800 Subject: [PATCH 297/320] ASoC: soc: change audio cpe drivers to use %pK Change cpe driver to use %pK instead of %p. %pK hides addresses when the users doesn't have kernel permissions. If address information is needed echo 0 > /proc/sys/kernel/kptr_restrict. CRs-Fixed: 1052832 Change-Id: I741d9e5c5b415011348e862c3f1ee4fe28c3969f Signed-off-by: Xiaojun Sang --- sound/soc/msm/msm-cpe-lsm.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/msm/msm-cpe-lsm.c b/sound/soc/msm/msm-cpe-lsm.c index d7153eadec1ff..4437c95f91225 100644 --- a/sound/soc/msm/msm-cpe-lsm.c +++ b/sound/soc/msm/msm-cpe-lsm.c @@ -457,7 +457,7 @@ static int msm_cpe_lab_buf_alloc(struct snd_pcm_substream *substream, pcm_buf[count].mem = pcm_buf[0].mem + (count * bufsz); pcm_buf[count].phys = pcm_buf[0].phys + (count * bufsz); dev_dbg(rtd->dev, - "%s: pcm_buf[%d].mem %p pcm_buf[%d].phys %pa\n", + "%s: pcm_buf[%d].mem %pK pcm_buf[%d].phys %pK\n", __func__, count, (void *)pcm_buf[count].mem, count, &(pcm_buf[count].phys)); @@ -681,7 +681,7 @@ static int msm_cpe_lab_thread(void *data) buf_count++; } dev_dbg(rtd->dev, - "%s: Cur buf = %p Next Buf = %p\n" + "%s: Cur buf = %pK Next Buf = %pK\n" " buf count = 0x%x\n", __func__, cur_buf, next_buf, buf_count); } else { @@ -1519,7 +1519,7 @@ static int msm_cpe_lsm_lab_start(struct snd_pcm_substream *substream, int rc; if (!substream || !substream->private_data) { - pr_err("%s: invalid substream (%p)\n", + pr_err("%s: invalid substream (%pK)\n", __func__, substream); return -EINVAL; } @@ -1609,7 +1609,7 @@ static int msm_cpe_lsm_ioctl(struct snd_pcm_substream *substream, struct wcd_cpe_lsm_ops *lsm_ops; if (!substream || !substream->private_data) { - pr_err("%s: invalid substream (%p)\n", + pr_err("%s: invalid substream (%pK)\n", __func__, substream); return -EINVAL; } @@ -1782,7 +1782,7 @@ static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream, struct wcd_cpe_lsm_ops *lsm_ops; if (!substream || !substream->private_data) { - pr_err("%s: invalid substream (%p)\n", + pr_err("%s: invalid substream (%pK)\n", __func__, substream); return -EINVAL; } @@ -2268,7 +2268,7 @@ static int msm_cpe_lsm_copy(struct snd_pcm_substream *substream, int a, if (lab_d->buf_idx >= (lsm_d->hw_params.period_count)) lab_d->buf_idx = 0; pcm_buf = (lab_d->pcm_buf[lab_d->buf_idx].mem); - pr_debug("%s: Buf IDX = 0x%x pcm_buf %pa\n", + pr_debug("%s: Buf IDX = 0x%x pcm_buf %pK\n", __func__, lab_d->buf_idx, &(lab_d->pcm_buf[lab_d->buf_idx])); From fb14b7031a795123e358d4ecf9a0b6a5c816b8b2 Mon Sep 17 00:00:00 2001 From: VijayaKumar T M Date: Thu, 6 Oct 2016 11:58:39 +0530 Subject: [PATCH 298/320] msm: camera: Change MAX_CID_CH macro to 3 Modify macro MAX_CID_CH to 3 as vfe can support maximum 3 CID_CH at an instance. CRs-Fixed: 1064689 Change-Id: Ibb993839c1057fb62f43e99df3bee8328a4c702f Signed-off-by: Trishansh Bhardwaj Signed-off-by: VijayaKumar T M --- drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c | 4 ++-- include/media/msmb_ispif.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c index 6ac76b7b7048f..73cbe4a5cfb8b 100644 --- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c +++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c @@ -562,7 +562,7 @@ static uint16_t msm_ispif_get_cids_mask_from_cfg( BUG_ON(!entry); - for (i = 0; i < entry->num_cids; i++) + for (i = 0; i < entry->num_cids && i < MAX_CID_CH_V2; i++) cids_mask |= (1 << entry->cids[i]); return cids_mask; @@ -702,7 +702,7 @@ static void msm_ispif_intf_cmd(struct ispif_device *ispif, uint32_t cmd_bits, pr_err("%s: invalid interface type\n", __func__); return; } - if (params->entries[i].num_cids > MAX_CID_CH) { + if (params->entries[i].num_cids > MAX_CID_CH_V2) { pr_err("%s: out of range of cid_num %d\n", __func__, params->entries[i].num_cids); return; diff --git a/include/media/msmb_ispif.h b/include/media/msmb_ispif.h index 2564c33b7b31e..7031380802147 100644 --- a/include/media/msmb_ispif.h +++ b/include/media/msmb_ispif.h @@ -24,6 +24,7 @@ enum msm_ispif_intftype { }; #define MAX_PARAM_ENTRIES (INTF_MAX * 2) #define MAX_CID_CH 8 +#define MAX_CID_CH_V2 3 #define PIX0_MASK (1 << PIX0) #define PIX1_MASK (1 << PIX1) @@ -72,7 +73,7 @@ struct msm_ispif_params_entry { enum msm_ispif_vfe_intf vfe_intf; enum msm_ispif_intftype intftype; int num_cids; - enum msm_ispif_cid cids[3]; + enum msm_ispif_cid cids[MAX_CID_CH_V2]; enum msm_ispif_csid csid; int crop_enable; uint16_t crop_start_pixel; From 8fffd7147d3ab094c62972b85fdaa5e671ece51d Mon Sep 17 00:00:00 2001 From: Surendar karka Date: Fri, 19 Aug 2016 15:17:50 +0530 Subject: [PATCH 299/320] ASoC: msm: qdsp5v2: Change audio drivers to use %pK Change all qdsp6v2 audio driver to use %pK instead of %p. %pK hides addresses when the users doesn't have kernel permissions. If address information is needed echo 0 > /proc/sys/kernel/kptr_restrict. CRs-Fixed: 1052832 Change-Id: Id6d45982cbe42a113e58c9b6509eb6ef8064aeef Signed-off-by: Surendar karka Signed-off-by: Divya Narayanan Poojary --- drivers/misc/qcom/qdsp6v2/amrwb_in.c | 5 +- drivers/misc/qcom/qdsp6v2/audio_aac.c | 8 +- drivers/misc/qcom/qdsp6v2/audio_alac.c | 3 +- drivers/misc/qcom/qdsp6v2/audio_amrnb.c | 4 +- drivers/misc/qcom/qdsp6v2/audio_amrwb.c | 4 +- drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c | 6 +- drivers/misc/qcom/qdsp6v2/audio_ape.c | 6 +- drivers/misc/qcom/qdsp6v2/audio_evrc.c | 4 +- drivers/misc/qcom/qdsp6v2/audio_mp3.c | 4 +- drivers/misc/qcom/qdsp6v2/audio_qcelp.c | 4 +- drivers/misc/qcom/qdsp6v2/audio_utils.c | 4 +- drivers/misc/qcom/qdsp6v2/audio_utils_aio.c | 210 +++++++++--------- drivers/misc/qcom/qdsp6v2/audio_wma.c | 6 +- drivers/misc/qcom/qdsp6v2/audio_wmapro.c | 4 +- drivers/misc/qcom/qdsp6v2/q6audio_v2_aio.c | 22 +- drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c | 12 +- .../misc/qcom/qdsp6v2/ultrasound/usfcdev.c | 6 +- 17 files changed, 156 insertions(+), 156 deletions(-) diff --git a/drivers/misc/qcom/qdsp6v2/amrwb_in.c b/drivers/misc/qcom/qdsp6v2/amrwb_in.c index 71adbce0e257c..43dcbd597d7c4 100644 --- a/drivers/misc/qcom/qdsp6v2/amrwb_in.c +++ b/drivers/misc/qcom/qdsp6v2/amrwb_in.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2011-2012, 2014 The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2012, 2014, 2016 The Linux Foundation. All rights + * reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -309,7 +310,7 @@ static int amrwb_in_open(struct inode *inode, struct file *file) (void *)audio); if (!audio->ac) { - pr_err("%s:audio[%p]: Could not allocate memory for audio" + pr_err("%s:audio[%pK]: Could not allocate memory for audio" "client\n", __func__, audio); kfree(audio->enc_cfg); kfree(audio); diff --git a/drivers/misc/qcom/qdsp6v2/audio_aac.c b/drivers/misc/qcom/qdsp6v2/audio_aac.c index 24e31e71fd2dd..245efb72d4294 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_aac.c +++ b/drivers/misc/qcom/qdsp6v2/audio_aac.c @@ -218,10 +218,10 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); if (rc) - pr_err("%s[%p]:Failed in utils_ioctl: %d\n", + pr_err("%s[%pK]:Failed in utils_ioctl: %d\n", __func__, audio, rc); } } @@ -325,10 +325,10 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_compat_ioctl(file, cmd, arg); if (rc) - pr_err("%s[%p]:Failed in utils_ioctl: %d\n", + pr_err("%s[%pK]:Failed in utils_ioctl: %d\n", __func__, audio, rc); } } diff --git a/drivers/misc/qcom/qdsp6v2/audio_alac.c b/drivers/misc/qcom/qdsp6v2/audio_alac.c index 94a1843040e64..239614115ab3a 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_alac.c +++ b/drivers/misc/qcom/qdsp6v2/audio_alac.c @@ -33,7 +33,8 @@ static long audio_ioctl_shared(struct file *file, unsigned int cmd, case AUDIO_START: { struct asm_alac_cfg alac_cfg; struct msm_audio_alac_config *alac_config; - pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__, + + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, audio, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ diff --git a/drivers/misc/qcom/qdsp6v2/audio_amrnb.c b/drivers/misc/qcom/qdsp6v2/audio_amrnb.c index 5d57293995902..26240ec410cd1 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_amrnb.c +++ b/drivers/misc/qcom/qdsp6v2/audio_amrnb.c @@ -30,7 +30,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) switch (cmd) { case AUDIO_START: { - pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__, + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, audio, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ @@ -59,7 +59,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } default: - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); } return rc; diff --git a/drivers/misc/qcom/qdsp6v2/audio_amrwb.c b/drivers/misc/qcom/qdsp6v2/audio_amrwb.c index d2728b7c67001..9b5bca64e3c56 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_amrwb.c +++ b/drivers/misc/qcom/qdsp6v2/audio_amrwb.c @@ -31,7 +31,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) switch (cmd) { case AUDIO_START: { - pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__, + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, audio, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ @@ -62,7 +62,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } default: - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); } return rc; diff --git a/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c b/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c index 295193c901126..25b6239107a48 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c +++ b/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c @@ -52,7 +52,7 @@ static long audio_ioctl_shared(struct file *file, unsigned int cmd, switch (cmd) { case AUDIO_START: { - pr_err("%s[%p]: AUDIO_START session_id[%d]\n", __func__, + pr_err("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, audio, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ @@ -159,7 +159,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); break; } @@ -275,7 +275,7 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_compat_ioctl(file, cmd, arg); break; } diff --git a/drivers/misc/qcom/qdsp6v2/audio_ape.c b/drivers/misc/qcom/qdsp6v2/audio_ape.c index ab3ddb58388f3..c98c3260c58c1 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_ape.c +++ b/drivers/misc/qcom/qdsp6v2/audio_ape.c @@ -36,7 +36,7 @@ static long audio_ioctl_shared(struct file *file, unsigned int cmd, case AUDIO_START: { struct asm_ape_cfg ape_cfg; struct msm_audio_ape_config *ape_config; - pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__, + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, audio, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ @@ -130,7 +130,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); if (rc) pr_err("Failed in utils_ioctl: %d\n", rc); @@ -228,7 +228,7 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_compat_ioctl(file, cmd, arg); if (rc) pr_err("Failed in utils_ioctl: %d\n", rc); diff --git a/drivers/misc/qcom/qdsp6v2/audio_evrc.c b/drivers/misc/qcom/qdsp6v2/audio_evrc.c index 2de2178936a4a..83c260012984c 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_evrc.c +++ b/drivers/misc/qcom/qdsp6v2/audio_evrc.c @@ -33,7 +33,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) switch (cmd) { case AUDIO_START: { - pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__, + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, audio, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ @@ -64,7 +64,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } default: - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); } return rc; diff --git a/drivers/misc/qcom/qdsp6v2/audio_mp3.c b/drivers/misc/qcom/qdsp6v2/audio_mp3.c index 9132486ef6cec..1105ed4ba3d62 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_mp3.c +++ b/drivers/misc/qcom/qdsp6v2/audio_mp3.c @@ -30,7 +30,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) int rc = 0; switch (cmd) { case AUDIO_START: { - pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__, + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, audio, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ @@ -66,7 +66,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } default: - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); } return rc; diff --git a/drivers/misc/qcom/qdsp6v2/audio_qcelp.c b/drivers/misc/qcom/qdsp6v2/audio_qcelp.c index acfcb654abe27..ec06083ba16f6 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_qcelp.c +++ b/drivers/misc/qcom/qdsp6v2/audio_qcelp.c @@ -33,7 +33,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) switch (cmd) { case AUDIO_START: { - pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__, + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, audio, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ @@ -64,7 +64,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } default: - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); } return rc; diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils.c b/drivers/misc/qcom/qdsp6v2/audio_utils.c index 172790c3082a1..4ce21a822cbe1 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils.c @@ -754,7 +754,7 @@ ssize_t audio_in_read(struct file *file, count -= bytes_to_copy; buf += bytes_to_copy; } else { - pr_err("%s:session id %d: short read data[%p] bytesavail[%d]bytesrequest[%zd]\n", + pr_err("%s:session id %d: short read data[%pK] bytesavail[%d]bytesrequest[%zd]\n", __func__, audio->ac->session, data, size, count); @@ -890,7 +890,7 @@ ssize_t audio_in_write(struct file *file, buf += xfer; } mutex_unlock(&audio->write_lock); - pr_debug("%s:session id %d: eos_condition 0x%x buf[0x%p] start[0x%p]\n", + pr_debug("%s:session id %d: eos_condition 0x%x buf[0x%pK] start[0x%pK]\n", __func__, audio->ac->session, nflags, buf, start); if (nflags & AUD_EOS_SET) { diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c index 725e912265fb5..f18661e2d64b4 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c @@ -84,7 +84,7 @@ int insert_eos_buf(struct q6audio_aio *audio, struct audio_aio_buffer_node *buf_node) { struct dec_meta_out *eos_buf = buf_node->kvaddr; - pr_debug("%s[%p]:insert_eos_buf\n", __func__, audio); + pr_debug("%s[%pK]:insert_eos_buf\n", __func__, audio); eos_buf->num_of_frames = 0xFFFFFFFF; eos_buf->meta_out_dsp[0].offset_to_frame = 0x0; eos_buf->meta_out_dsp[0].nflags = AUDIO_DEC_EOS_SET; @@ -132,14 +132,14 @@ static int audio_aio_ion_lookup_vaddr(struct q6audio_aio *audio, void *addr, } if (match_count > 1) { - pr_err("%s[%p]:multiple hits for vaddr %p, len %ld\n", + pr_err("%s[%pK]:multiple hits for vaddr %pK, len %ld\n", __func__, audio, addr, len); list_for_each_entry(region_elt, &audio->ion_region_queue, list) { if (addr >= region_elt->vaddr && addr < region_elt->vaddr + region_elt->len && addr + len <= region_elt->vaddr + region_elt->len) - pr_err("\t%s[%p]:%p, %ld --> %pa\n", + pr_err("\t%s[%pK]:%pK, %ld --> %pK\n", __func__, audio, region_elt->vaddr, region_elt->len, @@ -159,7 +159,7 @@ static phys_addr_t audio_aio_ion_fixup(struct q6audio_aio *audio, void *addr, ret = audio_aio_ion_lookup_vaddr(audio, addr, len, ®ion); if (ret) { - pr_err("%s[%p]:lookup (%p, %ld) failed\n", + pr_err("%s[%pK]:lookup (%pK, %ld) failed\n", __func__, audio, addr, len); return 0; } @@ -167,7 +167,7 @@ static phys_addr_t audio_aio_ion_fixup(struct q6audio_aio *audio, void *addr, region->ref_cnt++; else region->ref_cnt--; - pr_debug("%s[%p]:found region %p ref_cnt %d\n", + pr_debug("%s[%pK]:found region %pK ref_cnt %d\n", __func__, audio, region, region->ref_cnt); paddr = region->paddr + (addr - region->vaddr); /* provide kernel virtual address for accessing meta information */ @@ -180,26 +180,26 @@ static int audio_aio_pause(struct q6audio_aio *audio) { int rc = -EINVAL; - pr_debug("%s[%p], enabled = %d\n", __func__, audio, + pr_debug("%s[%pK], enabled = %d\n", __func__, audio, audio->enabled); if (audio->enabled) { rc = q6asm_cmd(audio->ac, CMD_PAUSE); if (rc < 0) - pr_err("%s[%p]: pause cmd failed rc=%d\n", + pr_err("%s[%pK]: pause cmd failed rc=%d\n", __func__, audio, rc); if (rc == 0) { /* Send suspend only if pause was successful */ rc = q6asm_cmd(audio->ac, CMD_SUSPEND); if (rc < 0) - pr_err("%s[%p]: suspend cmd failed rc=%d\n", + pr_err("%s[%pK]: suspend cmd failed rc=%d\n", __func__, audio, rc); } else - pr_err("%s[%p]: not sending suspend since pause failed\n", + pr_err("%s[%pK]: not sending suspend since pause failed\n", __func__, audio); } else - pr_err("%s[%p]: Driver not enabled\n", __func__, audio); + pr_err("%s[%pK]: Driver not enabled\n", __func__, audio); return rc; } @@ -213,7 +213,7 @@ static int audio_aio_flush(struct q6audio_aio *audio) if (!(audio->drv_status & ADRV_STATUS_PAUSE)) { rc = audio_aio_pause(audio); if (rc < 0) - pr_err("%s[%p}: pause cmd failed rc=%d\n", + pr_err("%s[%pK}: pause cmd failed rc=%d\n", __func__, audio, rc); else @@ -221,13 +221,13 @@ static int audio_aio_flush(struct q6audio_aio *audio) } rc = q6asm_cmd(audio->ac, CMD_FLUSH); if (rc < 0) - pr_err("%s[%p]: flush cmd failed rc=%d\n", + pr_err("%s[%pK]: flush cmd failed rc=%d\n", __func__, audio, rc); /* Not in stop state, reenable the stream */ if (audio->stopped == 0) { rc = audio_aio_enable(audio); if (rc) - pr_err("%s[%p]:audio re-enable failed\n", + pr_err("%s[%pK]:audio re-enable failed\n", __func__, audio); else { audio->enabled = 1; @@ -236,9 +236,9 @@ static int audio_aio_flush(struct q6audio_aio *audio) } } } - pr_debug("%s[%p]:in_bytes %d\n", + pr_debug("%s[%pK]:in_bytes %d\n", __func__, audio, atomic_read(&audio->in_bytes)); - pr_debug("%s[%p]:in_samples %d\n", + pr_debug("%s[%pK]:in_samples %d\n", __func__, audio, atomic_read(&audio->in_samples)); atomic_set(&audio->in_bytes, 0); atomic_set(&audio->in_samples, 0); @@ -251,7 +251,7 @@ static int audio_aio_outport_flush(struct q6audio_aio *audio) rc = q6asm_cmd(audio->ac, CMD_OUT_FLUSH); if (rc < 0) - pr_err("%s[%p}: output port flush cmd failed rc=%d\n", + pr_err("%s[%pK}: output port flush cmd failed rc=%d\n", __func__, audio, rc); return rc; } @@ -279,19 +279,19 @@ void audio_aio_async_write_ack(struct q6audio_aio *audio, uint32_t token, if (token == used_buf->token) { list_del(&used_buf->list); spin_unlock_irqrestore(&audio->dsp_lock, flags); - pr_debug("%s[%p]:consumed buffer\n", __func__, audio); + pr_debug("%s[%pK]:consumed buffer\n", __func__, audio); event_payload.aio_buf = used_buf->buf; audio_aio_post_event(audio, AUDIO_EVENT_WRITE_DONE, event_payload); kfree(used_buf); if (list_empty(&audio->out_queue) && (audio->drv_status & ADRV_STATUS_FSYNC)) { - pr_debug("%s[%p]: list is empty, reached EOS in Tunnel\n", + pr_debug("%s[%pK]: list is empty, reached EOS in Tunnel\n", __func__, audio); wake_up(&audio->write_wait); } } else { - pr_err("%s[%p]:expected=%lx ret=%x\n", + pr_err("%s[%pK]:expected=%lx ret=%x\n", __func__, audio, used_buf->token, token); spin_unlock_irqrestore(&audio->dsp_lock, flags); } @@ -305,13 +305,13 @@ void audio_aio_async_out_flush(struct q6audio_aio *audio) union msm_audio_event_payload payload; unsigned long flags; - pr_debug("%s[%p}\n", __func__, audio); + pr_debug("%s[%pK}\n", __func__, audio); /* EOS followed by flush, EOS response not guranteed, free EOS i/p buffer */ spin_lock_irqsave(&audio->dsp_lock, flags); if (audio->eos_flag && (audio->eos_write_payload.aio_buf.buf_addr)) { - pr_debug("%s[%p]: EOS followed by flush received,acknowledge"\ + pr_debug("%s[%pK]: EOS followed by flush received,acknowledge"\ " eos i/p buffer immediately\n", __func__, audio); audio_aio_post_event(audio, AUDIO_EVENT_WRITE_DONE, audio->eos_write_payload); @@ -325,7 +325,7 @@ void audio_aio_async_out_flush(struct q6audio_aio *audio) payload.aio_buf = buf_node->buf; audio_aio_post_event(audio, AUDIO_EVENT_WRITE_DONE, payload); kfree(buf_node); - pr_debug("%s[%p]: Propagate WRITE_DONE during flush\n", + pr_debug("%s[%pK]: Propagate WRITE_DONE during flush\n", __func__, audio); } } @@ -336,14 +336,14 @@ void audio_aio_async_in_flush(struct q6audio_aio *audio) struct list_head *ptr, *next; union msm_audio_event_payload payload; - pr_debug("%s[%p]\n", __func__, audio); + pr_debug("%s[%pK]\n", __func__, audio); list_for_each_safe(ptr, next, &audio->in_queue) { buf_node = list_entry(ptr, struct audio_aio_buffer_node, list); list_del(&buf_node->list); /* Forcefull send o/p eos buffer after flush, if no eos response * received by dsp even after sending eos command */ if ((audio->eos_rsp != 1) && audio->eos_flag) { - pr_debug("%s[%p]: send eos on o/p buffer during flush\n", + pr_debug("%s[%pK]: send eos on o/p buffer during flush\n", __func__, audio); payload.aio_buf = buf_node->buf; payload.aio_buf.data_len = @@ -356,7 +356,7 @@ void audio_aio_async_in_flush(struct q6audio_aio *audio) } audio_aio_post_event(audio, AUDIO_EVENT_READ_DONE, payload); kfree(buf_node); - pr_debug("%s[%p]: Propagate READ_DONE during flush\n", + pr_debug("%s[%pK]: Propagate READ_DONE during flush\n", __func__, audio); } } @@ -374,19 +374,19 @@ int audio_aio_disable(struct q6audio_aio *audio) if (audio->opened) { audio->enabled = 0; audio->opened = 0; - pr_debug("%s[%p]: inbytes[%d] insamples[%d]\n", __func__, + pr_debug("%s[%pK]: inbytes[%d] insamples[%d]\n", __func__, audio, atomic_read(&audio->in_bytes), atomic_read(&audio->in_samples)); /* Close the session */ rc = q6asm_cmd(audio->ac, CMD_CLOSE); if (rc < 0) - pr_err("%s[%p]:Failed to close the session rc=%d\n", + pr_err("%s[%pK]:Failed to close the session rc=%d\n", __func__, audio, rc); audio->stopped = 1; wake_up(&audio->write_wait); wake_up(&audio->cmd_wait); } - pr_debug("%s[%p]:enabled[%d]\n", __func__, audio, audio->enabled); + pr_debug("%s[%pK]:enabled[%d]\n", __func__, audio, audio->enabled); return rc; } @@ -435,16 +435,16 @@ static void audio_aio_unmap_ion_region(struct q6audio_aio *audio) struct list_head *ptr, *next; int rc = -EINVAL; - pr_debug("%s[%p]:\n", __func__, audio); + pr_debug("%s[%pK]:\n", __func__, audio); list_for_each_safe(ptr, next, &audio->ion_region_queue) { region = list_entry(ptr, struct audio_aio_ion_region, list); if (region != NULL) { - pr_debug("%s[%p]: phy_address = 0x%pa\n", + pr_debug("%s[%pK]: phy_address = 0x%pK\n", __func__, audio, ®ion->paddr); rc = q6asm_memory_unmap(audio->ac, region->paddr, IN); if (rc < 0) - pr_err("%s[%p]: memory unmap failed\n", + pr_err("%s[%pK]: memory unmap failed\n", __func__, audio); } } @@ -461,20 +461,20 @@ static void audio_aio_listner(u32 evt_id, union auddev_evt_data *evt_payload, switch (evt_id) { case AUDDEV_EVT_STREAM_VOL_CHG: audio->volume = evt_payload->session_vol; - pr_debug("%s[%p]: AUDDEV_EVT_STREAM_VOL_CHG, stream vol %d, enabled = %d\n", + pr_debug("%s[%pK]: AUDDEV_EVT_STREAM_VOL_CHG, stream vol %d, enabled = %d\n", __func__, audio, audio->volume, audio->enabled); if (audio->enabled == 1) { if (audio->ac) { rc = q6asm_set_volume(audio->ac, audio->volume); if (rc < 0) { - pr_err("%s[%p]: Send Volume command failed rc=%d\n", + pr_err("%s[%pK]: Send Volume command failed rc=%d\n", __func__, audio, rc); } } } break; default: - pr_err("%s[%p]:ERROR:wrong event\n", __func__, audio); + pr_err("%s[%pK]:ERROR:wrong event\n", __func__, audio); break; } } @@ -491,7 +491,7 @@ int register_volume_listener(struct q6audio_aio *audio) audio_aio_listner, (void *)audio); if (rc < 0) { - pr_err("%s[%p]: Event listener failed\n", __func__, audio); + pr_err("%s[%pK]: Event listener failed\n", __func__, audio); rc = -EACCES; } return rc; @@ -509,7 +509,7 @@ int enable_volume_ramp(struct q6audio_aio *audio) if (audio->ac == NULL) return -EINVAL; - pr_debug("%s[%p]\n", __func__, audio); + pr_debug("%s[%pK]\n", __func__, audio); softpause.enable = SOFT_PAUSE_ENABLE; softpause.period = SOFT_PAUSE_PERIOD; softpause.step = SOFT_PAUSE_STEP; @@ -569,7 +569,7 @@ int enable_volume_ramp(struct q6audio_aio *audio) int audio_aio_release(struct inode *inode, struct file *file) { struct q6audio_aio *audio = file->private_data; - pr_debug("%s[%p]\n", __func__, audio); + pr_debug("%s[%pK]\n", __func__, audio); mutex_lock(&audio->lock); audio->wflush = 1; if (audio->enabled) @@ -614,56 +614,56 @@ int audio_aio_fsync(struct file *file, loff_t start, loff_t end, int datasync) audio->drv_status |= ADRV_STATUS_FSYNC; mutex_unlock(&audio->lock); - pr_debug("%s[%p]:\n", __func__, audio); + pr_debug("%s[%pK]:\n", __func__, audio); audio->eos_rsp = 0; - pr_debug("%s[%p]Wait for write done from DSP\n", __func__, audio); + pr_debug("%s[%pK]Wait for write done from DSP\n", __func__, audio); rc = wait_event_interruptible(audio->write_wait, (list_empty(&audio->out_queue)) || audio->wflush || audio->stopped); if (audio->stopped || audio->wflush) { - pr_debug("%s[%p]: Audio Flushed or Stopped,this is not EOS\n" + pr_debug("%s[%pK]: Audio Flushed or Stopped,this is not EOS\n" , __func__, audio); audio->wflush = 0; rc = -EBUSY; } if (rc < 0) { - pr_err("%s[%p]: wait event for list_empty failed, rc = %d\n", + pr_err("%s[%pK]: wait event for list_empty failed, rc = %d\n", __func__, audio, rc); goto done; } rc = q6asm_cmd(audio->ac, CMD_EOS); - pr_debug("%s[%p]: EOS cmd sent to DSP\n", __func__, audio); + pr_debug("%s[%pK]: EOS cmd sent to DSP\n", __func__, audio); if (rc < 0) - pr_err("%s[%p]: q6asm_cmd failed, rc = %d", + pr_err("%s[%pK]: q6asm_cmd failed, rc = %d", __func__, audio, rc); - pr_debug("%s[%p]: wait for RENDERED_EOS from DSP\n" + pr_debug("%s[%pK]: wait for RENDERED_EOS from DSP\n" , __func__, audio); rc = wait_event_interruptible(audio->write_wait, (audio->eos_rsp || audio->wflush || audio->stopped)); if (rc < 0) { - pr_err("%s[%p]: wait event for eos_rsp failed, rc = %d\n", + pr_err("%s[%pK]: wait event for eos_rsp failed, rc = %d\n", __func__, audio, rc); goto done; } if (audio->stopped || audio->wflush) { audio->wflush = 0; - pr_debug("%s[%p]: Audio Flushed or Stopped,this is not EOS\n" + pr_debug("%s[%pK]: Audio Flushed or Stopped,this is not EOS\n" , __func__, audio); rc = -EBUSY; } if (audio->eos_rsp == 1) - pr_debug("%s[%p]: EOS\n", __func__, audio); + pr_debug("%s[%pK]: EOS\n", __func__, audio); done: @@ -728,21 +728,21 @@ static long audio_aio_process_event_req_common(struct q6audio_aio *audio, usr_evt->event_payload = drv_evt->payload; list_add_tail(&drv_evt->list, &audio->free_event_queue); } else { - pr_err("%s[%p]:Unexpected path\n", __func__, audio); + pr_err("%s[%pK]:Unexpected path\n", __func__, audio); spin_unlock_irqrestore(&audio->event_queue_lock, flags); return -EPERM; } spin_unlock_irqrestore(&audio->event_queue_lock, flags); if (drv_evt->event_type == AUDIO_EVENT_WRITE_DONE) { - pr_debug("%s[%p]:posted AUDIO_EVENT_WRITE_DONE to user\n", + pr_debug("%s[%pK]:posted AUDIO_EVENT_WRITE_DONE to user\n", __func__, audio); mutex_lock(&audio->write_lock); audio_aio_ion_fixup(audio, drv_evt->payload.aio_buf.buf_addr, drv_evt->payload.aio_buf.buf_len, 0, 0); mutex_unlock(&audio->write_lock); } else if (drv_evt->event_type == AUDIO_EVENT_READ_DONE) { - pr_debug("%s[%p]:posted AUDIO_EVENT_READ_DONE to user\n", + pr_debug("%s[%pK]:posted AUDIO_EVENT_READ_DONE to user\n", __func__, audio); mutex_lock(&audio->read_lock); audio_aio_ion_fixup(audio, drv_evt->payload.aio_buf.buf_addr, @@ -754,7 +754,7 @@ static long audio_aio_process_event_req_common(struct q6audio_aio *audio, * Once EOS indicated */ if (audio->eos_rsp && !list_empty(&audio->in_queue)) { - pr_debug("%s[%p]:Send flush command to release read buffers"\ + pr_debug("%s[%pK]:Send flush command to release read buffers" " held up in DSP\n", __func__, audio); audio_aio_flush(audio); } @@ -895,7 +895,7 @@ static int audio_aio_ion_check(struct q6audio_aio *audio, list_for_each_entry(region_elt, &audio->ion_region_queue, list) { if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) || OVERLAPS(region_elt, &t)) { - pr_err("%s[%p]:region (vaddr %p len %ld) clashes with registered region (vaddr %p paddr %pa len %ld)\n", + pr_err("%s[%pK]:region (vaddr %pK len %ld) clashes with registered region (vaddr %pK paddr %pK len %ld)\n", __func__, audio, vaddr, len, region_elt->vaddr, ®ion_elt->paddr, region_elt->len); @@ -917,7 +917,7 @@ static int audio_aio_ion_add(struct q6audio_aio *audio, unsigned long ionflag; void *kvaddr = NULL; - pr_debug("%s[%p]:\n", __func__, audio); + pr_debug("%s[%pK]:\n", __func__, audio); region = kmalloc(sizeof(*region), GFP_KERNEL); if (!region) { @@ -946,14 +946,14 @@ static int audio_aio_ion_add(struct q6audio_aio *audio, region->kvaddr = kvaddr; region->len = len; region->ref_cnt = 0; - pr_debug("%s[%p]:add region paddr %pa vaddr %p, len %lu kvaddr %p\n", + pr_debug("%s[%pK]:add region paddr %pK vaddr %pK, len %lu kvaddr %pK\n", __func__, audio, ®ion->paddr, region->vaddr, region->len, region->kvaddr); list_add_tail(®ion->list, &audio->ion_region_queue); rc = q6asm_memory_map(audio->ac, paddr, IN, len, 1); if (rc < 0) { - pr_err("%s[%p]: memory map failed\n", __func__, audio); + pr_err("%s[%pK]: memory map failed\n", __func__, audio); goto mmap_error; } else { goto end; @@ -975,7 +975,7 @@ static int audio_aio_ion_remove(struct q6audio_aio *audio, struct list_head *ptr, *next; int rc = -EINVAL; - pr_debug("%s[%p]:info fd %d vaddr %p\n", + pr_debug("%s[%pK]:info fd %d vaddr %pK\n", __func__, audio, info->fd, info->vaddr); list_for_each_safe(ptr, next, &audio->ion_region_queue) { @@ -984,17 +984,17 @@ static int audio_aio_ion_remove(struct q6audio_aio *audio, if ((region->fd == info->fd) && (region->vaddr == info->vaddr)) { if (region->ref_cnt) { - pr_debug("%s[%p]:region %p in use ref_cnt %d\n", + pr_debug("%s[%pK]:region %pK in use ref_cnt %d\n", __func__, audio, region, region->ref_cnt); break; } - pr_debug("%s[%p]:remove region fd %d vaddr %p\n", + pr_debug("%s[%pK]:remove region fd %d vaddr %pK\n", __func__, audio, info->fd, info->vaddr); rc = q6asm_memory_unmap(audio->ac, (uint32_t) region->paddr, IN); if (rc < 0) - pr_err("%s[%p]: memory unmap failed\n", + pr_err("%s[%pK]: memory unmap failed\n", __func__, audio); list_del(®ion->list); @@ -1017,15 +1017,15 @@ static void audio_aio_async_write(struct q6audio_aio *audio, struct audio_aio_write_param param; if (!audio || !buf_node) { - pr_err("%s NULL pointer audio=[0x%p], buf_node=[0x%p]\n", + pr_err("%s NULL pointer audio=[0x%pK], buf_node=[0x%pK]\n", __func__, audio, buf_node); return; } - pr_debug("%s[%p]: Send write buff %p phy %pa len %d meta_enable = %d\n", + pr_debug("%s[%pK]: Send write buff %pK phy %pK len %d meta_enable = %d\n", __func__, audio, buf_node, &buf_node->paddr, buf_node->buf.data_len, audio->buf_cfg.meta_info_enable); - pr_debug("%s[%p]: flags = 0x%x\n", __func__, audio, + pr_debug("%s[%pK]: flags = 0x%x\n", __func__, audio, buf_node->meta_info.meta_in.nflags); ac = audio->ac; @@ -1054,7 +1054,7 @@ static void audio_aio_async_write(struct q6audio_aio *audio, buf_node->token = ac->session; rc = q6asm_async_write(ac, ¶m); if (rc < 0) - pr_err("%s[%p]:failed\n", __func__, audio); + pr_err("%s[%pK]:failed\n", __func__, audio); } void audio_aio_post_event(struct q6audio_aio *audio, int type, @@ -1072,7 +1072,7 @@ void audio_aio_post_event(struct q6audio_aio *audio, int type, } else { e_node = kmalloc(sizeof(struct audio_aio_event), GFP_ATOMIC); if (!e_node) { - pr_err("%s[%p]:No mem to post event %d\n", + pr_err("%s[%pK]:No mem to post event %d\n", __func__, audio, type); spin_unlock_irqrestore(&audio->event_queue_lock, flags); return; @@ -1094,7 +1094,7 @@ static void audio_aio_async_read(struct q6audio_aio *audio, struct audio_aio_read_param param; int rc; - pr_debug("%s[%p]: Send read buff %p phy %pa len %d\n", + pr_debug("%s[%pK]: Send read buff %pK phy %pK len %d\n", __func__, audio, buf_node, &buf_node->paddr, buf_node->buf.buf_len); ac = audio->ac; @@ -1108,15 +1108,14 @@ static void audio_aio_async_read(struct q6audio_aio *audio, buf_node->token = param.paddr; rc = q6asm_async_read(ac, ¶m); if (rc < 0) - pr_err("%s[%p]:failed\n", __func__, audio); + pr_err("%s[%pK]:failed\n", __func__, audio); } static int audio_aio_buf_add_shared(struct q6audio_aio *audio, u32 dir, struct audio_aio_buffer_node *buf_node) { unsigned long flags; - - pr_debug("%s[%p]:node %p dir %x buf_addr %p buf_len %d data_len %d\n", + pr_debug("%s[%pK]:node %pK dir %x buf_addr %pK buf_len %d data_len %d\n", __func__, audio, buf_node, dir, buf_node->buf.buf_addr, buf_node->buf.buf_len, buf_node->buf.data_len); buf_node->paddr = audio_aio_ion_fixup(audio, buf_node->buf.buf_addr, @@ -1141,7 +1140,7 @@ static int audio_aio_buf_add_shared(struct q6audio_aio *audio, u32 dir, } else if (buf_node->meta_info.meta_in.nflags & AUDIO_DEC_EOS_SET) { if (!audio->wflush) { - pr_debug("%s[%p]:Send EOS cmd at i/p\n", + pr_debug("%s[%pK]:Send EOS cmd at i/p\n", __func__, audio); /* Driver will forcefully post writedone event * once eos ack recived from DSP @@ -1187,7 +1186,7 @@ static int audio_aio_buf_add_shared(struct q6audio_aio *audio, u32 dir, event_payload.aio_buf = buf_node->buf; event_payload.aio_buf.data_len = insert_eos_buf(audio, buf_node); - pr_debug("%s[%p]: propagate READ_DONE as EOS done\n",\ + pr_debug("%s[%pK]: propagate READ_DONE as EOS done\n", __func__, audio); audio_aio_post_event(audio, AUDIO_EVENT_READ_DONE, event_payload); @@ -1256,7 +1255,8 @@ void audio_aio_ioport_reset(struct q6audio_aio *audio) * abort due to flush */ if (audio->drv_status & ADRV_STATUS_FSYNC) { - pr_debug("%s[%p]:fsync in progress\n", __func__, audio); + pr_debug("%s[%pK]:fsync in progress\n", + __func__, audio); audio->drv_ops.out_flush(audio); } else audio->drv_ops.out_flush(audio); @@ -1283,13 +1283,13 @@ int audio_aio_open(struct q6audio_aio *audio, struct file *file) /* Only AIO interface */ if (file->f_flags & O_NONBLOCK) { - pr_debug("%s[%p]:set to aio interface\n", __func__, audio); + pr_debug("%s[%pK]:set to aio interface\n", __func__, audio); audio->drv_status |= ADRV_STATUS_AIO_INTF; audio->drv_ops.out_flush = audio_aio_async_out_flush; audio->drv_ops.in_flush = audio_aio_async_in_flush; q6asm_set_io_mode(audio->ac, ASYNC_IO_MODE); } else { - pr_err("%s[%p]:SIO interface not supported\n", + pr_err("%s[%pK]:SIO interface not supported\n", __func__, audio); rc = -EACCES; goto fail; @@ -1321,7 +1321,7 @@ int audio_aio_open(struct q6audio_aio *audio, struct file *file) if (e_node) list_add_tail(&e_node->list, &audio->free_event_queue); else { - pr_err("%s[%p]:event pkt alloc failed\n", + pr_err("%s[%pK]:event pkt alloc failed\n", __func__, audio); rc = -ENOMEM; goto cleanup; @@ -1333,7 +1333,7 @@ int audio_aio_open(struct q6audio_aio *audio, struct file *file) rc = -ENOMEM; goto cleanup; } - pr_debug("Ion client create in audio_aio_open %p", audio->client); + pr_debug("Ion client create in audio_aio_open %pK", audio->client); rc = register_volume_listener(audio); if (rc < 0) @@ -1367,11 +1367,11 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, break; } case AUDIO_OUTPORT_FLUSH: { - pr_debug("%s[%p]:AUDIO_OUTPORT_FLUSH\n", __func__, audio); + pr_debug("%s[%pK]:AUDIO_OUTPORT_FLUSH\n", __func__, audio); mutex_lock(&audio->read_lock); rc = audio_aio_outport_flush(audio); if (rc < 0) { - pr_err("%s[%p]: AUDIO_OUTPORT_FLUSH failed\n", + pr_err("%s[%pK]: AUDIO_OUTPORT_FLUSH failed\n", __func__, audio); rc = -EINTR; } @@ -1379,13 +1379,13 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, break; } case AUDIO_STOP: { - pr_debug("%s[%p]: AUDIO_STOP session_id[%d]\n", __func__, + pr_debug("%s[%pK]: AUDIO_STOP session_id[%d]\n", __func__, audio, audio->ac->session); mutex_lock(&audio->lock); audio->stopped = 1; rc = audio_aio_flush(audio); if (rc < 0) { - pr_err("%s[%p]:Audio Stop procedure failed rc=%d\n", + pr_err("%s[%pK]:Audio Stop procedure failed rc=%d\n", __func__, audio, rc); mutex_unlock(&audio->lock); break; @@ -1393,7 +1393,7 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, audio->enabled = 0; audio->drv_status &= ~ADRV_STATUS_PAUSE; if (audio->drv_status & ADRV_STATUS_FSYNC) { - pr_debug("%s[%p] Waking up the audio_aio_fsync\n", + pr_debug("%s[%pK] Waking up the audio_aio_fsync\n", __func__, audio); wake_up(&audio->write_wait); } @@ -1401,12 +1401,12 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, break; } case AUDIO_PAUSE: { - pr_debug("%s[%p]:AUDIO_PAUSE %ld\n", __func__, audio, arg); + pr_debug("%s[%pK]:AUDIO_PAUSE %ld\n", __func__, audio, arg); mutex_lock(&audio->lock); if (arg == 1) { rc = audio_aio_pause(audio); if (rc < 0) { - pr_err("%s[%p]: pause FAILED rc=%d\n", + pr_err("%s[%pK]: pause FAILED rc=%d\n", __func__, audio, rc); mutex_unlock(&audio->lock); break; @@ -1416,7 +1416,7 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, if (audio->drv_status & ADRV_STATUS_PAUSE) { rc = audio_aio_enable(audio); if (rc) - pr_err("%s[%p]: audio enable failed\n", + pr_err("%s[%pK]: audio enable failed\n", __func__, audio); else { audio->drv_status &= ~ADRV_STATUS_PAUSE; @@ -1428,13 +1428,13 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, break; } case AUDIO_FLUSH: { - pr_debug("%s[%p]: AUDIO_FLUSH sessionid[%d]\n", __func__, + pr_debug("%s[%pK]: AUDIO_FLUSH sessionid[%d]\n", __func__, audio, audio->ac->session); mutex_lock(&audio->lock); audio->rflush = 1; audio->wflush = 1; if (audio->drv_status & ADRV_STATUS_FSYNC) { - pr_debug("%s[%p] Waking up the audio_aio_fsync\n", + pr_debug("%s[%pK] Waking up the audio_aio_fsync\n", __func__, audio); wake_up(&audio->write_wait); } @@ -1443,7 +1443,7 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, /* Flush input / Output buffer in software*/ audio_aio_ioport_reset(audio); if (rc < 0) { - pr_err("%s[%p]:AUDIO_FLUSH interrupted\n", + pr_err("%s[%pK]:AUDIO_FLUSH interrupted\n", __func__, audio); rc = -EINTR; } else { @@ -1475,8 +1475,6 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, rc = -EINVAL; } return rc; - - } static long audio_aio_ioctl(struct file *file, unsigned int cmd, @@ -1533,7 +1531,7 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, break; } case AUDIO_GET_EVENT: { - pr_debug("%s[%p]:AUDIO_GET_EVENT\n", __func__, audio); + pr_debug("%s[%pK]:AUDIO_GET_EVENT\n", __func__, audio); if (mutex_trylock(&audio->get_event_lock)) { rc = audio_aio_process_event_req(audio, (void __user *)arg); @@ -1573,7 +1571,7 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, memset(&cfg, 0, sizeof(cfg)); cfg.buffer_size = audio->str_cfg.buffer_size; cfg.buffer_count = audio->str_cfg.buffer_count; - pr_debug("%s[%p]:GET STREAM CFG %d %d\n", + pr_debug("%s[%pK]:GET STREAM CFG %d %d\n", __func__, audio, cfg.buffer_size, cfg.buffer_count); if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) { pr_err( @@ -1586,7 +1584,7 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, } case AUDIO_SET_STREAM_CONFIG: { struct msm_audio_stream_config cfg; - pr_debug("%s[%p]:SET STREAM CONFIG\n", __func__, audio); + pr_debug("%s[%pK]:SET STREAM CONFIG\n", __func__, audio); mutex_lock(&audio->lock); if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) { pr_err( @@ -1616,7 +1614,7 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, } case AUDIO_SET_CONFIG: { struct msm_audio_config config; - pr_err("%s[%p]:AUDIO_SET_CONFIG\n", __func__, audio); + pr_err("%s[%pK]:AUDIO_SET_CONFIG\n", __func__, audio); mutex_lock(&audio->lock); if (copy_from_user(&config, (void *)arg, sizeof(config))) { pr_err( @@ -1627,7 +1625,7 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, break; } if (audio->feedback != NON_TUNNEL_MODE) { - pr_err("%s[%p]:Not sufficient permission to change the playback mode\n", + pr_err("%s[%pK]:Not sufficient permission to change the playback mode\n", __func__, audio); rc = -EACCES; mutex_unlock(&audio->lock); @@ -1667,14 +1665,14 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, } audio->buf_cfg.meta_info_enable = cfg.meta_info_enable; - pr_debug("%s[%p]:session id %d: Set-buf-cfg: meta[%d]", + pr_debug("%s[%pK]:session id %d: Set-buf-cfg: meta[%d]", __func__, audio, audio->ac->session, cfg.meta_info_enable); mutex_unlock(&audio->lock); break; } case AUDIO_GET_BUF_CFG: { - pr_debug("%s[%p]:session id %d: Get-buf-cfg: meta[%d] framesperbuf[%d]\n", + pr_debug("%s[%pK]:session id %d: Get-buf-cfg: meta[%d] framesperbuf[%d]\n", __func__, audio, audio->ac->session, audio->buf_cfg.meta_info_enable, audio->buf_cfg.frames_per_buf); @@ -1692,7 +1690,7 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, } case AUDIO_REGISTER_ION: { struct msm_audio_ion_info info; - pr_debug("%s[%p]:AUDIO_REGISTER_ION\n", __func__, audio); + pr_debug("%s[%pK]:AUDIO_REGISTER_ION\n", __func__, audio); mutex_lock(&audio->lock); if (copy_from_user(&info, (void *)arg, sizeof(info))) { pr_err( @@ -1708,7 +1706,7 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, case AUDIO_DEREGISTER_ION: { struct msm_audio_ion_info info; mutex_lock(&audio->lock); - pr_debug("%s[%p]:AUDIO_DEREGISTER_ION\n", __func__, audio); + pr_debug("%s[%pK]:AUDIO_DEREGISTER_ION\n", __func__, audio); if (copy_from_user(&info, (void *)arg, sizeof(info))) { pr_err( "%s: copy_from_user for AUDIO_DEREGISTER_ION failed\n", @@ -1842,7 +1840,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, break; } case AUDIO_GET_EVENT_32: { - pr_debug("%s[%p]:AUDIO_GET_EVENT\n", __func__, audio); + pr_debug("%s[%pK]:AUDIO_GET_EVENT\n", __func__, audio); if (mutex_trylock(&audio->get_event_lock)) { rc = audio_aio_process_event_req_compat(audio, (void __user *)arg); @@ -1882,7 +1880,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, memset(&cfg, 0, sizeof(cfg)); cfg.buffer_size = audio->str_cfg.buffer_size; cfg.buffer_count = audio->str_cfg.buffer_count; - pr_debug("%s[%p]:GET STREAM CFG %d %d\n", + pr_debug("%s[%pK]:GET STREAM CFG %d %d\n", __func__, audio, cfg.buffer_size, cfg.buffer_count); if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) { pr_err("%s: copy_to_user for AUDIO_GET_STREAM_CONFIG_32 failed\n", @@ -1895,7 +1893,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, case AUDIO_SET_STREAM_CONFIG_32: { struct msm_audio_stream_config32 cfg_32; struct msm_audio_stream_config cfg; - pr_debug("%s[%p]:SET STREAM CONFIG\n", __func__, audio); + pr_debug("%s[%pK]:SET STREAM CONFIG\n", __func__, audio); mutex_lock(&audio->lock); if (copy_from_user(&cfg_32, (void *)arg, sizeof(cfg_32))) { pr_err("%s: copy_from_user for AUDIO_SET_STREAM_CONFIG_32 failed\n", @@ -1939,13 +1937,13 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, mutex_lock(&audio->lock); if (audio->feedback != NON_TUNNEL_MODE) { - pr_err("%s[%p]:Not sufficient permission to change the playback mode\n", + pr_err("%s[%pK]:Not sufficient permission to change the playback mode\n", __func__, audio); rc = -EACCES; mutex_unlock(&audio->lock); break; } - pr_err("%s[%p]:AUDIO_SET_CONFIG\n", __func__, audio); + pr_err("%s[%pK]:AUDIO_SET_CONFIG\n", __func__, audio); if (copy_from_user(&config_32, (void *)arg, sizeof(config_32))) { pr_err("%s: copy_from_user for AUDIO_SET_CONFIG_32 failed\n", @@ -1999,7 +1997,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, } audio->buf_cfg.meta_info_enable = cfg.meta_info_enable; - pr_debug("%s[%p]:session id %d: Set-buf-cfg: meta[%d]", + pr_debug("%s[%pK]:session id %d: Set-buf-cfg: meta[%d]", __func__, audio, audio->ac->session, cfg.meta_info_enable); mutex_unlock(&audio->lock); @@ -2007,7 +2005,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, } case AUDIO_GET_BUF_CFG_32: { struct msm_audio_buf_cfg32 cfg_32; - pr_debug("%s[%p]:session id %d: Get-buf-cfg: meta[%d] framesperbuf[%d]\n", + pr_debug("%s[%pK]:session id %d: Get-buf-cfg: meta[%d] framesperbuf[%d]\n", __func__, audio, audio->ac->session, audio->buf_cfg.meta_info_enable, audio->buf_cfg.frames_per_buf); @@ -2028,7 +2026,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, case AUDIO_REGISTER_ION_32: { struct msm_audio_ion_info32 info_32; struct msm_audio_ion_info info; - pr_debug("%s[%p]:AUDIO_REGISTER_ION\n", __func__, audio); + pr_debug("%s[%pK]:AUDIO_REGISTER_ION\n", __func__, audio); mutex_lock(&audio->lock); if (copy_from_user(&info_32, (void *)arg, sizeof(info_32))) { pr_err("%s: copy_from_user for AUDIO_REGISTER_ION_32 failed\n", @@ -2046,7 +2044,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_ion_info32 info_32; struct msm_audio_ion_info info; mutex_lock(&audio->lock); - pr_debug("%s[%p]:AUDIO_DEREGISTER_ION\n", __func__, audio); + pr_debug("%s[%pK]:AUDIO_DEREGISTER_ION\n", __func__, audio); if (copy_from_user(&info_32, (void *)arg, sizeof(info_32))) { pr_err("%s: copy_from_user for AUDIO_DEREGISTER_ION_32 failed\n", __func__); diff --git a/drivers/misc/qcom/qdsp6v2/audio_wma.c b/drivers/misc/qcom/qdsp6v2/audio_wma.c index cb5a9b1c3157b..44c5ee733ed02 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_wma.c +++ b/drivers/misc/qcom/qdsp6v2/audio_wma.c @@ -37,7 +37,7 @@ static long audio_ioctl_shared(struct file *file, unsigned int cmd, case AUDIO_START: { struct asm_wma_cfg wma_cfg; struct msm_audio_wma_config_v2 *wma_config; - pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__, + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, audio, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ @@ -118,7 +118,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); if (rc) pr_err("Failed in utils_ioctl: %d\n", rc); @@ -207,7 +207,7 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_compat_ioctl(file, cmd, arg); if (rc) pr_err("Failed in utils_ioctl: %d\n", rc); diff --git a/drivers/misc/qcom/qdsp6v2/audio_wmapro.c b/drivers/misc/qcom/qdsp6v2/audio_wmapro.c index 1a97daeffef82..b6dad9bae28f4 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_wmapro.c +++ b/drivers/misc/qcom/qdsp6v2/audio_wmapro.c @@ -176,7 +176,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); if (rc) pr_err("Failed in utils_ioctl: %d\n", rc); @@ -286,7 +286,7 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_compat_ioctl(file, cmd, arg); if (rc) pr_err("Failed in utils_ioctl: %d\n", rc); diff --git a/drivers/misc/qcom/qdsp6v2/q6audio_v2_aio.c b/drivers/misc/qcom/qdsp6v2/q6audio_v2_aio.c index d8ae60d392a6a..d688bd5deff83 100644 --- a/drivers/misc/qcom/qdsp6v2/q6audio_v2_aio.c +++ b/drivers/misc/qcom/qdsp6v2/q6audio_v2_aio.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -54,18 +54,18 @@ void audio_aio_cb(uint32_t opcode, uint32_t token, switch (opcode) { case ASM_DATA_EVENT_WRITE_DONE_V2: - pr_debug("%s[%p]:ASM_DATA_EVENT_WRITE_DONE token = 0x%x\n", + pr_debug("%s[%pK]:ASM_DATA_EVENT_WRITE_DONE token = 0x%x\n", __func__, audio, token); audio_aio_async_write_ack(audio, token, payload); break; case ASM_DATA_EVENT_READ_DONE_V2: - pr_debug("%s[%p]:ASM_DATA_EVENT_READ_DONE token = 0x%x\n", + pr_debug("%s[%pK]:ASM_DATA_EVENT_READ_DONE token = 0x%x\n", __func__, audio, token); audio_aio_async_read_ack(audio, token, payload); break; case ASM_DATA_EVENT_RENDERED_EOS: /* EOS Handle */ - pr_debug("%s[%p]:ASM_DATA_CMDRSP_EOS\n", __func__, audio); + pr_debug("%s[%pK]:ASM_DATA_CMDRSP_EOS\n", __func__, audio); if (audio->feedback) { /* Non-Tunnel mode */ audio->eos_rsp = 1; /* propagate input EOS i/p buffer, @@ -87,16 +87,16 @@ void audio_aio_cb(uint32_t opcode, uint32_t token, break; case ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2: case ASM_STREAM_CMD_SET_ENCDEC_PARAM: - pr_debug("%s[%p]:payload0[%x] payloa1d[%x]opcode= 0x%x\n", + pr_debug("%s[%pK]:payload0[%x] payloa1d[%x]opcode= 0x%x\n", __func__, audio, payload[0], payload[1], opcode); break; case ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY: case ASM_DATA_EVENT_ENC_SR_CM_CHANGE_NOTIFY: - pr_debug("%s[%p]: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, payload[0]-sr = %d, payload[1]-chl = %d, payload[2] = %d, payload[3] = %d\n", + pr_debug("%s[%pK]: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, payload[0]-sr = %d, payload[1]-chl = %d, payload[2] = %d, payload[3] = %d\n", __func__, audio, payload[0], payload[1], payload[2], payload[3]); - pr_debug("%s[%p]: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, sr(prev) = %d, chl(prev) = %d,", + pr_debug("%s[%pK]: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, sr(prev) = %d, chl(prev) = %d,", __func__, audio, audio->pcm_cfg.sample_rate, audio->pcm_cfg.channel_count); @@ -129,7 +129,7 @@ void extract_meta_out_info(struct q6audio_aio *audio, else memset(&buf_node->meta_info.meta_in, 0, sizeof(struct dec_meta_in)); - pr_debug("%s[%p]:i/p: msw_ts 0x%d lsw_ts 0x%d nflags 0x%8x\n", + pr_debug("%s[%pK]:i/p: msw_ts 0x%d lsw_ts 0x%d nflags 0x%8x\n", __func__, audio, buf_node->meta_info.meta_in.ntimestamp.highpart, buf_node->meta_info.meta_in.ntimestamp.lowpart, @@ -144,7 +144,7 @@ void extract_meta_out_info(struct q6audio_aio *audio, meta_data->meta_out_dsp[0].lsw_ts; meta_data->meta_out_dsp[0].lsw_ts = temp; - pr_debug("%s[%p]:o/p: msw_ts 0x%d lsw_ts 0x%d nflags 0x%8x, num_frames = %d\n", + pr_debug("%s[%pK]:o/p: msw_ts 0x%d lsw_ts 0x%d nflags 0x%8x, num_frames = %d\n", __func__, audio, ((struct dec_meta_out *)buf_node->kvaddr)->\ meta_out_dsp[0].msw_ts, @@ -200,7 +200,7 @@ void audio_aio_async_read_ack(struct q6audio_aio *audio, uint32_t token, = payload[9]; event_payload.aio_buf.data_len = payload[4]\ + payload[5] + sizeof(struct dec_meta_out); - pr_debug("%s[%p]:nr of frames 0x%8x len=%d\n", + pr_debug("%s[%pK]:nr of frames 0x%8x len=%d\n", __func__, audio, filled_buf->meta_info.meta_out.num_of_frames, event_payload.aio_buf.data_len); @@ -212,7 +212,7 @@ void audio_aio_async_read_ack(struct q6audio_aio *audio, uint32_t token, event_payload); kfree(filled_buf); } else { - pr_err("%s[%p]:expected=%lx ret=%x\n", + pr_err("%s[%pK]:expected=%lx ret=%x\n", __func__, audio, filled_buf->token, token); spin_unlock_irqrestore(&audio->dsp_lock, flags); } diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c b/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c index cb8f37a54cd3c..c43d105365cff 100644 --- a/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c +++ b/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c @@ -207,7 +207,7 @@ static int q6usm_us_client_buf_free(unsigned int dir, rc = q6usm_memory_unmap(port->phys, dir, usc->session, *((uint32_t *)port->ext)); - pr_debug("%s: data[%p]phys[%llx][%p]\n", __func__, + pr_debug("%s: data[%pK]phys[%llx][%pK]\n", __func__, (void *)port->data, (u64)port->phys, (void *)&port->phys); msm_audio_ion_free(port->client, port->handle); @@ -247,7 +247,7 @@ int q6usm_us_param_buf_free(unsigned int dir, rc = q6usm_memory_unmap(port->param_phys, dir, usc->session, *((uint32_t *)port->param_buf_mem_handle)); - pr_debug("%s: data[%p]phys[%llx][%p]\n", __func__, + pr_debug("%s: data[%pK]phys[%llx][%pK]\n", __func__, (void *)port->param_buf, (u64)port->param_phys, (void *)&port->param_phys); @@ -361,7 +361,7 @@ struct us_client *q6usm_us_client_alloc( spin_lock_init(&usc->port[lcnt].dsp_lock); usc->port[lcnt].ext = (void *)p_mem_handle++; usc->port[lcnt].param_buf_mem_handle = (void *)p_mem_handle++; - pr_err("%s: usc->port[%d].ext=%p;\n", + pr_err("%s: usc->port[%d].ext=%pK;\n", __func__, lcnt, usc->port[lcnt].ext); } atomic_set(&usc->cmd_state, 0); @@ -416,7 +416,7 @@ int q6usm_us_client_buf_alloc(unsigned int dir, port->buf_cnt = bufcnt; port->buf_size = bufsz; - pr_debug("%s: data[%p]; phys[%llx]; [%p]\n", __func__, + pr_debug("%s: data[%pK]; phys[%llx]; [%pK]\n", __func__, (void *)port->data, (u64)port->phys, (void *)&port->phys); @@ -481,7 +481,7 @@ int q6usm_us_param_buf_alloc(unsigned int dir, } port->param_buf_size = bufsz; - pr_debug("%s: param_buf[%p]; param_phys[%llx]; [%p]\n", __func__, + pr_debug("%s: param_buf[%pK]; param_phys[%llx]; [%pK]\n", __func__, (void *)port->param_buf, (u64)port->param_phys, (void *)&port->param_phys); @@ -1334,7 +1334,7 @@ int q6usm_set_us_detection(struct us_client *usc, if ((usc == NULL) || (detect_info_size == 0) || (detect_info == NULL)) { - pr_err("%s: wrong input: usc=0x%p, inf_size=%d; info=0x%p", + pr_err("%s: wrong input: usc=0x%pK, inf_size=%d; info=0x%pK", __func__, usc, detect_info_size, diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.c b/drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.c index 76bcc83e1c5ec..a4d63f0c0d1ac 100644 --- a/drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.c +++ b/drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -170,7 +170,7 @@ static int usfcdev_connect(struct input_handler *handler, struct input_dev *dev, } usfc_handle->dev = dev; ret = input_register_handle(usfc_handle); - pr_debug("%s: name=[%s]; ind=%d; dev=0x%p\n", + pr_debug("%s: name=[%s]; ind=%d; dev=0x%pK\n", __func__, dev->name, ind, @@ -259,7 +259,7 @@ bool usfcdev_register( bool rc = false; if ((event_type_ind >= MAX_EVENT_TYPE_NUM) || !match_cb) { - pr_err("%s: wrong input: event_type_ind=%d; match_cb=0x%p\n", + pr_err("%s: wrong input: event_type_ind=%d; match_cb=0x%pK\n", __func__, event_type_ind, match_cb); From 161331ce3dbed3e61436fd6b7db96f74d08ed2f4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 10 Jul 2016 10:04:02 +0200 Subject: [PATCH 300/320] tcp: make challenge acks less predictable Yue Cao claims that current host rate limiting of challenge ACKS (RFC 5961) could leak enough information to allow a patient attacker to hijack TCP sessions. He will soon provide details in an academic paper. This patch increases the default limit from 100 to 1000, and adds some randomization so that the attacker can no longer hijack sessions without spending a considerable amount of probes. Based on initial analysis and patch from Linus. Note that we also have per socket rate limiting, so it is tempting to remove the host limit in the future. v2: randomize the count of challenge acks per second, not the period. Fixes: 282f23c6ee34 ("tcp: implement RFC 5961 3.2") Reported-by: Yue Cao Signed-off-by: Eric Dumazet Suggested-by: Linus Torvalds Cc: Yuchung Cheng Cc: Neal Cardwell Acked-by: Neal Cardwell Acked-by: Yuchung Cheng Signed-off-by: David S. Miller Change-Id: I9818e7d904aa39ce4327042233e3d0ef5982ce4f Git-commit: 75ff39ccc1bd5d3c455b6822ab09e533c551f758 Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git [rsiddoji@codeaurora.org: resolved trival conflits and removed the usages of READ_ONCE and WRITE_ONCE macro usage] Signed-off-by: Ravi Kumar Siddojigari --- net/ipv4/tcp_input.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index a75493979d55b..f0377f2614011 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -68,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -87,7 +88,7 @@ int sysctl_tcp_adv_win_scale __read_mostly = 1; EXPORT_SYMBOL(sysctl_tcp_adv_win_scale); /* rfc5961 challenge ack rate limiting */ -int sysctl_tcp_challenge_ack_limit = 100; +int sysctl_tcp_challenge_ack_limit = 1000; int sysctl_tcp_stdurg __read_mostly; int sysctl_tcp_rfc1337 __read_mostly; @@ -3288,12 +3289,19 @@ static void tcp_send_challenge_ack(struct sock *sk) static u32 challenge_timestamp; static unsigned int challenge_count; u32 now = jiffies / HZ; + u32 count; if (now != challenge_timestamp) { + u32 half = (sysctl_tcp_challenge_ack_limit + 1) >> 1; + challenge_timestamp = now; - challenge_count = 0; + ACCESS_ONCE(challenge_count) = half + + reciprocal_divide(prandom_u32(), + sysctl_tcp_challenge_ack_limit); } - if (++challenge_count <= sysctl_tcp_challenge_ack_limit) { + count = ACCESS_ONCE(challenge_count); + if (count > 0) { + ACCESS_ONCE(challenge_count) = count - 1; NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPCHALLENGEACK); tcp_send_ack(sk); } From 60e631e2efdec350758b6f37ebfa222df08b7b45 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 14 Mar 2016 09:56:35 -0300 Subject: [PATCH 301/320] net: Fix use after free in the recvmmsg exit path The syzkaller fuzzer hit the following use-after-free: Call Trace: [] __asan_report_load8_noabort+0x3e/0x40 mm/kasan/report.c:295 [] __sys_recvmmsg+0x6fa/0x7f0 net/socket.c:2261 [< inline >] SYSC_recvmmsg net/socket.c:2281 [] SyS_recvmmsg+0x16f/0x180 net/socket.c:2270 [] entry_SYSCALL_64_fastpath+0x16/0x7a arch/x86/entry/entry_64.S:185 And, as Dmitry rightly assessed, that is because we can drop the reference and then touch it when the underlying recvmsg calls return some packets and then hit an error, which will make recvmmsg to set sock->sk->sk_err, oops, fix it. Reported-and-Tested-by: Dmitry Vyukov Cc: Alexander Potapenko Cc: Eric Dumazet Cc: Kostya Serebryany Cc: Sasha Levin Fixes: a2e2725541fa ("net: Introduce recvmmsg socket syscall") http://lkml.kernel.org/r/20160122211644.GC2470@redhat.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller Git-commit: 34b88a68f26a75e4fded796f1a49c40f82234b7d Git-repo : http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Change-Id: I5d521014624e491e6eb471084b7896b29d4e2650 Signed-off-by: Ravi Kumar Siddojigari --- net/socket.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/net/socket.c b/net/socket.c index 10981131a81c8..6cd5f15bcfeea 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2425,13 +2425,14 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, break; } -out_put: - fput_light(sock->file, fput_needed); - if (err == 0) - return datagrams; + goto out_put; + + if (datagrams == 0) { + datagrams = err; + goto out_put; + } - if (datagrams != 0) { /* * We may return less entries than requested (vlen) if the * sock is non block and there aren't enough datagrams... @@ -2446,10 +2447,10 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, sock->sk->sk_err = -err; } - return datagrams; - } +out_put: + fput_light(sock->file, fput_needed); - return err; + return datagrams; } SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, From 3757af29d7f8a641018d14ba4c10190123cf131e Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Thu, 13 Oct 2016 18:07:22 -0700 Subject: [PATCH 302/320] crypto: msm: qcrypto: Fix _qcrypto_tfm_complete crash Null pointer de-reference may occur when there are multiple AES-CCM crypto users simultaneously. Specifically, _qcrypto_tfm_complete calls a user completion function and if it is the user's last request, cra_exit may be called to destroy the tfm context. The tfm context is no longer valid, and referring to the deleted tfm context after the callback is invoked may cause a crash. The solution is to look ahead to ensure that there are more entries in the response queue to process before calling the user completion callback. If there are no more entries to process after the callback is invoked, it won't proceed to look at tfm for additional completed responses to process. Change-Id: Ie9fb5212345676010bfa6f1e79ea7e4fab1d000b Signed-off-by: Zhen Kong --- drivers/crypto/msm/qcrypto.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c index 40a410555cd7e..e25cfc5c9e695 100644 --- a/drivers/crypto/msm/qcrypto.c +++ b/drivers/crypto/msm/qcrypto.c @@ -1248,6 +1248,7 @@ static void _qcrypto_tfm_complete(struct crypto_priv *cp, u32 type, struct qcrypto_resp_ctx *arsp; struct list_head *plist; struct crypto_async_request *areq; + bool pending_list; switch (type) { case CRYPTO_ALG_TYPE_AHASH: @@ -1263,6 +1264,7 @@ static void _qcrypto_tfm_complete(struct crypto_priv *cp, u32 type, spin_lock_irqsave(&cp->lock, flags); if (list_empty(plist)) { arsp = NULL; /* nothing to do */ + pending_list = false; } else { arsp = list_first_entry(plist, struct qcrypto_resp_ctx, list); @@ -1270,12 +1272,17 @@ static void _qcrypto_tfm_complete(struct crypto_priv *cp, u32 type, arsp = NULL; /* still in progress */ else list_del(&arsp->list); /* request is complete */ + if (list_empty(plist)) + pending_list = false; + else + pending_list = true; } spin_unlock_irqrestore(&cp->lock, flags); if (arsp) { areq = arsp->async_req; areq->complete(areq, arsp->res); - goto again; + if (pending_list) + goto again; } } From f723d33cc76b05d5bb1aa2190cd4a11eb8d4aa21 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Mon, 2 May 2016 13:53:47 -0700 Subject: [PATCH 303/320] msm: vidc: Add SEI extradata The change extend the support in video driver to enable few SEI extradata. Also update the extradata menu V4L2 control with all the available list of extradata. CRs-Fixed: 1007521 Change-Id: I6d060afb48aca34c2bb54221c5babc0ac55aff7c Signed-off-by: Vikash Garodia Signed-off-by: Vasantha Balla Signed-off-by: Pradosh Das --- .../platform/msm/vidc/hfi_packetization.c | 7 ++++ drivers/media/platform/msm/vidc/msm_vdec.c | 27 ++------------ drivers/media/platform/msm/vidc/msm_venc.c | 23 ------------ .../media/platform/msm/vidc/msm_vidc_common.c | 37 +++++++++++++++++++ .../media/platform/msm/vidc/msm_vidc_common.h | 3 ++ drivers/media/platform/msm/vidc/vidc_hfi.h | 6 +++ .../media/platform/msm/vidc/vidc_hfi_api.h | 2 + include/uapi/linux/v4l2-controls.h | 6 +++ include/uapi/media/msm_vidc.h | 20 ++++++++++ 9 files changed, 85 insertions(+), 46 deletions(-) diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c index d49acc41a775c..c7c05be49b16d 100644 --- a/drivers/media/platform/msm/vidc/hfi_packetization.c +++ b/drivers/media/platform/msm/vidc/hfi_packetization.c @@ -483,6 +483,13 @@ static int get_hfi_extradata_index(enum hal_extradata_id index) case HAL_EXTRADATA_METADATA_MBI: ret = HFI_PROPERTY_PARAM_VENC_MBI_DUMPING; break; + case HAL_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI: + ret = + HFI_PROPERTY_PARAM_VDEC_MASTERING_DISPLAY_COLOUR_SEI_EXTRADATA; + break; + case HAL_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI: + ret = HFI_PROPERTY_PARAM_VDEC_CONTENT_LIGHT_LEVEL_SEI_EXTRADATA; + break; default: dprintk(VIDC_WARN, "Extradata index not found: %d\n", index); break; diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c index 8c2b8731c2439..58cd698a51016 100644 --- a/drivers/media/platform/msm/vidc/msm_vdec.c +++ b/drivers/media/platform/msm/vidc/msm_vdec.c @@ -50,27 +50,6 @@ static const char *const mpeg_video_output_order[] = { "Decode Order", NULL }; -static const char *const mpeg_video_vidc_extradata[] = { - "Extradata none", - "Extradata MB Quantization", - "Extradata Interlace Video", - "Extradata VC1 Framedisp", - "Extradata VC1 Seqdisp", - "Extradata timestamp", - "Extradata S3D Frame Packing", - "Extradata Frame Rate", - "Extradata Panscan Window", - "Extradata Recovery point SEI", - "Extradata Closed Caption UD", - "Extradata AFD UD", - "Extradata Multislice info", - "Extradata number of concealed MB", - "Extradata metadata filler", - "Extradata input crop", - "Extradata digital zoom", - "Extradata aspect ratio", - "Extradata mpeg2 seqdisp", -}; static const char *const mpeg_vidc_video_alloc_mode_type[] = { "Buffer Allocation Static", "Buffer Allocation Ring Buffer", @@ -246,7 +225,7 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .name = "Extradata Type", .type = V4L2_CTRL_TYPE_MENU, .minimum = V4L2_MPEG_VIDC_EXTRADATA_NONE, - .maximum = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO, + .maximum = V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI, .default_value = V4L2_MPEG_VIDC_EXTRADATA_NONE, .menu_skip_mask = ~( (1 << V4L2_MPEG_VIDC_EXTRADATA_NONE) | @@ -268,7 +247,9 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { (1 << V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP) | (1 << V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA) | (1 << V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP) | - (1 << V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO) + (1 << V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO) | + (1 << V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI) | + (1 << V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI) ), .qmenu = mpeg_video_vidc_extradata, .step = 0, diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c index f36a152656a6e..465333d769dfa 100644 --- a/drivers/media/platform/msm/vidc/msm_venc.c +++ b/drivers/media/platform/msm/vidc/msm_venc.c @@ -152,29 +152,6 @@ static const char *const vp8_profile_level[] = { "2.0", "3.0", }; - -static const char *const mpeg_video_vidc_extradata[] = { - "Extradata none", - "Extradata MB Quantization", - "Extradata Interlace Video", - "Extradata VC1 Framedisp", - "Extradata VC1 Seqdisp", - "Extradata timestamp", - "Extradata S3D Frame Packing", - "Extradata Frame Rate", - "Extradata Panscan Window", - "Extradata Recovery point SEI", - "Extradata Closed Caption UD", - "Extradata AFD UD", - "Extradata Multislice info", - "Extradata number of concealed MB", - "Extradata metadata filler", - "Extradata input crop", - "Extradata digital zoom", - "Extradata aspect ratio", - "Extradata macroblock metadata", -}; - static const char *const perf_level[] = { "Nominal", "Performance", diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c index dc76227a1749d..86965a8ad469e 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c @@ -51,6 +51,37 @@ #define IS_SYS_CMD_VALID(cmd) (((cmd) >= SYS_MSG_START) && \ ((cmd) <= SYS_MSG_END)) +const char *const mpeg_video_vidc_extradata[] = { + "Extradata none", + "Extradata MB Quantization", + "Extradata Interlace Video", + "Extradata VC1 Framedisp", + "Extradata VC1 Seqdisp", + "Extradata timestamp", + "Extradata S3D Frame Packing", + "Extradata Frame Rate", + "Extradata Panscan Window", + "Extradata Recovery point SEI", + "Extradata Multislice info", + "Extradata number of concealed MB", + "Extradata metadata filler", + "Extradata input crop", + "Extradata digital zoom", + "Extradata aspect ratio", + "Extradata mpeg2 seqdisp", + "Extradata stream userdata", + "Extradata frame QP", + "Extradata frame bits info", + "Extradata LTR", + "Extradata macroblock metadata", + "Extradata VQZip SEI", + "Extradata YUV Stats", + "Extradata ROI QP", + "Extradata output crop", + "Extradata display colour SEI", + "Extradata light level SEI", +}; + struct getprop_buf { struct list_head list; void *data; @@ -4284,6 +4315,12 @@ enum hal_extradata_id msm_comm_get_hal_extradata_index( case V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI: ret = HAL_EXTRADATA_METADATA_MBI; break; + case V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI: + ret = HAL_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI; + break; + case V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI: + ret = HAL_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI; + break; default: dprintk(VIDC_WARN, "Extradata not found: %d\n", index); break; diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.h b/drivers/media/platform/msm/vidc/msm_vidc_common.h index 890153b933116..d9cb73a86bcf5 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.h +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.h @@ -18,6 +18,9 @@ struct vb2_buf_entry { struct list_head list; struct vb2_buffer *vb; }; + +extern const char *const mpeg_video_vidc_extradata[]; + struct msm_vidc_core *get_vidc_core(int core_id); const struct msm_vidc_format *msm_comm_get_pixel_fmt_index( const struct msm_vidc_format fmt[], int size, int index, int fmt_type); diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.h b/drivers/media/platform/msm/vidc/vidc_hfi.h index 6199c1516f080..484a4980882b8 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi.h @@ -217,6 +217,12 @@ struct hfi_extradata_header { (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x019) #define HFI_PROPERTY_PARAM_VDEC_SCS_THRESHOLD \ (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x01A) +#define HFI_PROPERTY_PARAM_VDEC_VPX_COLORSPACE_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001D) +#define HFI_PROPERTY_PARAM_VDEC_MASTERING_DISPLAY_COLOUR_SEI_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001E) +#define HFI_PROPERTY_PARAM_VDEC_CONTENT_LIGHT_LEVEL_SEI_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001F) #define HFI_PROPERTY_CONFIG_VDEC_OX_START \ (HFI_DOMAIN_BASE_VDEC + HFI_ARCH_OX_OFFSET + 0x0000) diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h index c92e179ae6281..abb5e9c1437e7 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h @@ -114,6 +114,8 @@ enum hal_extradata_id { HAL_EXTRADATA_DIGITAL_ZOOM, HAL_EXTRADATA_LTR_INFO, HAL_EXTRADATA_METADATA_MBI, + HAL_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI, + HAL_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI, }; enum hal_property { diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index 7576ce541889c..b95df76d5c17a 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -739,6 +739,12 @@ enum v4l2_mpeg_vidc_extradata { V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO = 19, V4L2_MPEG_VIDC_EXTRADATA_LTR = 20, V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI = 21, +#define V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI \ + V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI + V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI = 26, +#define V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI \ + V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI + V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI = 27, }; #define V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL (V4L2_CID_MPEG_MSM_VIDC_BASE + 26) diff --git a/include/uapi/media/msm_vidc.h b/include/uapi/media/msm_vidc.h index 6fa53ad7997b7..e1e8d3b6335a8 100644 --- a/include/uapi/media/msm_vidc.h +++ b/include/uapi/media/msm_vidc.h @@ -109,6 +109,20 @@ struct msm_vidc_s3d_frame_packing_payload { unsigned int fpa_extension_flag; }; +struct msm_vidc_mastering_display_colour_sei_payload { + unsigned int nDisplayPrimariesX[3]; + unsigned int nDisplayPrimariesY[3]; + unsigned int nWhitePointX; + unsigned int nWhitePointY; + unsigned int nMaxDisplayMasteringLuminance; + unsigned int nMinDisplayMasteringLuminance; +}; + +struct msm_vidc_content_light_level_sei_payload { + unsigned int nMaxContentLight; + unsigned int nMaxPicAverageLight; +}; + enum msm_vidc_extradata_type { MSM_VIDC_EXTRADATA_NONE = 0x00000000, MSM_VIDC_EXTRADATA_MB_QUANTIZATION = 0x00000001, @@ -124,6 +138,12 @@ enum msm_vidc_extradata_type { MSM_VIDC_EXTRADATA_STREAM_USERDATA = 0x0000000E, MSM_VIDC_EXTRADATA_FRAME_QP = 0x0000000F, MSM_VIDC_EXTRADATA_FRAME_BITS_INFO = 0x00000010, +#define MSM_VIDC_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI \ + MSM_VIDC_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI + MSM_VIDC_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI = 0x00000015, +#define MSM_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI \ + MSM_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI + MSM_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI = 0x00000016, MSM_VIDC_EXTRADATA_INPUT_CROP = 0x0700000E, MSM_VIDC_EXTRADATA_DIGITAL_ZOOM = 0x07000010, MSM_VIDC_EXTRADATA_MULTISLICE_INFO = 0x7F100000, From e107b0f42258ebbfc0df3a02ffb87cd30a123a63 Mon Sep 17 00:00:00 2001 From: Praneeth Paladugu Date: Tue, 24 May 2016 22:38:40 -0700 Subject: [PATCH 304/320] msm: vidc: Add support for color space information. When clients specify color space information, venus HW should embed it in the bit stream. This helps to regenerate original colors when decoded by decoder. When decoder detects the color space VUI, Venus fills the corresponding extradata. CRs-Fixed: 1026204 Change-Id: Ie9523558c23a8edc7a7ee058937658dd87ef5b16 Signed-off-by: Praneeth Paladugu Signed-off-by: Pradosh Das --- .../platform/msm/vidc/hfi_packetization.c | 26 ++++ drivers/media/platform/msm/vidc/msm_vdec.c | 7 +- drivers/media/platform/msm/vidc/msm_venc.c | 103 ++++++++++++++- .../media/platform/msm/vidc/msm_vidc_common.c | 9 +- .../media/platform/msm/vidc/msm_vidc_debug.c | 6 - drivers/media/platform/msm/vidc/vidc_hfi.h | 3 + .../media/platform/msm/vidc/vidc_hfi_api.h | 10 ++ .../media/platform/msm/vidc/vidc_hfi_helper.h | 12 +- include/uapi/linux/v4l2-controls.h | 23 ++++ include/uapi/media/msm_vidc.h | 118 ++++++++++++++++++ 10 files changed, 303 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c index c7c05be49b16d..b6ae43a718b6d 100644 --- a/drivers/media/platform/msm/vidc/hfi_packetization.c +++ b/drivers/media/platform/msm/vidc/hfi_packetization.c @@ -490,6 +490,12 @@ static int get_hfi_extradata_index(enum hal_extradata_id index) case HAL_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI: ret = HFI_PROPERTY_PARAM_VDEC_CONTENT_LIGHT_LEVEL_SEI_EXTRADATA; break; + case HAL_EXTRADATA_VUI_DISPLAY_INFO: + ret = HFI_PROPERTY_PARAM_VUI_DISPLAY_INFO_EXTRADATA; + break; + case HAL_EXTRADATA_VPX_COLORSPACE: + ret = HFI_PROPERTY_PARAM_VDEC_VPX_COLORSPACE_EXTRADATA; + break; default: dprintk(VIDC_WARN, "Extradata index not found: %d\n", index); break; @@ -1905,6 +1911,26 @@ int create_pkt_cmd_session_set_property( sizeof(struct hfi_hybrid_hierp); break; } + case HAL_PARAM_VENC_VIDEO_SIGNAL_INFO: + { + struct hal_video_signal_info *hal = pdata; + struct hfi_video_signal_metadata *signal_info = + (struct hfi_video_signal_metadata *) + &pkt->rg_property_data[1]; + + signal_info->enable = true; + signal_info->video_format = MSM_VIDC_NTSC; + signal_info->video_full_range = hal->full_range; + signal_info->color_description = MSM_VIDC_COLOR_DESC_PRESENT; + signal_info->color_primaries = hal->color_space; + signal_info->transfer_characteristics = hal->transfer_chars; + signal_info->matrix_coeffs = hal->matrix_coeffs; + + pkt->rg_property_data[0] = + HFI_PROPERTY_PARAM_VENC_VIDEO_SIGNAL_INFO; + pkt->size += sizeof(u32) + sizeof(*signal_info); + break; + } /* FOLLOWING PROPERTIES ARE NOT IMPLEMENTED IN CORE YET */ case HAL_CONFIG_BUFFER_REQUIREMENTS: case HAL_CONFIG_PRIORITY: diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c index 58cd698a51016..1a9cd222af863 100644 --- a/drivers/media/platform/msm/vidc/msm_vdec.c +++ b/drivers/media/platform/msm/vidc/msm_vdec.c @@ -225,7 +225,7 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .name = "Extradata Type", .type = V4L2_CTRL_TYPE_MENU, .minimum = V4L2_MPEG_VIDC_EXTRADATA_NONE, - .maximum = V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI, + .maximum = V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE, .default_value = V4L2_MPEG_VIDC_EXTRADATA_NONE, .menu_skip_mask = ~( (1 << V4L2_MPEG_VIDC_EXTRADATA_NONE) | @@ -249,7 +249,10 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { (1 << V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP) | (1 << V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO) | (1 << V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI) | - (1 << V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI) + (1 << + V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI) | + (1 << V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY) | + (1 << V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE) ), .qmenu = mpeg_video_vidc_extradata, .step = 0, diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c index 465333d769dfa..eed2263440efe 100644 --- a/drivers/media/platform/msm/vidc/msm_venc.c +++ b/drivers/media/platform/msm/vidc/msm_venc.c @@ -1060,6 +1060,46 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .step = 1, .qmenu = NULL, }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE, + .name = "Set Color space", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MSM_VIDC_BT709_5, + .maximum = MSM_VIDC_BT2020, + .default_value = MSM_VIDC_BT601_6_625, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE, + .name = "Set Color space range", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE_DISABLE, + .maximum = V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE_ENABLE, + .default_value = V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE_DISABLE, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS, + .name = "Set Color space transfer characterstics", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MSM_VIDC_TRANSFER_BT709_5, + .maximum = MSM_VIDC_TRANSFER_BT_2020_12, + .default_value = MSM_VIDC_TRANSFER_601_6_625, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS, + .name = "Set Color space matrix coefficients", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MSM_VIDC_MATRIX_BT_709_5, + .maximum = MSM_VIDC_MATRIX_BT_2020_CONST, + .default_value = MSM_VIDC_MATRIX_601_6_625, + .step = 1, + .qmenu = NULL, + }, + }; #define NUM_CTRLS ARRAY_SIZE(msm_venc_ctrls) @@ -1814,6 +1854,7 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) struct hal_hybrid_hierp hyb_hierp; u32 hier_p_layers = 0, hier_b_layers = 0; struct hal_venc_perf_mode venc_mode; + struct hal_video_signal_info signal_info = {0}; if (!inst || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); @@ -2674,6 +2715,64 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: property_id = 0; break; + case V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE: + { + signal_info.color_space = ctrl->val; + temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE); + signal_info.full_range = temp_ctrl ? temp_ctrl->val : 0; + temp_ctrl = + TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS); + signal_info.transfer_chars = temp_ctrl ? temp_ctrl->val : 0; + temp_ctrl = + TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS); + signal_info.matrix_coeffs = temp_ctrl ? temp_ctrl->val : 0; + property_id = HAL_PARAM_VENC_VIDEO_SIGNAL_INFO; + pdata = &signal_info; + break; + } + case V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE: + { + signal_info.full_range = ctrl->val; + temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE); + signal_info.color_space = temp_ctrl ? temp_ctrl->val : 0; + temp_ctrl = + TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS); + signal_info.transfer_chars = temp_ctrl ? temp_ctrl->val : 0; + temp_ctrl = + TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS); + signal_info.matrix_coeffs = temp_ctrl ? temp_ctrl->val : 0; + property_id = HAL_PARAM_VENC_VIDEO_SIGNAL_INFO; + pdata = &signal_info; + break; + } + case V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS: + { + signal_info.transfer_chars = ctrl->val; + temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE); + signal_info.full_range = temp_ctrl ? temp_ctrl->val : 0; + temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE); + signal_info.color_space = temp_ctrl ? temp_ctrl->val : 0; + temp_ctrl = + TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS); + signal_info.matrix_coeffs = temp_ctrl ? temp_ctrl->val : 0; + property_id = HAL_PARAM_VENC_VIDEO_SIGNAL_INFO; + pdata = &signal_info; + break; + } + case V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS: + { + signal_info.matrix_coeffs = ctrl->val; + temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE); + signal_info.full_range = temp_ctrl ? temp_ctrl->val : 0; + temp_ctrl = + TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS); + signal_info.transfer_chars = temp_ctrl ? temp_ctrl->val : 0; + temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE); + signal_info.color_space = temp_ctrl ? temp_ctrl->val : 0; + property_id = HAL_PARAM_VENC_VIDEO_SIGNAL_INFO; + pdata = &signal_info; + break; + } default: dprintk(VIDC_ERR, "Unsupported index: %x\n", ctrl->id); rc = -ENOTSUPP; @@ -3114,10 +3213,6 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) } hdev = inst->core->device; - if (msm_vidc_vpe_csc_601_to_709) { - msm_venc_set_csc(inst); - } - if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { fmt = msm_comm_get_pixel_fmt_fourcc(venc_formats, ARRAY_SIZE(venc_formats), f->fmt.pix_mp.pixelformat, diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c index 86965a8ad469e..d6860109f2fbf 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c @@ -80,6 +80,8 @@ const char *const mpeg_video_vidc_extradata[] = { "Extradata output crop", "Extradata display colour SEI", "Extradata light level SEI", + "Extradata display VUI", + "Extradata vpx color space", }; struct getprop_buf { @@ -113,7 +115,6 @@ static inline bool is_non_realtime_session(struct msm_vidc_inst *inst) rc = v4l2_g_ctrl(&inst->ctrl_handler, &ctrl); return (!rc && ctrl.value); } - enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst) { if (inst->session_type == MSM_VIDC_DECODER) { @@ -4321,6 +4322,12 @@ enum hal_extradata_id msm_comm_get_hal_extradata_index( case V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI: ret = HAL_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI; break; + case V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY: + ret = HAL_EXTRADATA_VUI_DISPLAY_INFO; + break; + case V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE: + ret = HAL_EXTRADATA_VPX_COLORSPACE; + break; default: dprintk(VIDC_WARN, "Extradata not found: %d\n", index); break; diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c index b0bda5de403fa..509ea440cf6e8 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c @@ -23,7 +23,6 @@ int msm_fw_debug_mode = 0x1; int msm_fw_low_power_mode = 0x1; int msm_vidc_hw_rsp_timeout = 1000; u32 msm_fw_coverage = 0x0; -int msm_vidc_vpe_csc_601_to_709 = 0x0; int msm_vidc_dcvs_mode = 0x1; int msm_vidc_sys_idle_indicator = 0x0; u32 msm_vidc_firmware_unload_delay = 15000; @@ -183,11 +182,6 @@ struct dentry *msm_vidc_debugfs_init_drv(void) dprintk(VIDC_ERR, "debugfs_create_file: fail\n"); goto failed_create_dir; } - if (!debugfs_create_bool("enable_vpe_csc_601_709", S_IRUGO | S_IWUSR, - dir, &msm_vidc_vpe_csc_601_to_709)) { - dprintk(VIDC_ERR, "debugfs_create_file: fail\n"); - goto failed_create_dir; - } if (!debugfs_create_bool("sys_idle_indicator", S_IRUGO | S_IWUSR, dir, &msm_vidc_sys_idle_indicator)) { dprintk(VIDC_ERR, diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.h b/drivers/media/platform/msm/vidc/vidc_hfi.h index 484a4980882b8..073985edc97b8 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi.h @@ -86,6 +86,7 @@ #define HFI_EXTRADATA_STREAM_USERDATA 0x0000000E #define HFI_EXTRADATA_FRAME_QP 0x0000000F #define HFI_EXTRADATA_FRAME_BITS_INFO 0x00000010 +#define HFI_EXTRADATA_VPX_COLORSPACE 0x00000014 #define HFI_EXTRADATA_MULTISLICE_INFO 0x7F100000 #define HFI_EXTRADATA_NUM_CONCEALED_MB 0x7F100001 #define HFI_EXTRADATA_INDEX 0x7F100002 @@ -217,6 +218,8 @@ struct hfi_extradata_header { (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x019) #define HFI_PROPERTY_PARAM_VDEC_SCS_THRESHOLD \ (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x01A) +#define HFI_PROPERTY_PARAM_VUI_DISPLAY_INFO_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x01B) #define HFI_PROPERTY_PARAM_VDEC_VPX_COLORSPACE_EXTRADATA \ (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001D) #define HFI_PROPERTY_PARAM_VDEC_MASTERING_DISPLAY_COLOUR_SEI_EXTRADATA \ diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h index abb5e9c1437e7..6c3bab17fa560 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h @@ -116,6 +116,8 @@ enum hal_extradata_id { HAL_EXTRADATA_METADATA_MBI, HAL_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI, HAL_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI, + HAL_EXTRADATA_VUI_DISPLAY_INFO, + HAL_EXTRADATA_VPX_COLORSPACE, }; enum hal_property { @@ -218,6 +220,7 @@ enum hal_property { HAL_PARAM_VENC_HIER_B_MAX_ENH_LAYERS, HAL_PARAM_VDEC_NON_SECURE_OUTPUT2, HAL_PARAM_VENC_HIER_P_HYBRID_MODE, + HAL_PARAM_VENC_VIDEO_SIGNAL_INFO, }; enum hal_domain { @@ -948,6 +951,13 @@ struct hal_vpe_color_space_conversion { u32 csc_limit[HAL_MAX_LIMIT_COEFFS]; }; +struct hal_video_signal_info { + u32 color_space; + u32 transfer_chars; + u32 matrix_coeffs; + bool full_range; +}; + enum vidc_resource_id { VIDC_RESOURCE_OCMEM = 0x00000001, VIDC_UNUSED_RESORUCE = 0x10000000, diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h index e6b58a0986737..8b981bd1578f2 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h @@ -338,7 +338,7 @@ struct hfi_buffer_info { (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01B) #define HFI_PROPERTY_PARAM_VENC_LTRMODE \ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01C) -#define HFI_PROPERTY_PARAM_VENC_VIDEO_FULL_RANGE \ +#define HFI_PROPERTY_PARAM_VENC_VIDEO_SIGNAL_INFO \ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01D) #define HFI_PROPERTY_PARAM_VENC_H264_VUI_TIMING_INFO \ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01E) @@ -626,6 +626,16 @@ struct hfi_frame_size { u32 height; }; +struct hfi_video_signal_metadata { + u32 enable; + u32 video_format; + u32 video_full_range; + u32 color_description; + u32 color_primaries; + u32 transfer_characteristics; + u32 matrix_coeffs; +}; + struct hfi_h264_vui_timing_info { u32 enable; u32 fixed_frame_rate; diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index b95df76d5c17a..d34305d791aa6 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -745,6 +745,12 @@ enum v4l2_mpeg_vidc_extradata { #define V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI \ V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI = 27, +#define V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY \ + V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY + V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY = 28, +#define V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE \ + V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE + V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE = 29, }; #define V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL (V4L2_CID_MPEG_MSM_VIDC_BASE + 26) @@ -1009,6 +1015,23 @@ enum v4l2_mpeg_vidc_video_priority { #define V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 75) +#define V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 80) + +#define V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 81) + +enum v4l2_cid_mpeg_vidc_video_full_range { + V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE_DISABLE = 0, + V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE_ENABLE = 1, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 82) + +#define V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 83) + /* Camera class control IDs */ #define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) diff --git a/include/uapi/media/msm_vidc.h b/include/uapi/media/msm_vidc.h index e1e8d3b6335a8..2fda501aa0042 100644 --- a/include/uapi/media/msm_vidc.h +++ b/include/uapi/media/msm_vidc.h @@ -43,6 +43,19 @@ struct msm_vidc_mpeg2_seqdisp_payload { unsigned int disp_width; unsigned int disp_height; }; + +struct msm_vidc_vc1_seqdisp_payload { + unsigned int prog_seg_format; + unsigned int uv_sampl_fmt; + unsigned int color_format; + unsigned int color_primaries; + unsigned int transfer_char; + unsigned int matrix_coeffs; + unsigned int aspect_ratio; + unsigned int aspect_horiz; + unsigned int aspect_vert; +}; + struct msm_vidc_input_crop_payload { unsigned int size; unsigned int version; @@ -109,6 +122,13 @@ struct msm_vidc_s3d_frame_packing_payload { unsigned int fpa_extension_flag; }; +struct msm_vidc_vpx_colorspace_payload { + unsigned int color_space; + unsigned int yuv_range_flag; + unsigned int sumsampling_x; + unsigned int sumsampling_y; +}; + struct msm_vidc_mastering_display_colour_sei_payload { unsigned int nDisplayPrimariesX[3]; unsigned int nDisplayPrimariesY[3]; @@ -123,6 +143,23 @@ struct msm_vidc_content_light_level_sei_payload { unsigned int nMaxPicAverageLight; }; +struct msm_vidc_vui_display_info_payload { + unsigned int video_signal_present_flag; + unsigned int video_format; + unsigned int bit_depth_y; + unsigned int bit_depth_c; + unsigned int video_full_range_flag; + unsigned int color_description_present_flag; + unsigned int color_primaries; + unsigned int transfer_characteristics; + unsigned int matrix_coefficients; + unsigned int chroma_location_info_present_flag; + unsigned int chroma_format_idc; + unsigned int separate_color_plane_flag; + unsigned int chroma_sample_loc_type_top_field; + unsigned int chroma_sample_loc_type_bottom_field; +}; + enum msm_vidc_extradata_type { MSM_VIDC_EXTRADATA_NONE = 0x00000000, MSM_VIDC_EXTRADATA_MB_QUANTIZATION = 0x00000001, @@ -146,6 +183,9 @@ enum msm_vidc_extradata_type { MSM_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI = 0x00000016, MSM_VIDC_EXTRADATA_INPUT_CROP = 0x0700000E, MSM_VIDC_EXTRADATA_DIGITAL_ZOOM = 0x07000010, +#define MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO \ + MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO + MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO = 0x070000011, MSM_VIDC_EXTRADATA_MULTISLICE_INFO = 0x7F100000, MSM_VIDC_EXTRADATA_NUM_CONCEALED_MB = 0x7F100001, MSM_VIDC_EXTRADATA_INDEX = 0x7F100002, @@ -153,6 +193,9 @@ enum msm_vidc_extradata_type { MSM_VIDC_EXTRADATA_METADATA_LTR = 0x7F100004, MSM_VIDC_EXTRADATA_METADATA_FILLER = 0x7FE00002, MSM_VIDC_EXTRADATA_METADATA_MBI = 0x7F100005, +#define MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO \ + MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO + MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO = 0x7F100006, }; enum msm_vidc_interlace_type { MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE = 0x01, @@ -171,4 +214,79 @@ enum msm_vidc_userdata_type { MSM_VIDC_USERDATA_TYPE_TOP_FIELD = 0x2, MSM_VIDC_USERDATA_TYPE_BOTTOM_FIELD = 0x3, }; +/* See colour_primaries of ISO/IEC 14496 for significance */ +enum msm_vidc_h264_color_primaries_values { + MSM_VIDC_RESERVED_1 = 0, + MSM_VIDC_BT709_5 = 1, + MSM_VIDC_UNSPECIFIED = 2, + MSM_VIDC_RESERVED_2 = 3, + MSM_VIDC_BT470_6_M = 4, + MSM_VIDC_BT601_6_625 = 5, + MSM_VIDC_BT470_6_BG = MSM_VIDC_BT601_6_625, + MSM_VIDC_BT601_6_525 = 6, + MSM_VIDC_SMPTE_240M = 7, + MSM_VIDC_GENERIC_FILM = 8, + MSM_VIDC_BT2020 = 9, +}; + +enum msm_vidc_vp9_color_primaries_values { + MSM_VIDC_CS_UNKNOWN, + MSM_VIDC_CS_BT_601, + MSM_VIDC_CS_BT_709, + MSM_VIDC_CS_SMPTE_170, + MSM_VIDC_CS_SMPTE_240, + MSM_VIDC_CS_BT_2020, + MSM_VIDC_CS_RESERVED, + MSM_VIDC_CS_RGB, +}; + +enum msm_vidc_h264_matrix_coeff_values { + MSM_VIDC_MATRIX_RGB = 0, + MSM_VIDC_MATRIX_BT_709_5 = 1, + MSM_VIDC_MATRIX_UNSPECIFIED = 2, + MSM_VIDC_MATRIX_RESERVED = 3, + MSM_VIDC_MATRIX_FCC_47 = 4, + MSM_VIDC_MATRIX_601_6_625 = 5, + MSM_VIDC_MATRIX_BT470_BG = MSM_VIDC_MATRIX_601_6_625, + MSM_VIDC_MATRIX_601_6_525 = 6, + MSM_VIDC_MATRIX_SMPTE_170M = MSM_VIDC_MATRIX_601_6_525, + MSM_VIDC_MATRIX_SMPTE_240M = 7, + MSM_VIDC_MATRIX_Y_CG_CO = 8, + MSM_VIDC_MATRIX_BT_2020 = 9, + MSM_VIDC_MATRIX_BT_2020_CONST = 10, +}; + +enum msm_vidc_h264_transfer_chars_values { + MSM_VIDC_TRANSFER_RESERVED_1 = 0, + MSM_VIDC_TRANSFER_BT709_5 = 1, + MSM_VIDC_TRANSFER_UNSPECIFIED = 2, + MSM_VIDC_TRANSFER_RESERVED_2 = 3, + MSM_VIDC_TRANSFER_BT_470_6_M = 4, + MSM_VIDC_TRANSFER_BT_470_6_BG = 5, + MSM_VIDC_TRANSFER_601_6_625 = 6, + MSM_VIDC_TRANSFER_601_6_525 = MSM_VIDC_TRANSFER_601_6_625, + MSM_VIDC_TRANSFER_SMPTE_240M = 7, + MSM_VIDC_TRANSFER_LINEAR = 8, + MSM_VIDC_TRANSFER_LOG_100_1 = 9, + MSM_VIDC_TRANSFER_LOG_100_SQRT10_1 = 10, + MSM_VIDC_TRANSFER_IEC_61966 = 11, + MSM_VIDC_TRANSFER_BT_1361 = 12, + MSM_VIDC_TRANSFER_SRGB = 13, + MSM_VIDC_TRANSFER_BT_2020_10 = 14, + MSM_VIDC_TRANSFER_BT_2020_12 = 15, +}; +enum msm_vidc_video_format { + MSM_VIDC_COMPONENT, + MSM_VIDC_PAL, + MSM_VIDC_NTSC, + MSM_VIDC_SECAM, + MSM_VIDC_MAC, + MSM_VIDC_UNSPECIFIED_FORMAT, + MSM_VIDC_RESERVED_1_FORMAT, + MSM_VIDC_RESERVED_2_FORMAT, +}; +enum msm_vidc_color_desc_flag { + MSM_VIDC_COLOR_DESC_NOT_PRESENT, + MSM_VIDC_COLOR_DESC_PRESENT, +}; #endif From f57531aa9a49137e07488e53cf9269449426ce20 Mon Sep 17 00:00:00 2001 From: Arun Menon Date: Mon, 14 Dec 2015 15:02:06 -0800 Subject: [PATCH 305/320] msm: vidc: Add control to set csc coefficients to firmware. A new v4l2 control V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC is added, to allow v4l2 driver client to enable setting of color space coefficients to firmware. Change-Id: Ib434f3e45f3ee8bb265be7b402da3ef16e682dbe Signed-off-by: Arun Menon Signed-off-by: Pradosh Das --- drivers/media/platform/msm/vidc/msm_venc.c | 20 +++++++++++++++++++- include/uapi/linux/v4l2-controls.h | 8 ++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c index eed2263440efe..6dc51242e8236 100644 --- a/drivers/media/platform/msm/vidc/msm_venc.c +++ b/drivers/media/platform/msm/vidc/msm_venc.c @@ -1099,6 +1099,15 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .step = 1, .qmenu = NULL, }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC, + .name = "Set VPE Color space conversion coefficients", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_DISABLE, + .maximum = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE, + .default_value = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_DISABLE, + .step = 1, + }, }; @@ -1180,6 +1189,8 @@ static struct msm_vidc_format venc_formats[] = { }, }; +static int msm_venc_set_csc(struct msm_vidc_inst *inst); + static int msm_venc_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, unsigned int *num_buffers, @@ -2773,6 +2784,13 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) pdata = &signal_info; break; } + case V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC: + if (ctrl->val == V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE) { + rc = msm_venc_set_csc(inst); + if (rc) + dprintk(VIDC_ERR, "fail to set csc: %d\n", rc); + } + break; default: dprintk(VIDC_ERR, "Unsupported index: %x\n", ctrl->id); rc = -ENOTSUPP; @@ -3170,7 +3188,7 @@ int msm_venc_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a) return rc; } -int msm_venc_set_csc(struct msm_vidc_inst *inst) +static int msm_venc_set_csc(struct msm_vidc_inst *inst) { int rc = 0; int count = 0; diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index d34305d791aa6..2803a2cd4ca45 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -1032,6 +1032,14 @@ enum v4l2_cid_mpeg_vidc_video_full_range { #define V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 83) +#define V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 87) + +enum v4l2_cid_mpeg_vidc_video_vpe_csc_type_enable { + V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_DISABLE = 0, + V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE = 1 +}; + /* Camera class control IDs */ #define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) From f90d04f749e3cb353562d85fc6143e4ce7d4e046 Mon Sep 17 00:00:00 2001 From: Arun Menon Date: Wed, 30 Mar 2016 16:55:40 -0700 Subject: [PATCH 306/320] msm: vidc: Set constrained intra refresh property If Intra Refresh mode is enabled during encode, then enable constrained intra refresh property on firmware. Without constrained intra refresh enabled, Intra Refresh mode will not be effective CRs-Fixed: 1001217 Change-Id: Id326c73f78f3fadb5193a1e840f295d764fb013b Signed-off-by: Arun Menon Signed-off-by: Paras Nagda Signed-off-by: Sanjay Singh Signed-off-by: Pradosh Das --- .../platform/msm/vidc/hfi_packetization.c | 18 +++++++++++++ drivers/media/platform/msm/vidc/msm_venc.c | 26 +++++++++++++++++-- .../media/platform/msm/vidc/vidc_hfi_api.h | 3 ++- .../media/platform/msm/vidc/vidc_hfi_helper.h | 4 ++- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c index b6ae43a718b6d..d3d32b4339163 100644 --- a/drivers/media/platform/msm/vidc/hfi_packetization.c +++ b/drivers/media/platform/msm/vidc/hfi_packetization.c @@ -176,6 +176,16 @@ static inline u32 get_hfi_codec(enum hal_video_codec hal_codec) return hfi_codec; } +static void create_pkt_enable(void *pkt, u32 type, bool enable) +{ + u32 *pkt_header = pkt; + u32 *pkt_type = &pkt_header[0]; + struct hfi_enable *hfi_enable = (struct hfi_enable *)&pkt_header[1]; + + *pkt_type = type; + hfi_enable->enable = enable; +} + int create_pkt_cmd_sys_init(struct hfi_cmd_sys_init_packet *pkt, u32 arch_type) { @@ -1931,6 +1941,14 @@ int create_pkt_cmd_session_set_property( pkt->size += sizeof(u32) + sizeof(*signal_info); break; } + case HAL_PARAM_VENC_CONSTRAINED_INTRA_PRED: + { + create_pkt_enable(pkt->rg_property_data, + HFI_PROPERTY_PARAM_VENC_CONSTRAINED_INTRA_PRED, + ((struct hal_enable *)pdata)->enable); + pkt->size += sizeof(u32) + sizeof(struct hfi_enable); + break; + } /* FOLLOWING PROPERTIES ARE NOT IMPLEMENTED IN CORE YET */ case HAL_CONFIG_BUFFER_REQUIREMENTS: case HAL_CONFIG_PRIORITY: diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c index 6dc51242e8236..4ec50e3b1d4c7 100644 --- a/drivers/media/platform/msm/vidc/msm_venc.c +++ b/drivers/media/platform/msm/vidc/msm_venc.c @@ -2376,12 +2376,34 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) } case V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE: { struct v4l2_ctrl *air_mbs, *air_ref, *cir_mbs; + bool is_cont_intra_supported = false; + air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS); air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF); cir_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS); - property_id = - HAL_PARAM_VENC_INTRA_REFRESH; + is_cont_intra_supported = + (inst->fmts[CAPTURE_PORT]->fourcc == V4L2_PIX_FMT_H264) || + (inst->fmts[CAPTURE_PORT]->fourcc == V4L2_PIX_FMT_HEVC); + + if (is_cont_intra_supported) { + if (air_mbs || air_ref || cir_mbs) + enable.enable = true; + else + enable.enable = false; + + rc = call_hfi_op(hdev, session_set_property, + (void *)inst->session, + HAL_PARAM_VENC_CONSTRAINED_INTRA_PRED, &enable); + if (rc) { + dprintk(VIDC_ERR, + "Failed to set constrained intra\n"); + rc = -EINVAL; + break; + } + } + + property_id = HAL_PARAM_VENC_INTRA_REFRESH; intra_refresh.mode = ctrl->val; intra_refresh.air_mbs = air_mbs->val; diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h index 6c3bab17fa560..323c4380e59cb 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -221,6 +221,7 @@ enum hal_property { HAL_PARAM_VDEC_NON_SECURE_OUTPUT2, HAL_PARAM_VENC_HIER_P_HYBRID_MODE, HAL_PARAM_VENC_VIDEO_SIGNAL_INFO, + HAL_PARAM_VENC_CONSTRAINED_INTRA_PRED, }; enum hal_domain { diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h index 8b981bd1578f2..13ed39410a660 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -358,6 +358,8 @@ struct hfi_buffer_info { (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x028) #define HFI_PROPERTY_PARAM_VENC_VPX_ERROR_RESILIENCE_MODE \ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x029) +#define HFI_PROPERTY_PARAM_VENC_CONSTRAINED_INTRA_PRED \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x02B) #define HFI_PROPERTY_PARAM_VENC_HIER_B_MAX_NUM_ENH_LAYER \ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x02C) #define HFI_PROPERTY_PARAM_VENC_HIER_P_HYBRID_MODE \ From 5cd2df10566ef781ee141316c1e7e23a692fd16d Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 23 Feb 2016 11:03:12 +0000 Subject: [PATCH 307/320] KEYS: Fix ASN.1 indefinite length object parsing This fixes CVE-2016-0758. In the ASN.1 decoder, when the length field of an ASN.1 value is extracted, it isn't validated against the remaining amount of data before being added to the cursor. With a sufficiently large size indicated, the check: datalen - dp < 2 may then fail due to integer overflow. Fix this by checking the length indicated against the amount of remaining data in both places a definite length is determined. Whilst we're at it, make the following changes: (1) Check the maximum size of extended length does not exceed the capacity of the variable it's being stored in (len) rather than the type that variable is assumed to be (size_t). (2) Compare the EOC tag to the symbolic constant ASN1_EOC rather than the integer 0. (3) To reduce confusion, move the initialisation of len outside of: for (len = 0; n > 0; n--) { since it doesn't have anything to do with the loop counter n. Change-Id: I49fe166717b765b50d49403cf697db11b8792d9c Signed-off-by: David Howells Reviewed-by: Mimi Zohar Acked-by: David Woodhouse Acked-by: Peter Jones Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Git-commit: 23c8a812dc3c621009e4f0e5342aa4e2ede1ceaa Signed-off-by: Ravi Kumar Siddojigari --- lib/asn1_decoder.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/asn1_decoder.c b/lib/asn1_decoder.c index 3787d02e2c49e..b1c885297113f 100644 --- a/lib/asn1_decoder.c +++ b/lib/asn1_decoder.c @@ -69,7 +69,7 @@ static int asn1_find_indefinite_length(const unsigned char *data, size_t datalen /* Extract a tag from the data */ tag = data[dp++]; - if (tag == 0) { + if (tag == ASN1_EOC) { /* It appears to be an EOC. */ if (data[dp++] != 0) goto invalid_eoc; @@ -91,10 +91,8 @@ static int asn1_find_indefinite_length(const unsigned char *data, size_t datalen /* Extract the length */ len = data[dp++]; - if (len <= 0x7f) { - dp += len; - goto next_tag; - } + if (len <= 0x7f) + goto check_length; if (unlikely(len == ASN1_INDEFINITE_LENGTH)) { /* Indefinite length */ @@ -105,14 +103,18 @@ static int asn1_find_indefinite_length(const unsigned char *data, size_t datalen } n = len - 0x80; - if (unlikely(n > sizeof(size_t) - 1)) + if (unlikely(n > sizeof(len) - 1)) goto length_too_long; if (unlikely(n > datalen - dp)) goto data_overrun_error; - for (len = 0; n > 0; n--) { + len = 0; + for (; n > 0; n--) { len <<= 8; len |= data[dp++]; } +check_length: + if (len > datalen - dp) + goto data_overrun_error; dp += len; goto next_tag; From 1b7e41748fc3252e1cc5869553ef162569e62a02 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Wed, 17 Aug 2016 16:00:08 -0700 Subject: [PATCH 308/320] binder: prevent kptr leak by using %pK format specifier Works in conjunction with kptr_restrict. Bug: 30143283 Change-Id: I2b3ce22f4e206e74614d51453a1d59b7080ab05a Git-repo: https://android.googlesource.com/kernel/msm.git Git-commit: b884cbf06200b18e660514a30293931a61126ef5 Signed-off-by: Dennis Cagle --- drivers/staging/android/binder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index 54a03af218573..40c20bc49d01d 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -3273,7 +3273,7 @@ static void print_binder_node(struct seq_file *m, struct binder_node *node) static void print_binder_ref(struct seq_file *m, struct binder_ref *ref) { - seq_printf(m, " ref %d: desc %d %snode %d s %d w %d d %p\n", + seq_printf(m, " ref %d: desc %d %snode %d s %d w %d d %pK\n", ref->debug_id, ref->desc, ref->node->proc ? "" : "dead ", ref->node->debug_id, ref->strong, ref->weak, ref->death); } From a6febd79cf71bf9510467d4b78921b800c054d21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Fri, 12 Aug 2016 16:04:28 -0700 Subject: [PATCH 309/320] ANDROID: binder: Clear binder and cookie when setting handle in flat binder struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevents leaking pointers between processes BUG: 30768347 Change-Id: Id898076926f658a1b8b27a3ccb848756b36de4ca Signed-off-by: Arve Hjønnevåg Git-repo: https://android.googlesource.com/kernel/msm.git Git-commit: 11032d745836280574827bb1db5e64a94945180e Signed-off-by: Dennis Cagle --- drivers/staging/android/binder.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index 54a03af218573..74dddfa828416 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -1559,7 +1559,9 @@ static void binder_transaction(struct binder_proc *proc, fp->type = BINDER_TYPE_HANDLE; else fp->type = BINDER_TYPE_WEAK_HANDLE; + fp->binder = 0; fp->handle = ref->desc; + fp->cookie = 0; binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE, &thread->todo); @@ -1603,7 +1605,9 @@ static void binder_transaction(struct binder_proc *proc, return_error = BR_FAILED_REPLY; goto err_binder_get_ref_for_node_failed; } + fp->binder = 0; fp->handle = new_ref->desc; + fp->cookie = 0; binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL); trace_binder_transaction_ref_to_ref(t, ref, new_ref); @@ -1655,6 +1659,7 @@ static void binder_transaction(struct binder_proc *proc, binder_debug(BINDER_DEBUG_TRANSACTION, " fd %d -> %d\n", fp->handle, target_fd); /* TODO: fput? */ + fp->binder = 0; fp->handle = target_fd; } break; From 74a7949bf2fc269f1fc61c6831d537e7a688d0fe Mon Sep 17 00:00:00 2001 From: Walter Yang Date: Wed, 28 Sep 2016 20:11:23 +0800 Subject: [PATCH 310/320] ASoC: msm: lock read/write when add/free audio ion memory As read/write get access to ion memory region as well, it's necessary to lock them when ion memory is about to be added/freed to avoid racing cases. CRs-Fixed: 1071809 Change-Id: I436ead23c93384961b38ca99b9312a40c50ad03a Signed-off-by: Walter Yang --- drivers/misc/qcom/qdsp6v2/audio_utils_aio.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c index 725e912265fb5..90a7203b087d8 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c @@ -571,6 +571,8 @@ int audio_aio_release(struct inode *inode, struct file *file) struct q6audio_aio *audio = file->private_data; pr_debug("%s[%p]\n", __func__, audio); mutex_lock(&audio->lock); + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); audio->wflush = 1; if (audio->enabled) audio_aio_flush(audio); @@ -585,6 +587,8 @@ int audio_aio_release(struct inode *inode, struct file *file) wake_up(&audio->event_wait); audio_aio_reset_event_queue(audio); q6asm_audio_client_free(audio->ac); + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); mutex_unlock(&audio->lock); mutex_destroy(&audio->lock); mutex_destroy(&audio->read_lock); @@ -1700,7 +1704,11 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, __func__); rc = -EFAULT; } else { + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); rc = audio_aio_ion_add(audio, &info); + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); } mutex_unlock(&audio->lock); break; @@ -1715,7 +1723,11 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, __func__); rc = -EFAULT; } else { + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); rc = audio_aio_ion_remove(audio, &info); + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); } mutex_unlock(&audio->lock); break; @@ -2037,7 +2049,11 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, } else { info.fd = info_32.fd; info.vaddr = compat_ptr(info_32.vaddr); + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); rc = audio_aio_ion_add(audio, &info); + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); } mutex_unlock(&audio->lock); break; @@ -2054,7 +2070,11 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, } else { info.fd = info_32.fd; info.vaddr = compat_ptr(info_32.vaddr); + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); rc = audio_aio_ion_remove(audio, &info); + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); } mutex_unlock(&audio->lock); break; From 4bfa640e9fdaccd50d57d47894d4e5f2b51164d3 Mon Sep 17 00:00:00 2001 From: "Suzuki K. Poulose" Date: Tue, 17 Mar 2015 18:14:58 +0000 Subject: [PATCH 311/320] ARM: perf: reject groups spanning multiple hardware PMUs The perf core implicitly rejects events spanning multiple HW PMUs, as in these cases the event->ctx will differ. However this validation is performed after pmu::event_init() is called in perf_init_event(), and thus pmu::event_init() may be called with a group leader from a different HW PMU. The ARM PMU driver does not take this fact into account, and when validating groups assumes that it can call to_arm_pmu(event->pmu) for any HW event. When the event in question is from another HW PMU this is wrong, and results in dereferencing garbage. This patch updates the ARM PMU driver to first test for and reject events from other PMUs, moving the to_arm_pmu and related logic after this test. Fixes a crash triggered by perf_fuzzer on Linux-4.0-rc2, with a CCI PMU present: --- CPU: 0 PID: 1527 Comm: perf_fuzzer Not tainted 4.0.0-rc2 #57 Hardware name: ARM-Versatile Express task: bd8484c0 ti: be676000 task.ti: be676000 PC is at 0xbf1bbc90 LR is at validate_event+0x34/0x5c pc : [] lr : [<80016060>] psr: 00000013 ... [<80016060>] (validate_event) from [<80016198>] (validate_group+0x28/0x90) [<80016198>] (validate_group) from [<80016398>] (armpmu_event_init+0x150/0x218) [<80016398>] (armpmu_event_init) from [<800882e4>] (perf_try_init_event+0x30/0x48) [<800882e4>] (perf_try_init_event) from [<8008f544>] (perf_init_event+0x5c/0xf4) [<8008f544>] (perf_init_event) from [<8008f8a8>] (perf_event_alloc+0x2cc/0x35c) [<8008f8a8>] (perf_event_alloc) from [<8009015c>] (SyS_perf_event_open+0x498/0xa70) [<8009015c>] (SyS_perf_event_open) from [<8000e420>] (ret_fast_syscall+0x0/0x34) Code: bf1be000 bf1bb380 802a2664 00000000 (00000002) ---[ end trace 01aff0ff00926a0a ]--- Also cleans up the code to use the arm_pmu only when we know that we are dealing with an arm pmu event. Cc: Will Deacon Acked-by: Mark Rutland Acked-by: Peter Ziljstra (Intel) Signed-off-by: Suzuki K. Poulose Signed-off-by: Will Deacon Git-commit: e429817b401f095ac483fcb02524b01faf45dad6 Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git Change-Id: I3b9a0078f7a4cd5370ed177c8bd1438c09425eb4 Signed-off-by: Patrick Fay [spathi@codeaurora.org: resolved trivial merge conflicts] Signed-off-by: Srinivasarao P --- arch/arm/kernel/perf_event.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index a0c1e318a7905..2914c69f2fa09 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -272,21 +272,30 @@ armpmu_add(struct perf_event *event, int flags) } static int -validate_event(struct pmu_hw_events *hw_events, - struct perf_event *event) +validate_event(struct pmu *pmu, struct pmu_hw_events *hw_events, + struct perf_event *event) { - struct arm_pmu *armpmu = to_arm_pmu(event->pmu); + struct arm_pmu *armpmu; struct pmu *leader_pmu = event->group_leader->pmu; if (is_software_event(event)) return 1; - if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF) + /* + * Reject groups spanning multiple HW PMUs (e.g. CPU + CCI). The + * core perf code won't check that the pmu->ctx == leader->ctx + * until after pmu->event_init(event). + */ + if (event->pmu != pmu) + return 0; + + if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF) return 1; if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec) return 1; + armpmu = to_arm_pmu(event->pmu); return armpmu->get_event_idx(hw_events, event) >= 0; } @@ -304,15 +313,15 @@ validate_group(struct perf_event *event) memset(fake_used_mask, 0, sizeof(fake_used_mask)); fake_pmu.used_mask = fake_used_mask; - if (!validate_event(&fake_pmu, leader)) + if (!validate_event(event->pmu, &fake_pmu, leader)) return -EINVAL; list_for_each_entry(sibling, &leader->sibling_list, group_entry) { - if (!validate_event(&fake_pmu, sibling)) + if (!validate_event(event->pmu, &fake_pmu, sibling)) return -EINVAL; } - if (!validate_event(&fake_pmu, event)) + if (!validate_event(event->pmu, &fake_pmu, event)) return -EINVAL; return 0; From a0476ebf79f46e7268ddf2f86866bb90c8bc3e76 Mon Sep 17 00:00:00 2001 From: Vinayak Menon Date: Mon, 17 Oct 2016 11:28:55 +0530 Subject: [PATCH 312/320] ARM: dts: msm: increase apq8016 peripheral_mem size Increase the size of peripheral_mem for apq8016 by 1MB. Change-Id: Iec770d58d97724b5a718d83f337fd0cf486dfbdc Signed-off-by: Vinayak Menon --- arch/arm/boot/dts/qcom/apq8016.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/qcom/apq8016.dtsi b/arch/arm/boot/dts/qcom/apq8016.dtsi index 7fa77b43971f4..b12c41a738e24 100644 --- a/arch/arm/boot/dts/qcom/apq8016.dtsi +++ b/arch/arm/boot/dts/qcom/apq8016.dtsi @@ -27,7 +27,7 @@ }; peripheral_mem: pheripheral_region@0 { - reg = <0x0 0x89300000 0x0 0x0600000>; + reg = <0x0 0x89300000 0x0 0x0700000>; }; }; }; From ae9155fa0c502171711103ef6679b6142b167a85 Mon Sep 17 00:00:00 2001 From: "Suzuki K. Poulose" Date: Tue, 17 Mar 2015 18:14:59 +0000 Subject: [PATCH 313/320] arm64: perf: reject groups spanning multiple HW PMUs The perf core implicitly rejects events spanning multiple HW PMUs, as in these cases the event->ctx will differ. However this validation is performed after pmu::event_init() is called in perf_init_event(), and thus pmu::event_init() may be called with a group leader from a different HW PMU. The ARM64 PMU driver does not take this fact into account, and when validating groups assumes that it can call to_arm_pmu(event->pmu) for any HW event. When the event in question is from another HW PMU this is wrong, and results in dereferencing garbage. This patch updates the ARM64 PMU driver to first test for and reject events from other PMUs, moving the to_arm_pmu and related logic after this test. Fixes a crash triggered by perf_fuzzer on Linux-4.0-rc2, with a CCI PMU present: Bad mode in Synchronous Abort handler detected, code 0x86000006 -- IABT (current EL) CPU: 0 PID: 1371 Comm: perf_fuzzer Not tainted 3.19.0+ #249 Hardware name: V2F-1XV7 Cortex-A53x2 SMM (DT) task: ffffffc07c73a280 ti: ffffffc07b0a0000 task.ti: ffffffc07b0a0000 PC is at 0x0 LR is at validate_event+0x90/0xa8 pc : [<0000000000000000>] lr : [] pstate: 00000145 sp : ffffffc07b0a3ba0 [< (null)>] (null) [] armpmu_event_init+0x174/0x3cc [] perf_try_init_event+0x34/0x70 [] perf_init_event+0xe0/0x10c [] perf_event_alloc+0x288/0x358 [] SyS_perf_event_open+0x464/0x98c Code: bad PC value Also cleans up the code to use the arm_pmu only when we know that we are dealing with an arm pmu event. Cc: Will Deacon Acked-by: Mark Rutland Acked-by: Peter Ziljstra (Intel) Signed-off-by: Suzuki K. Poulose Signed-off-by: Will Deacon Git-commit: 8fff105e13041e49b82f92eef034f363a6b1c071 Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git Change-Id: I2ab941e9936726c6222975bdfc9f98e46284fe25 Signed-off-by: Patrick Fay --- arch/arm64/kernel/perf_event.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 7952914c8fdcc..e6752e48a315f 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -357,22 +357,31 @@ armpmu_add(struct perf_event *event, int flags) } static int -validate_event(struct pmu_hw_events *hw_events, - struct perf_event *event) +validate_event(struct pmu *pmu, struct pmu_hw_events *hw_events, + struct perf_event *event) { - struct arm_pmu *armpmu = to_arm_pmu(event->pmu); + struct arm_pmu *armpmu; struct hw_perf_event fake_event = event->hw; struct pmu *leader_pmu = event->group_leader->pmu; if (is_software_event(event)) return 1; + /* + * Reject groups spanning multiple HW PMUs (e.g. CPU + CCI). The + * core perf code won't check that the pmu->ctx == leader->ctx + * until after pmu->event_init(event). + */ + if (event->pmu != pmu) + return 0; + if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF) return 1; if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec) return 1; + armpmu = to_arm_pmu(event->pmu); return armpmu->get_event_idx(hw_events, &fake_event) >= 0; } @@ -390,15 +399,15 @@ validate_group(struct perf_event *event) memset(fake_used_mask, 0, sizeof(fake_used_mask)); fake_pmu.used_mask = fake_used_mask; - if (!validate_event(&fake_pmu, leader)) + if (!validate_event(event->pmu, &fake_pmu, leader)) return -EINVAL; list_for_each_entry(sibling, &leader->sibling_list, group_entry) { - if (!validate_event(&fake_pmu, sibling)) + if (!validate_event(event->pmu, &fake_pmu, sibling)) return -EINVAL; } - if (!validate_event(&fake_pmu, event)) + if (!validate_event(event->pmu, &fake_pmu, event)) return -EINVAL; return 0; From 1c363ca019751e6e471dbf62e34585f6ad1c9e89 Mon Sep 17 00:00:00 2001 From: Carter Cooper Date: Thu, 17 Sep 2015 12:02:47 -0600 Subject: [PATCH 314/320] msm: kgsl: Verify the pointer isn't NULL before using it for kref Probably overkill, but ensure that the struct pointer we are going to dereference to send into kref calls is valid before we dereference. Change-Id: I308176df9f7476a2a9f1357612381a93160ad698 Signed-off-by: Carter Cooper --- drivers/gpu/msm/kgsl.c | 10 +++++----- drivers/gpu/msm/kgsl.h | 7 +++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index cc0f06c63c798..aaa8cdd5a790e 100755 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1370,16 +1370,15 @@ kgsl_sharedmem_region_empty(struct kgsl_process_private *private, static inline struct kgsl_mem_entry * __must_check kgsl_sharedmem_find_id(struct kgsl_process_private *process, unsigned int id) { - int result = 0; + int result; struct kgsl_mem_entry *entry; spin_lock(&process->mem_lock); entry = idr_find(&process->mem_idr, id); - if (entry) - result = kgsl_mem_entry_get(entry); + result = kgsl_mem_entry_get(entry); spin_unlock(&process->mem_lock); - if (!result) + if (result == 0) return NULL; return entry; } @@ -3937,7 +3936,8 @@ kgsl_mmap_memstore(struct kgsl_device *device, struct vm_area_struct *vma) static void kgsl_gpumem_vm_open(struct vm_area_struct *vma) { struct kgsl_mem_entry *entry = vma->vm_private_data; - if (!kgsl_mem_entry_get(entry)) + + if (kgsl_mem_entry_get(entry) == 0) vma->vm_private_data = NULL; } diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h index 010f8fcb0ac9c..812f5bd40d043 100644 --- a/drivers/gpu/msm/kgsl.h +++ b/drivers/gpu/msm/kgsl.h @@ -397,13 +397,16 @@ static inline int timestamp_cmp(unsigned int a, unsigned int b) static inline int kgsl_mem_entry_get(struct kgsl_mem_entry *entry) { - return kref_get_unless_zero(&entry->refcount); + if (entry) + return kref_get_unless_zero(&entry->refcount); + return 0; } static inline void kgsl_mem_entry_put(struct kgsl_mem_entry *entry) { - kref_put(&entry->refcount, kgsl_mem_entry_destroy); + if (entry) + kref_put(&entry->refcount, kgsl_mem_entry_destroy); } /* From 9fa98324542f9df46ed5fb68f25569feef0a2fa0 Mon Sep 17 00:00:00 2001 From: Ben Romberger Date: Tue, 19 May 2015 16:04:19 -0700 Subject: [PATCH 315/320] ASoC: msm: Add common custom topology interface Add support for a common custom topology interface. Command is sent through q6core driver. All ADSP custom topologies are sent through this new interface. Change-Id: Iac6e5646cf3c4d6c45109c7861f8d22d4fb5f3ba Signed-off-by: Ben Romberger --- include/sound/q6core.h | 71 ++++ include/uapi/linux/msm_audio_calibration.h | 1 + sound/soc/msm/qdsp6v2/audio_cal_utils.c | 2 + sound/soc/msm/qdsp6v2/q6core.c | 418 +++++++++++++++++++-- 4 files changed, 466 insertions(+), 26 deletions(-) diff --git a/include/sound/q6core.h b/include/sound/q6core.h index 83ae16760bd1a..a450723069e60 100644 --- a/include/sound/q6core.h +++ b/include/sound/q6core.h @@ -152,6 +152,77 @@ struct avcs_cmdrsp_get_license_validation_result { /* Length in bytes of the result that follows this structure*/ }; +/* Set Q6 topologies */ +/* + * Registers custom topologies in the aDSP for + * use in audio, voice, AFE and LSM. + */ + + +#define AVCS_CMD_SHARED_MEM_MAP_REGIONS 0x00012924 +#define AVCS_CMDRSP_SHARED_MEM_MAP_REGIONS 0x00012925 +#define AVCS_CMD_SHARED_MEM_UNMAP_REGIONS 0x00012926 + + +#define AVCS_CMD_REGISTER_TOPOLOGIES 0x00012923 + +/* The payload for the AVCS_CMD_REGISTER_TOPOLOGIES command */ +struct avcs_cmd_register_topologies { + struct apr_hdr hdr; + uint32_t payload_addr_lsw; + /* Lower 32 bits of the topology buffer address. */ + + uint32_t payload_addr_msw; + /* Upper 32 bits of the topology buffer address. */ + + uint32_t mem_map_handle; + /* Unique identifier for an address. + * -This memory map handle is returned by the aDSP through the + * memory map command. + * -NULL mem_map_handle is interpreted as in-band parameter + * passing. + * -Client has the flexibility to choose in-band or out-of-band. + * -Out-of-band is recommended in this case. + */ + + uint32_t payload_size; + /* Size in bytes of the valid data in the topology buffer. */ +} __packed; + + +#define AVCS_CMD_DEREGISTER_TOPOLOGIES 0x0001292a + +/* The payload for the AVCS_CMD_DEREGISTER_TOPOLOGIES command */ +struct avcs_cmd_deregister_topologies { + struct apr_hdr hdr; + uint32_t payload_addr_lsw; + /* Lower 32 bits of the topology buffer address. */ + + uint32_t payload_addr_msw; + /* Upper 32 bits of the topology buffer address. */ + + uint32_t mem_map_handle; + /* Unique identifier for an address. + * -This memory map handle is returned by the aDSP through the + * memory map command. + * -NULL mem_map_handle is interpreted as in-band parameter + * passing. + * -Client has the flexibility to choose in-band or out-of-band. + * -Out-of-band is recommended in this case. + */ + + uint32_t payload_size; + /* Size in bytes of the valid data in the topology buffer. */ + + uint32_t mode; + /* 0: Deregister selected topologies + * 1: Deregister all topologies + */ +} __packed; + +#define AVCS_MODE_DEREGISTER_ALL_CUSTOM_TOPOLOGIES 1 + + int32_t core_set_license(uint32_t key, uint32_t module_id); int32_t core_get_license_status(uint32_t module_id); diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h index de24f255dfa5c..990f576c67514 100644 --- a/include/uapi/linux/msm_audio_calibration.h +++ b/include/uapi/linux/msm_audio_calibration.h @@ -90,6 +90,7 @@ enum { AUDIO_CORE_METAINFO_CAL_TYPE, SRS_TRUMEDIA_CAL_TYPE, + CORE_CUSTOM_TOPOLOGIES_CAL_TYPE, MAX_CAL_TYPES, }; diff --git a/sound/soc/msm/qdsp6v2/audio_cal_utils.c b/sound/soc/msm/qdsp6v2/audio_cal_utils.c index 33e5dfc6950c8..c8e754474c3bb 100644 --- a/sound/soc/msm/qdsp6v2/audio_cal_utils.c +++ b/sound/soc/msm/qdsp6v2/audio_cal_utils.c @@ -56,6 +56,7 @@ size_t get_cal_info_size(int32_t cal_type) size = sizeof(struct audio_cal_info_adm_top); break; case ADM_CUST_TOPOLOGY_CAL_TYPE: + case CORE_CUSTOM_TOPOLOGIES_CAL_TYPE: size = 0; break; case ADM_AUDPROC_CAL_TYPE: @@ -174,6 +175,7 @@ size_t get_user_cal_type_size(int32_t cal_type) size = sizeof(struct audio_cal_type_adm_top); break; case ADM_CUST_TOPOLOGY_CAL_TYPE: + case CORE_CUSTOM_TOPOLOGIES_CAL_TYPE: size = sizeof(struct audio_cal_type_basic); break; case ADM_AUDPROC_CAL_TYPE: diff --git a/sound/soc/msm/qdsp6v2/q6core.c b/sound/soc/msm/qdsp6v2/q6core.c index a9ff7e6fe06ec..a5af8b52858e4 100644 --- a/sound/soc/msm/qdsp6v2/q6core.c +++ b/sound/soc/msm/qdsp6v2/q6core.c @@ -33,6 +33,12 @@ */ #define Q6_READY_TIMEOUT_MS 100 +enum { + META_CAL, + CUST_TOP_CAL, + CORE_MAX_CAL +}; + struct q6core_str { struct apr_svc *core_handle_q; wait_queue_head_t bus_bw_req_wait; @@ -50,8 +56,10 @@ struct q6core_str { } cmd_resp_payload; struct avcs_cmd_rsp_get_low_power_segments_info_t lp_ocm_payload; u32 param; - struct cal_type_data *cal_data; u32 q6_core_avs_version; + struct cal_type_data *cal_data[CORE_MAX_CAL]; + uint32_t mem_map_cal_handle; + int32_t adsp_status; }; static struct q6core_str q6core_lcl; @@ -96,6 +104,32 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) pr_info("%s: Cmd = AVCS_CMD_GET_LOW_POWER_SEGMENTS_INFO status[0x%x]\n", __func__, payload1[1]); break; + case AVCS_CMD_SHARED_MEM_UNMAP_REGIONS: + pr_debug("%s: Cmd = AVCS_CMD_SHARED_MEM_UNMAP_REGIONS status[0x%x]\n", + __func__, payload1[1]); + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + break; + case AVCS_CMD_SHARED_MEM_MAP_REGIONS: + pr_debug("%s: Cmd = AVCS_CMD_SHARED_MEM_MAP_REGIONS status[0x%x]\n", + __func__, payload1[1]); + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + break; + case AVCS_CMD_REGISTER_TOPOLOGIES: + pr_debug("%s: Cmd = AVCS_CMD_REGISTER_TOPOLOGIES status[0x%x]\n", + __func__, payload1[1]); + /* -ADSP status to match Linux error standard */ + q6core_lcl.adsp_status = -payload1[1]; + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + break; + case AVCS_CMD_DEREGISTER_TOPOLOGIES: + pr_debug("%s: Cmd = AVCS_CMD_DEREGISTER_TOPOLOGIES status[0x%x]\n", + __func__, payload1[1]); + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + break; default: pr_err("%s: Invalid cmd rsp[0x%x][0x%x] opcode %d\n", __func__, @@ -138,7 +172,14 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) q6core_lcl.core_handle_q = NULL; break; } - + case AVCS_CMDRSP_SHARED_MEM_MAP_REGIONS: + payload1 = data->payload; + pr_debug("%s: AVCS_CMDRSP_SHARED_MEM_MAP_REGIONS handle %d\n", + __func__, payload1[0]); + q6core_lcl.mem_map_cal_handle = payload1[0]; + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + break; case AVCS_CMDRSP_ADSP_EVENT_GET_STATE: payload1 = data->payload; q6core_lcl.param = payload1[0]; @@ -229,16 +270,18 @@ int32_t core_set_license(uint32_t key, uint32_t module_id) pr_debug("%s: key:0x%x, id:0x%x\n", __func__, key, module_id); mutex_lock(&(q6core_lcl.cmd_lock)); - if (q6core_lcl.cal_data == NULL) { + if (q6core_lcl.cal_data[META_CAL] == NULL) { pr_err("%s: cal_data not initialized yet!!\n", __func__); rc = -EINVAL; goto unlock1; } - mutex_lock(&((q6core_lcl.cal_data)->lock)); - cal_block = cal_utils_get_only_cal_block(q6core_lcl.cal_data); - if (cal_block == NULL || cal_block->cal_data.kvaddr == NULL || - cal_block->cal_data.size <= 0) { + mutex_lock(&((q6core_lcl.cal_data[META_CAL])->lock)); + cal_block = + cal_utils_get_only_cal_block(q6core_lcl.cal_data[META_CAL]); + if (cal_block == NULL || + cal_block->cal_data.kvaddr == NULL || + cal_block->cal_data.size <= 0) { pr_err("%s: Invalid cal block to send", __func__); rc = -EINVAL; goto unlock2; @@ -290,7 +333,8 @@ int32_t core_set_license(uint32_t key, uint32_t module_id) cmd_setl->overwrite = 1; cmd_setl->size = cal_block->cal_data.size; memcpy((uint8_t *)cmd_setl + sizeof(struct avcs_cmd_set_license), - cal_block->cal_data.kvaddr, cal_block->cal_data.size); + cal_block->cal_data.kvaddr, + cal_block->cal_data.size); pr_info("%s: Set license opcode=0x%x ,key=0x%x, id =0x%x, size = %d\n", __func__, cmd_setl->hdr.opcode, metainfo->nKey, cmd_setl->id, cmd_setl->size); @@ -302,7 +346,7 @@ int32_t core_set_license(uint32_t key, uint32_t module_id) fail_cmd: kfree(cmd_setl); unlock2: - mutex_unlock(&((q6core_lcl.cal_data)->lock)); + mutex_unlock(&((q6core_lcl.cal_data[META_CAL])->lock)); unlock1: mutex_unlock(&(q6core_lcl.cmd_lock)); @@ -654,35 +698,337 @@ bool q6core_is_adsp_ready(void) return ret; } + +static int q6core_map_memory_regions(phys_addr_t *buf_add, uint32_t mempool_id, + uint32_t *bufsz, uint32_t bufcnt, uint32_t *map_handle) +{ + struct avs_cmd_shared_mem_map_regions *mmap_regions = NULL; + struct avs_shared_map_region_payload *mregions = NULL; + void *mmap_region_cmd = NULL; + void *payload = NULL; + int ret = 0; + int i = 0; + int cmd_size = 0; + + cmd_size = sizeof(struct avs_cmd_shared_mem_map_regions) + + sizeof(struct avs_shared_map_region_payload) + * bufcnt; + + mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL); + if (mmap_region_cmd == NULL) + return -ENOMEM; + + mmap_regions = (struct avs_cmd_shared_mem_map_regions *)mmap_region_cmd; + mmap_regions->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mmap_regions->hdr.pkt_size = cmd_size; + mmap_regions->hdr.src_port = 0; + mmap_regions->hdr.dest_port = 0; + mmap_regions->hdr.token = 0; + mmap_regions->hdr.opcode = AVCS_CMD_SHARED_MEM_MAP_REGIONS; + mmap_regions->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL & 0x00ff; + mmap_regions->num_regions = bufcnt & 0x00ff; + mmap_regions->property_flag = 0x00; + + payload = ((u8 *) mmap_region_cmd + + sizeof(struct avs_cmd_shared_mem_map_regions)); + mregions = (struct avs_shared_map_region_payload *)payload; + + for (i = 0; i < bufcnt; i++) { + mregions->shm_addr_lsw = lower_32_bits(buf_add[i]); + mregions->shm_addr_msw = upper_32_bits(buf_add[i]); + mregions->mem_size_bytes = bufsz[i]; + ++mregions; + } + + pr_debug("%s: sending memory map, addr %pa, size %d, bufcnt = %d\n", + __func__, buf_add, bufsz[0], mmap_regions->num_regions); + + *map_handle = 0; + q6core_lcl.bus_bw_resp_received = 0; + ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) + mmap_regions); + if (ret < 0) { + pr_err("%s: mmap regions failed %d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(q6core_lcl.bus_bw_req_wait, + (q6core_lcl.bus_bw_resp_received == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: timeout. waited for memory map\n", __func__); + ret = -ETIME; + goto done; + } + + *map_handle = q6core_lcl.mem_map_cal_handle; +done: + kfree(mmap_region_cmd); + return ret; +} + +static int q6core_memory_unmap_regions(uint32_t mem_map_handle) +{ + struct avs_cmd_shared_mem_unmap_regions unmap_regions; + int ret = 0; + + memset(&unmap_regions, 0, sizeof(unmap_regions)); + unmap_regions.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + unmap_regions.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(unmap_regions)); + unmap_regions.hdr.src_svc = APR_SVC_ADSP_CORE; + unmap_regions.hdr.src_domain = APR_DOMAIN_APPS; + unmap_regions.hdr.src_port = 0; + unmap_regions.hdr.dest_svc = APR_SVC_ADSP_CORE; + unmap_regions.hdr.dest_domain = APR_DOMAIN_ADSP; + unmap_regions.hdr.dest_port = 0; + unmap_regions.hdr.token = 0; + unmap_regions.hdr.opcode = AVCS_CMD_SHARED_MEM_UNMAP_REGIONS; + unmap_regions.mem_map_handle = mem_map_handle; + + q6core_lcl.bus_bw_resp_received = 0; + + pr_debug("%s: unmap regions map handle %d\n", + __func__, mem_map_handle); + + ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) + &unmap_regions); + if (ret < 0) { + pr_err("%s: unmap regions failed %d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(q6core_lcl.bus_bw_req_wait, + (q6core_lcl.bus_bw_resp_received == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: timeout. waited for memory_unmap\n", + __func__); + ret = -ETIME; + goto done; + } +done: + return ret; +} + +static int q6core_dereg_all_custom_topologies(void) +{ + int ret = 0; + struct avcs_cmd_deregister_topologies dereg_top; + + memset(&dereg_top, 0, sizeof(dereg_top)); + dereg_top.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + dereg_top.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, sizeof(dereg_top)); + dereg_top.hdr.src_svc = APR_SVC_ADSP_CORE; + dereg_top.hdr.src_domain = APR_DOMAIN_APPS; + dereg_top.hdr.src_port = 0; + dereg_top.hdr.dest_svc = APR_SVC_ADSP_CORE; + dereg_top.hdr.dest_domain = APR_DOMAIN_ADSP; + dereg_top.hdr.dest_port = 0; + dereg_top.hdr.token = 0; + dereg_top.hdr.opcode = AVCS_CMD_DEREGISTER_TOPOLOGIES; + dereg_top.payload_addr_lsw = 0; + dereg_top.payload_addr_msw = 0; + dereg_top.mem_map_handle = 0; + dereg_top.payload_size = 0; + dereg_top.mode = AVCS_MODE_DEREGISTER_ALL_CUSTOM_TOPOLOGIES; + + q6core_lcl.bus_bw_resp_received = 0; + + pr_debug("%s: Deregister topologies mode %d\n", + __func__, dereg_top.mode); + + ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) &dereg_top); + if (ret < 0) { + pr_err("%s: Deregister topologies failed %d\n", + __func__, ret); + goto done; + } + + ret = wait_event_timeout(q6core_lcl.bus_bw_req_wait, + (q6core_lcl.bus_bw_resp_received == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout for Deregister topologies\n", + __func__); + goto done; + } +done: + return ret; +} + +static int q6core_send_custom_topologies(void) +{ + int ret = 0; + int ret2 = 0; + struct cal_block_data *cal_block = NULL; + struct avcs_cmd_register_topologies reg_top; + + memset(®_top, 0, sizeof(reg_top)); + mutex_lock(&q6core_lcl.cal_data[CUST_TOP_CAL]->lock); + mutex_lock(&q6core_lcl.cmd_lock); + + cal_block = cal_utils_get_only_cal_block( + q6core_lcl.cal_data[CUST_TOP_CAL]); + if (cal_block == NULL) { + pr_debug("%s: cal block is NULL!\n", __func__); + goto unlock; + } + if (cal_block->cal_data.size <= 0) { + pr_debug("%s: cal size is %zd not sending\n", + __func__, cal_block->cal_data.size); + goto unlock; + } + + if (!q6core_is_adsp_ready()) { + pr_err("%s: ADSP is not ready!\n", __func__); + ret = -ENODEV; + goto unlock; + } + + q6core_dereg_all_custom_topologies(); + + ret = q6core_map_memory_regions(&cal_block->cal_data.paddr, 0, + (uint32_t *)&cal_block->map_data.map_size, 1, + &cal_block->map_data.q6map_handle); + if (!ret) { + pr_err("%s: q6core_map_memory_regions failed\n", __func__); + goto unlock; + } + + reg_top.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + reg_top.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, sizeof(reg_top)); + reg_top.hdr.src_svc = APR_SVC_ADSP_CORE; + reg_top.hdr.src_domain = APR_DOMAIN_APPS; + reg_top.hdr.src_port = 0; + reg_top.hdr.dest_svc = APR_SVC_ADSP_CORE; + reg_top.hdr.dest_domain = APR_DOMAIN_ADSP; + reg_top.hdr.dest_port = 0; + reg_top.hdr.token = 0; + reg_top.hdr.opcode = AVCS_CMD_REGISTER_TOPOLOGIES; + reg_top.payload_addr_lsw = + lower_32_bits(cal_block->cal_data.paddr); + reg_top.payload_addr_msw = + upper_32_bits(cal_block->cal_data.paddr); + reg_top.mem_map_handle = cal_block->map_data.q6map_handle; + reg_top.payload_size = cal_block->cal_data.size; + + q6core_lcl.adsp_status = 0; + q6core_lcl.bus_bw_resp_received = 0; + + pr_debug("%s: Register topologies addr %pa, size %zd, map handle %d\n", + __func__, &cal_block->cal_data.paddr, cal_block->cal_data.size, + cal_block->map_data.q6map_handle); + + ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) ®_top); + if (ret < 0) { + pr_err("%s: Register topologies failed %d\n", + __func__, ret); + goto unmap; + } + + ret = wait_event_timeout(q6core_lcl.bus_bw_req_wait, + (q6core_lcl.bus_bw_resp_received == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout for Register topologies\n", + __func__); + goto unmap; + } + + if (q6core_lcl.adsp_status < 0) + ret = q6core_lcl.adsp_status; +unmap: + ret2 = q6core_memory_unmap_regions(cal_block->map_data.q6map_handle); + if (!ret2) { + pr_err("%s: q6core_memory_unmap_regions failed for map handle %d\n", + __func__, cal_block->map_data.q6map_handle); + ret = ret2; + goto unlock; + } + +unlock: + mutex_unlock(&q6core_lcl.cmd_lock); + mutex_unlock(&q6core_lcl.cal_data[CUST_TOP_CAL]->lock); + + return ret; +} + +static int get_cal_type_index(int32_t cal_type) +{ + int ret = -EINVAL; + + switch (cal_type) { + case AUDIO_CORE_METAINFO_CAL_TYPE: + ret = META_CAL; + break; + case CORE_CUSTOM_TOPOLOGIES_CAL_TYPE: + ret = CUST_TOP_CAL; + break; + default: + pr_err("%s: invalid cal type %d!\n", __func__, cal_type); + } + return ret; +} + static int q6core_alloc_cal(int32_t cal_type, size_t data_size, void *data) { - int ret = 0; - pr_debug("%s:\n", __func__); + int ret = 0; + int cal_index; + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + ret = cal_utils_alloc_cal(data_size, data, - q6core_lcl.cal_data, 0, NULL); + q6core_lcl.cal_data[cal_index], 0, NULL); if (ret < 0) { pr_err("%s: cal_utils_alloc_block failed, ret = %d, cal type = %d!\n", __func__, ret, cal_type); - ret = -EINVAL; + goto done; } +done: return ret; } static int q6core_dealloc_cal(int32_t cal_type, size_t data_size, void *data) { - int ret = 0; - pr_debug("%s:\n", __func__); + int ret = 0; + int cal_index; + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + ret = cal_utils_dealloc_cal(data_size, data, - q6core_lcl.cal_data); + q6core_lcl.cal_data[cal_index]); if (ret < 0) { pr_err("%s: cal_utils_dealloc_block failed, ret = %d, cal type = %d!\n", __func__, ret, cal_type); - ret = -EINVAL; + goto done; } +done: return ret; } @@ -690,15 +1036,28 @@ static int q6core_set_cal(int32_t cal_type, size_t data_size, void *data) { int ret = 0; - pr_debug("%s:\n", __func__); + int cal_index; + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + ret = cal_utils_set_cal(data_size, data, - q6core_lcl.cal_data, 0, NULL); + q6core_lcl.cal_data[cal_index], 0, NULL); if (ret < 0) { pr_err("%s: cal_utils_set_cal failed, ret = %d, cal type = %d!\n", __func__, ret, cal_type); - ret = -EINVAL; + goto done; } + + if (cal_index == CUST_TOP_CAL) + ret = q6core_send_custom_topologies(); +done: return ret; } @@ -706,7 +1065,7 @@ static void q6core_delete_cal_data(void) { pr_debug("%s:\n", __func__); - cal_utils_destroy_cal_types(1, &q6core_lcl.cal_data); + cal_utils_destroy_cal_types(CORE_MAX_CAL, q6core_lcl.cal_data); return; } @@ -714,16 +1073,21 @@ static void q6core_delete_cal_data(void) static int q6core_init_cal_data(void) { int ret = 0; - struct cal_type_info cal_type_info = { - {AUDIO_CORE_METAINFO_CAL_TYPE, + struct cal_type_info cal_type_info[] = { + {{AUDIO_CORE_METAINFO_CAL_TYPE, + {q6core_alloc_cal, q6core_dealloc_cal, NULL, + q6core_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{CORE_CUSTOM_TOPOLOGIES_CAL_TYPE, {q6core_alloc_cal, q6core_dealloc_cal, NULL, q6core_set_cal, NULL, NULL} }, - {NULL, NULL, cal_utils_match_buf_num} + {NULL, NULL, cal_utils_match_buf_num} } }; pr_debug("%s:\n", __func__); - ret = cal_utils_create_cal_types(1, &q6core_lcl.cal_data, - &cal_type_info); + ret = cal_utils_create_cal_types(CORE_MAX_CAL, + q6core_lcl.cal_data, cal_type_info); if (ret < 0) { pr_err("%s: could not create cal type!\n", __func__); @@ -747,6 +1111,8 @@ static int __init core_init(void) init_waitqueue_head(&q6core_lcl.cmd_req_wait); q6core_lcl.cmd_resp_received_flag = FLAG_NONE; mutex_init(&q6core_lcl.cmd_lock); + q6core_lcl.mem_map_cal_handle = 0; + q6core_lcl.adsp_status = 0; if (q6core_init_cal_data()) pr_err("%s: could not init cal data!\n", __func__); From 6f6c1af8e9d5f547f4762b1e1f6a26dd2fae4d84 Mon Sep 17 00:00:00 2001 From: Karthik Reddy Katta Date: Mon, 9 May 2016 14:43:41 +0530 Subject: [PATCH 316/320] msm: Fix failure in deregistering custom topologies AVCS_MODE_DEREGISTER_ALL_CUSTOM_TOPOLOGIES is defined as "1" where as in ADSP the value is "2". Redefine the same to fix the mis-match with ADSP code. CRs-Fixed: 1005434 Change-Id: I210e43b53c6170425ee35c02b728698b33afb591 Signed-off-by: Karthik Reddy Katta --- include/sound/q6core.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/sound/q6core.h b/include/sound/q6core.h index a450723069e60..7d2eeef73a46f 100644 --- a/include/sound/q6core.h +++ b/include/sound/q6core.h @@ -215,12 +215,12 @@ struct avcs_cmd_deregister_topologies { /* Size in bytes of the valid data in the topology buffer. */ uint32_t mode; - /* 0: Deregister selected topologies - * 1: Deregister all topologies + /* 1: Deregister selected topologies + * 2: Deregister all topologies */ } __packed; -#define AVCS_MODE_DEREGISTER_ALL_CUSTOM_TOPOLOGIES 1 +#define AVCS_MODE_DEREGISTER_ALL_CUSTOM_TOPOLOGIES 2 int32_t core_set_license(uint32_t key, uint32_t module_id); From 3a6ac8111a88d8e79df4f17bd348772e279563db Mon Sep 17 00:00:00 2001 From: Surendar karka Date: Fri, 14 Oct 2016 20:14:33 +0530 Subject: [PATCH 317/320] ASoc: msm: Add support for configuring sample rate Add support to configure sample rate from user space and set AFE clock based on sample rate. Change-Id: I479939891b36e119864dce4aaf4325b769f899a3 Signed-off-by: Surendar karka --- sound/soc/msm/msm8x16.c | 83 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 4 deletions(-) diff --git a/sound/soc/msm/msm8x16.c b/sound/soc/msm/msm8x16.c index 99d0d5a22ece8..b79bce05ba9e5 100644 --- a/sound/soc/msm/msm8x16.c +++ b/sound/soc/msm/msm8x16.c @@ -80,6 +80,7 @@ static int msm_btsco_ch = 1; static int msm_mi2s_tx_ch = 2; static int msm_pri_mi2s_rx_ch = 2; static int pri_rx_sample_rate = SAMPLING_RATE_48KHZ; +static int mi2s_tx_sample_rate = SAMPLING_RATE_48KHZ; static int msm_proxy_rx_ch = 2; static int msm8909_auxpcm_rate = 8000; @@ -410,6 +411,9 @@ static const char *const loopback_mclk_text[] = {"DISABLE", "ENABLE"}; static char const *pri_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96", "KHZ_192", "KHZ_8", "KHZ_16", "KHZ_32"}; +static char const *mi2s_tx_sample_rate_text[] = {"KHZ_48", "KHZ_96", + "KHZ_192", "KHZ_8", + "KHZ_16", "KHZ_32"}; static int msm_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) @@ -709,8 +713,9 @@ static int msm_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); - pr_debug("%s(), channel:%d\n", __func__, msm_mi2s_tx_ch); - rate->min = rate->max = 48000; + pr_debug("%s(), channel:%d sample rate %d\n", __func__, + msm_mi2s_tx_ch, mi2s_tx_sample_rate); + rate->min = rate->max = mi2s_tx_sample_rate; channels->min = channels->max = msm_mi2s_tx_ch; return 0; @@ -796,6 +801,68 @@ static int pri_rx_sample_rate_put(struct snd_kcontrol *kcontrol, return 0; } +static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val = 0; + + switch (mi2s_tx_sample_rate) { + case SAMPLING_RATE_32KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_8KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_48KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: sample_rate_val = %d\n", __func__, + sample_rate_val); + + return 0; +} + +static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 5: + mi2s_tx_sample_rate = SAMPLING_RATE_32KHZ; + break; + case 4: + mi2s_tx_sample_rate = SAMPLING_RATE_16KHZ; + break; + case 3: + mi2s_tx_sample_rate = SAMPLING_RATE_8KHZ; + break; + case 2: + mi2s_tx_sample_rate = SAMPLING_RATE_192KHZ; + break; + case 1: + mi2s_tx_sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + mi2s_tx_sample_rate = SAMPLING_RATE_48KHZ; + } + pr_debug("%s: mi2s_tx_sample_rate = %d\n", __func__, + mi2s_tx_sample_rate); + return 0; +} + static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -954,6 +1021,11 @@ static uint32_t get_mi2s_rx_clk_val(void) return clk_val; } +static uint32_t get_mi2s_tx_clk_val(void) +{ + return mi2s_tx_sample_rate * bits_per_sample * 2; +} + static int ext_mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) { int ret = 0; @@ -995,7 +1067,7 @@ static int ext_mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) switch (q6core_get_avs_version()) { case (Q6_SUBSYS_AVS2_6): mi2s_tx_clk_v1.clk_val1 = - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; + get_mi2s_tx_clk_val(); ret = afe_set_lpass_clock( port_id, &mi2s_tx_clk_v1); @@ -1006,7 +1078,7 @@ static int ext_mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) mi2s_tx_clk.clk_id = msm8x16_get_clk_id(port_id); mi2s_tx_clk.clk_freq_in_hz = - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; + get_mi2s_tx_clk_val(); ret = afe_set_lpass_clock_v2(port_id, &mi2s_tx_clk); break; @@ -1171,6 +1243,7 @@ static const struct soc_enum msm_snd_enum[] = { SOC_ENUM_SINGLE_EXT(4, mi2s_tx_ch_text), SOC_ENUM_SINGLE_EXT(2, loopback_mclk_text), SOC_ENUM_SINGLE_EXT(6, pri_rx_sample_rate_text), + SOC_ENUM_SINGLE_EXT(6, mi2s_tx_sample_rate_text), }; static const char *const btsco_rate_text[] = {"BTSCO_RATE_8KHZ", @@ -1192,6 +1265,8 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_btsco_rate_get, msm_btsco_rate_put), SOC_ENUM_EXT("RX SampleRate", msm_snd_enum[3], pri_rx_sample_rate_get, pri_rx_sample_rate_put), + SOC_ENUM_EXT("MI2S TX SampleRate", msm_snd_enum[4], + mi2s_tx_sample_rate_get, mi2s_tx_sample_rate_put), }; static int msm8x16_mclk_event(struct snd_soc_dapm_widget *w, From 56a4620bd990f066073be80e7f31aeb9ecfaa308 Mon Sep 17 00:00:00 2001 From: Surendar karka Date: Fri, 21 Oct 2016 17:35:44 +0530 Subject: [PATCH 318/320] ASoC: msm: qdsp6v2: update condition for ADM open v6 Use ADM_CMD_OPEN_V6 if far end port and channels is set for tx path. Change-Id: I92d5913abb701f8bd992a86b0d231225ad6a56a5 Signed-off-by: Surendar karka --- sound/soc/msm/qdsp6v2/q6adm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c index ef051c1114c5d..997e09b68c226 100644 --- a/sound/soc/msm/qdsp6v2/q6adm.c +++ b/sound/soc/msm/qdsp6v2/q6adm.c @@ -2135,8 +2135,8 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, __func__, open.endpoint_id_1, open.sample_rate, open.topology_id); - if (open.topology_id == VPM_TX_LEC_STEREO_REF || - open.topology_id == VPM_TX_LEC_MONO_REF) { + if ((this_adm.ec_ref_cfg.channel != 0) && (path != 1) && + (open.endpoint_id_2 != 0xFFFF)) { int ref_end_channel_mode = this_adm.ec_ref_cfg.channel; use_open_v6 = true; /* overwrite open opcode and pkt size here to use From 73ff50fb28915c40137525dc9942b8f61b31c624 Mon Sep 17 00:00:00 2001 From: Prema Chand Alugu Date: Sun, 11 Sep 2016 00:35:58 +0530 Subject: [PATCH 319/320] Regenerate deconfig for N --- arch/arm/configs/cyanogenmod_wt88047_defconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/configs/cyanogenmod_wt88047_defconfig b/arch/arm/configs/cyanogenmod_wt88047_defconfig index 8af4dbd912925..94ce71968abfa 100644 --- a/arch/arm/configs/cyanogenmod_wt88047_defconfig +++ b/arch/arm/configs/cyanogenmod_wt88047_defconfig @@ -32,7 +32,7 @@ CONFIG_BUILDTIME_EXTABLE_SORT=y # CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_CROSS_COMPILE="" -CONFIG_LOCALVERSION="-blackhawk" +CONFIG_LOCALVERSION="-cyanogenmod" CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_LZMA=y @@ -666,6 +666,7 @@ CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_INET_UDP_DIAG is not set +# CONFIG_INET_DIAG_DESTROY is not set # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" From f4b8814b5df12f00f56e58a8eb22441a4836bd25 Mon Sep 17 00:00:00 2001 From: nicknitewolf Date: Mon, 12 Dec 2016 19:54:02 +0800 Subject: [PATCH 320/320] defconfig: Enable NF_MATCH_RPFILTER Change-Id: I14345b2368a43534388a502bc044e0d7009359bd --- arch/arm/configs/cyanogenmod_wt88047_defconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/configs/cyanogenmod_wt88047_defconfig b/arch/arm/configs/cyanogenmod_wt88047_defconfig index 94ce71968abfa..4f1062096b4e1 100644 --- a/arch/arm/configs/cyanogenmod_wt88047_defconfig +++ b/arch/arm/configs/cyanogenmod_wt88047_defconfig @@ -846,7 +846,7 @@ CONFIG_NF_CONNTRACK_PROC_COMPAT=y CONFIG_IP_NF_IPTABLES=y CONFIG_IP_NF_MATCH_AH=y CONFIG_IP_NF_MATCH_ECN=y -# CONFIG_IP_NF_MATCH_RPFILTER is not set +CONFIG_IP_NF_MATCH_RPFILTER=y CONFIG_IP_NF_MATCH_TTL=y CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y @@ -883,7 +883,7 @@ CONFIG_IP6_NF_IPTABLES=y # CONFIG_IP6_NF_MATCH_HL is not set # CONFIG_IP6_NF_MATCH_IPV6HEADER is not set # CONFIG_IP6_NF_MATCH_MH is not set -# CONFIG_IP6_NF_MATCH_RPFILTER is not set +CONFIG_IP6_NF_MATCH_RPFILTER=y # CONFIG_IP6_NF_MATCH_RT is not set # CONFIG_IP6_NF_TARGET_HL is not set CONFIG_IP6_NF_FILTER=y