SPI device driver with userspace interface

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In the process of enabling the AMD Elba SoC I pulled out a driver that
was not converging on acceptance.  Please provide guidance on how I should
implement a spi device driver, with emmc reset control, and access from
userspace in a form that is acceptable if possible.

The device tree topology describes this:

+------------+              +-----------+
|            | <-- spi0 --> |           |
|            | --- cs0 ---> |           |
|            | --- cs1 ---> | CPLD/FPGA | --+
|    SoC     | --- cs2 ---> |           |   |
|            | --- cs3 ---> |           |   | rstc
|            |              +-----------+   |
|            |              +-----------+   |
|            | --- spi1 --> +   eMMC    | <-+
+------------+              +-----------+

The functionality is exclusively accessed via userspace programs 
except for the mmc hardware reset which is triggered by the kernel. 
The choice of CPLD or FPGA is decided based on cost/functionality.

CS0: CPLD/FPGA Board controller registers
CS1: Designware SPI to I2C to board peripherals
CS2: Lattice dual I2C master for transceiver peripherals
CS3: CPLD/FPGA internal storage for firmware update

The desired CS0, CS1 and CS3 interfaces are /dev/penctrl.0,
/dev/penctrl.1, and /dev/penctrl.3.  This is very similar
to the spidev.c driver which is considered inappropriate for
production.  CS2 is matched to a Lattice spi to i2c driver to
provide /dev/i2c-1 and /dev/i2c-2 to access to transceiver I2C
peripherals.

Relevant DT fragments are shown below:

        emmc: mmc@30440000 {
                compatible = "amd,pensando-elba-sd4hc", "cdns,sd4hc";
                reg = <0x0 0x30440000 0x0 0x10000>,
                      <0x0 0x30480044 0x0 0x4>; /* byte-lane ctrl */
                ...
        };

&emmc {
       bus-width = <8>;
       cap-mmc-hw-reset;
       resets = <&rstc 0>;   <== mmc hwreset is a bit in a CPLD CS0 register
       status = "okay";
};

One possible hardware description is shown below with a common driver for
three of the chip-selects and a different driver for cs2.

&spi0 {
       #address-cells = <1>;
       #size-cells = <0>;
       num-cs = <4>;
       cs-gpios = <0>, <0>, <&porta 1 GPIO_ACTIVE_LOW>,
                  <&porta 7 GPIO_ACTIVE_LOW>;
       status = "okay";

       rstc: system-controller@0 {   <== common driver for cs0/cs1/cs3
               compatible = "amd,pensando-elba-ctrl";
               reg = <0>;
               spi-max-frequency = <12000000>;
               interrupt-parent = <&porta>;
               interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
               #reset-cells = <1>;
       };

       system-controller@2 {
                compatible = "amd,pensando-cpld-rd1173";
                #address-cells = <1>;
                #size-cells = <1>;
                spi-max-frequency = <12000000>;
                reg = <2>;
                interrupt-parent = <&porta>;
                interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
        };
};

The spidev driver provides the needed userspace interface, however
- Having multiple sub-device nodes with the same compatible is unacceptable
- The spidev driver is not for production and can't extend compatible list
- MMC hardware reset is problematic in DT description to driver implementation

Is there a recommended way to implement this driver with userspace access
using normal kernel abstractions.  I thought the use of cdev and file_operations
would be acceptable.

Thanks for the help!

Regards,
Brad




[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux