From 0ed3b2e19dc9d3d7067cd3af67bc51b061ed8049 Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Tue, 7 Mar 2017 19:26:14 -0800 Subject: [PATCH] misc: qpnp-misc: add support for clients to read register from misc device On certain PMICs, PMIC peripheral drivers like haptics need to read MISC peripheral register. Add support for clients to read it by using qpnp_misc_read_reg(). Change-Id: Id5dfd9e440a8861b56572dab50839d1583535882 Signed-off-by: Subbaraman Narayanamurthy --- drivers/misc/qpnp-misc.c | 41 +++++++++++++++++++++++++++++++++++++++ include/linux/qpnp-misc.h | 22 +++++++++++++++++++-- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/drivers/misc/qpnp-misc.c b/drivers/misc/qpnp-misc.c index adf9eccda736..8f244811f740 100644 --- a/drivers/misc/qpnp-misc.c +++ b/drivers/misc/qpnp-misc.c @@ -130,6 +130,47 @@ static bool __misc_irqs_available(struct qpnp_misc_dev *dev) return 1; } +int qpnp_misc_read_reg(struct device_node *node, u16 addr, u8 *val) +{ + struct qpnp_misc_dev *mdev = NULL; + struct qpnp_misc_dev *mdev_found = NULL; + int rc; + u8 temp; + + if (IS_ERR_OR_NULL(node)) { + pr_err("Invalid device node pointer\n"); + return -EINVAL; + } + + mutex_lock(&qpnp_misc_dev_list_mutex); + list_for_each_entry(mdev, &qpnp_misc_dev_list, list) { + if (mdev->dev->of_node == node) { + mdev_found = mdev; + break; + } + } + mutex_unlock(&qpnp_misc_dev_list_mutex); + + if (!mdev_found) { + /* + * No MISC device was found. This API should only + * be called by drivers which have specified the + * misc phandle in their device tree node. + */ + pr_err("no probed misc device found\n"); + return -EPROBE_DEFER; + } + + rc = qpnp_read_byte(mdev, addr, &temp); + if (rc < 0) { + dev_err(mdev->dev, "Failed to read addr %x, rc=%d\n", addr, rc); + return rc; + } + + *val = temp; + return 0; +} + int qpnp_misc_irqs_available(struct device *consumer_dev) { struct device_node *misc_node = NULL; diff --git a/include/linux/qpnp-misc.h b/include/linux/qpnp-misc.h index ab3302f6ea78..7d95bf24a425 100644 --- a/include/linux/qpnp-misc.h +++ b/include/linux/qpnp-misc.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2014, 2017, 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 @@ -29,8 +29,26 @@ */ int qpnp_misc_irqs_available(struct device *consumer_dev); + +/** + * qpnp_misc_read_reg - read register from misc device + * + * @node: device node pointer + * @address: address offset in misc peripheral to be read + * @val: data read from register + * + * This function returns zero if reading the MISC register succeeds. + * + */ + +int qpnp_misc_read_reg(struct device_node *node, u16 addr, u8 *val); #else -static int qpnp_misc_irqs_available(struct device *consumer_dev) +static inline int qpnp_misc_irqs_available(struct device *consumer_dev) +{ + return 0; +} +static inline int qpnp_misc_read_reg(struct device_node *node, u16 addr, + u8 *val) { return 0; }