diff options
Diffstat (limited to 'drivers/iio/trigger/stm32-timer-trigger.c')
-rw-r--r-- | drivers/iio/trigger/stm32-timer-trigger.c | 113 |
1 files changed, 99 insertions, 14 deletions
diff --git a/drivers/iio/trigger/stm32-timer-trigger.c b/drivers/iio/trigger/stm32-timer-trigger.c index 25248d644e7c..0797f2fe584f 100644 --- a/drivers/iio/trigger/stm32-timer-trigger.c +++ b/drivers/iio/trigger/stm32-timer-trigger.c | |||
@@ -14,19 +14,19 @@ | |||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | 16 | ||
17 | #define MAX_TRIGGERS 6 | 17 | #define MAX_TRIGGERS 7 |
18 | #define MAX_VALIDS 5 | 18 | #define MAX_VALIDS 5 |
19 | 19 | ||
20 | /* List the triggers created by each timer */ | 20 | /* List the triggers created by each timer */ |
21 | static const void *triggers_table[][MAX_TRIGGERS] = { | 21 | static const void *triggers_table[][MAX_TRIGGERS] = { |
22 | { TIM1_TRGO, TIM1_CH1, TIM1_CH2, TIM1_CH3, TIM1_CH4,}, | 22 | { TIM1_TRGO, TIM1_TRGO2, TIM1_CH1, TIM1_CH2, TIM1_CH3, TIM1_CH4,}, |
23 | { TIM2_TRGO, TIM2_CH1, TIM2_CH2, TIM2_CH3, TIM2_CH4,}, | 23 | { TIM2_TRGO, TIM2_CH1, TIM2_CH2, TIM2_CH3, TIM2_CH4,}, |
24 | { TIM3_TRGO, TIM3_CH1, TIM3_CH2, TIM3_CH3, TIM3_CH4,}, | 24 | { TIM3_TRGO, TIM3_CH1, TIM3_CH2, TIM3_CH3, TIM3_CH4,}, |
25 | { TIM4_TRGO, TIM4_CH1, TIM4_CH2, TIM4_CH3, TIM4_CH4,}, | 25 | { TIM4_TRGO, TIM4_CH1, TIM4_CH2, TIM4_CH3, TIM4_CH4,}, |
26 | { TIM5_TRGO, TIM5_CH1, TIM5_CH2, TIM5_CH3, TIM5_CH4,}, | 26 | { TIM5_TRGO, TIM5_CH1, TIM5_CH2, TIM5_CH3, TIM5_CH4,}, |
27 | { TIM6_TRGO,}, | 27 | { TIM6_TRGO,}, |
28 | { TIM7_TRGO,}, | 28 | { TIM7_TRGO,}, |
29 | { TIM8_TRGO, TIM8_CH1, TIM8_CH2, TIM8_CH3, TIM8_CH4,}, | 29 | { TIM8_TRGO, TIM8_TRGO2, TIM8_CH1, TIM8_CH2, TIM8_CH3, TIM8_CH4,}, |
30 | { TIM9_TRGO, TIM9_CH1, TIM9_CH2,}, | 30 | { TIM9_TRGO, TIM9_CH1, TIM9_CH2,}, |
31 | { }, /* timer 10 */ | 31 | { }, /* timer 10 */ |
32 | { }, /* timer 11 */ | 32 | { }, /* timer 11 */ |
@@ -56,9 +56,16 @@ struct stm32_timer_trigger { | |||
56 | u32 max_arr; | 56 | u32 max_arr; |
57 | const void *triggers; | 57 | const void *triggers; |
58 | const void *valids; | 58 | const void *valids; |
59 | bool has_trgo2; | ||
59 | }; | 60 | }; |
60 | 61 | ||
62 | static bool stm32_timer_is_trgo2_name(const char *name) | ||
63 | { | ||
64 | return !!strstr(name, "trgo2"); | ||
65 | } | ||
66 | |||
61 | static int stm32_timer_start(struct stm32_timer_trigger *priv, | 67 | static int stm32_timer_start(struct stm32_timer_trigger *priv, |
68 | struct iio_trigger *trig, | ||
62 | unsigned int frequency) | 69 | unsigned int frequency) |
63 | { | 70 | { |
64 | unsigned long long prd, div; | 71 | unsigned long long prd, div; |
@@ -102,7 +109,12 @@ static int stm32_timer_start(struct stm32_timer_trigger *priv, | |||
102 | regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE); | 109 | regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE); |
103 | 110 | ||
104 | /* Force master mode to update mode */ | 111 | /* Force master mode to update mode */ |
105 | regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS, 0x20); | 112 | if (stm32_timer_is_trgo2_name(trig->name)) |
113 | regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2, | ||
114 | 0x2 << TIM_CR2_MMS2_SHIFT); | ||
115 | else | ||
116 | regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS, | ||
117 | 0x2 << TIM_CR2_MMS_SHIFT); | ||
106 | 118 | ||
107 | /* Make sure that registers are updated */ | 119 | /* Make sure that registers are updated */ |
108 | regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); | 120 | regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); |
@@ -150,7 +162,7 @@ static ssize_t stm32_tt_store_frequency(struct device *dev, | |||
150 | if (freq == 0) { | 162 | if (freq == 0) { |
151 | stm32_timer_stop(priv); | 163 | stm32_timer_stop(priv); |
152 | } else { | 164 | } else { |
153 | ret = stm32_timer_start(priv, freq); | 165 | ret = stm32_timer_start(priv, trig, freq); |
154 | if (ret) | 166 | if (ret) |
155 | return ret; | 167 | return ret; |
156 | } | 168 | } |
@@ -183,6 +195,9 @@ static IIO_DEV_ATTR_SAMP_FREQ(0660, | |||
183 | stm32_tt_read_frequency, | 195 | stm32_tt_read_frequency, |
184 | stm32_tt_store_frequency); | 196 | stm32_tt_store_frequency); |
185 | 197 | ||
198 | #define MASTER_MODE_MAX 7 | ||
199 | #define MASTER_MODE2_MAX 15 | ||
200 | |||
186 | static char *master_mode_table[] = { | 201 | static char *master_mode_table[] = { |
187 | "reset", | 202 | "reset", |
188 | "enable", | 203 | "enable", |
@@ -191,7 +206,16 @@ static char *master_mode_table[] = { | |||
191 | "OC1REF", | 206 | "OC1REF", |
192 | "OC2REF", | 207 | "OC2REF", |
193 | "OC3REF", | 208 | "OC3REF", |
194 | "OC4REF" | 209 | "OC4REF", |
210 | /* Master mode selection 2 only */ | ||
211 | "OC5REF", | ||
212 | "OC6REF", | ||
213 | "compare_pulse_OC4REF", | ||
214 | "compare_pulse_OC6REF", | ||
215 | "compare_pulse_OC4REF_r_or_OC6REF_r", | ||
216 | "compare_pulse_OC4REF_r_or_OC6REF_f", | ||
217 | "compare_pulse_OC5REF_r_or_OC6REF_r", | ||
218 | "compare_pulse_OC5REF_r_or_OC6REF_f", | ||
195 | }; | 219 | }; |
196 | 220 | ||
197 | static ssize_t stm32_tt_show_master_mode(struct device *dev, | 221 | static ssize_t stm32_tt_show_master_mode(struct device *dev, |
@@ -199,10 +223,15 @@ static ssize_t stm32_tt_show_master_mode(struct device *dev, | |||
199 | char *buf) | 223 | char *buf) |
200 | { | 224 | { |
201 | struct stm32_timer_trigger *priv = dev_get_drvdata(dev); | 225 | struct stm32_timer_trigger *priv = dev_get_drvdata(dev); |
226 | struct iio_trigger *trig = to_iio_trigger(dev); | ||
202 | u32 cr2; | 227 | u32 cr2; |
203 | 228 | ||
204 | regmap_read(priv->regmap, TIM_CR2, &cr2); | 229 | regmap_read(priv->regmap, TIM_CR2, &cr2); |
205 | cr2 = (cr2 & TIM_CR2_MMS) >> TIM_CR2_MMS_SHIFT; | 230 | |
231 | if (stm32_timer_is_trgo2_name(trig->name)) | ||
232 | cr2 = (cr2 & TIM_CR2_MMS2) >> TIM_CR2_MMS2_SHIFT; | ||
233 | else | ||
234 | cr2 = (cr2 & TIM_CR2_MMS) >> TIM_CR2_MMS_SHIFT; | ||
206 | 235 | ||
207 | return snprintf(buf, PAGE_SIZE, "%s\n", master_mode_table[cr2]); | 236 | return snprintf(buf, PAGE_SIZE, "%s\n", master_mode_table[cr2]); |
208 | } | 237 | } |
@@ -212,13 +241,25 @@ static ssize_t stm32_tt_store_master_mode(struct device *dev, | |||
212 | const char *buf, size_t len) | 241 | const char *buf, size_t len) |
213 | { | 242 | { |
214 | struct stm32_timer_trigger *priv = dev_get_drvdata(dev); | 243 | struct stm32_timer_trigger *priv = dev_get_drvdata(dev); |
244 | struct iio_trigger *trig = to_iio_trigger(dev); | ||
245 | u32 mask, shift, master_mode_max; | ||
215 | int i; | 246 | int i; |
216 | 247 | ||
217 | for (i = 0; i < ARRAY_SIZE(master_mode_table); i++) { | 248 | if (stm32_timer_is_trgo2_name(trig->name)) { |
249 | mask = TIM_CR2_MMS2; | ||
250 | shift = TIM_CR2_MMS2_SHIFT; | ||
251 | master_mode_max = MASTER_MODE2_MAX; | ||
252 | } else { | ||
253 | mask = TIM_CR2_MMS; | ||
254 | shift = TIM_CR2_MMS_SHIFT; | ||
255 | master_mode_max = MASTER_MODE_MAX; | ||
256 | } | ||
257 | |||
258 | for (i = 0; i <= master_mode_max; i++) { | ||
218 | if (!strncmp(master_mode_table[i], buf, | 259 | if (!strncmp(master_mode_table[i], buf, |
219 | strlen(master_mode_table[i]))) { | 260 | strlen(master_mode_table[i]))) { |
220 | regmap_update_bits(priv->regmap, TIM_CR2, | 261 | regmap_update_bits(priv->regmap, TIM_CR2, mask, |
221 | TIM_CR2_MMS, i << TIM_CR2_MMS_SHIFT); | 262 | i << shift); |
222 | /* Make sure that registers are updated */ | 263 | /* Make sure that registers are updated */ |
223 | regmap_update_bits(priv->regmap, TIM_EGR, | 264 | regmap_update_bits(priv->regmap, TIM_EGR, |
224 | TIM_EGR_UG, TIM_EGR_UG); | 265 | TIM_EGR_UG, TIM_EGR_UG); |
@@ -229,8 +270,31 @@ static ssize_t stm32_tt_store_master_mode(struct device *dev, | |||
229 | return -EINVAL; | 270 | return -EINVAL; |
230 | } | 271 | } |
231 | 272 | ||
232 | static IIO_CONST_ATTR(master_mode_available, | 273 | static ssize_t stm32_tt_show_master_mode_avail(struct device *dev, |
233 | "reset enable update compare_pulse OC1REF OC2REF OC3REF OC4REF"); | 274 | struct device_attribute *attr, |
275 | char *buf) | ||
276 | { | ||
277 | struct iio_trigger *trig = to_iio_trigger(dev); | ||
278 | unsigned int i, master_mode_max; | ||
279 | size_t len = 0; | ||
280 | |||
281 | if (stm32_timer_is_trgo2_name(trig->name)) | ||
282 | master_mode_max = MASTER_MODE2_MAX; | ||
283 | else | ||
284 | master_mode_max = MASTER_MODE_MAX; | ||
285 | |||
286 | for (i = 0; i <= master_mode_max; i++) | ||
287 | len += scnprintf(buf + len, PAGE_SIZE - len, | ||
288 | "%s ", master_mode_table[i]); | ||
289 | |||
290 | /* replace trailing space by newline */ | ||
291 | buf[len - 1] = '\n'; | ||
292 | |||
293 | return len; | ||
294 | } | ||
295 | |||
296 | static IIO_DEVICE_ATTR(master_mode_available, 0444, | ||
297 | stm32_tt_show_master_mode_avail, NULL, 0); | ||
234 | 298 | ||
235 | static IIO_DEVICE_ATTR(master_mode, 0660, | 299 | static IIO_DEVICE_ATTR(master_mode, 0660, |
236 | stm32_tt_show_master_mode, | 300 | stm32_tt_show_master_mode, |
@@ -240,7 +304,7 @@ static IIO_DEVICE_ATTR(master_mode, 0660, | |||
240 | static struct attribute *stm32_trigger_attrs[] = { | 304 | static struct attribute *stm32_trigger_attrs[] = { |
241 | &iio_dev_attr_sampling_frequency.dev_attr.attr, | 305 | &iio_dev_attr_sampling_frequency.dev_attr.attr, |
242 | &iio_dev_attr_master_mode.dev_attr.attr, | 306 | &iio_dev_attr_master_mode.dev_attr.attr, |
243 | &iio_const_attr_master_mode_available.dev_attr.attr, | 307 | &iio_dev_attr_master_mode_available.dev_attr.attr, |
244 | NULL, | 308 | NULL, |
245 | }; | 309 | }; |
246 | 310 | ||
@@ -264,6 +328,12 @@ static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv) | |||
264 | 328 | ||
265 | while (cur && *cur) { | 329 | while (cur && *cur) { |
266 | struct iio_trigger *trig; | 330 | struct iio_trigger *trig; |
331 | bool cur_is_trgo2 = stm32_timer_is_trgo2_name(*cur); | ||
332 | |||
333 | if (cur_is_trgo2 && !priv->has_trgo2) { | ||
334 | cur++; | ||
335 | continue; | ||
336 | } | ||
267 | 337 | ||
268 | trig = devm_iio_trigger_alloc(priv->dev, "%s", *cur); | 338 | trig = devm_iio_trigger_alloc(priv->dev, "%s", *cur); |
269 | if (!trig) | 339 | if (!trig) |
@@ -277,7 +347,7 @@ static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv) | |||
277 | * should only be available on trgo trigger which | 347 | * should only be available on trgo trigger which |
278 | * is always the first in the list. | 348 | * is always the first in the list. |
279 | */ | 349 | */ |
280 | if (cur == priv->triggers) | 350 | if (cur == priv->triggers || cur_is_trgo2) |
281 | trig->dev.groups = stm32_trigger_attr_groups; | 351 | trig->dev.groups = stm32_trigger_attr_groups; |
282 | 352 | ||
283 | iio_trigger_set_drvdata(trig, priv); | 353 | iio_trigger_set_drvdata(trig, priv); |
@@ -584,6 +654,20 @@ bool is_stm32_timer_trigger(struct iio_trigger *trig) | |||
584 | } | 654 | } |
585 | EXPORT_SYMBOL(is_stm32_timer_trigger); | 655 | EXPORT_SYMBOL(is_stm32_timer_trigger); |
586 | 656 | ||
657 | static void stm32_timer_detect_trgo2(struct stm32_timer_trigger *priv) | ||
658 | { | ||
659 | u32 val; | ||
660 | |||
661 | /* | ||
662 | * Master mode selection 2 bits can only be written and read back when | ||
663 | * timer supports it. | ||
664 | */ | ||
665 | regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2, TIM_CR2_MMS2); | ||
666 | regmap_read(priv->regmap, TIM_CR2, &val); | ||
667 | regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2, 0); | ||
668 | priv->has_trgo2 = !!val; | ||
669 | } | ||
670 | |||
587 | static int stm32_timer_trigger_probe(struct platform_device *pdev) | 671 | static int stm32_timer_trigger_probe(struct platform_device *pdev) |
588 | { | 672 | { |
589 | struct device *dev = &pdev->dev; | 673 | struct device *dev = &pdev->dev; |
@@ -614,6 +698,7 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev) | |||
614 | priv->max_arr = ddata->max_arr; | 698 | priv->max_arr = ddata->max_arr; |
615 | priv->triggers = triggers_table[index]; | 699 | priv->triggers = triggers_table[index]; |
616 | priv->valids = valids_table[index]; | 700 | priv->valids = valids_table[index]; |
701 | stm32_timer_detect_trgo2(priv); | ||
617 | 702 | ||
618 | ret = stm32_setup_iio_triggers(priv); | 703 | ret = stm32_setup_iio_triggers(priv); |
619 | if (ret) | 704 | if (ret) |