summaryrefslogtreecommitdiffstats
path: root/target/linux/generic/patches-3.14/065-iio_ad799x_backport_fixes.patch
blob: 41506f96917ae95b9f218b69ef88a0eb175eddb2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
Backport essential fixes from 3.15

From Linux 3.10 on this driver required platform data to load, which makes it
unusable in OpenWRT. This commit backports the following fixes:
  * Move to regulator framework for scaling
  * Fix device-removal path
This commit should not be moved to newer kernel versions!

Signed-off-by: Hartmut Knaack <knaack.h@gmx.de>
---
--- a/drivers/staging/iio/adc/ad799x_core.c
+++ b/drivers/staging/iio/adc/ad799x_core.c
@@ -179,7 +179,10 @@ static int ad799x_read_raw(struct iio_de
 			RES_MASK(chan->scan_type.realbits);
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_SCALE:
-		*val = st->int_vref_mv;
+		ret = regulator_get_voltage(st->vref);
+		if (ret < 0)
+			return ret;
+		*val =  ret / 1000;
 		*val2 = chan->scan_type.realbits;
 		return IIO_VAL_FRACTIONAL_LOG2;
 	}
@@ -533,7 +536,6 @@ static int ad799x_probe(struct i2c_clien
 				   const struct i2c_device_id *id)
 {
 	int ret;
-	struct ad799x_platform_data *pdata = client->dev.platform_data;
 	struct ad799x_state *st;
 	struct iio_dev *indio_dev;
 
@@ -551,17 +553,21 @@ static int ad799x_probe(struct i2c_clien
 
 	/* TODO: Add pdata options for filtering and bit delay */
 
-	if (!pdata)
-		return -EINVAL;
-
-	st->int_vref_mv = pdata->vref_mv;
-
 	st->reg = devm_regulator_get(&client->dev, "vcc");
-	if (!IS_ERR(st->reg)) {
-		ret = regulator_enable(st->reg);
-		if (ret)
-			return ret;
+	if (IS_ERR(st->reg))
+		return PTR_ERR(st->reg);
+	ret = regulator_enable(st->reg);
+	if (ret)
+		return ret;
+	st->vref = devm_regulator_get(&client->dev, "vref");
+	if (IS_ERR(st->vref)) {
+		ret = PTR_ERR(st->vref);
+		goto error_disable_reg;
 	}
+	ret = regulator_enable(st->vref);
+	if (ret)
+		goto error_disable_reg;
+
 	st->client = client;
 
 	indio_dev->dev.parent = &client->dev;
@@ -574,7 +580,7 @@ static int ad799x_probe(struct i2c_clien
 
 	ret = ad799x_register_ring_funcs_and_init(indio_dev);
 	if (ret)
-		goto error_disable_reg;
+		goto error_disable_vref;
 
 	if (client->irq > 0) {
 		ret = request_threaded_irq(client->irq,
@@ -598,9 +604,10 @@ error_free_irq:
 		free_irq(client->irq, indio_dev);
 error_cleanup_ring:
 	ad799x_ring_cleanup(indio_dev);
+error_disable_vref:
+	regulator_disable(st->vref);
 error_disable_reg:
-	if (!IS_ERR(st->reg))
-		regulator_disable(st->reg);
+	regulator_disable(st->reg);
 
 	return ret;
 }
@@ -615,8 +622,8 @@ static int ad799x_remove(struct i2c_clie
 		free_irq(client->irq, indio_dev);
 
 	ad799x_ring_cleanup(indio_dev);
-	if (!IS_ERR(st->reg))
-		regulator_disable(st->reg);
+	regulator_disable(st->vref);
+	regulator_disable(st->reg);
 	kfree(st->rx_buf);
 
 	return 0;
--- a/drivers/staging/iio/adc/ad799x.h
+++ b/drivers/staging/iio/adc/ad799x.h
@@ -95,7 +95,7 @@ struct ad799x_state {
 	struct i2c_client		*client;
 	const struct ad799x_chip_info	*chip_info;
 	struct regulator		*reg;
-	u16				int_vref_mv;
+	struct regulator		*vref;
 	unsigned			id;
 	u16				config;
 
@@ -103,14 +103,6 @@ struct ad799x_state {
 	unsigned int			transfer_size;
 };
 
-/*
- * TODO: struct ad799x_platform_data needs to go into include/linux/iio
- */
-
-struct ad799x_platform_data {
-	u16				vref_mv;
-};
-
 #ifdef CONFIG_AD799X_RING_BUFFER
 int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev);
 void ad799x_ring_cleanup(struct iio_dev *indio_dev);