diff options
| -rw-r--r-- | MAINTAINERS | 1 | ||||
| -rw-r--r-- | drivers/staging/iio/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/staging/iio/Makefile | 1 | ||||
| -rw-r--r-- | drivers/staging/iio/trigger/Kconfig | 19 | ||||
| -rw-r--r-- | drivers/staging/iio/trigger/Makefile | 5 | ||||
| -rw-r--r-- | drivers/staging/iio/trigger/iio-trig-bfin-timer.c | 292 | ||||
| -rw-r--r-- | drivers/staging/iio/trigger/iio-trig-bfin-timer.h | 25 |
7 files changed, 0 insertions, 344 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index c06fcd0e1514..48486a505a4e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -866,7 +866,6 @@ F: drivers/iio/*/ad* | |||
| 866 | F: drivers/iio/adc/ltc2497* | 866 | F: drivers/iio/adc/ltc2497* |
| 867 | X: drivers/iio/*/adjd* | 867 | X: drivers/iio/*/adjd* |
| 868 | F: drivers/staging/iio/*/ad* | 868 | F: drivers/staging/iio/*/ad* |
| 869 | F: drivers/staging/iio/trigger/iio-trig-bfin-timer.c | ||
| 870 | 869 | ||
| 871 | ANDROID CONFIG FRAGMENTS | 870 | ANDROID CONFIG FRAGMENTS |
| 872 | M: Rob Herring <robh@kernel.org> | 871 | M: Rob Herring <robh@kernel.org> |
diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index 8abc1ab3c0c7..bd9445956511 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig | |||
| @@ -14,6 +14,5 @@ source "drivers/staging/iio/impedance-analyzer/Kconfig" | |||
| 14 | source "drivers/staging/iio/light/Kconfig" | 14 | source "drivers/staging/iio/light/Kconfig" |
| 15 | source "drivers/staging/iio/meter/Kconfig" | 15 | source "drivers/staging/iio/meter/Kconfig" |
| 16 | source "drivers/staging/iio/resolver/Kconfig" | 16 | source "drivers/staging/iio/resolver/Kconfig" |
| 17 | source "drivers/staging/iio/trigger/Kconfig" | ||
| 18 | 17 | ||
| 19 | endmenu | 18 | endmenu |
diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile index 455bffc29649..e99a375c07b9 100644 --- a/drivers/staging/iio/Makefile +++ b/drivers/staging/iio/Makefile | |||
| @@ -13,4 +13,3 @@ obj-y += impedance-analyzer/ | |||
| 13 | obj-y += light/ | 13 | obj-y += light/ |
| 14 | obj-y += meter/ | 14 | obj-y += meter/ |
| 15 | obj-y += resolver/ | 15 | obj-y += resolver/ |
| 16 | obj-y += trigger/ | ||
diff --git a/drivers/staging/iio/trigger/Kconfig b/drivers/staging/iio/trigger/Kconfig deleted file mode 100644 index 0b01d24cea51..000000000000 --- a/drivers/staging/iio/trigger/Kconfig +++ /dev/null | |||
| @@ -1,19 +0,0 @@ | |||
| 1 | # | ||
| 2 | # Industrial I/O standalone triggers | ||
| 3 | # | ||
| 4 | comment "Triggers - standalone" | ||
| 5 | |||
| 6 | if IIO_TRIGGER | ||
| 7 | |||
| 8 | config IIO_BFIN_TMR_TRIGGER | ||
| 9 | tristate "Blackfin TIMER trigger" | ||
| 10 | depends on BLACKFIN | ||
| 11 | select BFIN_GPTIMERS | ||
| 12 | help | ||
| 13 | Provides support for using a Blackfin timer as IIO triggers. | ||
| 14 | If unsure, say N (but it's safe to say "Y"). | ||
| 15 | |||
| 16 | To compile this driver as a module, choose M here: the | ||
| 17 | module will be called iio-trig-bfin-timer. | ||
| 18 | |||
| 19 | endif # IIO_TRIGGER | ||
diff --git a/drivers/staging/iio/trigger/Makefile b/drivers/staging/iio/trigger/Makefile deleted file mode 100644 index 1300a21363db..000000000000 --- a/drivers/staging/iio/trigger/Makefile +++ /dev/null | |||
| @@ -1,5 +0,0 @@ | |||
| 1 | # | ||
| 2 | # Makefile for triggers not associated with iio-devices | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-$(CONFIG_IIO_BFIN_TMR_TRIGGER) += iio-trig-bfin-timer.o | ||
diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c deleted file mode 100644 index 71f11d7472c0..000000000000 --- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c +++ /dev/null | |||
| @@ -1,292 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2011 Analog Devices Inc. | ||
| 3 | * | ||
| 4 | * Licensed under the GPL-2. | ||
| 5 | * | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <linux/kernel.h> | ||
| 9 | #include <linux/module.h> | ||
| 10 | #include <linux/platform_device.h> | ||
| 11 | #include <linux/slab.h> | ||
| 12 | #include <linux/interrupt.h> | ||
| 13 | #include <linux/irq.h> | ||
| 14 | #include <linux/delay.h> | ||
| 15 | |||
| 16 | #include <asm/gptimers.h> | ||
| 17 | #include <asm/portmux.h> | ||
| 18 | |||
| 19 | #include <linux/iio/iio.h> | ||
| 20 | #include <linux/iio/trigger.h> | ||
| 21 | |||
| 22 | #include "iio-trig-bfin-timer.h" | ||
| 23 | |||
| 24 | struct bfin_timer { | ||
| 25 | unsigned short id, bit; | ||
| 26 | unsigned long irqbit; | ||
| 27 | int irq; | ||
| 28 | int pin; | ||
| 29 | }; | ||
| 30 | |||
| 31 | /* | ||
| 32 | * this covers all hardware timer configurations on | ||
| 33 | * all Blackfin derivatives out there today | ||
| 34 | */ | ||
| 35 | |||
| 36 | static struct bfin_timer iio_bfin_timer_code[MAX_BLACKFIN_GPTIMERS] = { | ||
| 37 | {TIMER0_id, TIMER0bit, TIMER_STATUS_TIMIL0, IRQ_TIMER0, P_TMR0}, | ||
| 38 | {TIMER1_id, TIMER1bit, TIMER_STATUS_TIMIL1, IRQ_TIMER1, P_TMR1}, | ||
| 39 | {TIMER2_id, TIMER2bit, TIMER_STATUS_TIMIL2, IRQ_TIMER2, P_TMR2}, | ||
| 40 | #if (MAX_BLACKFIN_GPTIMERS > 3) | ||
| 41 | {TIMER3_id, TIMER3bit, TIMER_STATUS_TIMIL3, IRQ_TIMER3, P_TMR3}, | ||
| 42 | {TIMER4_id, TIMER4bit, TIMER_STATUS_TIMIL4, IRQ_TIMER4, P_TMR4}, | ||
| 43 | {TIMER5_id, TIMER5bit, TIMER_STATUS_TIMIL5, IRQ_TIMER5, P_TMR5}, | ||
| 44 | {TIMER6_id, TIMER6bit, TIMER_STATUS_TIMIL6, IRQ_TIMER6, P_TMR6}, | ||
| 45 | {TIMER7_id, TIMER7bit, TIMER_STATUS_TIMIL7, IRQ_TIMER7, P_TMR7}, | ||
| 46 | #endif | ||
| 47 | #if (MAX_BLACKFIN_GPTIMERS > 8) | ||
| 48 | {TIMER8_id, TIMER8bit, TIMER_STATUS_TIMIL8, IRQ_TIMER8, P_TMR8}, | ||
| 49 | {TIMER9_id, TIMER9bit, TIMER_STATUS_TIMIL9, IRQ_TIMER9, P_TMR9}, | ||
| 50 | {TIMER10_id, TIMER10bit, TIMER_STATUS_TIMIL10, IRQ_TIMER10, P_TMR10}, | ||
| 51 | #if (MAX_BLACKFIN_GPTIMERS > 11) | ||
| 52 | {TIMER11_id, TIMER11bit, TIMER_STATUS_TIMIL11, IRQ_TIMER11, P_TMR11}, | ||
| 53 | #endif | ||
| 54 | #endif | ||
| 55 | }; | ||
| 56 | |||
| 57 | struct bfin_tmr_state { | ||
| 58 | struct iio_trigger *trig; | ||
| 59 | struct bfin_timer *t; | ||
| 60 | unsigned int timer_num; | ||
| 61 | bool output_enable; | ||
| 62 | unsigned int duty; | ||
| 63 | int irq; | ||
| 64 | }; | ||
| 65 | |||
| 66 | static int iio_bfin_tmr_set_state(struct iio_trigger *trig, bool state) | ||
| 67 | { | ||
| 68 | struct bfin_tmr_state *st = iio_trigger_get_drvdata(trig); | ||
| 69 | |||
| 70 | if (get_gptimer_period(st->t->id) == 0) | ||
| 71 | return -EINVAL; | ||
| 72 | |||
| 73 | if (state) | ||
| 74 | enable_gptimers(st->t->bit); | ||
| 75 | else | ||
| 76 | disable_gptimers(st->t->bit); | ||
| 77 | |||
| 78 | return 0; | ||
| 79 | } | ||
| 80 | |||
| 81 | static ssize_t frequency_store(struct device *dev, | ||
| 82 | struct device_attribute *attr, | ||
| 83 | const char *buf, size_t count) | ||
| 84 | { | ||
| 85 | struct iio_trigger *trig = to_iio_trigger(dev); | ||
| 86 | struct bfin_tmr_state *st = iio_trigger_get_drvdata(trig); | ||
| 87 | unsigned int val; | ||
| 88 | bool enabled; | ||
| 89 | int ret; | ||
| 90 | |||
| 91 | ret = kstrtouint(buf, 10, &val); | ||
| 92 | if (ret) | ||
| 93 | return ret; | ||
| 94 | |||
| 95 | if (val > 100000) | ||
| 96 | return -EINVAL; | ||
| 97 | |||
| 98 | enabled = get_enabled_gptimers() & st->t->bit; | ||
| 99 | |||
| 100 | if (enabled) | ||
| 101 | disable_gptimers(st->t->bit); | ||
| 102 | |||
| 103 | if (!val) | ||
| 104 | return count; | ||
| 105 | |||
| 106 | val = get_sclk() / val; | ||
| 107 | if (val <= 4 || val <= st->duty) | ||
| 108 | return -EINVAL; | ||
| 109 | |||
| 110 | set_gptimer_period(st->t->id, val); | ||
| 111 | set_gptimer_pwidth(st->t->id, val - st->duty); | ||
| 112 | |||
| 113 | if (enabled) | ||
| 114 | enable_gptimers(st->t->bit); | ||
| 115 | |||
| 116 | return count; | ||
| 117 | } | ||
| 118 | |||
| 119 | static ssize_t frequency_show(struct device *dev, | ||
| 120 | struct device_attribute *attr, | ||
| 121 | char *buf) | ||
| 122 | { | ||
| 123 | struct iio_trigger *trig = to_iio_trigger(dev); | ||
| 124 | struct bfin_tmr_state *st = iio_trigger_get_drvdata(trig); | ||
| 125 | unsigned int period = get_gptimer_period(st->t->id); | ||
| 126 | unsigned long val; | ||
| 127 | |||
| 128 | if (!period) | ||
| 129 | val = 0; | ||
| 130 | else | ||
| 131 | val = get_sclk() / get_gptimer_period(st->t->id); | ||
| 132 | |||
| 133 | return sprintf(buf, "%lu\n", val); | ||
| 134 | } | ||
| 135 | |||
| 136 | static DEVICE_ATTR_RW(frequency); | ||
| 137 | |||
| 138 | static struct attribute *iio_bfin_tmr_trigger_attrs[] = { | ||
| 139 | &dev_attr_frequency.attr, | ||
| 140 | NULL, | ||
| 141 | }; | ||
| 142 | |||
| 143 | static const struct attribute_group iio_bfin_tmr_trigger_attr_group = { | ||
| 144 | .attrs = iio_bfin_tmr_trigger_attrs, | ||
| 145 | }; | ||
| 146 | |||
| 147 | static const struct attribute_group *iio_bfin_tmr_trigger_attr_groups[] = { | ||
| 148 | &iio_bfin_tmr_trigger_attr_group, | ||
| 149 | NULL | ||
| 150 | }; | ||
| 151 | |||
| 152 | static irqreturn_t iio_bfin_tmr_trigger_isr(int irq, void *devid) | ||
| 153 | { | ||
| 154 | struct bfin_tmr_state *st = devid; | ||
| 155 | |||
| 156 | clear_gptimer_intr(st->t->id); | ||
| 157 | iio_trigger_poll(st->trig); | ||
| 158 | |||
| 159 | return IRQ_HANDLED; | ||
| 160 | } | ||
| 161 | |||
| 162 | static int iio_bfin_tmr_get_number(int irq) | ||
| 163 | { | ||
| 164 | int i; | ||
| 165 | |||
| 166 | for (i = 0; i < MAX_BLACKFIN_GPTIMERS; i++) | ||
| 167 | if (iio_bfin_timer_code[i].irq == irq) | ||
| 168 | return i; | ||
| 169 | |||
| 170 | return -ENODEV; | ||
| 171 | } | ||
| 172 | |||
| 173 | static const struct iio_trigger_ops iio_bfin_tmr_trigger_ops = { | ||
| 174 | .set_trigger_state = iio_bfin_tmr_set_state, | ||
| 175 | }; | ||
| 176 | |||
| 177 | static int iio_bfin_tmr_trigger_probe(struct platform_device *pdev) | ||
| 178 | { | ||
| 179 | struct iio_bfin_timer_trigger_pdata *pdata; | ||
| 180 | struct bfin_tmr_state *st; | ||
| 181 | unsigned int config; | ||
| 182 | int ret; | ||
| 183 | |||
| 184 | st = devm_kzalloc(&pdev->dev, sizeof(*st), GFP_KERNEL); | ||
| 185 | if (!st) | ||
| 186 | return -ENOMEM; | ||
| 187 | |||
| 188 | st->irq = platform_get_irq(pdev, 0); | ||
| 189 | if (st->irq < 0) { | ||
| 190 | dev_err(&pdev->dev, "No IRQs specified"); | ||
| 191 | return st->irq; | ||
| 192 | } | ||
| 193 | |||
| 194 | ret = iio_bfin_tmr_get_number(st->irq); | ||
| 195 | if (ret < 0) | ||
| 196 | return ret; | ||
| 197 | |||
| 198 | st->timer_num = ret; | ||
| 199 | st->t = &iio_bfin_timer_code[st->timer_num]; | ||
| 200 | |||
| 201 | st->trig = iio_trigger_alloc("bfintmr%d", st->timer_num); | ||
| 202 | if (!st->trig) | ||
| 203 | return -ENOMEM; | ||
| 204 | |||
| 205 | st->trig->ops = &iio_bfin_tmr_trigger_ops; | ||
| 206 | st->trig->dev.groups = iio_bfin_tmr_trigger_attr_groups; | ||
| 207 | iio_trigger_set_drvdata(st->trig, st); | ||
| 208 | ret = iio_trigger_register(st->trig); | ||
| 209 | if (ret) | ||
| 210 | goto out; | ||
| 211 | |||
| 212 | ret = request_irq(st->irq, iio_bfin_tmr_trigger_isr, | ||
| 213 | 0, st->trig->name, st); | ||
| 214 | if (ret) { | ||
| 215 | dev_err(&pdev->dev, | ||
| 216 | "request IRQ-%d failed", st->irq); | ||
| 217 | goto out1; | ||
| 218 | } | ||
| 219 | |||
| 220 | config = PWM_OUT | PERIOD_CNT | IRQ_ENA; | ||
| 221 | |||
| 222 | pdata = dev_get_platdata(&pdev->dev); | ||
| 223 | if (pdata && pdata->output_enable) { | ||
| 224 | unsigned long long val; | ||
| 225 | |||
| 226 | st->output_enable = true; | ||
| 227 | |||
| 228 | ret = peripheral_request(st->t->pin, st->trig->name); | ||
| 229 | if (ret) | ||
| 230 | goto out_free_irq; | ||
| 231 | |||
| 232 | val = (unsigned long long)get_sclk() * pdata->duty_ns; | ||
| 233 | do_div(val, NSEC_PER_SEC); | ||
| 234 | st->duty = val; | ||
| 235 | |||
| 236 | /** | ||
| 237 | * The interrupt will be generated at the end of the period, | ||
| 238 | * since we want the interrupt to be generated at end of the | ||
| 239 | * pulse we invert both polarity and duty cycle, so that the | ||
| 240 | * pulse will be generated directly before the interrupt. | ||
| 241 | */ | ||
| 242 | if (pdata->active_low) | ||
| 243 | config |= PULSE_HI; | ||
| 244 | } else { | ||
| 245 | st->duty = 1; | ||
| 246 | config |= OUT_DIS; | ||
| 247 | } | ||
| 248 | |||
| 249 | set_gptimer_config(st->t->id, config); | ||
| 250 | |||
| 251 | dev_info(&pdev->dev, "iio trigger Blackfin TMR%d, IRQ-%d", | ||
| 252 | st->timer_num, st->irq); | ||
| 253 | platform_set_drvdata(pdev, st); | ||
| 254 | |||
| 255 | return 0; | ||
| 256 | out_free_irq: | ||
| 257 | free_irq(st->irq, st); | ||
| 258 | out1: | ||
| 259 | iio_trigger_unregister(st->trig); | ||
| 260 | out: | ||
| 261 | iio_trigger_free(st->trig); | ||
| 262 | return ret; | ||
| 263 | } | ||
| 264 | |||
| 265 | static int iio_bfin_tmr_trigger_remove(struct platform_device *pdev) | ||
| 266 | { | ||
| 267 | struct bfin_tmr_state *st = platform_get_drvdata(pdev); | ||
| 268 | |||
| 269 | disable_gptimers(st->t->bit); | ||
| 270 | if (st->output_enable) | ||
| 271 | peripheral_free(st->t->pin); | ||
| 272 | free_irq(st->irq, st); | ||
| 273 | iio_trigger_unregister(st->trig); | ||
| 274 | iio_trigger_free(st->trig); | ||
| 275 | |||
| 276 | return 0; | ||
| 277 | } | ||
| 278 | |||
| 279 | static struct platform_driver iio_bfin_tmr_trigger_driver = { | ||
| 280 | .driver = { | ||
| 281 | .name = "iio_bfin_tmr_trigger", | ||
| 282 | }, | ||
| 283 | .probe = iio_bfin_tmr_trigger_probe, | ||
| 284 | .remove = iio_bfin_tmr_trigger_remove, | ||
| 285 | }; | ||
| 286 | |||
| 287 | module_platform_driver(iio_bfin_tmr_trigger_driver); | ||
| 288 | |||
| 289 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
| 290 | MODULE_DESCRIPTION("Blackfin system timer based trigger for the iio subsystem"); | ||
| 291 | MODULE_LICENSE("GPL v2"); | ||
| 292 | MODULE_ALIAS("platform:iio-trig-bfin-timer"); | ||
diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.h b/drivers/staging/iio/trigger/iio-trig-bfin-timer.h deleted file mode 100644 index fb05a2a8397c..000000000000 --- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.h +++ /dev/null | |||
| @@ -1,25 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | #ifndef __IIO_BFIN_TIMER_TRIGGER_H__ | ||
| 3 | #define __IIO_BFIN_TIMER_TRIGGER_H__ | ||
| 4 | |||
| 5 | /** | ||
| 6 | * struct iio_bfin_timer_trigger_pdata - timer trigger platform data | ||
| 7 | * @output_enable: Enable external trigger pulse generation. | ||
| 8 | * @active_low: Whether the trigger pulse is active low. | ||
| 9 | * @duty_ns: Length of the trigger pulse in nanoseconds. | ||
| 10 | * | ||
| 11 | * This struct is used to configure the output pulse generation of the blackfin | ||
| 12 | * timer trigger. If output_enable is set to true an external trigger signal | ||
| 13 | * will generated on the pin corresponding to the timer. This is useful for | ||
| 14 | * converters which needs an external signal to start conversion. active_low and | ||
| 15 | * duty_ns are used to configure the type of the trigger pulse. If output_enable | ||
| 16 | * is set to false no external trigger pulse will be generated and active_low | ||
| 17 | * and duty_ns are ignored. | ||
| 18 | **/ | ||
| 19 | struct iio_bfin_timer_trigger_pdata { | ||
| 20 | bool output_enable; | ||
| 21 | bool active_low; | ||
| 22 | unsigned int duty_ns; | ||
| 23 | }; | ||
| 24 | |||
| 25 | #endif | ||
