Lines Matching +full:ftm +full:- +full:timer

1 // SPDX-License-Identifier: GPL-2.0
3 * Flex Timer Module Quadrature decoder
5 * This module implements a driver for decoding the FTM quadrature
9 #include <linux/fsl/ftm.h>
19 #define FTM_FIELD_UPDATE(ftm, offset, mask, val) \ argument
22 ftm_read(ftm, offset, &flags); \
25 ftm_write(ftm, offset, flags); \
35 static void ftm_read(struct ftm_quaddec *ftm, uint32_t offset, uint32_t *data) in ftm_read() argument
37 if (ftm->big_endian) in ftm_read()
38 *data = ioread32be(ftm->ftm_base + offset); in ftm_read()
40 *data = ioread32(ftm->ftm_base + offset); in ftm_read()
43 static void ftm_write(struct ftm_quaddec *ftm, uint32_t offset, uint32_t data) in ftm_write() argument
45 if (ftm->big_endian) in ftm_write()
46 iowrite32be(data, ftm->ftm_base + offset); in ftm_write()
48 iowrite32(data, ftm->ftm_base + offset); in ftm_write()
52 static void ftm_clear_write_protection(struct ftm_quaddec *ftm) in ftm_clear_write_protection() argument
57 ftm_read(ftm, FTM_FMS, &flag); in ftm_clear_write_protection()
60 FTM_FIELD_UPDATE(ftm, FTM_MODE, FTM_MODE_WPDIS, 1); in ftm_clear_write_protection()
63 static void ftm_set_write_protection(struct ftm_quaddec *ftm) in ftm_set_write_protection() argument
65 FTM_FIELD_UPDATE(ftm, FTM_FMS, FTM_FMS_WPEN, 1); in ftm_set_write_protection()
68 static void ftm_reset_counter(struct ftm_quaddec *ftm) in ftm_reset_counter() argument
71 ftm_write(ftm, FTM_CNT, 0x0); in ftm_reset_counter()
74 static void ftm_quaddec_init(struct ftm_quaddec *ftm) in ftm_quaddec_init() argument
76 ftm_clear_write_protection(ftm); in ftm_quaddec_init()
83 ftm_write(ftm, FTM_MODE, FTM_MODE_FTMEN); in ftm_quaddec_init()
84 ftm_write(ftm, FTM_CNTIN, 0x0000); in ftm_quaddec_init()
85 ftm_write(ftm, FTM_MOD, 0xffff); in ftm_quaddec_init()
86 ftm_write(ftm, FTM_CNT, 0x0); in ftm_quaddec_init()
88 ftm_write(ftm, FTM_SC, FTM_SC_PS_1); in ftm_quaddec_init()
91 ftm_write(ftm, FTM_QDCTRL, FTM_QDCTRL_QUADEN); in ftm_quaddec_init()
94 ftm_write(ftm, FTM_POL, 0x0); in ftm_quaddec_init()
95 ftm_write(ftm, FTM_FLTCTRL, 0x0); in ftm_quaddec_init()
96 ftm_write(ftm, FTM_SYNCONF, 0x0); in ftm_quaddec_init()
97 ftm_write(ftm, FTM_SYNC, 0xffff); in ftm_quaddec_init()
99 /* Lock the FTM */ in ftm_quaddec_init()
100 ftm_set_write_protection(ftm); in ftm_quaddec_init()
103 static void ftm_quaddec_disable(void *ftm) in ftm_quaddec_disable() argument
105 struct ftm_quaddec *ftm_qua = ftm; in ftm_quaddec_disable()
120 struct ftm_quaddec *ftm = counter_priv(counter); in ftm_quaddec_get_prescaler() local
123 ftm_read(ftm, FTM_SC, &scflags); in ftm_quaddec_get_prescaler()
133 struct ftm_quaddec *ftm = counter_priv(counter); in ftm_quaddec_set_prescaler() local
135 mutex_lock(&ftm->ftm_quaddec_mutex); in ftm_quaddec_set_prescaler()
137 ftm_clear_write_protection(ftm); in ftm_quaddec_set_prescaler()
138 FTM_FIELD_UPDATE(ftm, FTM_SC, FTM_SC_PS_MASK, cnt_mode); in ftm_quaddec_set_prescaler()
139 ftm_set_write_protection(ftm); in ftm_quaddec_set_prescaler()
142 ftm_reset_counter(ftm); in ftm_quaddec_set_prescaler()
144 mutex_unlock(&ftm->ftm_quaddec_mutex); in ftm_quaddec_set_prescaler()
164 struct ftm_quaddec *const ftm = counter_priv(counter); in ftm_quaddec_count_read() local
167 ftm_read(ftm, FTM_CNT, &cntval); in ftm_quaddec_count_read()
178 struct ftm_quaddec *const ftm = counter_priv(counter); in ftm_quaddec_count_write() local
181 dev_warn(&ftm->pdev->dev, "Can only accept '0' as new counter value\n"); in ftm_quaddec_count_write()
182 return -EINVAL; in ftm_quaddec_count_write()
185 ftm_reset_counter(ftm); in ftm_quaddec_count_write()
262 struct ftm_quaddec *ftm; in ftm_quaddec_probe() local
264 struct device_node *node = pdev->dev.of_node; in ftm_quaddec_probe()
268 counter = devm_counter_alloc(&pdev->dev, sizeof(*ftm)); in ftm_quaddec_probe()
270 return -ENOMEM; in ftm_quaddec_probe()
271 ftm = counter_priv(counter); in ftm_quaddec_probe()
275 dev_err(&pdev->dev, "Failed to get memory region\n"); in ftm_quaddec_probe()
276 return -ENODEV; in ftm_quaddec_probe()
279 ftm->pdev = pdev; in ftm_quaddec_probe()
280 ftm->big_endian = of_property_read_bool(node, "big-endian"); in ftm_quaddec_probe()
281 ftm->ftm_base = devm_ioremap(&pdev->dev, io->start, resource_size(io)); in ftm_quaddec_probe()
283 if (!ftm->ftm_base) { in ftm_quaddec_probe()
284 dev_err(&pdev->dev, "Failed to map memory region\n"); in ftm_quaddec_probe()
285 return -EINVAL; in ftm_quaddec_probe()
287 counter->name = dev_name(&pdev->dev); in ftm_quaddec_probe()
288 counter->parent = &pdev->dev; in ftm_quaddec_probe()
289 counter->ops = &ftm_quaddec_cnt_ops; in ftm_quaddec_probe()
290 counter->counts = &ftm_quaddec_counts; in ftm_quaddec_probe()
291 counter->num_counts = 1; in ftm_quaddec_probe()
292 counter->signals = ftm_quaddec_signals; in ftm_quaddec_probe()
293 counter->num_signals = ARRAY_SIZE(ftm_quaddec_signals); in ftm_quaddec_probe()
295 mutex_init(&ftm->ftm_quaddec_mutex); in ftm_quaddec_probe()
297 ftm_quaddec_init(ftm); in ftm_quaddec_probe()
299 ret = devm_add_action_or_reset(&pdev->dev, ftm_quaddec_disable, ftm); in ftm_quaddec_probe()
303 ret = devm_counter_add(&pdev->dev, counter); in ftm_quaddec_probe()
305 return dev_err_probe(&pdev->dev, ret, "Failed to add counter\n"); in ftm_quaddec_probe()
311 { .compatible = "fsl,ftm-quaddec" },
318 .name = "ftm-quaddec",
326 MODULE_DESCRIPTION("Flex Timer Module Quadrature decoder");