diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-10 14:10:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-10 14:10:27 -0400 |
commit | 3aa78e0cb5c9b8b4ed2a617bb1e1542bfb508379 (patch) | |
tree | a446e1f8a81f63933423ef11ea7d31cc918b30f6 /drivers/iio | |
parent | dc5ef1f56968c67e81ad1c81ab7dce678f480285 (diff) | |
parent | 25f311fa58c18c19ae1348336265ccb8368638f0 (diff) |
Merge tag 'mfd-3.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-next
Pull MFD update from Samuel Ortiz:
"For the 3.11 merge we only have one new MFD driver for the Kontron
PLD.
But we also have:
- Support for the TPS659038 PMIC from the palmas driver.
- Intel's Coleto Creek and Avoton SoCs support from the lpc_ich
driver.
- RTL8411B support from the rtsx driver.
- More DT support for the Arizona, max8998, twl4030-power and the
ti_am335x_tsadc drivers.
- The SSBI driver move under MFD.
- A conversion to the devm_* API for most of the MFD drivers.
- The twl4030-power got split from twl-core into its own module.
- A major ti_am335x_adc cleanup, leading to a proper DT support.
- Our regular arizona and wm* updates and cleanups from the Wolfson
folks.
- A better error handling and initialization, and a regulator
subdevice addition for the 88pm80x driver.
- A bulk platform_set_drvdata() call removal that's no longer need
since commit 0998d0631001 ("device-core: Ensure drvdata = NULL when
no driver is bound")
* tag 'mfd-3.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-next: (102 commits)
mfd: sec: Provide max_register to regmap
mfd: wm8994: Remove duplicate check for active JACKDET
MAINTAINERS: Add include directory to MFD file patterns
mfd: sec: Remove fields not used since regmap conversion
watchdog: Kontron PLD watchdog timer driver
mfd: max8998: Add support for Device Tree
regulator: max8998: Use arrays for specifying voltages in platform data
mfd: max8998: Add irq domain support
regulator: palmas: Add TPS659038 support
mfd: Kontron PLD mfd driver
mfd: palmas: Add TPS659038 PMIC support
mfd: palmas: Add SMPS10_BOOST feature
mfd: palmas: Check if irq is valid
mfd: lpc_ich: iTCO_wdt patch for Intel Coleto Creek DeviceIDs
mfd: twl-core: Change TWL6025 references to TWL6032
mfd: davinci_voicecodec: Fix build breakage
mfd: vexpress: Make the driver optional for arm and arm64
mfd: htc-egpio: Use devm_ioremap_nocache() instead of ioremap_nocache()
mfd: davinci_voicecodec: Convert to use devm_* APIs
mfd: twl4030-power: Fix relocking on error
...
Diffstat (limited to 'drivers/iio')
-rw-r--r-- | drivers/iio/adc/ti_am335x_adc.c | 132 |
1 files changed, 100 insertions, 32 deletions
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index 5f9a7e7d3135..4427e8e46a7f 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c | |||
@@ -22,13 +22,18 @@ | |||
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/iio/iio.h> | 24 | #include <linux/iio/iio.h> |
25 | #include <linux/of.h> | ||
26 | #include <linux/of_device.h> | ||
27 | #include <linux/iio/machine.h> | ||
28 | #include <linux/iio/driver.h> | ||
25 | 29 | ||
26 | #include <linux/mfd/ti_am335x_tscadc.h> | 30 | #include <linux/mfd/ti_am335x_tscadc.h> |
27 | #include <linux/platform_data/ti_am335x_adc.h> | ||
28 | 31 | ||
29 | struct tiadc_device { | 32 | struct tiadc_device { |
30 | struct ti_tscadc_dev *mfd_tscadc; | 33 | struct ti_tscadc_dev *mfd_tscadc; |
31 | int channels; | 34 | int channels; |
35 | u8 channel_line[8]; | ||
36 | u8 channel_step[8]; | ||
32 | }; | 37 | }; |
33 | 38 | ||
34 | static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg) | 39 | static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg) |
@@ -42,10 +47,20 @@ static void tiadc_writel(struct tiadc_device *adc, unsigned int reg, | |||
42 | writel(val, adc->mfd_tscadc->tscadc_base + reg); | 47 | writel(val, adc->mfd_tscadc->tscadc_base + reg); |
43 | } | 48 | } |
44 | 49 | ||
50 | static u32 get_adc_step_mask(struct tiadc_device *adc_dev) | ||
51 | { | ||
52 | u32 step_en; | ||
53 | |||
54 | step_en = ((1 << adc_dev->channels) - 1); | ||
55 | step_en <<= TOTAL_STEPS - adc_dev->channels + 1; | ||
56 | return step_en; | ||
57 | } | ||
58 | |||
45 | static void tiadc_step_config(struct tiadc_device *adc_dev) | 59 | static void tiadc_step_config(struct tiadc_device *adc_dev) |
46 | { | 60 | { |
47 | unsigned int stepconfig; | 61 | unsigned int stepconfig; |
48 | int i, channels = 0, steps; | 62 | int i, steps; |
63 | u32 step_en; | ||
49 | 64 | ||
50 | /* | 65 | /* |
51 | * There are 16 configurable steps and 8 analog input | 66 | * There are 16 configurable steps and 8 analog input |
@@ -58,43 +73,63 @@ static void tiadc_step_config(struct tiadc_device *adc_dev) | |||
58 | */ | 73 | */ |
59 | 74 | ||
60 | steps = TOTAL_STEPS - adc_dev->channels; | 75 | steps = TOTAL_STEPS - adc_dev->channels; |
61 | channels = TOTAL_CHANNELS - adc_dev->channels; | ||
62 | |||
63 | stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1; | 76 | stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1; |
64 | 77 | ||
65 | for (i = (steps + 1); i <= TOTAL_STEPS; i++) { | 78 | for (i = 0; i < adc_dev->channels; i++) { |
66 | tiadc_writel(adc_dev, REG_STEPCONFIG(i), | 79 | int chan; |
67 | stepconfig | STEPCONFIG_INP(channels)); | 80 | |
68 | tiadc_writel(adc_dev, REG_STEPDELAY(i), | 81 | chan = adc_dev->channel_line[i]; |
82 | tiadc_writel(adc_dev, REG_STEPCONFIG(steps), | ||
83 | stepconfig | STEPCONFIG_INP(chan)); | ||
84 | tiadc_writel(adc_dev, REG_STEPDELAY(steps), | ||
69 | STEPCONFIG_OPENDLY); | 85 | STEPCONFIG_OPENDLY); |
70 | channels++; | 86 | adc_dev->channel_step[i] = steps; |
87 | steps++; | ||
71 | } | 88 | } |
72 | tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB); | 89 | step_en = get_adc_step_mask(adc_dev); |
90 | am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en); | ||
73 | } | 91 | } |
74 | 92 | ||
93 | static const char * const chan_name_ain[] = { | ||
94 | "AIN0", | ||
95 | "AIN1", | ||
96 | "AIN2", | ||
97 | "AIN3", | ||
98 | "AIN4", | ||
99 | "AIN5", | ||
100 | "AIN6", | ||
101 | "AIN7", | ||
102 | }; | ||
103 | |||
75 | static int tiadc_channel_init(struct iio_dev *indio_dev, int channels) | 104 | static int tiadc_channel_init(struct iio_dev *indio_dev, int channels) |
76 | { | 105 | { |
106 | struct tiadc_device *adc_dev = iio_priv(indio_dev); | ||
77 | struct iio_chan_spec *chan_array; | 107 | struct iio_chan_spec *chan_array; |
108 | struct iio_chan_spec *chan; | ||
78 | int i; | 109 | int i; |
79 | 110 | ||
80 | indio_dev->num_channels = channels; | 111 | indio_dev->num_channels = channels; |
81 | chan_array = kcalloc(indio_dev->num_channels, | 112 | chan_array = kcalloc(channels, |
82 | sizeof(struct iio_chan_spec), GFP_KERNEL); | 113 | sizeof(struct iio_chan_spec), GFP_KERNEL); |
83 | |||
84 | if (chan_array == NULL) | 114 | if (chan_array == NULL) |
85 | return -ENOMEM; | 115 | return -ENOMEM; |
86 | 116 | ||
87 | for (i = 0; i < (indio_dev->num_channels); i++) { | 117 | chan = chan_array; |
88 | struct iio_chan_spec *chan = chan_array + i; | 118 | for (i = 0; i < channels; i++, chan++) { |
119 | |||
89 | chan->type = IIO_VOLTAGE; | 120 | chan->type = IIO_VOLTAGE; |
90 | chan->indexed = 1; | 121 | chan->indexed = 1; |
91 | chan->channel = i; | 122 | chan->channel = adc_dev->channel_line[i]; |
92 | chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); | 123 | chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); |
124 | chan->datasheet_name = chan_name_ain[chan->channel]; | ||
125 | chan->scan_type.sign = 'u'; | ||
126 | chan->scan_type.realbits = 12; | ||
127 | chan->scan_type.storagebits = 32; | ||
93 | } | 128 | } |
94 | 129 | ||
95 | indio_dev->channels = chan_array; | 130 | indio_dev->channels = chan_array; |
96 | 131 | ||
97 | return indio_dev->num_channels; | 132 | return 0; |
98 | } | 133 | } |
99 | 134 | ||
100 | static void tiadc_channels_remove(struct iio_dev *indio_dev) | 135 | static void tiadc_channels_remove(struct iio_dev *indio_dev) |
@@ -108,7 +143,9 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, | |||
108 | { | 143 | { |
109 | struct tiadc_device *adc_dev = iio_priv(indio_dev); | 144 | struct tiadc_device *adc_dev = iio_priv(indio_dev); |
110 | int i; | 145 | int i; |
111 | unsigned int fifo1count, readx1; | 146 | unsigned int fifo1count, read; |
147 | u32 step = UINT_MAX; | ||
148 | bool found = false; | ||
112 | 149 | ||
113 | /* | 150 | /* |
114 | * When the sub-system is first enabled, | 151 | * When the sub-system is first enabled, |
@@ -121,14 +158,26 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, | |||
121 | * Hence we need to flush out this data. | 158 | * Hence we need to flush out this data. |
122 | */ | 159 | */ |
123 | 160 | ||
161 | for (i = 0; i < ARRAY_SIZE(adc_dev->channel_step); i++) { | ||
162 | if (chan->channel == adc_dev->channel_line[i]) { | ||
163 | step = adc_dev->channel_step[i]; | ||
164 | break; | ||
165 | } | ||
166 | } | ||
167 | if (WARN_ON_ONCE(step == UINT_MAX)) | ||
168 | return -EINVAL; | ||
169 | |||
124 | fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT); | 170 | fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT); |
125 | for (i = 0; i < fifo1count; i++) { | 171 | for (i = 0; i < fifo1count; i++) { |
126 | readx1 = tiadc_readl(adc_dev, REG_FIFO1); | 172 | read = tiadc_readl(adc_dev, REG_FIFO1); |
127 | if (i == chan->channel) | 173 | if (read >> 16 == step) { |
128 | *val = readx1 & 0xfff; | 174 | *val = read & 0xfff; |
175 | found = true; | ||
176 | } | ||
129 | } | 177 | } |
130 | tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB); | 178 | am335x_tsc_se_update(adc_dev->mfd_tscadc); |
131 | 179 | if (found == false) | |
180 | return -EBUSY; | ||
132 | return IIO_VAL_INT; | 181 | return IIO_VAL_INT; |
133 | } | 182 | } |
134 | 183 | ||
@@ -140,13 +189,15 @@ static int tiadc_probe(struct platform_device *pdev) | |||
140 | { | 189 | { |
141 | struct iio_dev *indio_dev; | 190 | struct iio_dev *indio_dev; |
142 | struct tiadc_device *adc_dev; | 191 | struct tiadc_device *adc_dev; |
143 | struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data; | 192 | struct device_node *node = pdev->dev.of_node; |
144 | struct mfd_tscadc_board *pdata; | 193 | struct property *prop; |
194 | const __be32 *cur; | ||
145 | int err; | 195 | int err; |
196 | u32 val; | ||
197 | int channels = 0; | ||
146 | 198 | ||
147 | pdata = tscadc_dev->dev->platform_data; | 199 | if (!node) { |
148 | if (!pdata || !pdata->adc_init) { | 200 | dev_err(&pdev->dev, "Could not find valid DT data.\n"); |
149 | dev_err(&pdev->dev, "Could not find platform data\n"); | ||
150 | return -EINVAL; | 201 | return -EINVAL; |
151 | } | 202 | } |
152 | 203 | ||
@@ -158,8 +209,13 @@ static int tiadc_probe(struct platform_device *pdev) | |||
158 | } | 209 | } |
159 | adc_dev = iio_priv(indio_dev); | 210 | adc_dev = iio_priv(indio_dev); |
160 | 211 | ||
161 | adc_dev->mfd_tscadc = tscadc_dev; | 212 | adc_dev->mfd_tscadc = ti_tscadc_dev_get(pdev); |
162 | adc_dev->channels = pdata->adc_init->adc_channels; | 213 | |
214 | of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) { | ||
215 | adc_dev->channel_line[channels] = val; | ||
216 | channels++; | ||
217 | } | ||
218 | adc_dev->channels = channels; | ||
163 | 219 | ||
164 | indio_dev->dev.parent = &pdev->dev; | 220 | indio_dev->dev.parent = &pdev->dev; |
165 | indio_dev->name = dev_name(&pdev->dev); | 221 | indio_dev->name = dev_name(&pdev->dev); |
@@ -191,10 +247,15 @@ err_ret: | |||
191 | static int tiadc_remove(struct platform_device *pdev) | 247 | static int tiadc_remove(struct platform_device *pdev) |
192 | { | 248 | { |
193 | struct iio_dev *indio_dev = platform_get_drvdata(pdev); | 249 | struct iio_dev *indio_dev = platform_get_drvdata(pdev); |
250 | struct tiadc_device *adc_dev = iio_priv(indio_dev); | ||
251 | u32 step_en; | ||
194 | 252 | ||
195 | iio_device_unregister(indio_dev); | 253 | iio_device_unregister(indio_dev); |
196 | tiadc_channels_remove(indio_dev); | 254 | tiadc_channels_remove(indio_dev); |
197 | 255 | ||
256 | step_en = get_adc_step_mask(adc_dev); | ||
257 | am335x_tsc_se_clr(adc_dev->mfd_tscadc, step_en); | ||
258 | |||
198 | iio_device_free(indio_dev); | 259 | iio_device_free(indio_dev); |
199 | 260 | ||
200 | return 0; | 261 | return 0; |
@@ -205,9 +266,10 @@ static int tiadc_suspend(struct device *dev) | |||
205 | { | 266 | { |
206 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | 267 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
207 | struct tiadc_device *adc_dev = iio_priv(indio_dev); | 268 | struct tiadc_device *adc_dev = iio_priv(indio_dev); |
208 | struct ti_tscadc_dev *tscadc_dev = dev->platform_data; | 269 | struct ti_tscadc_dev *tscadc_dev; |
209 | unsigned int idle; | 270 | unsigned int idle; |
210 | 271 | ||
272 | tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev)); | ||
211 | if (!device_may_wakeup(tscadc_dev->dev)) { | 273 | if (!device_may_wakeup(tscadc_dev->dev)) { |
212 | idle = tiadc_readl(adc_dev, REG_CTRL); | 274 | idle = tiadc_readl(adc_dev, REG_CTRL); |
213 | idle &= ~(CNTRLREG_TSCSSENB); | 275 | idle &= ~(CNTRLREG_TSCSSENB); |
@@ -243,16 +305,22 @@ static const struct dev_pm_ops tiadc_pm_ops = { | |||
243 | #define TIADC_PM_OPS NULL | 305 | #define TIADC_PM_OPS NULL |
244 | #endif | 306 | #endif |
245 | 307 | ||
308 | static const struct of_device_id ti_adc_dt_ids[] = { | ||
309 | { .compatible = "ti,am3359-adc", }, | ||
310 | { } | ||
311 | }; | ||
312 | MODULE_DEVICE_TABLE(of, ti_adc_dt_ids); | ||
313 | |||
246 | static struct platform_driver tiadc_driver = { | 314 | static struct platform_driver tiadc_driver = { |
247 | .driver = { | 315 | .driver = { |
248 | .name = "tiadc", | 316 | .name = "TI-am335x-adc", |
249 | .owner = THIS_MODULE, | 317 | .owner = THIS_MODULE, |
250 | .pm = TIADC_PM_OPS, | 318 | .pm = TIADC_PM_OPS, |
319 | .of_match_table = of_match_ptr(ti_adc_dt_ids), | ||
251 | }, | 320 | }, |
252 | .probe = tiadc_probe, | 321 | .probe = tiadc_probe, |
253 | .remove = tiadc_remove, | 322 | .remove = tiadc_remove, |
254 | }; | 323 | }; |
255 | |||
256 | module_platform_driver(tiadc_driver); | 324 | module_platform_driver(tiadc_driver); |
257 | 325 | ||
258 | MODULE_DESCRIPTION("TI ADC controller driver"); | 326 | MODULE_DESCRIPTION("TI ADC controller driver"); |