The branch main has been updated by wulf:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=3c086734381945f6d779a98582d8eae3edca0b68

commit 3c086734381945f6d779a98582d8eae3edca0b68
Author:     Val Packett <v...@packett.cool>
AuthorDate: 2023-04-24 09:41:52 +0000
Commit:     Vladimir Kondratyev <w...@freebsd.org>
CommitDate: 2023-04-24 09:41:52 +0000

    spibus: extend API: add cs_delay ivar, KEEP_CS and NO_SLEEP flags
    
    These feature are required for an upcoming Apple MacBook topcase
    (HID over SPI) driver:
    
    A delay after toggling CS is required to avoid anomalies like an extra
    junk byte in front of the message. Keeping CS asserted is required to
    be able to read a status report after writing a command. (The device
    won't return the status if CS was deasserted.)
    
    Sleep is not allowed in the interrupt context where the Apple input
    driver runs its transactions. Use a flag to tell the SPI driver to
    avoid mtx_sleep.
    
    Reviewed by:    manu (ok to SPI part of larger patch)
    MFC afret:      1 month
    Differential revision:  https://reviews.freebsd.org/D29534
---
 sys/dev/spibus/spi.h       | 4 ++++
 sys/dev/spibus/spibus.c    | 6 ++++++
 sys/dev/spibus/spibusvar.h | 3 +++
 3 files changed, 13 insertions(+)

diff --git a/sys/dev/spibus/spi.h b/sys/dev/spibus/spi.h
index 4cb5c8905b61..fc5b4ab2c148 100644
--- a/sys/dev/spibus/spi.h
+++ b/sys/dev/spibus/spi.h
@@ -34,9 +34,13 @@ struct spi_command {
        uint32_t tx_data_sz;
        void    *rx_data;
        uint32_t rx_data_sz;
+       uint32_t flags;
 };
 #define        SPI_COMMAND_INITIALIZER { 0 }
 
+#define        SPI_FLAG_KEEP_CS        0x1             /* Keep chip select 
asserted */
+#define        SPI_FLAG_NO_SLEEP       0x2             /* Prevent driver from 
sleeping (use polling) */
+
 #define        SPI_CHIP_SELECT_HIGH    0x1             /* Chip select high 
(else low) */
 
 #ifdef FDT
diff --git a/sys/dev/spibus/spibus.c b/sys/dev/spibus/spibus.c
index b0b2b5eb73ad..40ebb916a649 100644
--- a/sys/dev/spibus/spibus.c
+++ b/sys/dev/spibus/spibus.c
@@ -146,6 +146,9 @@ spibus_read_ivar(device_t bus, device_t child, int which, 
uintptr_t *result)
        case SPIBUS_IVAR_CLOCK:
                *(uint32_t *)result = devi->clock;
                break;
+       case SPIBUS_IVAR_CS_DELAY:
+               *(uint32_t *)result = devi->cs_delay;
+               break;
        }
        return (0);
 }
@@ -174,6 +177,9 @@ spibus_write_ivar(device_t bus, device_t child, int which, 
uintptr_t value)
                        return (EINVAL);
                devi->mode = (uint32_t)value;
                break;
+       case SPIBUS_IVAR_CS_DELAY:
+               devi->cs_delay = (uint32_t)value;
+               break;
        default:
                return (EINVAL);
        }
diff --git a/sys/dev/spibus/spibusvar.h b/sys/dev/spibus/spibusvar.h
index 58a7bf784787..db94d30831e6 100644
--- a/sys/dev/spibus/spibusvar.h
+++ b/sys/dev/spibus/spibusvar.h
@@ -43,6 +43,7 @@ struct spibus_ivar
        uint32_t        cs;
        uint32_t        mode;
        uint32_t        clock;
+       uint32_t        cs_delay;
        struct resource_list    rl;
 };
 
@@ -52,6 +53,7 @@ enum {
        SPIBUS_IVAR_CS,         /* chip select that we're on */
        SPIBUS_IVAR_MODE,       /* SPI mode (0-3) */
        SPIBUS_IVAR_CLOCK,      /* maximum clock freq for device */
+       SPIBUS_IVAR_CS_DELAY,   /* delay in microseconds after toggling chip 
select */
 };
 
 #define SPIBUS_ACCESSOR(A, B, T)                                       \
@@ -71,6 +73,7 @@ spibus_set_ ## A(device_t dev, T t)                           
        \
 SPIBUS_ACCESSOR(cs,            CS,             uint32_t)
 SPIBUS_ACCESSOR(mode,          MODE,           uint32_t)
 SPIBUS_ACCESSOR(clock,         CLOCK,          uint32_t)
+SPIBUS_ACCESSOR(cs_delay,              CS_DELAY,               uint32_t)
 
 extern driver_t spibus_driver;
 extern driver_t ofw_spibus_driver;

Reply via email to