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. - qcom,channel-type : Bitmak of channels to set as voltage and current.
These are platform dependent and the appropriate scaling These are platform dependent and the appropriate scaling
functions are used for returning voltage and current. 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 10 25 33 100 10 10 3 1000 1000 1000
1000>; 1000>;
qcom,channel-type = <0xf0000000>; 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 1 1 1 1 1 1 1 1 1
1>; 1>;
qcom,channel-type = <0xf0000000>; 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 10 25 33 100 10 10 3 1000 1000 1000
1000>; 1000>;
qcom,channel-type = <0xf0000000>; 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 100 500 20 200 1000 20 1000 1000 70 200
50>; 50>;
qcom,channel-type = <0x1540>; qcom,channel-type = <0x1540>;
qcom,epm-enable-gpio = <&msmgpio 81 0>;
}; };
}; };

View file

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