/
0012-ti_tscadc-Update-with-IIO-map-interface-deal-with-pa.patch
186 lines (167 loc) · 5.36 KB
/
0012-ti_tscadc-Update-with-IIO-map-interface-deal-with-pa.patch
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
From cbede1cacf0be315579e3b6a173c78c0134274fd Mon Sep 17 00:00:00 2001
From: Pantelis Antoniou <panto@antoniou-consulting.com>
Date: Sat, 13 Oct 2012 16:37:24 +0300
Subject: [PATCH 12/13] ti_tscadc: Update with IIO map interface & deal with
partial activation
Add an IIO map interface that consumers can use.
While we're here fix the mfd device in the case where a subdevice
might not be activated.
---
drivers/iio/adc/ti_am335x_adc.c | 53 ++++++++++++++++++++++++++++------
drivers/mfd/ti_am335x_tscadc.c | 30 +++++++++++++------
include/linux/mfd/ti_am335x_tscadc.h | 8 ++---
3 files changed, 68 insertions(+), 23 deletions(-)
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index 02a43c8..d48fd79 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -20,8 +20,9 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <linux/io.h>
#include <linux/iio/iio.h>
+#include <linux/iio/machine.h>
+#include <linux/iio/driver.h>
#include <linux/mfd/ti_am335x_tscadc.h>
#include <linux/platform_data/ti_am335x_adc.h>
@@ -29,6 +30,8 @@
struct tiadc_device {
struct ti_tscadc_dev *mfd_tscadc;
int channels;
+ char *buf;
+ struct iio_map *map;
};
static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg)
@@ -75,25 +78,57 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
{
struct iio_chan_spec *chan_array;
- int i;
-
- indio_dev->num_channels = channels;
- chan_array = kcalloc(indio_dev->num_channels,
- sizeof(struct iio_chan_spec), GFP_KERNEL);
+ struct iio_chan_spec *chan;
+ char *s;
+ int i, len, size, ret;
+ size = indio_dev->num_channels * (sizeof(struct iio_chan_spec) + 6);
+ chan_array = kzalloc(size, GFP_KERNEL);
if (chan_array == NULL)
return -ENOMEM;
- for (i = 0; i < (indio_dev->num_channels); i++) {
- struct iio_chan_spec *chan = chan_array + i;
+ /* buffer space is after the array */
+ s = (char *)(chan_array + indio_dev->num_channels);
+ chan = chan_array;
+ for (i = 0; i < indio_dev->num_channels; i++, chan++, s += len + 1) {
+
+ len = sprintf(s, "AIN%d", i);
+
chan->type = IIO_VOLTAGE;
chan->indexed = 1;
chan->channel = i;
- chan->info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT;
+ chan->datasheet_name = s;
+ chan->scan_type.sign = 'u';
+ chan->scan_type.realbits = 12;
+ chan->scan_type.storagebits = 32;
+ chan->scan_type.shift = 0;
}
indio_dev->channels = chan_array;
+ size = (indio_dev->num_channels + 1) * sizeof(struct iio_map);
+ adc_dev->map = kzalloc(size, GFP_KERNEL);
+ if (adc_dev->map == NULL) {
+ kfree(chan_array);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < indio_dev->num_channels; i++) {
+ adc_dev->map[i].adc_channel_label = chan_array[i].datasheet_name;
+ adc_dev->map[i].consumer_dev_name = "any";
+ adc_dev->map[i].consumer_channel = chan_array[i].datasheet_name;
+ }
+ adc_dev->map[i].adc_channel_label = NULL;
+ adc_dev->map[i].consumer_dev_name = NULL;
+ adc_dev->map[i].consumer_channel = NULL;
+
+ ret = iio_map_array_register(indio_dev, adc_dev->map);
+ if (ret != 0) {
+ kfree(adc_dev->map);
+ kfree(chan_array);
+ return -ENOMEM;
+ }
+
return indio_dev->num_channels;
}
diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
index e947dd8..cbb8b70c 100644
--- a/drivers/mfd/ti_am335x_tscadc.c
+++ b/drivers/mfd/ti_am335x_tscadc.c
@@ -176,26 +176,38 @@ static int __devinit ti_tscadc_probe(struct platform_device *pdev)
ctrl |= CNTRLREG_TSCSSENB;
tscadc_writel(tscadc, REG_CTRL, ctrl);
+ tscadc->used_cells = 0;
+ tscadc->tsc_cell = -1;
+ tscadc->adc_cell = -1;
+
/* TSC Cell */
- cell = &tscadc->cells[TSC_CELL];
- cell->name = "tsc";
- cell->platform_data = tscadc;
- cell->pdata_size = sizeof(*tscadc);
+ if (tsc_wires > 0) {
+ tscadc->tsc_cell = tscadc->used_cells;
+ cell = &tscadc->cells[tscadc->used_cells++];
+ cell->name = "tsc";
+ cell->platform_data = tscadc;
+ cell->pdata_size = sizeof(*tscadc);
+ }
/* ADC Cell */
- cell = &tscadc->cells[ADC_CELL];
- cell->name = "tiadc";
- cell->platform_data = tscadc;
- cell->pdata_size = sizeof(*tscadc);
+ if (adc_channels > 0) {
+ tscadc->adc_cell = tscadc->used_cells;
+ cell = &tscadc->cells[tscadc->used_cells++];
+ cell->name = "tiadc";
+ cell->platform_data = tscadc;
+ cell->pdata_size = sizeof(*tscadc);
+ }
err = mfd_add_devices(&pdev->dev, pdev->id, tscadc->cells,
- TSCADC_CELLS, NULL, 0, NULL);
+ tscadc->used_cells, NULL, 0, NULL);
if (err < 0)
goto err_disable_clk;
device_init_wakeup(&pdev->dev, true);
platform_set_drvdata(pdev, tscadc);
+ dev_info(&pdev->dev, "Initialized OK.\n");
+
return 0;
err_disable_clk:
diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
index 9624fea..50a245f 100644
--- a/include/linux/mfd/ti_am335x_tscadc.h
+++ b/include/linux/mfd/ti_am335x_tscadc.h
@@ -128,11 +128,6 @@
#define TSCADC_CELLS 2
-enum tscadc_cells {
- TSC_CELL,
- ADC_CELL,
-};
-
struct mfd_tscadc_board {
struct tsc_data *tsc_init;
struct adc_data *adc_init;
@@ -143,6 +138,9 @@ struct ti_tscadc_dev {
struct regmap *regmap_tscadc;
void __iomem *tscadc_base;
int irq;
+ int used_cells; /* 0-2 */
+ int tsc_cell; /* -1 if not used */
+ int adc_cell; /* -1 if not used */
struct mfd_cell cells[TSCADC_CELLS];
/* tsc device */
--
1.7.7.6