hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/spi/spidev.c
....@@ -1,19 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Simple synchronous userspace interface to SPI devices
34 *
45 * Copyright (C) 2006 SWAPP
56 * Andrea Paterniani <a.paterniani@swapp-eng.it>
67 * Copyright (C) 2007 David Brownell (simplification, cleanup)
7
- *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License as published by
10
- * the Free Software Foundation; either version 2 of the License, or
11
- * (at your option) any later version.
12
- *
13
- * This program is distributed in the hope that it will be useful,
14
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
- * GNU General Public License for more details.
178 */
189
1910 #include <linux/init.h>
....@@ -71,7 +62,8 @@
7162 #define SPI_MODE_MASK (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH \
7263 | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP \
7364 | SPI_NO_CS | SPI_READY | SPI_TX_DUAL \
74
- | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD)
65
+ | SPI_TX_QUAD | SPI_TX_OCTAL | SPI_RX_DUAL \
66
+ | SPI_RX_QUAD | SPI_RX_OCTAL)
7567
7668 struct spidev_data {
7769 dev_t devt;
....@@ -154,7 +146,7 @@
154146 spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
155147 {
156148 struct spidev_data *spidev;
157
- ssize_t status = 0;
149
+ ssize_t status;
158150
159151 /* chipselect only toggles at start or end of operation */
160152 if (count > bufsiz)
....@@ -184,7 +176,7 @@
184176 size_t count, loff_t *f_pos)
185177 {
186178 struct spidev_data *spidev;
187
- ssize_t status = 0;
179
+ ssize_t status;
188180 unsigned long missing;
189181
190182 /* chipselect only toggles at start or end of operation */
....@@ -279,20 +271,24 @@
279271 k_tmp->tx_nbits = u_tmp->tx_nbits;
280272 k_tmp->rx_nbits = u_tmp->rx_nbits;
281273 k_tmp->bits_per_word = u_tmp->bits_per_word;
282
- k_tmp->delay_usecs = u_tmp->delay_usecs;
274
+ k_tmp->delay.value = u_tmp->delay_usecs;
275
+ k_tmp->delay.unit = SPI_DELAY_UNIT_USECS;
283276 k_tmp->speed_hz = u_tmp->speed_hz;
277
+ k_tmp->word_delay.value = u_tmp->word_delay_usecs;
278
+ k_tmp->word_delay.unit = SPI_DELAY_UNIT_USECS;
284279 if (!k_tmp->speed_hz)
285280 k_tmp->speed_hz = spidev->speed_hz;
286281 #ifdef VERBOSE
287282 dev_dbg(&spidev->spi->dev,
288
- " xfer len %u %s%s%s%dbits %u usec %uHz\n",
289
- u_tmp->len,
290
- u_tmp->rx_buf ? "rx " : "",
291
- u_tmp->tx_buf ? "tx " : "",
292
- u_tmp->cs_change ? "cs " : "",
293
- u_tmp->bits_per_word ? : spidev->spi->bits_per_word,
294
- u_tmp->delay_usecs,
295
- u_tmp->speed_hz ? : spidev->spi->max_speed_hz);
283
+ " xfer len %u %s%s%s%dbits %u usec %u usec %uHz\n",
284
+ k_tmp->len,
285
+ k_tmp->rx_buf ? "rx " : "",
286
+ k_tmp->tx_buf ? "tx " : "",
287
+ k_tmp->cs_change ? "cs " : "",
288
+ k_tmp->bits_per_word ? : spidev->spi->bits_per_word,
289
+ k_tmp->delay.value,
290
+ k_tmp->word_delay.value,
291
+ k_tmp->speed_hz ? : spidev->spi->max_speed_hz);
296292 #endif
297293 spi_message_add_tail(k_tmp, &msg);
298294 }
....@@ -380,12 +376,23 @@
380376 switch (cmd) {
381377 /* read requests */
382378 case SPI_IOC_RD_MODE:
383
- retval = put_user(spi->mode & SPI_MODE_MASK,
384
- (__u8 __user *)arg);
385
- break;
386379 case SPI_IOC_RD_MODE32:
387
- retval = put_user(spi->mode & SPI_MODE_MASK,
388
- (__u32 __user *)arg);
380
+ tmp = spi->mode;
381
+
382
+ {
383
+ struct spi_controller *ctlr = spi->controller;
384
+
385
+ if (ctlr->use_gpio_descriptors && ctlr->cs_gpiods &&
386
+ ctlr->cs_gpiods[spi->chip_select])
387
+ tmp &= ~SPI_CS_HIGH;
388
+ }
389
+
390
+ if (cmd == SPI_IOC_RD_MODE)
391
+ retval = put_user(tmp & SPI_MODE_MASK,
392
+ (__u8 __user *)arg);
393
+ else
394
+ retval = put_user(tmp & SPI_MODE_MASK,
395
+ (__u32 __user *)arg);
389396 break;
390397 case SPI_IOC_RD_LSB_FIRST:
391398 retval = put_user((spi->mode & SPI_LSB_FIRST) ? 1 : 0,
....@@ -406,12 +413,17 @@
406413 else
407414 retval = get_user(tmp, (u32 __user *)arg);
408415 if (retval == 0) {
416
+ struct spi_controller *ctlr = spi->controller;
409417 u32 save = spi->mode;
410418
411419 if (tmp & ~SPI_MODE_MASK) {
412420 retval = -EINVAL;
413421 break;
414422 }
423
+
424
+ if (ctlr->use_gpio_descriptors && ctlr->cs_gpiods &&
425
+ ctlr->cs_gpiods[spi->chip_select])
426
+ tmp |= SPI_CS_HIGH;
415427
416428 tmp |= spi->mode & ~SPI_MODE_MASK;
417429 spi->mode = (u16)tmp;
....@@ -459,10 +471,11 @@
459471
460472 spi->max_speed_hz = tmp;
461473 retval = spi_setup(spi);
462
- if (retval >= 0)
474
+ if (retval == 0) {
463475 spidev->speed_hz = tmp;
464
- else
465
- dev_dbg(&spi->dev, "%d Hz (max)\n", tmp);
476
+ dev_dbg(&spi->dev, "%d Hz (max)\n",
477
+ spidev->speed_hz);
478
+ }
466479 spi->max_speed_hz = save;
467480 }
468481 break;
....@@ -579,7 +592,6 @@
579592 if (!spidev->tx_buffer) {
580593 spidev->tx_buffer = kmalloc(bufsiz, GFP_KERNEL);
581594 if (!spidev->tx_buffer) {
582
- dev_dbg(&spidev->spi->dev, "open/ENOMEM\n");
583595 status = -ENOMEM;
584596 goto err_find_dev;
585597 }
....@@ -588,7 +600,6 @@
588600 if (!spidev->rx_buffer) {
589601 spidev->rx_buffer = kmalloc(bufsiz, GFP_KERNEL);
590602 if (!spidev->rx_buffer) {
591
- dev_dbg(&spidev->spi->dev, "open/ENOMEM\n");
592603 status = -ENOMEM;
593604 goto err_alloc_rx_buf;
594605 }
....@@ -596,7 +607,7 @@
596607
597608 spidev->users++;
598609 filp->private_data = spidev;
599
- nonseekable_open(inode, filp);
610
+ stream_open(inode, filp);
600611
601612 mutex_unlock(&device_list_lock);
602613 return 0;
....@@ -677,6 +688,9 @@
677688 { .compatible = "lineartechnology,ltc2488" },
678689 { .compatible = "ge,achc" },
679690 { .compatible = "semtech,sx1301" },
691
+ { .compatible = "lwn,bk4" },
692
+ { .compatible = "dh,dhcom-board" },
693
+ { .compatible = "menlo,m53cpld" },
680694 { .compatible = "rockchip,spidev" },
681695 {},
682696 };