summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShreshtha Kumar Sahu <shreshthakumar.sahu@stericsson.com>2011-11-03 16:01:37 +0530
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:01:11 +0200
commit1fa4ffa3bd74c841979a4f05cf6dd9a64e9769e7 (patch)
tree584c5aadc6819304d4a74ff0fdfbf2002ec14f96
parent056e6e09ac185ed00a3fa08764af0efb18c97f1d (diff)
ab5500: enable GPADC-0 and provide sysfs interfce
This patch enables GPADC-0 to convert from voltage range 0 to 1.8v and also adds sysfs interface for reading gpadc ch-0. "/sys/devices/platform/ab5500-core.0/ab5500-adc.0/adc0volt" ST-Ericsson ID: 370066 ST-Ericsson Linux next: NA ST-Ericsson FOSS-OUT ID: Trivial Change-Id: Ic23caa22ff4e10d3dbb151e10eb4625ec5d7078a Signed-off-by: Shreshtha Kumar Sahu <shreshthakumar.sahu@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/36216 Reviewed-by: QATOOLS Reviewed-by: QABUILD Reviewed-by: Linus WALLEIJ <linus.walleij@stericsson.com>
-rw-r--r--Documentation/ABI/testing/sysfs-devices-platform-ab5500-core-adc20
-rw-r--r--drivers/mfd/ab5500-gpadc.c41
-rw-r--r--include/linux/mfd/abx500/ab5500-gpadc.h1
3 files changed, 62 insertions, 0 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-platform-ab5500-core-adc b/Documentation/ABI/testing/sysfs-devices-platform-ab5500-core-adc
new file mode 100644
index 00000000000..fcfc0ed26fb
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-platform-ab5500-core-adc
@@ -0,0 +1,20 @@
+What: /sys/devices/platform/ab5500-core.0/ab5500-adc.0/adc0volt
+Date: Nov 2011
+KernelVersion: 3.0
+Contact: Shreshtha Kumar SAHU <shreshthakumar.sahu@stericsson.com>
+Description: The adc0volt attribute allows the userspace to read the
+ voltage of the device connected to the General Purpose
+ Analog to Digital Converter (GPADC) channel-0. Voltage
+ conversion from analog to digital happens only when this
+ attribute is read. GPADC block is present in AB5500 chip
+ and has input voltage range of 0-1.8 volt for GPADC Ch-0.
+ It provides result of the converted voltage in 10 bits.
+ Other GPADC channels attributes may appear in this path
+ later. For minimum and maximum input voltage range for
+ each channel please refer to the ST-Ericssons AB5500
+ datasheet. An example usage of GPADC can be an ALS device
+ connected to the channel and user space adapts the
+ LCD backlight brightness based on ambient light value
+ read from the attribute.
+Users: HAL.
+
diff --git a/drivers/mfd/ab5500-gpadc.c b/drivers/mfd/ab5500-gpadc.c
index 6756d3cf37a..51d1fa9049a 100644
--- a/drivers/mfd/ab5500-gpadc.c
+++ b/drivers/mfd/ab5500-gpadc.c
@@ -67,6 +67,7 @@
#define GPADC_MANUAL_ADOUT1_MASK 0xC0
#define GPADC_MANUAL_ADOUT0_ON 0x10
#define GPADC_MANUAL_ADOUT1_ON 0x40
+#define MUX_SCALE_GPADC0_MASK 0x08
#define MUX_SCALE_VBAT_MASK 0x02
#define MUX_SCALE_45 0x02
#define MUX_SCALE_BDATA_MASK 0x01
@@ -74,6 +75,8 @@
#define MUX_SCALE_BDATA18 0x01
#define MUX_SCALE_ACCDET2_MASK 0x01
#define MUX_SCALE_ACCDET3_MASK 0x02
+#define GPADC0_SCALE_VOL27 0x00
+#define GPADC0_SCALE_VOL18 0x01
#define ACCDET2_SCALE_VOL27 0x00
#define ACCDET3_SCALE_VOL27 0x00
#define TRIGX_FREQ_MASK 0x07
@@ -98,6 +101,8 @@
#define CTRL_INDEX 0x01
/* GPADC constants from AB5500 spec */
+#define GPADC0_MIN 0
+#define GPADC0_MAX 1800
#define BTEMP_MIN 0
#define BTEMP_MAX 1800
#define BDATA_MIN 0
@@ -229,6 +234,7 @@ struct adc_data {
}
struct adc_data adc_tab[] = {
+ ADC_DATA(GPADC0_V, 0x00, GPADC0_MIN, GPADC0_MAX, 0),
ADC_DATA(BTEMP_BALL, 0x0D, BTEMP_MIN, BTEMP_MAX, ADOUT0),
ADC_DATA(BAT_CTRL, 0x0D, BDATA_MIN, BDATA_MAX, 0),
ADC_DATA(MAIN_BAT_V, 0x0C, VBAT_MIN, VBAT_MAX, 0),
@@ -270,6 +276,7 @@ static int ab5500_gpadc_ad_to_voltage(struct ab5500_gpadc *gpadc,
int res;
switch (in) {
+ case GPADC0_V:
case PCB_TEMP:
case BTEMP_BALL:
case MAIN_BAT_V:
@@ -367,6 +374,15 @@ int ab5500_gpadc_convert(struct ab5500_gpadc *gpadc, u8 input)
goto out;
}
break;
+ case GPADC0_V:
+ ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
+ AB5500_BANK_ADC, AB5500_GPADC_MANUAL_MODE_CTRL,
+ MUX_SCALE_GPADC0_MASK, GPADC0_SCALE_VOL18);
+ if (ret < 0) {
+ dev_err(gpadc->dev, "gpadc: fail to set gpadc0\n");
+ goto out;
+ }
+ break;
case ACC_DETECT2:
ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
AB5500_BANK_ADC, AB5500_GPADC_MANUAL_MODE_CTRL2,
@@ -775,6 +791,19 @@ out:
}
EXPORT_SYMBOL(ab5500_gpadc_convert_auto);
+/* sysfs interface for GPADC0 */
+static ssize_t ab5500_gpadc0_get(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int voltage;
+ struct ab5500_gpadc *gpadc = dev_get_drvdata(dev);
+
+ voltage = ab5500_gpadc_convert(gpadc, GPADC0_V);
+
+ return sprintf(buf, "%d\n", voltage);
+}
+static DEVICE_ATTR(adc0volt, 0644, ab5500_gpadc0_get, NULL);
+
static void ab5500_gpadc_trigx_work(struct ab5500_gpadc *gp, int trig)
{
unsigned long flags;
@@ -1114,9 +1143,19 @@ static int __devinit ab5500_gpadc_probe(struct platform_device *pdev)
dev_err(gpadc->dev, "gpadc: configuration failed\n");
goto free_wq;
}
+
+ ret = device_create_file(gpadc->dev, &dev_attr_adc0volt);
+ if (ret < 0) {
+ dev_err(gpadc->dev, "File device creation failed: %d\n", ret);
+ ret = -ENODEV;
+ goto fail_sysfs;
+ }
list_add_tail(&gpadc->node, &ab5500_gpadc_list);
+ platform_set_drvdata(pdev, gpadc);
+
return 0;
+fail_sysfs:
free_wq:
destroy_workqueue(gpadc->gpadc_wq);
fail_irq:
@@ -1134,6 +1173,8 @@ static int __devexit ab5500_gpadc_remove(struct platform_device *pdev)
int i, irq;
struct ab5500_gpadc *gpadc = platform_get_drvdata(pdev);
+ device_remove_file(gpadc->dev, &dev_attr_adc0volt);
+
/* remove this gpadc entry from the list */
list_del(&gpadc->node);
/* Disable interrupts */
diff --git a/include/linux/mfd/abx500/ab5500-gpadc.h b/include/linux/mfd/abx500/ab5500-gpadc.h
index 3282b44114e..67dc3cc9034 100644
--- a/include/linux/mfd/abx500/ab5500-gpadc.h
+++ b/include/linux/mfd/abx500/ab5500-gpadc.h
@@ -33,6 +33,7 @@
#define MAIN_BAT_V_TXON_TRIG_MIN 13
/* VBAT with TX off only min trigger */
#define MAIN_BAT_V_TRIG_MIN 14
+#define GPADC0_V 15
/*
* Frequency of auto adc conversion