summaryrefslogtreecommitdiff
path: root/drivers/hwmon/ast_adc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/ast_adc.c')
-rw-r--r--drivers/hwmon/ast_adc.c83
1 files changed, 69 insertions, 14 deletions
diff --git a/drivers/hwmon/ast_adc.c b/drivers/hwmon/ast_adc.c
index 0969e398a8c8..3f95dc6f0f06 100644
--- a/drivers/hwmon/ast_adc.c
+++ b/drivers/hwmon/ast_adc.c
@@ -42,7 +42,7 @@
#include <plat/ast-scu.h>
-#define REST_DESIGN 0
+#define REST_DESIGN 5
struct adc_vcc_ref_data {
int v2;
@@ -50,7 +50,7 @@ struct adc_vcc_ref_data {
int r2;
};
-static struct adc_vcc_ref_data adc_vcc_ref[5] = {
+static struct adc_vcc_ref_data adc_vcc_ref[6] = {
[0] = {
.v2 = 0,
.r1 = 5600,
@@ -76,8 +76,20 @@ static struct adc_vcc_ref_data adc_vcc_ref[5] = {
.r1 = 56000,
.r2 = 1000,
},
+ [5] = {
+ .v2 = 0,
+ .r1 = 1000,
+ .r2 = 1000,
+ },
};
+/* Divisors for voltage sense; right now adc5 & adc6 divide by 2 */
+
+static int adc_divisor[] = { 1, 1, 1, 1,
+ 1, 2, 2, 1,
+ 1, 1, 1, 1,
+ 1, 1, 1, 1};
+
struct ast_adc_data {
struct device *hwmon_dev;
void __iomem *reg_base; /* virtual */
@@ -388,6 +400,22 @@ ast_set_adc_en(struct ast_adc_data *ast_adc, u8 adc_ch, u8 enable)
}
+/* NAME sysfs */
+static ssize_t
+show_name(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ return sprintf(buf, "ast_adc\n");
+}
+static SENSOR_DEVICE_ATTR_2(name, S_IRUGO, show_name, NULL, 0, 0);
+static struct attribute *name_attributes[] = {
+ &sensor_dev_attr_name.dev_attr.attr,
+ NULL
+};
+static const struct attribute_group name_attribute_groups = {
+ .attrs = name_attributes,
+};
+
/* attr ADC sysfs 0~max adc channel
* 0 - show/store channel enable
* 1 - show value
@@ -399,12 +427,31 @@ ast_set_adc_en(struct ast_adc_data *ast_adc, u8 adc_ch, u8 enable)
* 7 - show/store hystersis low
*/
+static u32
+ast_get_voltage(int idx) {
+ u16 tmp;
+ u32 voltage, tmp1, tmp2, tmp3;
+ tmp = ast_get_adc_value(ast_adc, idx);
+ // Voltage Sense Method
+ tmp1 = (adc_vcc_ref[REST_DESIGN].r1 + adc_vcc_ref[REST_DESIGN].r2) * tmp * 25 * 10;
+ tmp2 = adc_vcc_ref[REST_DESIGN].r2 * 1024 ;
+ tmp3 = (adc_vcc_ref[REST_DESIGN].r1 * adc_vcc_ref[REST_DESIGN].v2) / adc_vcc_ref[REST_DESIGN].r2;
+ // printk("tmp3 = %d \n",tmp3);
+ voltage = (tmp1/tmp2) - tmp3;
+
+ // Higher voltage inputs require a divisor
+
+ if (adc_divisor[idx])
+ voltage /= adc_divisor[idx];
+
+ return voltage;
+}
+
static ssize_t
ast_show_adc(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
{
struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
- u16 tmp;
- u32 voltage,tmp1, tmp2,tmp3;
+ u32 voltage;
//sensor_attr->index : pwm_ch#
//sensor_attr->nr : attr#
@@ -414,15 +461,7 @@ ast_show_adc(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
return sprintf(sysfsbuf, "%d : %s\n", ast_get_adc_en(ast_adc,sensor_attr->index),ast_get_adc_en(ast_adc,sensor_attr->index) ? "Enable":"Disable");
break;
case 1: //value
- tmp = ast_get_adc_value(ast_adc, sensor_attr->index);
- //Voltage Sense Method
- tmp1 = (adc_vcc_ref[REST_DESIGN].r1 + adc_vcc_ref[REST_DESIGN].r2) * tmp * 25 * 10;
- tmp2 = adc_vcc_ref[REST_DESIGN].r2 * 1023 ;
-
- tmp3 = (adc_vcc_ref[REST_DESIGN].r1 * adc_vcc_ref[REST_DESIGN].v2) / adc_vcc_ref[REST_DESIGN].r2;
- // printk("tmp3 = %d \n",tmp3);
- voltage = (tmp1/tmp2) - tmp3;
-
+ voltage = ast_get_voltage(sensor_attr->index);
return sprintf(sysfsbuf, "%d.%d (V)\n",voltage/100, voltage%100);
break;
case 2: //alarm
@@ -443,6 +482,9 @@ ast_show_adc(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
case 7: //hystersis lower
return sprintf(sysfsbuf, "%d \n", ast_get_adc_hyster_lower(ast_adc,sensor_attr->index));
break;
+ case 8:
+ voltage = ast_get_voltage(sensor_attr->index);
+ return sprintf(sysfsbuf, "%d\n",voltage * 10);
default:
return -EINVAL;
@@ -504,6 +546,7 @@ ast_store_adc(struct device *dev, struct device_attribute *attr, const char *sys
* 5 - show/store hystersis enable
* 6 - show/store hystersis upper
* 7 - show/store hystersis low
+* 8 - show value as 1000s, expected by lm-sensors
*/
#define sysfs_adc_ch(index) \
@@ -531,6 +574,9 @@ static SENSOR_DEVICE_ATTR_2(adc##index##_hyster_upper, S_IRUGO | S_IWUSR, \
static SENSOR_DEVICE_ATTR_2(adc##index##_hyster_lower, S_IRUGO | S_IWUSR, \
ast_show_adc, ast_store_adc, 7, index); \
\
+static SENSOR_DEVICE_ATTR_2(in##index##_input, S_IRUGO | S_IWUSR, \
+ ast_show_adc, NULL, 8, index); \
+\
static struct attribute *adc##index##_attributes[] = { \
&sensor_dev_attr_adc##index##_en.dev_attr.attr, \
&sensor_dev_attr_adc##index##_value.dev_attr.attr, \
@@ -540,6 +586,7 @@ static struct attribute *adc##index##_attributes[] = { \
&sensor_dev_attr_adc##index##_hyster_en.dev_attr.attr, \
&sensor_dev_attr_adc##index##_hyster_upper.dev_attr.attr, \
&sensor_dev_attr_adc##index##_hyster_lower.dev_attr.attr, \
+ &sensor_dev_attr_in##index##_input.dev_attr.attr, \
NULL \
};
@@ -637,10 +684,14 @@ ast_adc_probe(struct platform_device *pdev)
goto out_region;
}
+ err = sysfs_create_group(&pdev->dev.kobj, &name_attribute_groups);
+ if (err)
+ goto out_region;
+
for(i=0; i<MAX_CH_NO; i++) {
err = sysfs_create_group(&pdev->dev.kobj, &adc_attribute_groups[i]);
if (err)
- goto out_region;
+ goto out_sysfs00;
}
ast_adc_ctrl_init();
@@ -652,6 +703,8 @@ ast_adc_probe(struct platform_device *pdev)
//out_irq:
// free_irq(ast_adc->irq, NULL);
+out_sysfs00:
+ sysfs_remove_group(&pdev->dev.kobj, &name_attribute_groups);
out_region:
release_mem_region(res->start, res->end - res->start + 1);
out_mem:
@@ -674,6 +727,8 @@ ast_adc_remove(struct platform_device *pdev)
for(i=0; i<5; i++)
sysfs_remove_group(&pdev->dev.kobj, &adc_attribute_groups[i]);
+ sysfs_remove_group(&pdev->dev.kobj, &name_attribute_groups);
+
platform_set_drvdata(pdev, NULL);
// free_irq(ast_adc->irq, ast_adc);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);