]> Git Repo - linux.git/blame - drivers/spi/spi-rzv2m-csi.c
spi: rzv2m-csi: Add missing include
[linux.git] / drivers / spi / spi-rzv2m-csi.c
CommitLineData
83c624d8
FC
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Renesas RZ/V2M Clocked Serial Interface (CSI) driver
4 *
5 * Copyright (C) 2023 Renesas Electronics Corporation
6 */
7
f572ba79 8#include <linux/bits.h>
83c624d8
FC
9#include <linux/clk.h>
10#include <linux/count_zeros.h>
11#include <linux/interrupt.h>
12#include <linux/iopoll.h>
13#include <linux/platform_device.h>
14#include <linux/reset.h>
15#include <linux/spi/spi.h>
16
17/* Registers */
18#define CSI_MODE 0x00 /* CSI mode control */
19#define CSI_CLKSEL 0x04 /* CSI clock select */
20#define CSI_CNT 0x08 /* CSI control */
21#define CSI_INT 0x0C /* CSI interrupt status */
22#define CSI_IFIFOL 0x10 /* CSI receive FIFO level display */
23#define CSI_OFIFOL 0x14 /* CSI transmit FIFO level display */
24#define CSI_IFIFO 0x18 /* CSI receive window */
25#define CSI_OFIFO 0x1C /* CSI transmit window */
26#define CSI_FIFOTRG 0x20 /* CSI FIFO trigger level */
27
28/* CSI_MODE */
29#define CSI_MODE_CSIE BIT(7)
30#define CSI_MODE_TRMD BIT(6)
31#define CSI_MODE_CCL BIT(5)
32#define CSI_MODE_DIR BIT(4)
33#define CSI_MODE_CSOT BIT(0)
34
35#define CSI_MODE_SETUP 0x00000040
36
37/* CSI_CLKSEL */
38#define CSI_CLKSEL_CKP BIT(17)
39#define CSI_CLKSEL_DAP BIT(16)
40#define CSI_CLKSEL_SLAVE BIT(15)
41#define CSI_CLKSEL_CKS GENMASK(14, 1)
42
43/* CSI_CNT */
44#define CSI_CNT_CSIRST BIT(28)
45#define CSI_CNT_R_TRGEN BIT(19)
46#define CSI_CNT_UNDER_E BIT(13)
47#define CSI_CNT_OVERF_E BIT(12)
48#define CSI_CNT_TREND_E BIT(9)
49#define CSI_CNT_CSIEND_E BIT(8)
50#define CSI_CNT_T_TRGR_E BIT(4)
51#define CSI_CNT_R_TRGR_E BIT(0)
52
53/* CSI_INT */
54#define CSI_INT_UNDER BIT(13)
55#define CSI_INT_OVERF BIT(12)
56#define CSI_INT_TREND BIT(9)
57#define CSI_INT_CSIEND BIT(8)
58#define CSI_INT_T_TRGR BIT(4)
59#define CSI_INT_R_TRGR BIT(0)
60
61/* CSI_FIFOTRG */
62#define CSI_FIFOTRG_R_TRG GENMASK(2, 0)
63
64#define CSI_FIFO_SIZE_BYTES 32
65#define CSI_FIFO_HALF_SIZE 16
66#define CSI_EN_DIS_TIMEOUT_US 100
67#define CSI_CKS_MAX 0x3FFF
68
69#define UNDERRUN_ERROR BIT(0)
70#define OVERFLOW_ERROR BIT(1)
71#define TX_TIMEOUT_ERROR BIT(2)
72#define RX_TIMEOUT_ERROR BIT(3)
73
74#define CSI_MAX_SPI_SCKO 8000000
75
76struct rzv2m_csi_priv {
77 void __iomem *base;
78 struct clk *csiclk;
79 struct clk *pclk;
80 struct device *dev;
81 struct spi_controller *controller;
82 const u8 *txbuf;
83 u8 *rxbuf;
84 int buffer_len;
85 int bytes_sent;
86 int bytes_received;
87 int bytes_to_transfer;
88 int words_to_transfer;
89 unsigned char bytes_per_word;
90 wait_queue_head_t wait;
91 u8 errors;
92 u32 status;
93};
94
95static const unsigned char x_trg[] = {
96 0, 1, 1, 2, 2, 2, 2, 3,
97 3, 3, 3, 3, 3, 3, 3, 4,
98 4, 4, 4, 4, 4, 4, 4, 4,
99 4, 4, 4, 4, 4, 4, 4, 5
100};
101
102static const unsigned char x_trg_words[] = {
103 1, 2, 2, 4, 4, 4, 4, 8,
104 8, 8, 8, 8, 8, 8, 8, 16,
105 16, 16, 16, 16, 16, 16, 16, 16,
106 16, 16, 16, 16, 16, 16, 16, 32
107};
108
109static void rzv2m_csi_reg_write_bit(const struct rzv2m_csi_priv *csi,
110 int reg_offs, int bit_mask, u32 value)
111{
112 int nr_zeros;
113 u32 tmp;
114
115 nr_zeros = count_trailing_zeros(bit_mask);
116 value <<= nr_zeros;
117
118 tmp = (readl(csi->base + reg_offs) & ~bit_mask) | value;
119 writel(tmp, csi->base + reg_offs);
120}
121
122static int rzv2m_csi_sw_reset(struct rzv2m_csi_priv *csi, int assert)
123{
124 u32 reg;
125
126 rzv2m_csi_reg_write_bit(csi, CSI_CNT, CSI_CNT_CSIRST, assert);
127
128 if (assert) {
129 return readl_poll_timeout(csi->base + CSI_MODE, reg,
130 !(reg & CSI_MODE_CSOT), 0,
131 CSI_EN_DIS_TIMEOUT_US);
132 }
133
134 return 0;
135}
136
137static int rzv2m_csi_start_stop_operation(const struct rzv2m_csi_priv *csi,
138 int enable, bool wait)
139{
140 u32 reg;
141
142 rzv2m_csi_reg_write_bit(csi, CSI_MODE, CSI_MODE_CSIE, enable);
143
144 if (!enable && wait)
145 return readl_poll_timeout(csi->base + CSI_MODE, reg,
146 !(reg & CSI_MODE_CSOT), 0,
147 CSI_EN_DIS_TIMEOUT_US);
148
149 return 0;
150}
151
152static int rzv2m_csi_fill_txfifo(struct rzv2m_csi_priv *csi)
153{
154 int i;
155
156 if (readl(csi->base + CSI_OFIFOL))
157 return -EIO;
158
159 if (csi->bytes_per_word == 2) {
160 u16 *buf = (u16 *)csi->txbuf;
161
162 for (i = 0; i < csi->words_to_transfer; i++)
163 writel(buf[i], csi->base + CSI_OFIFO);
164 } else {
165 u8 *buf = (u8 *)csi->txbuf;
166
167 for (i = 0; i < csi->words_to_transfer; i++)
168 writel(buf[i], csi->base + CSI_OFIFO);
169 }
170
171 csi->txbuf += csi->bytes_to_transfer;
172 csi->bytes_sent += csi->bytes_to_transfer;
173
174 return 0;
175}
176
177static int rzv2m_csi_read_rxfifo(struct rzv2m_csi_priv *csi)
178{
179 int i;
180
181 if (readl(csi->base + CSI_IFIFOL) != csi->bytes_to_transfer)
182 return -EIO;
183
184 if (csi->bytes_per_word == 2) {
185 u16 *buf = (u16 *)csi->rxbuf;
186
187 for (i = 0; i < csi->words_to_transfer; i++)
188 buf[i] = (u16)readl(csi->base + CSI_IFIFO);
189 } else {
190 u8 *buf = (u8 *)csi->rxbuf;
191
192 for (i = 0; i < csi->words_to_transfer; i++)
193 buf[i] = (u8)readl(csi->base + CSI_IFIFO);
194 }
195
196 csi->rxbuf += csi->bytes_to_transfer;
197 csi->bytes_received += csi->bytes_to_transfer;
198
199 return 0;
200}
201
202static inline void rzv2m_csi_calc_current_transfer(struct rzv2m_csi_priv *csi)
203{
204 int bytes_transferred = max_t(int, csi->bytes_received, csi->bytes_sent);
205 int bytes_remaining = csi->buffer_len - bytes_transferred;
206 int to_transfer;
207
208 if (csi->txbuf)
209 /*
210 * Leaving a little bit of headroom in the FIFOs makes it very
211 * hard to raise an overflow error (which is only possible
212 * when IP transmits and receives at the same time).
213 */
214 to_transfer = min_t(int, CSI_FIFO_HALF_SIZE, bytes_remaining);
215 else
216 to_transfer = min_t(int, CSI_FIFO_SIZE_BYTES, bytes_remaining);
217
218 if (csi->bytes_per_word == 2)
219 to_transfer >>= 1;
220
221 /*
222 * We can only choose a trigger level from a predefined set of values.
223 * This will pick a value that is the greatest possible integer that's
224 * less than or equal to the number of bytes we need to transfer.
225 * This may result in multiple smaller transfers.
226 */
227 csi->words_to_transfer = x_trg_words[to_transfer - 1];
228
229 if (csi->bytes_per_word == 2)
230 csi->bytes_to_transfer = csi->words_to_transfer << 1;
231 else
232 csi->bytes_to_transfer = csi->words_to_transfer;
233}
234
235static inline void rzv2m_csi_set_rx_fifo_trigger_level(struct rzv2m_csi_priv *csi)
236{
237 rzv2m_csi_reg_write_bit(csi, CSI_FIFOTRG, CSI_FIFOTRG_R_TRG,
238 x_trg[csi->words_to_transfer - 1]);
239}
240
241static inline void rzv2m_csi_enable_rx_trigger(struct rzv2m_csi_priv *csi,
242 bool enable)
243{
244 rzv2m_csi_reg_write_bit(csi, CSI_CNT, CSI_CNT_R_TRGEN, enable);
245}
246
247static void rzv2m_csi_disable_irqs(const struct rzv2m_csi_priv *csi,
248 u32 enable_bits)
249{
250 u32 cnt = readl(csi->base + CSI_CNT);
251
252 writel(cnt & ~enable_bits, csi->base + CSI_CNT);
253}
254
255static void rzv2m_csi_disable_all_irqs(struct rzv2m_csi_priv *csi)
256{
257 rzv2m_csi_disable_irqs(csi, CSI_CNT_R_TRGR_E | CSI_CNT_T_TRGR_E |
258 CSI_CNT_CSIEND_E | CSI_CNT_TREND_E |
259 CSI_CNT_OVERF_E | CSI_CNT_UNDER_E);
260}
261
262static inline void rzv2m_csi_clear_irqs(struct rzv2m_csi_priv *csi, u32 irqs)
263{
264 writel(irqs, csi->base + CSI_INT);
265}
266
267static void rzv2m_csi_clear_all_irqs(struct rzv2m_csi_priv *csi)
268{
269 rzv2m_csi_clear_irqs(csi, CSI_INT_UNDER | CSI_INT_OVERF |
270 CSI_INT_TREND | CSI_INT_CSIEND | CSI_INT_T_TRGR |
271 CSI_INT_R_TRGR);
272}
273
274static void rzv2m_csi_enable_irqs(struct rzv2m_csi_priv *csi, u32 enable_bits)
275{
276 u32 cnt = readl(csi->base + CSI_CNT);
277
278 writel(cnt | enable_bits, csi->base + CSI_CNT);
279}
280
281static int rzv2m_csi_wait_for_interrupt(struct rzv2m_csi_priv *csi,
282 u32 wait_mask, u32 enable_bits)
283{
284 int ret;
285
286 rzv2m_csi_enable_irqs(csi, enable_bits);
287
288 ret = wait_event_timeout(csi->wait,
289 ((csi->status & wait_mask) == wait_mask) ||
290 csi->errors, HZ);
291
292 rzv2m_csi_disable_irqs(csi, enable_bits);
293
294 if (csi->errors)
295 return -EIO;
296
297 if (!ret)
298 return -ETIMEDOUT;
299
300 return 0;
301}
302
303static int rzv2m_csi_wait_for_tx_empty(struct rzv2m_csi_priv *csi)
304{
305 int ret;
306
307 if (readl(csi->base + CSI_OFIFOL) == 0)
308 return 0;
309
310 ret = rzv2m_csi_wait_for_interrupt(csi, CSI_INT_TREND, CSI_CNT_TREND_E);
311
312 if (ret == -ETIMEDOUT)
313 csi->errors |= TX_TIMEOUT_ERROR;
314
315 return ret;
316}
317
318static inline int rzv2m_csi_wait_for_rx_ready(struct rzv2m_csi_priv *csi)
319{
320 int ret;
321
322 if (readl(csi->base + CSI_IFIFOL) == csi->bytes_to_transfer)
323 return 0;
324
325 ret = rzv2m_csi_wait_for_interrupt(csi, CSI_INT_R_TRGR,
326 CSI_CNT_R_TRGR_E);
327
328 if (ret == -ETIMEDOUT)
329 csi->errors |= RX_TIMEOUT_ERROR;
330
331 return ret;
332}
333
334static irqreturn_t rzv2m_csi_irq_handler(int irq, void *data)
335{
336 struct rzv2m_csi_priv *csi = (struct rzv2m_csi_priv *)data;
337
338 csi->status = readl(csi->base + CSI_INT);
339 rzv2m_csi_disable_irqs(csi, csi->status);
340
341 if (csi->status & CSI_INT_OVERF)
342 csi->errors |= OVERFLOW_ERROR;
343 if (csi->status & CSI_INT_UNDER)
344 csi->errors |= UNDERRUN_ERROR;
345
346 wake_up(&csi->wait);
347
348 return IRQ_HANDLED;
349}
350
351static void rzv2m_csi_setup_clock(struct rzv2m_csi_priv *csi, u32 spi_hz)
352{
353 unsigned long csiclk_rate = clk_get_rate(csi->csiclk);
354 unsigned long pclk_rate = clk_get_rate(csi->pclk);
355 unsigned long csiclk_rate_limit = pclk_rate >> 1;
356 u32 cks;
357
358 /*
359 * There is a restriction on the frequency of CSICLK, it has to be <=
360 * PCLK / 2.
361 */
362 if (csiclk_rate > csiclk_rate_limit) {
363 clk_set_rate(csi->csiclk, csiclk_rate >> 1);
364 csiclk_rate = clk_get_rate(csi->csiclk);
365 } else if ((csiclk_rate << 1) <= csiclk_rate_limit) {
366 clk_set_rate(csi->csiclk, csiclk_rate << 1);
367 csiclk_rate = clk_get_rate(csi->csiclk);
368 }
369
370 spi_hz = spi_hz > CSI_MAX_SPI_SCKO ? CSI_MAX_SPI_SCKO : spi_hz;
371
372 cks = DIV_ROUND_UP(csiclk_rate, spi_hz << 1);
373 if (cks > CSI_CKS_MAX)
374 cks = CSI_CKS_MAX;
375
376 dev_dbg(csi->dev, "SPI clk rate is %ldHz\n", csiclk_rate / (cks << 1));
377
378 rzv2m_csi_reg_write_bit(csi, CSI_CLKSEL, CSI_CLKSEL_CKS, cks);
379}
380
381static void rzv2m_csi_setup_operating_mode(struct rzv2m_csi_priv *csi,
382 struct spi_transfer *t)
383{
384 if (t->rx_buf && !t->tx_buf)
385 /* Reception-only mode */
386 rzv2m_csi_reg_write_bit(csi, CSI_MODE, CSI_MODE_TRMD, 0);
387 else
388 /* Send and receive mode */
389 rzv2m_csi_reg_write_bit(csi, CSI_MODE, CSI_MODE_TRMD, 1);
390
391 csi->bytes_per_word = t->bits_per_word / 8;
392 rzv2m_csi_reg_write_bit(csi, CSI_MODE, CSI_MODE_CCL,
393 csi->bytes_per_word == 2);
394}
395
396static int rzv2m_csi_setup(struct spi_device *spi)
397{
398 struct rzv2m_csi_priv *csi = spi_controller_get_devdata(spi->controller);
399 int ret;
400
401 rzv2m_csi_sw_reset(csi, 0);
402
403 writel(CSI_MODE_SETUP, csi->base + CSI_MODE);
404
405 /* Setup clock polarity and phase timing */
406 rzv2m_csi_reg_write_bit(csi, CSI_CLKSEL, CSI_CLKSEL_CKP,
407 !(spi->mode & SPI_CPOL));
408 rzv2m_csi_reg_write_bit(csi, CSI_CLKSEL, CSI_CLKSEL_DAP,
409 !(spi->mode & SPI_CPHA));
410
411 /* Setup serial data order */
412 rzv2m_csi_reg_write_bit(csi, CSI_MODE, CSI_MODE_DIR,
413 !!(spi->mode & SPI_LSB_FIRST));
414
415 /* Set the operation mode as master */
416 rzv2m_csi_reg_write_bit(csi, CSI_CLKSEL, CSI_CLKSEL_SLAVE, 0);
417
418 /* Give the IP a SW reset */
419 ret = rzv2m_csi_sw_reset(csi, 1);
420 if (ret)
421 return ret;
422 rzv2m_csi_sw_reset(csi, 0);
423
424 /*
425 * We need to enable the communication so that the clock will settle
426 * for the right polarity before enabling the CS.
427 */
428 rzv2m_csi_start_stop_operation(csi, 1, false);
429 udelay(10);
430 rzv2m_csi_start_stop_operation(csi, 0, false);
431
432 return 0;
433}
434
435static int rzv2m_csi_pio_transfer(struct rzv2m_csi_priv *csi)
436{
437 bool tx_completed = csi->txbuf ? false : true;
438 bool rx_completed = csi->rxbuf ? false : true;
439 int ret = 0;
440
441 /* Make sure the TX FIFO is empty */
442 writel(0, csi->base + CSI_OFIFOL);
443
444 csi->bytes_sent = 0;
445 csi->bytes_received = 0;
446 csi->errors = 0;
447
448 rzv2m_csi_disable_all_irqs(csi);
449 rzv2m_csi_clear_all_irqs(csi);
450 rzv2m_csi_enable_rx_trigger(csi, true);
451
452 while (!tx_completed || !rx_completed) {
453 /*
454 * Decide how many words we are going to transfer during
455 * this cycle (for both TX and RX), then set the RX FIFO trigger
456 * level accordingly. No need to set a trigger level for the
457 * TX FIFO, as this IP comes with an interrupt that fires when
458 * the TX FIFO is empty.
459 */
460 rzv2m_csi_calc_current_transfer(csi);
461 rzv2m_csi_set_rx_fifo_trigger_level(csi);
462
463 rzv2m_csi_enable_irqs(csi, CSI_INT_OVERF | CSI_INT_UNDER);
464
465 /* Make sure the RX FIFO is empty */
466 writel(0, csi->base + CSI_IFIFOL);
467
468 writel(readl(csi->base + CSI_INT), csi->base + CSI_INT);
469 csi->status = 0;
470
471 rzv2m_csi_start_stop_operation(csi, 1, false);
472
473 /* TX */
474 if (csi->txbuf) {
475 ret = rzv2m_csi_fill_txfifo(csi);
476 if (ret)
477 break;
478
479 ret = rzv2m_csi_wait_for_tx_empty(csi);
480 if (ret)
481 break;
482
483 if (csi->bytes_sent == csi->buffer_len)
484 tx_completed = true;
485 }
486
487 /*
488 * Make sure the RX FIFO contains the desired number of words.
489 * We then either flush its content, or we copy it onto
490 * csi->rxbuf.
491 */
492 ret = rzv2m_csi_wait_for_rx_ready(csi);
493 if (ret)
494 break;
495
496 /* RX */
497 if (csi->rxbuf) {
498 rzv2m_csi_start_stop_operation(csi, 0, false);
499
500 ret = rzv2m_csi_read_rxfifo(csi);
501 if (ret)
502 break;
503
504 if (csi->bytes_received == csi->buffer_len)
505 rx_completed = true;
506 }
507
508 ret = rzv2m_csi_start_stop_operation(csi, 0, true);
509 if (ret)
510 goto pio_quit;
511
512 if (csi->errors) {
513 ret = -EIO;
514 goto pio_quit;
515 }
516 }
517
518 rzv2m_csi_start_stop_operation(csi, 0, true);
519
520pio_quit:
521 rzv2m_csi_disable_all_irqs(csi);
522 rzv2m_csi_enable_rx_trigger(csi, false);
523 rzv2m_csi_clear_all_irqs(csi);
524
525 return ret;
526}
527
528static int rzv2m_csi_transfer_one(struct spi_controller *controller,
529 struct spi_device *spi,
530 struct spi_transfer *transfer)
531{
532 struct rzv2m_csi_priv *csi = spi_controller_get_devdata(controller);
533 struct device *dev = csi->dev;
534 int ret;
535
536 csi->txbuf = transfer->tx_buf;
537 csi->rxbuf = transfer->rx_buf;
538 csi->buffer_len = transfer->len;
539
540 rzv2m_csi_setup_operating_mode(csi, transfer);
541
542 rzv2m_csi_setup_clock(csi, transfer->speed_hz);
543
544 ret = rzv2m_csi_pio_transfer(csi);
545 if (ret) {
546 if (csi->errors & UNDERRUN_ERROR)
547 dev_err(dev, "Underrun error\n");
548 if (csi->errors & OVERFLOW_ERROR)
549 dev_err(dev, "Overflow error\n");
550 if (csi->errors & TX_TIMEOUT_ERROR)
551 dev_err(dev, "TX timeout error\n");
552 if (csi->errors & RX_TIMEOUT_ERROR)
553 dev_err(dev, "RX timeout error\n");
554 }
555
556 return ret;
557}
558
559static int rzv2m_csi_probe(struct platform_device *pdev)
560{
561 struct spi_controller *controller;
562 struct device *dev = &pdev->dev;
563 struct rzv2m_csi_priv *csi;
564 struct reset_control *rstc;
565 int irq;
566 int ret;
567
568 controller = devm_spi_alloc_master(dev, sizeof(*csi));
569 if (!controller)
570 return -ENOMEM;
571
572 csi = spi_controller_get_devdata(controller);
573 platform_set_drvdata(pdev, csi);
574
575 csi->dev = dev;
576 csi->controller = controller;
577
578 csi->base = devm_platform_ioremap_resource(pdev, 0);
579 if (IS_ERR(csi->base))
580 return PTR_ERR(csi->base);
581
582 irq = platform_get_irq(pdev, 0);
583 if (irq < 0)
584 return irq;
585
586 csi->csiclk = devm_clk_get(dev, "csiclk");
587 if (IS_ERR(csi->csiclk))
588 return dev_err_probe(dev, PTR_ERR(csi->csiclk),
589 "could not get csiclk\n");
590
591 csi->pclk = devm_clk_get(dev, "pclk");
592 if (IS_ERR(csi->pclk))
593 return dev_err_probe(dev, PTR_ERR(csi->pclk),
594 "could not get pclk\n");
595
596 rstc = devm_reset_control_get_shared(dev, NULL);
597 if (IS_ERR(rstc))
598 return dev_err_probe(dev, PTR_ERR(rstc), "Missing reset ctrl\n");
599
600 init_waitqueue_head(&csi->wait);
601
602 controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
603 controller->dev.of_node = pdev->dev.of_node;
604 controller->bits_per_word_mask = SPI_BPW_MASK(16) | SPI_BPW_MASK(8);
605 controller->setup = rzv2m_csi_setup;
606 controller->transfer_one = rzv2m_csi_transfer_one;
607 controller->use_gpio_descriptors = true;
608
609 ret = devm_request_irq(dev, irq, rzv2m_csi_irq_handler, 0,
610 dev_name(dev), csi);
611 if (ret)
612 return dev_err_probe(dev, ret, "cannot request IRQ\n");
613
614 /*
615 * The reset also affects other HW that is not under the control
616 * of Linux. Therefore, all we can do is make sure the reset is
617 * deasserted.
618 */
619 reset_control_deassert(rstc);
620
621 /* Make sure the IP is in SW reset state */
622 ret = rzv2m_csi_sw_reset(csi, 1);
623 if (ret)
624 return ret;
625
626 ret = clk_prepare_enable(csi->csiclk);
627 if (ret)
628 return dev_err_probe(dev, ret, "could not enable csiclk\n");
629
630 ret = spi_register_controller(controller);
631 if (ret) {
632 clk_disable_unprepare(csi->csiclk);
633 return dev_err_probe(dev, ret, "register controller failed\n");
634 }
635
636 return 0;
637}
638
93033314 639static void rzv2m_csi_remove(struct platform_device *pdev)
83c624d8
FC
640{
641 struct rzv2m_csi_priv *csi = platform_get_drvdata(pdev);
642
643 spi_unregister_controller(csi->controller);
644 rzv2m_csi_sw_reset(csi, 1);
645 clk_disable_unprepare(csi->csiclk);
83c624d8
FC
646}
647
648static const struct of_device_id rzv2m_csi_match[] = {
649 { .compatible = "renesas,rzv2m-csi" },
650 { /* sentinel */ }
651};
652MODULE_DEVICE_TABLE(of, rzv2m_csi_match);
653
654static struct platform_driver rzv2m_csi_drv = {
655 .probe = rzv2m_csi_probe,
93033314 656 .remove_new = rzv2m_csi_remove,
83c624d8
FC
657 .driver = {
658 .name = "rzv2m_csi",
659 .of_match_table = rzv2m_csi_match,
660 },
661};
662module_platform_driver(rzv2m_csi_drv);
663
664MODULE_LICENSE("GPL");
665MODULE_AUTHOR("Fabrizio Castro <[email protected]>");
666MODULE_DESCRIPTION("Clocked Serial Interface Driver");
This page took 0.116932 seconds and 4 git commands to generate.