hwmon: epm_adc: Add configurable global GPIO enable

Embedded power monitor (EPM) PSoC is powered through a GPIO.
Add a property to pass the GPIO to the driver since this
the global enable for the EPM varies from target to target.

Change-Id: I731302f9ab33c216f5794721a4d36ee20fb261ec
Signed-off-by: Siddartha Mohanadoss <smohanad@codeaurora.org>
This commit is contained in:
Siddartha Mohanadoss 2013-12-18 16:53:08 -08:00
parent 1e99760d03
commit a5b117f24f
6 changed files with 29 additions and 10 deletions

View file

@ -23,3 +23,6 @@ Required properties:
- qcom,channel-type : Bitmak of channels to set as voltage and current.
These are platform dependent and the appropriate scaling
functions are used for returning voltage and current.
- qcom,<gpio-name>-gpio : Handle to the GPIO node, see "gpios property" in
Documentation/devicetree/bindings/gpio/gpio.txt.
"gpio-name" can be "epm-enable" which is the EPM global enable GPIO for powering up the PSoC.

View file

@ -799,6 +799,7 @@
10 25 33 100 10 10 3 1000 1000 1000
1000>;
qcom,channel-type = <0xf0000000>;
qcom,epm-enable-gpio = <&msmgpio 92 0>;
};
};

View file

@ -712,6 +712,7 @@
1 1 1 1 1 1 1 1 1 1
1>;
qcom,channel-type = <0xf0000000>;
qcom,epm-enable-gpio = <&msmgpio 81 0>;
};
};

View file

@ -803,6 +803,7 @@
10 25 33 100 10 10 3 1000 1000 1000
1000>;
qcom,channel-type = <0xf0000000>;
qcom,epm-enable-gpio = <&msmgpio 81 0>;
};
};

View file

@ -728,6 +728,7 @@
100 500 20 200 1000 20 1000 1000 70 200
50>;
qcom,channel-type = <0x1540>;
qcom,epm-enable-gpio = <&msmgpio 81 0>;
};
};

View file

@ -18,6 +18,7 @@
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/hwmon.h>
#include <linux/delay.h>
#include <linux/epm_adc.h>
@ -133,6 +134,7 @@ struct epm_adc_drv {
uint32_t bus_id;
struct miscdevice misc;
uint32_t channel_mask;
uint32_t epm_global_en_gpio;
struct epm_chan_properties epm_psoc_ch_prop[0];
};
@ -705,22 +707,24 @@ conv_err:
return rc;
}
static int epm_adc_psoc_gpio_init(bool enable)
static int epm_adc_psoc_gpio_init(struct epm_adc_drv *epm_adc,
bool enable)
{
int rc = 0;
if (enable) {
rc = gpio_request(EPM_PSOC_GLOBAL_ENABLE, "EPM_PSOC_GLOBAL_EN");
rc = gpio_request(epm_adc->epm_global_en_gpio,
"EPM_PSOC_GLOBAL_EN");
if (!rc) {
gpio_direction_output(EPM_PSOC_GLOBAL_ENABLE, 1);
gpio_direction_output(epm_adc->epm_global_en_gpio, 1);
} else {
pr_err("%s: Configure EPM_GLOBAL_EN Failed\n",
__func__);
return rc;
}
} else {
gpio_direction_output(EPM_PSOC_GLOBAL_ENABLE, 0);
gpio_free(EPM_PSOC_GLOBAL_ENABLE);
gpio_direction_output(epm_adc->epm_global_en_gpio, 0);
gpio_free(epm_adc->epm_global_en_gpio);
}
return 0;
@ -1694,7 +1698,7 @@ static long epm_adc_ioctl(struct file *file, unsigned int cmd,
}
if (!rc) {
rc = epm_adc_psoc_gpio_init(true);
rc = epm_adc_psoc_gpio_init(epm_adc, true);
if (rc) {
pr_err("GPIO init failed\n");
return -EINVAL;
@ -1709,7 +1713,7 @@ static long epm_adc_ioctl(struct file *file, unsigned int cmd,
case EPM_PSOC_ADC_DEINIT:
{
uint32_t result;
result = epm_adc_psoc_gpio_init(false);
result = epm_adc_psoc_gpio_init(epm_adc, false);
if (copy_to_user((void __user *)arg, &result,
sizeof(uint32_t)))
@ -2071,7 +2075,7 @@ static ssize_t epm_adc_psoc_show_in(struct device *dev,
struct epm_psoc_get_data psoc_get_meas;
int rc = 0;
rc = epm_adc_psoc_gpio_init(true);
rc = epm_adc_psoc_gpio_init(epm_adc, true);
if (rc) {
pr_err("GPIO init failed\n");
return 0;
@ -2111,7 +2115,7 @@ static ssize_t epm_adc_psoc_show_in(struct device *dev,
psoc_get_meas.reading_value,
attr->index);
rc = epm_adc_psoc_gpio_init(false);
rc = epm_adc_psoc_gpio_init(epm_adc, false);
if (rc) {
pr_err("GPIO de-init failed\n");
return 0;
@ -2177,7 +2181,7 @@ static int get_device_tree_data(struct spi_device *spi)
const struct device_node *node = spi->dev.of_node;
struct epm_adc_drv *epm_adc;
u32 *epm_ch_gain, *epm_ch_rsense;
u32 rc = 0, epm_num_channels, i, channel_mask;
u32 rc = 0, epm_num_channels, i, channel_mask, epm_gpio_num;
if (!node)
return -EINVAL;
@ -2224,6 +2228,13 @@ static int get_device_tree_data(struct spi_device *spi)
return -ENODEV;
}
epm_gpio_num = of_get_named_gpio(spi->dev.of_node,
"qcom,epm-enable-gpio", 0);
if (epm_gpio_num < 0) {
dev_err(&spi->dev, "missing global en gpio num\n");
return -ENODEV;
}
epm_adc = devm_kzalloc(&spi->dev,
sizeof(struct epm_adc_drv) +
(epm_num_channels *
@ -2242,6 +2253,7 @@ static int get_device_tree_data(struct spi_device *spi)
}
epm_adc->channel_mask = channel_mask;
epm_adc->epm_global_en_gpio = epm_gpio_num;
epm_adc_drv = epm_adc;
return 0;