]> rtime.felk.cvut.cz Git - vajnamar/linux-xlnx.git/commitdiff
staging: Remove Digilent pmods drivers
authorMichal Simek <michal.simek@xilinx.com>
Mon, 13 Feb 2017 10:13:20 +0000 (11:13 +0100)
committerMichal Simek <michal.simek@xilinx.com>
Mon, 13 Feb 2017 10:13:20 +0000 (11:13 +0100)
They are untested for really long time. Remove them.

Signed-off-by: Michal Simek <michal.simek@xilinx.com>
15 files changed:
Documentation/pmods/00-INDEX [deleted file]
Documentation/pmods/pmodad1.txt [deleted file]
Documentation/pmods/pmodclp.txt [deleted file]
Documentation/pmods/pmodcls.txt [deleted file]
Documentation/pmods/pmodda1.txt [deleted file]
Documentation/pmods/pmodoled.txt [deleted file]
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/pmods/Kconfig [deleted file]
drivers/staging/pmods/Makefile [deleted file]
drivers/staging/pmods/pmodad1.c [deleted file]
drivers/staging/pmods/pmodclp.c [deleted file]
drivers/staging/pmods/pmodcls.c [deleted file]
drivers/staging/pmods/pmodda1.c [deleted file]
drivers/staging/pmods/pmodoled-gpio.c [deleted file]

diff --git a/Documentation/pmods/00-INDEX b/Documentation/pmods/00-INDEX
deleted file mode 100644 (file)
index 813f5b4..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-Documentation for pmods, a set of peripheral modules provided by Digilent Inc.,
-which can be plugged to various development boards to add additional functionalities.
-These drivers are maintained by Digilent Inc.
-
-00-INDEX
-       - this file
-pmodoled.txt
-       - PmodOLED: 128 by 32 pixel 0.9" Organic LED Graphic Display
diff --git a/Documentation/pmods/pmodad1.txt b/Documentation/pmods/pmodad1.txt
deleted file mode 100644 (file)
index f29aa2b..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-PmodAD1
-========
-
-Copyright 2012, Digilent Inc.
-
-
-Description
------------
-
-The Analog to Digital Module Converter Board converts signals at a
-maximum sampling rate of one million samples per second.
-
-The Digilent PmodAD1 relies on two Analog Devices AD7476, thus implementing two
-simultaneous A/D conversion channels, each with an 12-bit converter.
-
-The AD1 converts an analog input signal ranging from 0-3.3 volts to a 12-bit
-digital value in the range 0 to 4095 (0x0FFF).
-
-This Linux driver is based on SPI. Because SPI can not read on Data Out line of
-SPI, only the channel corresponding to the second AD7476 can be accessed using
-this driver (the channel corresponding to P3, P4 pins of J2 connector of PmodAD1).
-
-The driver is implemented as a character driver. The basic action of the driver is
-read, when 12 bits data is read over SPI.
-
-The Reference Manual for PmodAD1 display is available online at
-Digilent Inc. Website (www.digilentinc.com).
-
-
-Interface
----------
-
-Signal     Description
-
-SDOUT      SPI Data In (MISO)
-SCLK       SPI Clock
-SS        Slave Select
-
-
-Devicetree
-----------
-
-Required Properties:
-- compatible : Should be "dlgnt,pmodad1"
-- spi-bus-num :  Should specify the bus number for PmodAD1 SPI controller.
-  This value cannot be shared by any other SPI controller present in the
-  device tree.
-- spi-sclk-gpio :  Should specify the GPIO for SCLK, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-- spi-sdout-gpio :  Should specify the GPIO for SDOUT, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-
-Optional Properties:
-- spi-cs-gpio :  Should specify the GPIO for CS, see "gpios property" in
-  Documentation/devicetree/gpio.txt. If unspecified, CS is assumed to be
-  tied to ground.
-- spi-speed-hz : Should specify the spi speed (in Hz). If unspecified, spi
-  speed is assumed to be 625000 (625 kHz).
-
-Example:
-
-               pmodad1 {
-                       compatible = "dglnt,pmodad1";
-                       spi-bus-num = <0x5>;
-                       spi-speed-hz = <1000000>;
-                       spi-sclk-gpio = <0x8 85 0>;
-                       spi-sdout-gpio = <0x8 84 0>;
-                       spi-cs-gpio = <0x8 82 0>;
-               };
-
-This example corresponds to PmodAD1 plugged into JA connector, pins 1-7.
-
-Configuration
--------------
-
-The PmodAD1 is located in the kernel configuration menu at
-Device Drivers -> Pmods -> PmodAD1. The driver can be built into the kernel
-by selecting (*) for it, or loadable module by selecting (M) for it.
-
-
-Device Nodes
-------------
-
-A char device node will be created for each PmodAD1 device automatically.
-The name of the node is default to the one declared in the device tree.
-
-Reading from the device
------------
-The PmodAD1 is a "read only" device, read being its main action.
-2 bytes of data are read over the spi, a mask is applied so that the 12 LSB
-bits are used to fill the read buffer.
-
-Example of commands
------------
-
-- Read (repeatedly) the device
-hexdump -v -d /dev/pmodad1
diff --git a/Documentation/pmods/pmodclp.txt b/Documentation/pmods/pmodclp.txt
deleted file mode 100644 (file)
index 7dfaa71..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-PmodCLP
-========
-
-Copyright 2012, Digilent Inc.
-
-
-Description
------------
-
-The PmodCLP is a 16x2 character LCD module that uses two Pmod connectors to present a
-8-bit parallel data interface to system boards.
-The PmodCLP features an SPI-controlled monochrome LCD 16x2 Character Display,
-perfect for embedded applications requiring small, simple text output.
-
-The PmodCLP uses simple terminal-like display interface. It provides
-flexible communications using UART, SPI or TWI interface.
-
-Some of the PmodCLP implement a backlight feature. This is implemented by using the
-optional bk-gpio in the Device Tree.
-
-This Linux character driver sends commands and data to the device using parallel access
-to GPIOs. The set of commands is based on escape characters.
-
-The Reference Manual for PmodCLP device is available online at
-Digilent Inc. Website (www.digilentinc.com).
-
-
-Interface
----------
-
-Signal     Description
-
-RS             RS (Register Select) signal of the parallel interface
-RW             RW (Read/Write) signal of the parallel interface
-E              E (Enable) signal of the parallel interface
-BK             (Optional) - BackLight signal
-DATA0          Signal for Bit 0 of the parallel interface
-DATA1          Signal for Bit 1 of the parallel interface
-DATA2          Signal for Bit 2 of the parallel interface
-DATA3          Signal for Bit 3 of the parallel interface
-DATA4          Signal for Bit 4 of the parallel interface
-DATA5          Signal for Bit 5 of the parallel interface
-DATA6          Signal for Bit 6 of the parallel interface
-DATA7          Signal for Bit 7 of the parallel interface
-
-Devicetree
-----------
-
-Required Properties:
-- compatible : Should be "dlgnt,pmodclp"
-- rs-gpio :  Should specify the GPIO for RS, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-- rw-gpio :  Should specify the GPIO for RW, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-- e-gpio :  Should specify the GPIO for E, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-- data0-gpio :  Should specify the GPIO for DATA0, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-- data1-gpio :  Should specify the GPIO for DATA1, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-- data2-gpio :  Should specify the GPIO for DATA2, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-- data3-gpio :  Should specify the GPIO for DATA3, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-- data4-gpio :  Should specify the GPIO for DATA4, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-- data5-gpio :  Should specify the GPIO for DATA5, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-- data6-gpio :  Should specify the GPIO for DATA6, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-- data7-gpio :  Should specify the GPIO for DATA7, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-
-Optional Properties:
-- bk-gpio :  Should specify the GPIO for BK, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-
-Example:
-(corresponds to
-J1 connector of PmodCLP connected to JA connector of Zed
-J2 connector of PmodCLP connected to Jb connector of Zed):
-
-               pmodclp {
-                       compatible = "dglnt,pmodclp";
-                       rs-gpio = <0x8 94 0>;
-                       rw-gpio = <0x8 95 0>;
-                       e-gpio = <0x8 96 0>;
-                       bk-gpio = <0x8 97 0>;
-                       data0-gpio = <0x8 82 0>;
-                       data1-gpio = <0x8 83 0>;
-                       data2-gpio = <0x8 84 0>;
-                       data3-gpio = <0x8 85 0>;
-                       data4-gpio = <0x8 86 0>;
-                       data5-gpio = <0x8 87 0>;
-                       data6-gpio = <0x8 88 0>;
-                       data7-gpio = <0x8 89 0>;
-               };
-
-
-Configuration
--------------
-
-The PmodCLP is located in the kernel configuration menu at
-Device Drivers -> Pmods -> PmodCLP. The driver can be built into the kernel
-by selecting (*) for it, or loadable module by selecting (M) for it.
-
-
-Device Nodes
-------------
-
-A char device node will be created for each PmodCLP device automatically.
-The name of the node is default to the one declared in the device tree.
-
-
-Instruction set
------------
-Instructions are sent using escape sequences. An escape sequence
-begins with ESC (character code 0x1B) followed by the left
-square bracket ‘[‘ , followed by 0 or more parameters separated by
-semicolons ‘;’ and ending with the command character.
-
-The implemented commands are:
-
-<pr>;<pc>H     - set cursor position to <pr> row and <pc> col
-
-<pn>@          - scroll left <pn> columns
-
-<pn>A          - scroll right <pn> columns
-
-<ps>e          - enable/disable display
-               0 = display off,
-                     backlight off
-               1 = display on,
-                     backlight off
-               2 = display off,
-                     backlight on
-               3 = display on,
-                     backlight on
-
-<ps>c          - set cursor mode
-               0 = cursor off
-               1 = cursor on,
-                       blink off
-               2 = cursor on,
-                       blink on
-
-j              - clear display and home cursor
-
-
-<pn>;…<pn>;<ps>d     - define user programmable character
-Be aware that after defining a user character you must issue a
-set position command.
-
-Notations:
-<pr>           row number (0 - 1)
-<pc>           column number (0 – 39)
-<pn>           numeric parameter
-               - decimal: 122 for ex.
-               - hex: 0x7A for ex.
-               - binary: 0b01111010 for ex.
-<ps>           decimal selection parameter
-
-
-Examples of commands
------------
-
-- Set display on, backlight on
-echo -n -e "\x1B[3e" > /dev/pmodclp
-
-- Clear screen, cursor home
-echo -n -e "\x1B[j" > /dev/pmodclp
-
-- Position cursor (row 1, col 0)
-echo -n -e "\x1B[1;0H" > /dev/pmodclp
-
-- Display string
-echo -n -e "Digilent" > /dev/pmodclp
-
-- Display string on 2 rows (when current row is the first)
-echo -n -e "Hello\nDigilent" > /dev/pmodclp
-
-- Scroll right 2 positions
-echo -n -e "\x1B[2A" > /dev/pmodclp
-
-- Scroll left 2 positions
-echo -n -e "\x1B[2@" > /dev/pmodclp
-
-
-- Define user char 1
-echo -n -e "\x1B[0x00;0x0A;0x15;0x11;0x0A;0x04;0x00;0x00;1d" > /dev/pmodclp
-
-- Display user char 1 on row 1, col 3
-echo -n -e "\x1B[1;3H" > /dev/pmodclp
-echo -n -e "\x01" > /dev/pmodclp
-
-
-
-
diff --git a/Documentation/pmods/pmodcls.txt b/Documentation/pmods/pmodcls.txt
deleted file mode 100644 (file)
index 41887f5..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-PmodCLS
-========
-
-Copyright 2012, Digilent Inc.
-
-
-Description
------------
-
-The PmodCLS features an SPI-controlled monochrome LCD 16x2 Character Display,
-perfect for embedded applications requiring small, simple text output.
-
-The PmodCLS uses simple terminal-like display interface. It provides
-flexible communications using UART, SPI or TWI interface.
-
-This Linux character driver uses an SPI interface in order to configure the device,
-as well as to send the text to be displayed on the device.
-
-Commands are sent and characters are written to the display simply by sending
-characters over the communication link.
-
-
-The Reference Manual for PmodCLS display is available online at
-Digilent Inc. Website (www.digilentinc.com).
-
-
-Interface
----------
-
-Signal     Description
-
-SDIN       SPI Data In (MOSI)
-SCLK       SPI Clock
-SS        Slave Select
-
-
-Devicetree
-----------
-
-Required Properties:
-- compatible : Should be "dlgnt,pmodcls"
-- spi-bus-num :  Should specify the bus number for PmodCLS SPI controller.
-  This value cannot be shared by any other SPI controller present in the
-  device tree.
-- spi-sclk-gpio :  Should specify the GPIO for SCLK, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-- spi-sdin-gpio :  Should specify the GPIO for SDIN, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-
-Optional Properties:
-- spi-cs-gpio :  Should specify the GPIO for CS, see "gpios property" in
-  Documentation/devicetree/gpio.txt. If unspecified, CS is assumed to be
-  tied to ground.
-- spi-speed-hz : Should specify the spi speed (in Hz). If unspecified, spi
-  speed is assumed to be 625000 (625 kHz).
-
-Examples:
-
-       pmodcls {
-               compatible = "dglnt,pmodcls";
-               spi-bus-num = <0x3>;
-               spi-speed-hz = <625000>;
-               spi-sclk-gpio = <0x8 85 0>;
-               spi-sdin-gpio = <0x8 83 0>;
-               spi-cs-gpio = <0x8 82 0>;
-       };
-
-
-Configuration
--------------
-
-The PmodCLS is located in the kernel configuration menu at
-Device Drivers -> Pmods -> PmodCLS. The driver can be built into the kernel
-by selecting (*) for it, or as a loadable module by selecting (M) for it.
-
-
-Device Nodes
-------------
-
-A char device node will be created for each PmodCLS device automatically.
-The name of the node is default to the one declared in the device tree.
-
-Instruction set
------------
-Instructions are sent using escape sequences. An escape sequence
-begins with ESC (character code 0x1B) followed by the left
-square bracket ‘[‘ , followed by 0 or more parameters separated by
-semicolons ‘;’ and ending with the command character.
-
-The commands are (as stated in the PmodCLS reference Manual):
-
-<pr>;<pc>H     - set cursor position to <pr> row and <pc> col
-s              - save cursor position
-u              - restore saved cursor position
-j              - clear display and home cursor
-<ps>K          - erase within line
-               0 = current position to end of line
-               1 = start of line to current position
-               2 = entire line
-<ps>N          erase field in current line
-               <ps> = number of chars starting at current position
-<pn>@          - scroll left <pn> columns
-<pn>A          - scroll right <pn> columns
-*              - reset; equivalent to cycling power of PmodCLS
-<ps>e          - enable/disable display
-               0 = display off,
-                     backlight off
-               1 = display on,
-                     backlight off
-               2 = display off,
-                     backlight on
-               3 = display on,
-                     backlight on
-<ps>h          - set display mode
-               0 = wrap line at 16 characters
-               1 = wrap line at 40 characters
-<ps>c          - set cursor mode
-               0 = cursor off
-               1 = cursor on,
-                       blink off
-               2 = cursor on,
-                       blink on
-<pn>a          - save TWI address in EEPROM to <pn>
-<pn>b          - save baud rate value in EEPROM to <pn>
-<pt>p          - program character table into LCD
-<pt>t          - save RAM character table to EEPROM
-<pt>l          - load EEPROM character table to RAM
-<pn>;…<pn>;<ps>d- define user programmable character
-                Be aware that after defining a user character you must
-                program the character table into LCD (command 'p').
-<ps>m          - save communication mode to EEPROM
-w              - enable write to EEPROM
-<ps>n          - save cursor mode to EEPROM
-<ps>o          - save display mode to EEPROM
-
-Notations:
-<pr>           row number (0 - 1)
-<pc>           column number (0 – 39)
-<pn>           numeric parameter
-               - decimal: 122 for ex.
-               - hex: 0x7A for ex.
-               - binary: 0b01111010 for ex.
-<ps>           decimal selection parameter
-<pt>           character table selector
-               (0 – 2 in EEPROM, 3 in RAM)
-
-
-Example of commands
------------
-
-- Set backlight on, display on
-echo -n -e "\x1B[3e" > /dev/pmodcls
-
-- Clear screen, cursor home
-echo -n -e "\x1B[j" > /dev/pmodcls
-
-- Position cursor (row 1, col 0)
-echo -n -e "\x1B[1;0H" > /dev/pmodcls
-
-- Display string
-echo -n -e "Digilent" > /dev/pmodcls
-
-- Display string on 2 rows (when current row is the first)
-echo -n -e "Hello\nDigilent" > /dev/pmodcls
-
-- Define user character 1 (in RAM)
-echo -n -e "\x1B[0;10;21;17;10;4;0;0;1d\x1B[3p" > /dev/pmodcls
-
-- Display user char 1
-echo -n -e "\x01" > /dev/pmodcls
-
-
-
-
diff --git a/Documentation/pmods/pmodda1.txt b/Documentation/pmods/pmodda1.txt
deleted file mode 100644 (file)
index 50b5e91..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-PmodDA1
-========
-
-Copyright 2012, Digilent Inc.
-
-
-Description
------------
-
-The Digilent PmodDA1 Digital To Analog Module Converter Board (the DA1) converts
-signals from digital to analog at up to one MSa per second.
-
-The Digilent PmodDA1 relies on two Analog Devices AD7303, thus implementing four
-simultaneous D/A conversion channels, each with an 8-bit converter that can
-process a separate digital signal.
-
-The PmodDA1 converts an 8 bit digital value to an analog output
-ranging from 0-3.3 volts.
-
-This Linux driver is based on SPI. Because SPI can not write on Data Out line of
-SPI, only the 2 channels corresponding to the first AD7303 (the channels corresponding
-to A1 and B1 pins of J2 connector of PmodDA1) can be accessed using this driver.
-
-The driver is implemented as a character driver. Corresponding to each channel,
-two separates nodes are created by the driver code, having different minor numbers.
-
-The basic action of the driver is write, when 8 bits data is outputted to each of the
-two channels. Still, read function is also implemented, by providing the last written
-value.
-
-The Reference Manual for PmodDA1 device is available online at
-Digilent Inc. Website (www.digilentinc.com).
-
-
-Interface
----------
-
-Signal     Description
-
-SDIN       SPI Data Out (MOSI)
-SCLK       SPI Clock
-SS        Slave Select
-
-
-Devicetree
-----------
-
-Required Properties:
-- compatible : Should be "dlgnt,pmodda1"
-- spi-bus-num :  Should specify the bus number for PmodDA1 SPI controller.
-  This value cannot be shared by any other SPI controller present in the
-  device tree.
-- spi-sclk-gpio :  Should specify the GPIO for SCLK, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-- spi-sdin-gpio :  Should specify the GPIO for SDIN, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-
-Optional Properties:
-- spi-cs-gpio :  Should specify the GPIO for CS, see "gpios property" in
-  Documentation/devicetree/gpio.txt. If unspecified, CS is assumed to be
-  tied to ground.
-- spi-speed-hz : Should specify the spi speed (in Hz). If unspecified, spi
-  speed is assumed to be 625000 (625 kHz).
-
-Examples:
-
-               pmodda1 {
-                       compatible = "dglnt,pmodda1";
-                       spi-bus-num = <0x4>;
-                       spi-speed-hz = <625000>;
-                       spi-sclk-gpio = <0x8 85 0>;
-                       spi-sdin-gpio = <0x8 83 0>;
-                       spi-cs-gpio = <0x8 82 0>;
-               };
-
-
-Configuration
--------------
-
-The PmodDA1 is located in the kernel configuration menu at
-Device Drivers -> Pmods -> PmodDA1. The driver can be built into the kernel
-by selecting (*) for it, or loadable module by selecting (M) for it.
-
-
-Device Nodes
-------------
-
-Two char device nodes are created for each PmodDA1 device automatically,
-having 0 and 1 as minor numbers.
-
-The name of the nodes is by default the one declared in the device tree,
-postfixed with "_0" (for channel A1) and "_1" (for channel B1).
-
-
-Writing to the device
------------
-Characters written to the device are used as 8 bits values sent to the appropriate
-converter channel. While writing to a channel the other channel is not disabled,
-allowing it to perform its current task.
-
-
-Reading from the device
------------
-The PmodDA1 is a "write only" device. Still, the driver implements a shadow register
-that also maintains the last value written to the converter. When read occurs, this
-value is used to fill the read buffer.
-
-
-Example of commands
------------
-
-- Write 0x80 value to second channel (B1) of the device
-echo -n -e "\x80" > /dev/pmodda1_1
-
-- Read (repeatedly) first channel (A1) of the device
-hexdump -C -v /dev/pmodda1_0
-
-
-
-
diff --git a/Documentation/pmods/pmodoled.txt b/Documentation/pmods/pmodoled.txt
deleted file mode 100644 (file)
index 85feb43..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-PmodOLED
-========
-
-Copyright 2012, Digilent Inc.
-
-
-Description
------------
-
-The PmodOLED features an SPI-controlled monochrome OLED display,
-perfect for embedded applications requiring small, complex visual output.
-
-The PmodOLED uses a standard 12-pin connector to display output on
-a 128x32 pixel organic LED (OLED) panel. The graphic display panel uses
-the Solomon Systech SSD1306 display controller.
-
-An SPI interface is used to configure the display,
-as well as to send the bitmap data to the device.
-
-The PmodOLED displays the last image drawn on the screen until it is
-powered down or a new image is drawn to the display. Refreshing and
-updating is handled internally.
-
-The Reference Manual for PmodOLED display is available online at
-Digilent Inc. Website (www.digilentinc.com)
-
-For more information on the OLED display interface, see the
-UG-2832HSWEG04 datasheet available online or from Univisio.
-
-The OLED display uses a compatible command set from the SSD1306 device.
-For more information, see the SSD1306 datasheet available at
-www.solomon-systech.com.
-
-
-Interface
----------
-
-Signal     Description
-
-CS         SPI Chip Select (Slave Select)
-SDIN       SPI Data In (MOSI)
-SCLK       SPI Clock
-D/C        Data/Command Control
-RES        Power Reset
-VBATC      VBAT Battery Voltage Control
-VDDC       VDD Logic Voltage Control
-
-
-Devicetree
-----------
-
-Required Properties:
-- compatible : Should be "dlgnt,pmodoled-gpio"
-- vbat-gpio :  Should specify the GPIO for VBATC, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-- vdd-gpio :  Should specify the GPIO for VDDC, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-- res-gpio :  Should specify the GPIO for RES, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-- dc-gpio :  Should specify the GPIO for D/C, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-- spi-bus-num :  Should specify the bus number for PmodOLED SPI controller.
-  This value cannot be shared by any other SPI controller present in the
-  device tree.
-- spi-sclk-gpio :  Should specify the GPIO for SCLK, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-- spi-sdin-gpio :  Should specify the GPIO for SDIN, see "gpios property" in
-  Documentation/devicetree/gpio.txt.
-
-Optional Properties:
-- spi-cs-gpio :  Should specify the GPIO for CS, see "gpios property" in
-  Documentation/devicetree/gpio.txt. If unspecified, CS is assumed to be
-  tied to ground.
-
-Examples:
-
-zed_oled {
-       compatible = "dglnt,pmodoled-gpio";
-       /* GPIO Pins */
-       vbat-gpio = <&gpiops 55 0>;
-       vdd-gpio = <&gpiops 56 0>;
-       res-gpio = <&gpiops 57 0>;
-       dc-gpio = <&gpiops 58 0>;
-       /* SPI-GPIOs */
-       spi-bus-num = <2>;
-       spi-sclk-gpio = <&gpiops 59 0>;
-       spi-sdin-gpio = <&gpiops 60 0>;
-};
-
-pmodoled_A {
-       compatible = "dglnt,pmodoled-gpio";
-       vbat-gpio = <&gpiops 88 0>;
-       vdd-gpio = <&gpiops 89 0>;
-       res-gpio = <&gpiops 87 0>;
-       dc-gpio = <&gpiops 86 0>;
-       spi-bus-num = <3>;
-       spi-sclk-gpio = <&gpiops 85 0>;
-       spi-sdin-gpio = <&gpiops 83 0>;
-       spi-cs-gpio = <&gpiops 82 0>;
-};
-
-
-Configuration
--------------
-
-The PmodOLED is located in the kernel configuration menu at
-Device Drivers -> Pmods -> PmodOLED. The driver can be built into the kernel
-by selecting (*) for it, or loadable module by selecting (M) for it.
-
-
-Device Nodes
-------------
-
-A char device node will be created for each PmodOLED device automatically.
-The name of the node is default to the one declared in the device tree.
-
-
-Read/Writes
------------
-
-The driver provides a 512 Byte display buffer for the display of PmodOLED.
-The Whole screen is divided into four lines, each of them is 128 bits wide
-and 8 bits high, as shown in the figure below.
-
-    +--------------------------...----------------------------+
-    +                         Line 4                          +
-    +--------------------------...----------------------------+
-    +                         Line 3                          +
-    +--------------------------...----------------------------+
-    +                         Line 2                          +
-    +--------------------------...----------------------------+ MSB (bit 7)
-    +                         Line 1                          +
-    +--------------------------...----------------------------+ LSB (bit 0)
-byte 127                                                     byte 0
-
-Users can perform read and write functions to the device node to access the data
-inside the display buffer.
index 7e77d623388b0d29496e40e24795aa00a262b982..cf94a6fceb57b2226f06ba864fa712109cb68119 100644 (file)
@@ -92,8 +92,6 @@ source "drivers/staging/video/axivdma/Kconfig"
 
 source "drivers/staging/apf/Kconfig"
 
-source "drivers/staging/pmods/Kconfig"
-
 source "drivers/staging/clocking-wizard/Kconfig"
 
 source "drivers/staging/fbtft/Kconfig"
index d508059d0156a12c4b243b3921ce1f625bee32d1..98e8cc56c3dd067aa6a139f3b6d7b89c8360543f 100644 (file)
@@ -35,7 +35,6 @@ obj-$(CONFIG_CRYPTO_SKEIN)    += skein/
 obj-$(CONFIG_UNISYSSPAR)       += unisys/
 obj-$(CONFIG_XILINX_VIDEO_IP)  += video/axivdma/
 obj-$(CONFIG_XILINX_APF)       += apf/
-obj-$(CONFIG_PMODS)            += pmods/
 obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD)  += clocking-wizard/
 obj-$(CONFIG_FB_TFT)           += fbtft/
 obj-$(CONFIG_FSL_MC_BUS)       += fsl-mc/
diff --git a/drivers/staging/pmods/Kconfig b/drivers/staging/pmods/Kconfig
deleted file mode 100644 (file)
index c4c94ce..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-menuconfig PMODS
-       bool "Pmod Support"
-       depends on HAS_IOMEM && OF
-       help
-               Digilent PMOD Support
-
-if PMODS
-
-config PMODS_DEBUG
-       bool "Enable Debug Message"
-
-config PMODOLED
-       tristate "PmodOLED1"
-       depends on SPI_BITBANG
-       depends on SPI_GPIO
-       help
-               The Digilent PmodOLED1, as well as ZED on-board OLED. Uses SPI over GPIO.
-
-config PMODCLS
-       tristate "pmodcls"
-       depends on SPI_BITBANG
-       help
-               This is the Digilent PmodCLS driver. Uses SPI over GPIO.
-
-config PMODCLP
-       tristate "pmodclp"
-       help
-               This is the Digilent PmodCLP driver. Implements parallel access.
-
-config PMODDA1
-       tristate "pmodda1"
-       depends on SPI_BITBANG
-       help
-               This is the Digilent PmodDA1 driver. Uses SPI over GPIO.
-
-config PMODAD1
-       tristate "pmodad1"
-       depends on SPI_BITBANG
-       help
-               This is the Digilent PmodAD1 driver. Uses SPI over GPIO.
-
-endif # PMODS
diff --git a/drivers/staging/pmods/Makefile b/drivers/staging/pmods/Makefile
deleted file mode 100644 (file)
index f8865f8..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-
-ccflags-$(CONFIG_PMODS_DEBUG)  += -DDEBUG
-
-obj-$(CONFIG_PMODOLED) += pmodoled-gpio.o
-obj-$(CONFIG_PMODCLS) += pmodcls.o
-obj-$(CONFIG_PMODCLP) += pmodclp.o
-obj-$(CONFIG_PMODDA1) += pmodda1.o
-obj-$(CONFIG_PMODAD1) += pmodad1.o
diff --git a/drivers/staging/pmods/pmodad1.c b/drivers/staging/pmods/pmodad1.c
deleted file mode 100644 (file)
index bc7db70..0000000
+++ /dev/null
@@ -1,633 +0,0 @@
-/*
- * pmodad1.c - Digilent PmodAD1 driver
- *
- * Copyright (c) 2012 Digilent. All right reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_gpio.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/spi_gpio.h>
-#include <linux/cdev.h>
-#include <linux/mutex.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/types.h>
-#include <linux/uaccess.h>
-
-#define DRIVER_NAME "pmodad1"
-#define SPI_DRIVER_NAME "pmodad1-spi"
-
-#define DEFAULT_SPI_SPEED 625000
-#define MAX_PMODAD1_DEV_NUM 16
-#define TXT_BUF_SIZE 1024
-#define MAX_NO_ROWS 2 /* The device has 2 rows */
-
-static dev_t pmodad1_dev_id;
-static unsigned int device_num;
-static unsigned int cur_minor;
-static unsigned int spi_drv_registered;
-static struct class *pmodad1_class;
-
-/* Kernel space buffer size (in bytes) for the ad1_read function.
- * Can be entered from the command line during insmod
- */
-static int read_buf_size = 512;
-module_param(read_buf_size, int, 0);
-
-struct pmodad1_device {
-       char *name;
-       /* R/W Mutex Lock */
-       struct mutex mutex;
-
-       unsigned short *val_buf;
-
-       /* Pin Assignment */
-
-       unsigned long iSCLK;
-       unsigned long iSDOUT;
-       unsigned long iCS;
-
-       /* SPI Info */
-       uint32_t spi_speed;
-       uint32_t spi_id;
-       /* platform device structures */
-       struct platform_device *pdev;
-       /* Char Device */
-       struct cdev cdev;
-       struct spi_device *spi;
-       dev_t dev_id;
-};
-
-/*
- * Driver read function
- *
- * This function uses a generic SPI read to read values from the Pmod.
- * It will only read full values, so if the length from user space is
- * not a multiple of 2, it will read up to length - 1 bytes.
- *
- * Function can possibly error out if:
- *             The mutex cannot be locked
- *             spi_read fails on the first read
- *
- * Otherwise, the function returns the number of successful values read,
- * each with a size of 2 bytes. So for instance, if 13 bytes are read,
- * the function will return 12, indicating 6 values were read successfully
- * from the pmod. Additionally, if copy_to_user cannot successfully
- * copy everything, the number of successfully copied full values (2 bytes)
- * will be returned.
- *
- * We use goto in this function because there are multiple exit points,
- * and it prevents us from having to call mutex_unlock() for the mutex
- * each time.
- */
-static ssize_t pmodad1_read(struct file *fp, char __user *buffer, size_t length, loff_t *offset)
-{
-       int status;             /* spi_read return value */
-       int num_reads;          /* Number of values to read from Pmod */
-       int i;
-       ssize_t retval;         /* Function return value */
-       ssize_t ret;            /* copy_to_user return value */
-       unsigned short buf;     /* Temporary storage for each read value */
-       struct pmodad1_device *dev;
-
-       dev = fp->private_data;
-       status = 0;
-       num_reads = length / 2;
-
-       if (mutex_lock_interruptible(&dev->mutex)) {
-               retval = -ERESTARTSYS;
-               goto lock_err;
-       }
-
-       if (buffer == NULL) {
-               retval = -EINVAL;
-               goto read_out;
-       }
-
-       for (i = 0; i < num_reads; i++) {
-               /* Use generic SPI read */
-               status = spi_read(dev->spi, &buf, 2);
-               if (status)
-                       break;
-               /* Change endianness of result, if necessary
-                * The result from the Pmod hardware is big endian,
-                * whereas Microblaze and other CPU architectures are
-                * little endian.
-                */
-               dev->val_buf[i] = be16_to_cpu(buf) & 0x0FFF; /* only 12 bits matters */
-       }
-
-       if (i == 0) {
-               dev_err(&dev->spi->dev, "SPI read failure: %d\n", status);
-               retval = status;
-               goto read_out;
-       }
-
-       /*
-        * Only copy full values (2 bytes) in the case of a user space length
-        *      that is not a multiple of 2.
-        */
-       ret = copy_to_user(buffer, (void *)dev->val_buf, i * 2);
-
-       retval = num_reads * 2 - (ret + (ret % 2));
-read_out:
-       mutex_unlock(&dev->mutex);
-lock_err:
-       return retval;
-}
-
-/**
- * A basic open function.
- */
-static int pmodad1_open(struct inode *inode, struct file *fp)
-{
-       struct pmodad1_device *dev;
-
-       dev = container_of(inode->i_cdev, struct pmodad1_device, cdev);
-       fp->private_data = dev;
-
-       return 0;
-}
-
-static const struct file_operations pmodad1_cdev_fops = {
-       .owner  = THIS_MODULE,
-       .open   = pmodad1_open,
-       .read   = pmodad1_read,
-};
-
-/**
- * add_pmodad1_device_to_bus - Add device to SPI bus, initialize SPI data.
- * @dev: pointer to device tree node
- *
- * This function adds device to SPI bus, initialize SPI data.
- */
-static int add_pmodad1_device_to_bus(struct pmodad1_device *dev)
-{
-       struct spi_master *spi_master;
-       struct spi_device *spi_device;
-       int status = 0;
-
-       spi_master = spi_busnum_to_master(dev->spi_id);
-       if (!spi_master) {
-               dev_err(&dev->pdev->dev, "spi_busnum_to_master(%d) returned NULL\n", dev->spi_id);
-               return -ENOSYS;
-       }
-
-       spi_device = spi_alloc_device(spi_master);
-       if (!spi_device) {
-               put_device(&spi_master->dev);
-               dev_err(&dev->pdev->dev, "spi_alloc_device() failed\n");
-               return -ENOMEM;
-       }
-
-       spi_device->chip_select = 0;
-       spi_device->max_speed_hz = dev->spi_speed;
-/*     spi_device->max_speed_hz = 625000; */
-       spi_device->mode = SPI_MODE_0;
-       spi_device->bits_per_word = 8;
-       spi_device->controller_data = (void *)dev->iCS;
-       spi_device->dev.platform_data = dev;
-       strlcpy(spi_device->modalias, SPI_DRIVER_NAME, sizeof(SPI_DRIVER_NAME));
-
-       status = spi_add_device(spi_device);
-       if (status < 0) {
-               spi_dev_put(spi_device);
-               dev_err(&dev->pdev->dev, "spi_add_device() failed %d\n", status);
-               return status;
-       }
-       dev->spi = spi_device;
-
-       put_device(&spi_master->dev);
-       pr_info(DRIVER_NAME " SPI initialized, max_speed_hz\t%d\n", spi_device->max_speed_hz);
-       return status;
-}
-
-/**
- * pmodad1_setup_cdev - Setup Char Device for ZED PmodAD1 device.
- * @dev: pointer to device tree node
- * @dev_id: pointer to device major and minor number
- * @spi: pointer to spi_device structure
- *
- * This function initializes char device for PmodAD1 device, and add it into
- * kernel device structure. It returns 0, if the cdev is successfully
- * initialized, or a negative value if there is an error.
- */
-static int pmodad1_setup_cdev(struct pmodad1_device *dev, dev_t *dev_id, struct spi_device *spi)
-{
-       int status = 0;
-       struct device *device;
-
-       cdev_init(&dev->cdev, &pmodad1_cdev_fops);
-       dev->cdev.owner = THIS_MODULE;
-       dev->cdev.ops = &pmodad1_cdev_fops;
-       dev->spi = spi;
-
-       *dev_id = MKDEV(MAJOR(pmodad1_dev_id), cur_minor++);
-       status = cdev_add(&dev->cdev, *dev_id, 1);
-       if (status < 0)
-               return status;
-
-       /* Add Device node in system */
-       device = device_create(pmodad1_class, NULL,
-                              *dev_id, NULL,
-                              "%s", dev->name);
-       if (IS_ERR(device)) {
-               status = PTR_ERR(device);
-               dev_err(&spi->dev, "failed to create device node %s, err %d\n",
-                       dev->name, status);
-               cdev_del(&dev->cdev);
-       }
-
-       return status;
-}
-
-/**
- * SPI hardware probe. Sets correct SPI mode, attempts
- * to obtain memory needed by the driver, and performs
- * a simple initialization of the device.
- * @spi        : pointer to spi device being initialized.
- */
-static int pmodad1_spi_probe(struct spi_device *spi)
-{
-       int status = 0;
-       struct pmodad1_device *pmodad1_dev;
-
-       if (spi->master->flags & SPI_MASTER_HALF_DUPLEX) {
-               status = -EINVAL;
-               pr_info(SPI_DRIVER_NAME "SPI settings incorrect: %d\n", status);
-               goto spi_err;
-       }
-
-       /* use SPI_MODE_0 */
-       spi->mode = SPI_MODE_0;
-       spi->bits_per_word = 8;
-
-       status = spi_setup(spi);
-       if (status < 0) {
-               dev_err(&spi->dev, "needs SPI mode %02x, %d KHz; %d\n",
-                       spi->mode, spi->max_speed_hz / 1000,
-                       status);
-               goto spi_err;
-       }
-
-       /* Get pmodad1_device structure */
-       pmodad1_dev = (struct pmodad1_device *)spi->dev.platform_data;
-       if (pmodad1_dev == NULL) {
-               dev_err(&spi->dev, "Cannot get pmodad1_device.\n");
-               status = -EINVAL;
-               goto spi_platform_data_err;
-       }
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(SPI_DRIVER_NAME " [%s] spi_probe: setup char device\n", pmodad1_dev->name);
-#endif
-
-       /* Setup char driver */
-       status = pmodad1_setup_cdev(pmodad1_dev, &(pmodad1_dev->dev_id), spi);
-       if (status) {
-               pr_info(" spi_probe: Error adding %s device: %d\n", SPI_DRIVER_NAME, status);
-               dev_err(&spi->dev, "spi_probe: Error adding %s device: %d\n", SPI_DRIVER_NAME, status);
-               goto cdev_add_err;
-       }
-
-       /* Initialize Mutex */
-       mutex_init(&pmodad1_dev->mutex);
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(SPI_DRIVER_NAME " [%s] spi_probe: initialize device\n", pmodad1_dev->name);
-#endif
-
-       return status;
-
-cdev_add_err:
-spi_platform_data_err:
-spi_err:
-       return status;
-}
-
-/**
- * pmodad1_spi_remove - SPI hardware remove.
- * Performs tasks required when SPI is removed.
- * @spi        : pointer to spi device being removed
- */
-static int pmodad1_spi_remove(struct spi_device *spi)
-{
-       int status;
-       struct pmodad1_device *dev;
-
-       dev = (struct pmodad1_device *)spi->dev.platform_data;
-
-       if (dev == NULL) {
-               dev_err(&spi->dev, "spi_remove: Error fetch pmodad1_device struct\n");
-               return -EINVAL;
-       }
-
-       if (&dev->cdev) {
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(SPI_DRIVER_NAME " [%s] spi_remove: Destroy Char Device\n", dev->name);
-#endif
-               device_destroy(pmodad1_class, dev->dev_id);
-               cdev_del(&dev->cdev);
-       }
-
-       cur_minor--;
-
-       return status;
-}
-
-static struct spi_driver pmodad1_spi_driver = {
-       .driver         = {
-               .name   = SPI_DRIVER_NAME,
-               .bus    = &spi_bus_type,
-               .owner  = THIS_MODULE,
-       },
-       .probe          = pmodad1_spi_probe,
-       .remove         = pmodad1_spi_remove,
-};
-
-static const struct of_device_id pmodad1_of_match[] = {
-       { .compatible = "dglnt,pmodad1", },
-       {},
-};
-MODULE_DEVICE_TABLE(of, pmodad1_of_match);
-
-/**
- * pmodad1_of_probe - Probe method for PmodAD1 device (over GPIO).
- * @pdev: pointer to platform devices
- *
- * This function probes the PmodAD1 device in the device tree. It initializes the
- * PmodAD1 driver data structure. It returns 0, if the driver is bound to the PmodAD1
- * device, or a negative value if there is an error.
- */
-static int pmodad1_of_probe(struct platform_device *pdev)
-{
-       struct pmodad1_device *pmodad1_dev;
-       struct platform_device *pmodad1_pdev;
-       struct spi_gpio_platform_data *pmodad1_pdata;
-
-       struct device_node *np = pdev->dev.of_node;
-
-       const u32 *tree_info;
-       const u32 *spi_speed;
-       int status = 0;
-
-       /* Alloc Space for platform device structure */
-       pmodad1_dev = kzalloc(sizeof(*pmodad1_dev), GFP_KERNEL);
-       if (!pmodad1_dev) {
-               status = -ENOMEM;
-               dev_err(&pdev->dev, "Platform device structure allocation failed: %d\n", status);
-               goto dev_alloc_err;
-       }
-
-       pmodad1_dev->val_buf = kmalloc(read_buf_size, GFP_KERNEL);
-       if (!pmodad1_dev->val_buf) {
-               status = -ENOMEM;
-               dev_err(&pdev->dev, "Device value buffer allocation failed: %d\n", status);
-               goto buf_alloc_err;
-       }
-
-       /* Get the GPIO Pins */
-
-       pmodad1_dev->iSCLK = of_get_named_gpio(np, "spi-sclk-gpio", 0);
-       pmodad1_dev->iSDOUT = of_get_named_gpio(np, "spi-sdout-gpio", 0);
-       status = of_get_named_gpio(np, "spi-cs-gpio", 0);
-       pmodad1_dev->iCS = (status < 0) ? SPI_GPIO_NO_CHIPSELECT : status;
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s: iSCLK: 0x%lx\n", np->name, pmodad1_dev->iSCLK);
-       pr_info(DRIVER_NAME " %s: iSDOUT: 0x%lx\n", np->name, pmodad1_dev->iSDOUT);
-       pr_info(DRIVER_NAME " %s: iCS : 0x%lx\n", np->name, pmodad1_dev->iCS);
-#endif
-
-       /* Get SPI Related Params */
-       tree_info = of_get_property(np, "spi-bus-num", NULL);
-       if (tree_info) {
-               pmodad1_dev->spi_id = be32_to_cpup((tree_info));
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " %s: BUS_ID\t%x\n", np->name, pmodad1_dev->spi_id);
-#endif
-       }
-
-       spi_speed = of_get_property(np, "spi-speed-hz", NULL);
-       if (spi_speed) {
-               pmodad1_dev->spi_speed = be32_to_cpup((spi_speed));
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " %s: SPI_SPEED\t%x\n", np->name, pmodad1_dev->spi_speed);
-#endif
-       } else {
-               pmodad1_dev->spi_speed = DEFAULT_SPI_SPEED;
-       }
-
-       /* Alloc Space for platform data structure */
-       pmodad1_pdata = kzalloc(sizeof(*pmodad1_pdata), GFP_KERNEL);
-       if (!pmodad1_pdata) {
-               status = -ENOMEM;
-               goto pdata_alloc_err;
-       }
-
-       /* Fill up Platform Data Structure */
-       pmodad1_pdata->sck = pmodad1_dev->iSCLK;
-       pmodad1_pdata->miso = pmodad1_dev->iSDOUT;
-       pmodad1_pdata->mosi = SPI_GPIO_NO_MOSI;
-       pmodad1_pdata->num_chipselect = 1;
-
-       /* Alloc Space for platform data structure */
-       pmodad1_pdev = kzalloc(sizeof(*pmodad1_pdev), GFP_KERNEL);
-       if (!pmodad1_pdev) {
-               status = -ENOMEM;
-               goto pdev_alloc_err;
-       }
-
-       /* Fill up Platform Device Structure */
-       pmodad1_pdev->name = "spi_gpio";
-       pmodad1_pdev->id = pmodad1_dev->spi_id;
-       pmodad1_pdev->dev.platform_data = pmodad1_pdata;
-       pmodad1_dev->pdev = pmodad1_pdev;
-
-       /* Register spi_gpio master */
-       status = platform_device_register(pmodad1_dev->pdev);
-       if (status < 0) {
-               dev_err(&pdev->dev, "platform_device_register failed: %d\n", status);
-               goto pdev_reg_err;
-       }
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s: spi_gpio platform device registered.\n", np->name);
-#endif
-       pmodad1_dev->name = (char *)np->name;
-
-       /* Fill up Board Info for SPI device */
-       status = add_pmodad1_device_to_bus(pmodad1_dev);
-       if (status < 0) {
-               dev_err(&pdev->dev, "add_pmodad1_device_to_bus failed: %d\n", status);
-               goto spi_add_err;
-       }
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s: spi device registered.\n", np->name);
-#endif
-
-       /* Point device node data to pmodad1_device structure */
-       if (np->data == NULL)
-               np->data = pmodad1_dev;
-
-       if (pmodad1_dev_id == 0) {
-               /* Alloc Major & Minor number for char device */
-               status = alloc_chrdev_region(&pmodad1_dev_id, 0, MAX_PMODAD1_DEV_NUM, DRIVER_NAME);
-               if (status) {
-                       dev_err(&pdev->dev, "Character device region not allocated correctly: %d\n", status);
-                       goto err_alloc_chrdev_region;
-               }
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : Char Device Region Registered, with Major: %d.\n",
-                       MAJOR(pmodad1_dev_id));
-#endif
-       }
-
-       if (pmodad1_class == NULL) {
-               /* Create Pmodad1 Device Class */
-               pmodad1_class = class_create(THIS_MODULE, DRIVER_NAME);
-               if (IS_ERR(pmodad1_class)) {
-                       status = PTR_ERR(pmodad1_class);
-                       goto err_create_class;
-               }
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : pmodad1 device class registered.\n");
-#endif
-       }
-
-       if (spi_drv_registered == 0) {
-               /* Register SPI Driver for Pmodad1 Device */
-               status = spi_register_driver(&pmodad1_spi_driver);
-               if (status < 0) {
-                       dev_err(&pdev->dev, "pmodad1_spi_driver register failed: %d\n", status);
-                       goto err_spi_register;
-               }
-               spi_drv_registered = 1;
-       }
-
-       device_num++;
-
-       return status;
-
-err_spi_register:
-       class_destroy(pmodad1_class);
-       pmodad1_class = NULL;
-err_create_class:
-       unregister_chrdev_region(pmodad1_dev_id, MAX_PMODAD1_DEV_NUM);
-       pmodad1_dev_id = 0;
-err_alloc_chrdev_region:
-       spi_unregister_device(pmodad1_dev->spi);
-spi_add_err:
-       platform_device_unregister(pmodad1_dev->pdev);
-pdev_reg_err:
-       kfree(pmodad1_pdev);
-pdev_alloc_err:
-       kfree(pmodad1_pdata);
-pdata_alloc_err:
-       kfree(pmodad1_dev->val_buf);
-buf_alloc_err:
-       kfree(pmodad1_dev);
-dev_alloc_err:
-       return status;
-}
-
-/**
- * pmodad1_of_remove - Remove method for ZED PmodAD1 device.
- * @np: pointer to device tree node
- *
- * This function removes the PmodAD1 device in the device tree. It frees the
- * PmodAD1 driver data structure. It returns 0, if the driver is successfully
- * removed, or a negative value if there is an error.
- */
-static int pmodad1_of_remove(struct platform_device *pdev)
-{
-       struct pmodad1_device *pmodad1_dev;
-       struct device_node *np = pdev->dev.of_node;
-
-       if (np->data == NULL) {
-               dev_err(&pdev->dev, "pmodad1 %s: ERROR: No pmodad1_device structure found!\n", np->name);
-               return -ENOSYS;
-       }
-       pmodad1_dev = (struct pmodad1_device *)(np->data);
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s : Free display buffer.\n", np->name);
-#endif
-
-       if (pmodad1_dev->val_buf != NULL)
-               kfree(pmodad1_dev->val_buf);
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s : Unregister gpio_spi Platform Devices.\n", np->name);
-#endif
-
-       if (pmodad1_dev->pdev != NULL)
-               platform_device_unregister(pmodad1_dev->pdev);
-
-       np->data = NULL;
-       device_num--;
-
-       /* Unregister SPI Driver, Destroy pmodad1 class, Release device id Region after
-        * all pmodad1 devices have been removed.
-        */
-       if (device_num == 0) {
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : Unregister SPI Driver.\n");
-#endif
-               spi_unregister_driver(&pmodad1_spi_driver);
-               spi_drv_registered = 0;
-
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : Destroy pmodad1 Class.\n");
-#endif
-
-               if (pmodad1_class)
-                       class_destroy(pmodad1_class);
-               pmodad1_class = NULL;
-
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : Release Char Device Region.\n");
-#endif
-
-               unregister_chrdev_region(pmodad1_dev_id, MAX_PMODAD1_DEV_NUM);
-               pmodad1_dev_id = 0;
-       }
-
-       return 0;
-}
-
-static struct platform_driver pmodad1_driver = {
-       .driver                 = {
-               .name           = DRIVER_NAME,
-               .owner          = THIS_MODULE,
-               .of_match_table = pmodad1_of_match,
-       },
-       .probe                  = pmodad1_of_probe,
-       .remove                 = pmodad1_of_remove,
-};
-
-module_platform_driver(pmodad1_driver);
-
-MODULE_AUTHOR("Cristian Fatu");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION(DRIVER_NAME ": PmodAD1 driver");
-MODULE_ALIAS(DRIVER_NAME);
diff --git a/drivers/staging/pmods/pmodclp.c b/drivers/staging/pmods/pmodclp.c
deleted file mode 100644 (file)
index 492af58..0000000
+++ /dev/null
@@ -1,1096 +0,0 @@
-/*
- * pmodclp.c - Digilent PmodCLP driver
- *
- * Copyright (c) 2012 Digilent. All right reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_gpio.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/cdev.h>
-#include <linux/mutex.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/types.h>
-#include <asm/uaccess.h>
-
-#define DRIVER_NAME "pmodclp"
-#define MAX_PMODCLP_DEV_NUM 16
-#define TXT_BUF_SIZE 1024
-#define MAX_NO_ROWS 2   /* The device has 2 rows */
-#define MAX_NO_COLS 40  /* The device has max 40 columns */
-
-#define CMD_LCDFNCINIT 0x38             /* function set command, (8-bit interface, 2 lines, and 5x8 dots) */
-#define CMD_LCDCTLINIT 0x08             /* display control set command */
-#define CMD_LCDCLEAR 0x01               /* clear display command */
-#define CMD_LCDRETHOME 0x02             /* return home command */
-#define CMD_LCDDISPLAYSHIFT 0x18        /* shift display command */
-#define CMD_LCDCURSORSHIFT 0x10         /* shift cursor command */
-#define CMD_LCDSETDDRAMPOS 0x80         /* set DDRAM position command */
-#define CMD_LCDSETCGRAMPOS 0x40         /* set CGRAM position command */
-
-#define MSK_BSTATUS 0x80                /* bit busy */
-#define MSK_SHIFTRL 0x04                /* shift direction mask */
-#define OPT_DISPLAYON 0x4               /* Set Display On option */
-#define OPT_CURSORON 0x2                /* Set Cursor On option */
-#define OPT_BLINKON 0x1                 /* Set Blink On option */
-
-static dev_t pmodclp_dev_id;
-static unsigned int device_num;
-static unsigned int cur_minor;
-static struct class *pmodclp_class;
-
-/* structure that keeps the parallel port related information */
-struct par_device {
-       /* Pin Assignment */
-
-       unsigned long iRS;
-       unsigned long iRW;
-       unsigned long iE;
-       unsigned long iBK;
-       unsigned long iData[8];
-};
-
-struct pmodclp_device {
-       char *name;
-       /* R/W Mutex Lock */
-       struct mutex mutex;
-       /* Text Buffer */
-       char *txt_buf;          /* Device Text buffer */
-       unsigned long cur_row;  /* Maintain current row */
-       int exceeded_rows;      /* Flag for situation where maximum number of rows is exceeded */
-
-       int display_on;
-       int cursor_on;
-       int blink_on;
-       int bk_on;
-
-       /* Pin Assignment */
-       struct par_device par_dev;
-
-       /* Char Device */
-       struct cdev cdev;
-       dev_t dev_id;
-};
-
-/* Forward definitions */
-void parse_text(char *txt_buf, int cnt, struct pmodclp_device *dev);
-void pmodclp_write_command(struct par_device *par_dev, unsigned char cmd);
-static int pmodclp_init_gpio(struct pmodclp_device *pmodclp_dev);
-
-/**
- * A basic open function.
- */
-static int pmodclp_open(struct inode *inode, struct file *fp)
-{
-       struct pmodclp_device *dev;
-
-       dev = container_of(inode->i_cdev, struct pmodclp_device, cdev);
-       fp->private_data = dev;
-
-       return 0;
-}
-
-/**
- * A basic close function, do nothing.
- */
-
-static int pmodclp_close(struct inode *inode, struct file *fp)
-{
-       return 0;
-}
-
-/*
- * Driver write function
- *
- * This function uses a generic SPI write to send values to the Pmod device.
- * It takes a string from the app in the buffer.
- * It interprets the string of characters, and sends the commands and the text to PmodCLP over the parallel interface.
- */
-
-static ssize_t pmodclp_write(struct file *fp, const char __user *buffer, size_t length, loff_t *offset)
-{
-       ssize_t retval = 0;
-       int cnt;
-       struct pmodclp_device *dev;
-
-       dev = fp->private_data;
-
-       if (mutex_lock_interruptible(&dev->mutex)) {
-               retval = -ERESTARTSYS;
-               goto write_lock_err;
-       }
-
-       cnt = length;
-
-       if (copy_from_user(dev->txt_buf, buffer, cnt)) {
-               retval = -EFAULT;
-               goto quit_write;
-       }
-       retval = cnt;
-
-       dev->txt_buf[cnt] = '\0';
-
-       parse_text(dev->txt_buf, cnt, dev);
-
-quit_write:
-       mutex_unlock(&dev->mutex);
-write_lock_err:
-       return retval;
-}
-
-static void write_display_control_cmd(struct pmodclp_device *dev)
-{
-       unsigned char cmd = CMD_LCDCTLINIT +
-                           (dev->display_on ? OPT_DISPLAYON : 0) +
-                           (dev->cursor_on ? OPT_CURSORON : 0) +
-                           (dev->blink_on ? OPT_BLINKON : 0);
-
-       pmodclp_write_command(&(dev->par_dev), cmd);
-
-}
-
-/* Begin of parallel interface functions */
-
-/**
- * gpio_par_define_data_direction - Configure the gpio data pins as input or output.
- *
- * Parameters:
- * @struct par_device *par_dev:        pointer to the structure containing parallel interface information
- * @bool fOutput:              true if the pins are configured as output
-                               false if the pins are configured as input
- * @unsigned char bOutputVal   the 8 bit value corresponding to the initial value set for the 8 lines if they are defined as output
- *
- *
- * This function configures the gpio data pins as input or output, as required by read or write operations.
- */
-static int gpio_par_define_data_direction(struct par_device *par_dev, bool fOutput, unsigned char bOutputVal)
-{
-       int i;
-       int status = 0;
-
-       for (i = 0; !status && (i < 8); i++) {
-               if (fOutput)
-                       status = gpio_direction_output(par_dev->iData[i], ((bOutputVal & (1 << i)) ? 1 : 0));
-               else
-                       status = gpio_direction_input(par_dev->iData[i]);
-       }
-       udelay(20);
-       return status;
-}
-
-/**
- * gpio_par_read_byte - Read one byte function.
- *
- * Parameters:
- * @struct par_device *par_dev:        pointer to the structure containing parallel interface information
- *
- * Return value                        the byte read
- *
- * This function implements the parallel read cycle on the gpio pins. It is the basic read function.
- */
-static unsigned char gpio_par_read_byte(struct par_device *par_dev)
-{
-       int i;
-       unsigned char bData = 0;
-
-       /* Set RW */
-       gpio_set_value(par_dev->iRW, 1);
-       udelay(20);
-       /* Set Enable */
-       gpio_set_value(par_dev->iE, 1);
-       udelay(20);
-       for (i = 0; i < 8; i++)
-               bData += ((unsigned char)gpio_get_value(par_dev->iData[i]) << i);
-
-       /* Clear Enable */
-       gpio_set_value(par_dev->iE, 0);
-       udelay(20);
-       /* Clear RW */
-       gpio_set_value(par_dev->iRW, 0);
-       udelay(20);
-       return bData;
-}
-
-/**
- * gpio_par_write_byte - Write one byte function.
- *
- * Parameters:
- * @struct par_device *par_dev:        pointer to the structure containing parallel interface information
- * @unsigned char bData:       the byte to be written over the parallel interface.
- *
- *
- * This function implements the parallel write cycle on the gpio pins. It is the basic write function,
- * it writes one byte over the parallel interface.
- */
-static void gpio_par_write_byte(struct par_device *par_dev, unsigned char bData)
-{
-       int i;
-
-       /* Clear RW */
-       gpio_set_value(par_dev->iRW, 0);
-       udelay(20);
-       /* Set Enable */
-       gpio_set_value(par_dev->iE, 1);
-       udelay(20);
-       for (i = 0; i < 8; i++)
-               gpio_set_value(par_dev->iData[i], (bData >> i) & 0x01);
-
-       /* Clear Enable */
-       gpio_set_value(par_dev->iE, 0);
-       udelay(20);
-       /* Set RW */
-       gpio_set_value(par_dev->iRW, 1);
-       udelay(20);
-}
-
-/**
- * pmodclp_read_status - Read Status function
- *
- * Parameters:
- * @struct par_device *par_dev:        pointer to the structure containing parallel interface information
- *
- *
- * This function reads the status of the PmodCLP device.
- */
-static unsigned char pmodclp_read_status(struct par_device *par_dev)
-{
-       unsigned char bStatus;
-
-       /* define data pins as input */
-       gpio_par_define_data_direction(par_dev, false, 0);
-
-       /* clear RS, meaning instruction register */
-       gpio_set_value(par_dev->iRS, 0);
-       udelay(20);
-
-       bStatus = gpio_par_read_byte(par_dev);
-
-       return bStatus;
-}
-
-/**
- * pmodclp_wait_until_not_busy - Wait until device is ready function
- *
- * Parameters:
- * @struct par_device *par_dev:        pointer to the structure containing parallel interface information
- *
- *
- * This function loops until the device reports to be not busy.
- */
-static void pmodclp_wait_until_not_busy(struct par_device *par_dev)
-{
-       unsigned char bStatus;
-
-       /* read status */
-       bStatus = pmodclp_read_status(par_dev);
-       while (bStatus & MSK_BSTATUS) {
-               mdelay(10);
-               bStatus = pmodclp_read_status(par_dev);
-       }
-}
-
-/**
- * gpio_par_write_byte - Write one command byte function.
- *
- * Parameters:
- * @struct par_device *par_dev:        pointer to the structure containing parallel interface information
- * @unsigned char bData:       the byte containing the command to be written over the parallel interface.
- *
- *
- * This function writes a command byte over the parallel interface.
- */
-void pmodclp_write_command(struct par_device *par_dev, unsigned char cmd)
-{
-       /* wait until LCD is not busy */
-       pmodclp_wait_until_not_busy(par_dev);
-
-       /* clear RS, meaning instruction register */
-       gpio_set_value(par_dev->iRS, 0);
-       udelay(20);
-
-       /* Write command byte */
-       /* define data pins as output, and provide initial output value */
-       gpio_par_define_data_direction(par_dev, true, cmd);
-
-       /* implement write command */
-       gpio_par_write_byte(par_dev, cmd);
-}
-
-/**
- * gpio_par_write_byte - Write array of caracters as data function.
- *
- * Parameters:
- * @struct par_device *par_dev:        pointer to the structure containing parallel interface information
- * @char *txt_buf: the text array to be written
- * @int cnt the number of charcaters in the text array
- *
- * This function writes a number of characters as data over the parallel interface.
- */
-static void pmodclp_write_data(struct par_device *par_dev, char *txt_buf, int cnt)
-{
-       int i;
-
-       /* set RS, meaning data */
-       gpio_set_value(par_dev->iRS, 1);
-       udelay(20);
-
-       /* define data pins as output, and provide initial output value */
-       gpio_par_define_data_direction(par_dev, true, txt_buf[0]);
-       for (i = 0; i < cnt; i++)
-               /* implement write command */
-               gpio_par_write_byte(par_dev, txt_buf[i]);
-}
-
-/**
- * pmodclp_init - Required initialization sequence for PmodCLP.
- *
- * Parameters:
- * @struct par_device *par_dev: pointer to the structure containing parallel interface information
- *
- *
- * This function performs the required initialization sequence for PmodCLP. See the reference manual for more information.
- */
-static void pmodclp_init(struct par_device *par_dev)
-{
-
-       /* perform initialization sequence, according to datasheet */
-
-       /*      wait 20 ms */
-       mdelay(20);
-       /* Set function */
-       pmodclp_write_command(par_dev, CMD_LCDFNCINIT);
-       /* Wait 37 us */
-       udelay(37);
-
-       /* display on, no cursor, no blinking */
-       pmodclp_write_command(par_dev, CMD_LCDCTLINIT);
-
-       /* Wait 37 us */
-       udelay(37);
-
-       /* Display Clear */
-       pmodclp_write_command(par_dev, CMD_LCDCLEAR);
-       /* Wait 1.52 ms */
-       udelay(1520);
-
-}
-/* Begin of parse functions */
-
-/**
- * is_decimal_digit - This function returns true if the specified character is among decimal characters.
- *
- * Parameters
- * @char c: character that is searched to be among decimal characters
- *
- * Return value
- *     true if the specified character is among decimal characters
- *     false if the character character is not among decimal characters
- *
- * This function returns true if the specified character is among hexa characters ('0', '1', ...'9').
- */
-static bool is_decimal_digit(char c)
-{
-       return c >= '0' && c <= '9';
-}
-
-/**
- * is_hexa_digit - This function returns true if the specified character is among hexa characters.
- *
- * Parameters
- * @char c: character that is searched to be among hexa characters
- *
- * Return value
- *     true if the specified character is among hexa characters
- *     false if the character character is not among hexa characters
- *
- * This function returns true if the specified character is among hexa characters ('0', '1', ...'9', 'A', 'B', ... , 'F', 'a', 'b', ..., 'f').
- */
-static bool is_hexa_digit(char c)
-{
-       return is_decimal_digit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
-}
-
-/**
- * is_binary_digit - This function returns true if the specified character is among binary characters.
- *
- * Parameters
- * @char c: character that is searched to be among binary characters
- *
- * Return value
- *     true if the specified character is among binary characters
- *     false if the character character is not among binary characters
- *
- * This function returns true if the specified character is among binary characters ('0' and '1').
- */
-static bool is_binary_digit(char c)
-{
-       return c == '0' || c == '1';
-}
-
-/**
- * parse_cmd - This function builds the commands to be sent for each recognized escape sequence.
- *
- * Parameters
- * @char c: character that is searched to be among command codes
- * @unsigned char *pars parameters array, built in parse_text function
- * @int idx_par                        index of last parameter in parameters array, built in parse_text function
- * @int par_typ                        the type of the last parameter
- *                                     0 - decimal
- *                                     1 - hexa
- *                                     2 - binary
- * @struct pmodclp_device *dev pointer to device structure
- *
- * Return value
- *     1 if the character was recognized as a command code and the parameters configuration is correct for that command
- *     0 if the character is not a command code
- *
- * This function tries to mach the specified character and the parameters configuration to a command.
- *     If it does, the command is built and sent to PmodCLP on parallel interface and 1 is returned.
- * If no command is recognized for the character, 0 is returned.
- */
-
-static int parse_cmd(char c, unsigned char *pars, int idx_par, int par_type, struct pmodclp_device *dev)
-{
-       int is_consumed_char = 0; /* this will be returned */
-       unsigned char cmd;
-
-       switch (c) {
-       case 'e':
-               /* enable/disable display */
-               if (idx_par >= 0 && par_type == 0 && pars[0] >= 0 && pars[0] <= 3) {
-                       /* set display */
-                       int display, bk;
-                       display = (pars[0] & 1) != 0;
-                       if (display != dev->display_on) {
-                               dev->display_on = display;
-                               write_display_control_cmd(dev);
-                       }
-
-                       /* set background light, if the pin is defined. */
-                       if (dev->par_dev.iBK != -1) {
-                               bk = (pars[0] & 2) >> 1;
-                               if (bk != dev->bk_on) {
-                                       dev->bk_on = bk;
-                                       gpio_set_value(dev->par_dev.iBK, bk);
-                               }
-                       }
-                       is_consumed_char = 1; /* mark char as consumed. */
-               }
-               break;
-       case 'H': /* set cursor position */
-               if (idx_par == 1 && pars[0] >= 0 && pars[0] < MAX_NO_ROWS && pars[1] >= 0 && pars[1] < MAX_NO_COLS) {
-                       /* allow only decimal parameter */
-                       dev->cur_row = pars[0];
-                       dev->exceeded_rows = 0;
-                       cmd = 0x40 * pars[0] + pars[1];
-                       cmd |= CMD_LCDSETDDRAMPOS;
-                       pmodclp_write_command(&(dev->par_dev), cmd);
-                       is_consumed_char = 1; /* mark char as consumed. */
-               }
-               break;
-       case 'j': /* clear display and home cursor */
-               dev->cur_row = 0;
-               dev->exceeded_rows = 0;
-               pmodclp_write_command(&(dev->par_dev), CMD_LCDCLEAR);
-               is_consumed_char = 1;   /* mark char as consumed. */
-               break;
-       case '@':                       /* scroll left */
-               if (idx_par == 0 && pars[0] >= 0 && pars[0] < MAX_NO_COLS) {
-                       /* allow only decimal parameter */
-                       int i;
-                       cmd = CMD_LCDDISPLAYSHIFT;
-                       for (i = 0; i < pars[0]; i++)
-                               /* scroll one position */
-                               pmodclp_write_command(&(dev->par_dev), cmd);
-                       is_consumed_char = 1; /* mark char as consumed. */
-               }
-               break;
-       case 'A': /* scroll right */
-               if (idx_par == 0 && pars[0] >= 0 && pars[0] < MAX_NO_COLS) {
-                       /* allow only decimal parameter */
-                       int i;
-                       cmd = CMD_LCDDISPLAYSHIFT | MSK_SHIFTRL;
-                       for (i = 0; i < pars[0]; i++)
-                               /* scroll one position */
-                               pmodclp_write_command(&(dev->par_dev), cmd);
-                       is_consumed_char = 1; /* mark char as consumed. */
-               }
-               break;
-       case 'c': /* set cursor mode */
-               if (idx_par == 0 && par_type == 0 && pars[0] >= 0 && pars[0] <= 2) {
-                       /* allow only decimal parameter */
-                       int cursor, blink;
-
-                       /* set cursor */
-                       cursor = pars[0] >= 1; /* 1 and 2 */
-                       if (cursor != dev->cursor_on) {
-                               dev->cursor_on = cursor;
-                               write_display_control_cmd(dev);
-                       }
-                       /* set blink */
-                       blink = pars[0] <= 1; /* 0 and 1 */
-
-                       if (blink != dev->blink_on) {
-                               dev->blink_on = blink;
-                               write_display_control_cmd(dev);
-                       }
-                       is_consumed_char = 1; /* mark char as consumed. */
-               }
-               break;
-       case 'd': /* define user programmable character */
-       {
-               /* define user char */
-               if (idx_par == 8 && par_type == 0) {
-                       /* 9 params
-                               - first 8 definition bytes and
-                               - last one is the character number, allow only ecimal character
-                        */
-
-                       /* set CGRAM pos */
-                       unsigned char cmd = CMD_LCDSETCGRAMPOS | (pars[8] << 3);
-                       pmodclp_write_command(&(dev->par_dev), cmd);
-
-                       /* write 8 character definition bytes as data */
-                       pmodclp_write_data(&(dev->par_dev), pars, 8);
-                       is_consumed_char = 1; /* mark} char as consumed. */
-               }
-       }
-       break;
-       default:
-       break;
-               /* no command was recognized */
-       }
-       return is_consumed_char;
-}
-
-/**
- * parse_text - This function builds the commands to be sent for each recognized escape sequence.
- *
- * Parameters
- * @char *txt_buf: the text array to be parsed
- * @int cnt the number of charcaters to be parsed in the text array
- * @struct pmodclp_device *dev pointer to device structure
- *
- *
- * This function parses a text array, containing a sequence of one or more text or commands sent to PmodCLP. Its purpose is:
- * - recognize, interpret the text sent to the device:
- * - split the separate commands / text and process them individually.
- * - recognize escape code commands and translate them into PmodCLP commands on parallel interface
- * - send text data to PmodCLP device on parallel interface
- * - maintain a shadow value of the current row (this is because the cursor position cannot be read)
- * - recognize LF character ('\n') inside a text to be sent to the device
- * - if current line is the first, move the cursor to the beginning of the next line
- * - if current line is the second, there is no room for new line. Text characters after LF are ignored, commands are still interpreted.
- *
- */
-void parse_text(char *txt_buf, int cnt, struct pmodclp_device *dev)
-{
-       int is_ignore_txt;
-       int is_cmd = 0;
-       int is_inside_par = -1;
-       int is_consumed_char;
-       int par_type = 0;
-
-       char *parse_ptr, *processed_ptr, *par_ptr;
-       int idx_par = -1;
-       unsigned char pars[10];
-
-       par_ptr = NULL;
-       parse_ptr = txt_buf;
-       processed_ptr = txt_buf - 1;
-       is_cmd = 0;
-       par_type = -1;
-       is_ignore_txt = dev->exceeded_rows;
-       while (parse_ptr < (txt_buf + cnt)) {
-               is_consumed_char = 0; /* waiting to be consumed */
-               /* recognize command - look for ESC code, followed by '[' */
-               if ((!is_cmd) && ((*parse_ptr) == 0x1B) && (parse_ptr[1] == '[')) {
-                       /* enter command mode */
-                       is_cmd = 1;
-                       is_inside_par = 0; /* able to receive the parameter */
-                       /* send previous text (before the ESC sequence) */
-                       if ((parse_ptr - processed_ptr) > 1)
-                               pmodclp_write_data(&(dev->par_dev), processed_ptr + 1, parse_ptr - 1 - processed_ptr);
-                       parse_ptr++; /* skip '[' char */
-               } else {
-                       if (is_cmd) {
-                               /* look for commands */
-                               if (!(par_type == 1 && (parse_ptr - par_ptr) <= 2))
-                                       /* do not look for commands when current parameter is hexa and less than 2 chars are parsed */
-                                       is_consumed_char = parse_cmd(*parse_ptr, pars, idx_par, par_type, dev);
-                               is_ignore_txt = dev->exceeded_rows; /* because command parsing may change this parameter */
-                               if (is_consumed_char) {
-                                       /* mark text as processed including the command char */
-                                       if ((parse_ptr - processed_ptr) > 0) {
-                                               processed_ptr = parse_ptr;
-                                               is_cmd = 0; /* comand mode is abandonned */
-                                       }
-                               }
-                               if (!is_inside_par) {
-                                       /* look for begining of a parameter */
-                                       if (is_decimal_digit(*parse_ptr)) {
-                                               par_type = -1;
-                                               if (*parse_ptr == '0') {
-                                                       if (parse_ptr[1] == 'x' || parse_ptr[1] == 'X') {
-                                                               /* 0x or 0X sequence detected, start a hexa parameter */
-                                                               par_type = 1;
-                                                               is_consumed_char = 1;   /* char was consumed */
-                                                               parse_ptr++;            /* skip 'x' or 'X' char */
-                                                       } else {
-                                                               if (parse_ptr[1] == 'b' || parse_ptr[1] == 'B') {
-                                                                       /* 0B or 0b sequence detected, start a binary parameter */
-                                                                       par_type = 2;
-                                                                       is_consumed_char = 1;   /* char was consumed */
-                                                                       parse_ptr++;            /* skip 'b' or 'B' char */
-                                                               }
-                                                       }
-                                               }
-                                               idx_par++;
-                                               if (!is_consumed_char) {
-                                                       /* 0x or 0b were not detected, start a decimal parameter */
-                                                       par_type = 0;
-                                                       pars[idx_par] = (*parse_ptr - '0');
-                                                       is_consumed_char = 1; /* char was consumed */
-                                               } else {
-                                                       pars[idx_par] = 0;
-                                               }
-                                               par_ptr = parse_ptr;
-                                               is_inside_par = 1;
-                                       }
-                               } else {
-                                       /* inside parameter, look for ';' separator and parameter digits */
-                                       if (!is_consumed_char) {
-                                               if ((*parse_ptr) == ';') {      /* parameters separator */
-                                                       par_ptr = NULL;
-                                                       is_inside_par = 0;      /* look for a new parameter */
-                                                       is_consumed_char = 1;   /* char was consumed */
-                                               }
-                                       }
-                                       if (!is_consumed_char) {
-                                               switch (par_type) {
-                                               /* interpret parameter digit */
-                                               case 0: /* decimal */
-                                                       if (is_decimal_digit(*parse_ptr)) {
-                                                               pars[idx_par] = 10 * pars[idx_par] + (*parse_ptr - '0');
-                                                               is_consumed_char = 1; /* char was consumed */
-                                                       }
-                                                       /* else wrong char, expecting decimal digit, do not consume char */
-                                                       break;
-                                               case 1: /* hexa */
-                                                       if (is_hexa_digit(*parse_ptr)) {
-                                                               pars[idx_par] = pars[idx_par] << 4;
-                                                               if (*parse_ptr >= '0' && *parse_ptr <= '9')
-                                                                       pars[idx_par] += (*parse_ptr - '0');
-                                                               else{
-                                                                       if (*parse_ptr >= 'A' && *parse_ptr <= 'F')
-                                                                               pars[idx_par] += 10 + (*parse_ptr - 'A');
-                                                                       else
-                                                                               pars[idx_par] += 10 + (*parse_ptr - 'a');
-                                                               }
-                                                               is_consumed_char = 1; /* char was consumed */
-                                                       }
-                                                       /* else wrong char, expecting decimal digit, do not consume char */
-                                                       break;
-                                               case 2: /* binary */
-                                                       if (is_binary_digit(*parse_ptr)) {
-                                                               pars[idx_par] = (pars[idx_par] << 1) + (*parse_ptr - '0');
-                                                               is_consumed_char = 1; /* char was consumed */
-                                                       }
-                                                       /* else wrong char, expecting binary digit, leave command mode */
-                                                       break;
-                                               }
-                                       }       /* end of interpret parameter digit */
-                               }               /* end of parameter} */
-                               if (!is_consumed_char) {
-                                       /* inside command mode, if character is not consumed, leave command mode */
-                                       is_cmd = 0;
-                                       /* consume unrecongnized command characters, makes no sense to display them on LCD */
-                                       pr_info(" Wrong command: %.*s\n", (int)(parse_ptr - processed_ptr + 1), processed_ptr);
-                                       processed_ptr = parse_ptr;
-                               }
-                               /* end of inside command */
-                       } else {
-                               /* free text, not inside a command */
-                               if (is_ignore_txt) {
-                                       /* if text is ignored, processed_ptr advances together with parse_ptr */
-                                       processed_ptr = parse_ptr;
-                               } else {
-                                       if ((*parse_ptr) == '\n') { /* LF */
-                                               /* mark processed before the LF char */
-                                               if ((parse_ptr - processed_ptr) > 0)
-                                                       pmodclp_write_data(&(dev->par_dev), processed_ptr + 1, parse_ptr - 1 - processed_ptr);
-                                               /* position the cursor on the beginning of the next line */
-                                               if (dev->cur_row < (MAX_NO_ROWS - 1)) {
-                                                       dev->cur_row++;
-                                                       pmodclp_write_command(&(dev->par_dev), CMD_LCDSETDDRAMPOS + 0x40 * dev->cur_row);
-                                               } else {
-                                                       /* there is no room to place a third line. Enter ignore text (still look for the comands) */
-                                                       is_ignore_txt = 1;
-                                               }
-                                               /* advance the pointers so that LF char is skipped next time when chars are sent */
-                                               processed_ptr = parse_ptr;
-                                       }
-                               }
-                       }
-               }
-               parse_ptr++; /* advance one character */
-       }
-       parse_ptr--;
-       /* send remaining chars */
-
-       if (((parse_ptr - processed_ptr) > 0)) {
-               if (!is_cmd)
-                       pmodclp_write_data(&(dev->par_dev), processed_ptr + 1, parse_ptr - processed_ptr);
-               else
-                       pr_info(" Wrong command: %.*s\n", (int)(parse_ptr - processed_ptr + 2), processed_ptr + 1);
-       }
-
-       dev->exceeded_rows = is_ignore_txt;
-}
-
-/**
- * Driver Read Function
- *
- * This function does not actually read the PmodCLP as it is a write-only device.
- */
-static ssize_t pmodclp_read(struct file *fp, char __user *buffer, size_t length, loff_t *offset)
-{
-       ssize_t retval = 0;
-
-       return retval;
-}
-
-static const struct file_operations pmodclp_cdev_fops = {
-       .owner          = THIS_MODULE,
-       .write          = pmodclp_write,
-       .read           = pmodclp_read,
-       .open           = pmodclp_open,
-       .release        = pmodclp_close,
-};
-
-/**
- * pmodclp_setup_cdev - Setup Char Device for ZED PmodCLP device.
- * @dev: pointer to device tree node
- * @dev_id: pointer to device major and minor number
- * @spi: pointer to spi_device structure
- *
- * This function initializes char device for PmodCLP device, and add it into
- * kernel device structure. It returns 0, if the cdev is successfully
- * initialized, or a negative value if there is an error.
- */
-static int pmodclp_setup_cdev(struct pmodclp_device *dev, dev_t *dev_id)
-{
-       int status = 0;
-       struct device *device;
-
-       cdev_init(&dev->cdev, &pmodclp_cdev_fops);
-       dev->cdev.owner = THIS_MODULE;
-       dev->cdev.ops = &pmodclp_cdev_fops;
-
-       *dev_id = MKDEV(MAJOR(pmodclp_dev_id), cur_minor++);
-       status = cdev_add(&dev->cdev, *dev_id, 1);
-       if (status < 0) {
-               pr_info(" cdev_add failed ...\n");
-               return status;
-       }
-
-       /* Add Device node in system */
-       device = device_create(pmodclp_class, NULL,
-                              *dev_id, NULL,
-                              "%s", dev->name);
-       if (IS_ERR(device)) {
-               status = PTR_ERR(device);
-               pr_info("failed to create device node %s, err %d\n",
-                        dev->name, status);
-               cdev_del(&dev->cdev);
-       }
-
-       return status;
-}
-
-static const struct of_device_id pmodclp_of_match[] = {
-       { .compatible = "dglnt,pmodclp", },
-       {},
-};
-MODULE_DEVICE_TABLE(of, pmodclp_of_match);
-
-/**
- * pmodclp_of_probe - Probe method for PmodCLP device (over GPIO).
- * @pdev: pointer to platform devices
- *
- * This function probes the PmodCLP device in the device tree. It initializes the
- * PmodCLP driver data structure. It returns 0, if the driver is bound to the PmodCLP
- * device, or a negative value if there is an error.
- */
-static int pmodclp_of_probe(struct platform_device *pdev)
-{
-       struct pmodclp_device *pmodclp_dev;
-
-       struct device_node *np = pdev->dev.of_node;
-
-       int status = 0;
-
-       /* Alloc Space for platform device structure */
-       pmodclp_dev = kzalloc(sizeof(*pmodclp_dev), GFP_KERNEL);
-       if (!pmodclp_dev) {
-               status = -ENOMEM;
-               goto dev_alloc_err;
-       }
-
-       /* Alloc Text Buffer for device */
-       pmodclp_dev->txt_buf = kmalloc(TXT_BUF_SIZE, GFP_KERNEL);
-       if (!pmodclp_dev->txt_buf) {
-               status = -ENOMEM;
-               dev_err(&pdev->dev, "Device Display data buffer allocation failed: %d\n", status);
-               goto txt_buf_alloc_err;
-       }
-
-       /* Get the GPIO Pins */
-       pmodclp_dev->par_dev.iRS = of_get_named_gpio(np, "rs-gpio", 0);
-       pmodclp_dev->par_dev.iRW = of_get_named_gpio(np, "rw-gpio", 0);
-       pmodclp_dev->par_dev.iE = of_get_named_gpio(np, "e-gpio", 0);
-       status = of_get_named_gpio(np, "bk-gpio", 0);
-       pmodclp_dev->par_dev.iBK = (status < 0) ? -1 : status;
-
-       pmodclp_dev->par_dev.iData[0] = of_get_named_gpio(np, "data0-gpio", 0);
-       pmodclp_dev->par_dev.iData[1] = of_get_named_gpio(np, "data1-gpio", 0);
-       pmodclp_dev->par_dev.iData[2] = of_get_named_gpio(np, "data2-gpio", 0);
-       pmodclp_dev->par_dev.iData[3] = of_get_named_gpio(np, "data3-gpio", 0);
-       pmodclp_dev->par_dev.iData[4] = of_get_named_gpio(np, "data4-gpio", 0);
-       pmodclp_dev->par_dev.iData[5] = of_get_named_gpio(np, "data5-gpio", 0);
-       pmodclp_dev->par_dev.iData[6] = of_get_named_gpio(np, "data6-gpio", 0);
-       pmodclp_dev->par_dev.iData[7] = of_get_named_gpio(np, "data7-gpio", 0);
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s: iRS: 0x%lx\n", np->name, pmodclp_dev->par_dev.iRS);
-       pr_info(DRIVER_NAME " %s: iRW: 0x%lx\n", np->name, pmodclp_dev->par_dev.iRW);
-       pr_info(DRIVER_NAME " %s: iE : 0x%lx\n", np->name, pmodclp_dev->par_dev.iE);
-       pr_info(DRIVER_NAME " %s: iBK : 0x%lx\n", np->name, pmodclp_dev->par_dev.iBK);
-
-       pr_info(DRIVER_NAME " %s: iData[0] : 0x%lx\n", np->name, pmodclp_dev->par_dev.iData[0]);
-       pr_info(DRIVER_NAME " %s: iData[1] : 0x%lx\n", np->name, pmodclp_dev->par_dev.iData[1]);
-       pr_info(DRIVER_NAME " %s: iData[2] : 0x%lx\n", np->name, pmodclp_dev->par_dev.iData[2]);
-       pr_info(DRIVER_NAME " %s: iData[3] : 0x%lx\n", np->name, pmodclp_dev->par_dev.iData[3]);
-       pr_info(DRIVER_NAME " %s: iData[4] : 0x%lx\n", np->name, pmodclp_dev->par_dev.iData[4]);
-       pr_info(DRIVER_NAME " %s: iData[5] : 0x%lx\n", np->name, pmodclp_dev->par_dev.iData[5]);
-       pr_info(DRIVER_NAME " %s: iData[6] : 0x%lx\n", np->name, pmodclp_dev->par_dev.iData[6]);
-       pr_info(DRIVER_NAME " %s: iData[7] : 0x%lx\n", np->name, pmodclp_dev->par_dev.iData[7]);
-#endif
-       pmodclp_dev->name = (char *)np->name;
-
-       /* initialize device data */
-       pmodclp_dev->cur_row = 0;
-       pmodclp_dev->exceeded_rows = 0;
-
-       pmodclp_dev->display_on = 0;
-       pmodclp_dev->cursor_on = 0;
-       pmodclp_dev->blink_on = 0;
-       pmodclp_dev->bk_on = 0;
-
-       /* Point device node data to pmodclp_device structure */
-       if (np->data == NULL)
-               np->data = pmodclp_dev;
-
-       if (pmodclp_dev_id == 0) {
-               /* Alloc Major & Minor number for char device */
-               status = alloc_chrdev_region(&pmodclp_dev_id, 0, MAX_PMODCLP_DEV_NUM, DRIVER_NAME);
-               if (status) {
-                       dev_err(&pdev->dev, "Character device region not allocated correctly: %d\n", status);
-                       goto err_alloc_chrdev_region;
-               }
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : Char Device Region Registered, with Major: %d.\n",
-                       MAJOR(pmodclp_dev_id));
-#endif
-       }
-
-       if (pmodclp_class == NULL) {
-               /* Create Pmodclp Device Class */
-               pmodclp_class = class_create(THIS_MODULE, DRIVER_NAME);
-               if (IS_ERR(pmodclp_class)) {
-                       status = PTR_ERR(pmodclp_class);
-                       goto err_create_class;
-               }
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : pmodclp device class registered.\n");
-#endif
-       }
-
-       /* Setup char driver */
-       status = pmodclp_setup_cdev(pmodclp_dev, &(pmodclp_dev->dev_id));
-       if (status) {
-               pr_info(" pmodclp_probe: Error adding %s device: %d\n", DRIVER_NAME, status);
-               goto cdev_add_err;
-       }
-
-       device_num++;
-
-       /* Initialize Mutex */
-       mutex_init(&pmodclp_dev->mutex);
-
-       status = pmodclp_init_gpio(pmodclp_dev);
-       if (status) {
-               pr_info(" spi_probe: Error init gpio: %d\n", status);
-               goto cdev_add_err;
-       }
-
-       pmodclp_init(&pmodclp_dev->par_dev);
-
-       return status;
-
-err_create_class:
-       unregister_chrdev_region(pmodclp_dev_id, MAX_PMODCLP_DEV_NUM);
-       pmodclp_dev_id = 0;
-err_alloc_chrdev_region:
-cdev_add_err:
-
-       pr_info(DRIVER_NAME " Free text buffer.\n");
-
-       kfree(pmodclp_dev->txt_buf);
-txt_buf_alloc_err:
-       kfree(pmodclp_dev);
-dev_alloc_err:
-       return status;
-}
-
-/**
- * pmodclp_init_gpio - Initialize GPIO for ZED PmodCLP device
- * @dev - pmodclp_device
- *
- * Initializes PmodCLP GPIO Control Pins.
- * It returns 0, if the gpio pins are successfully
- * initialized, or a negative value if there is an error.
- */
-static int pmodclp_init_gpio(struct pmodclp_device *pmodclp_dev)
-{
-       struct gpio pmodclp_ctrl[] = {
-               { pmodclp_dev->par_dev.iRS,      GPIOF_OUT_INIT_HIGH, "CLP RS"      },
-               { pmodclp_dev->par_dev.iRW,      GPIOF_OUT_INIT_HIGH, "CLP RW"      },
-               { pmodclp_dev->par_dev.iE,       GPIOF_OUT_INIT_HIGH, "CLP E"       },
-               { pmodclp_dev->par_dev.iData[0], GPIOF_OUT_INIT_HIGH, "CLP DATA[0]" },
-               { pmodclp_dev->par_dev.iData[1], GPIOF_OUT_INIT_HIGH, "CLP DATA[1]" },
-               { pmodclp_dev->par_dev.iData[2], GPIOF_OUT_INIT_HIGH, "CLP DATA[2]" },
-               { pmodclp_dev->par_dev.iData[3], GPIOF_OUT_INIT_HIGH, "CLP DATA[3]" },
-               { pmodclp_dev->par_dev.iData[4], GPIOF_OUT_INIT_HIGH, "CLP DATA[4]" },
-               { pmodclp_dev->par_dev.iData[5], GPIOF_OUT_INIT_HIGH, "CLP DATA[5]" },
-               { pmodclp_dev->par_dev.iData[6], GPIOF_OUT_INIT_HIGH, "CLP DATA[6]" },
-               { pmodclp_dev->par_dev.iData[7], GPIOF_OUT_INIT_HIGH, "CLP DATA[7]" },
-               { pmodclp_dev->par_dev.iBK,      GPIOF_OUT_INIT_HIGH, "CLP BK"      }
-       };
-       int status;
-       int i;
-       int array_size = pmodclp_dev->par_dev.iBK == -1 ? (ARRAY_SIZE(pmodclp_ctrl) - 1) : ARRAY_SIZE(pmodclp_ctrl);
-
-       for (i = 0; i < array_size; i++) {
-               status = gpio_is_valid(pmodclp_ctrl[i].gpio);
-               if (!status) {
-                       pr_info("!! gpio_is_valid for GPIO %d, %s FAILED!, status: %d\n",
-                               pmodclp_ctrl[i].gpio, pmodclp_ctrl[i].label, status);
-                       goto gpio_invalid;
-               }
-       }
-
-       pr_info("** gpio_request_array array_size = %d, ARRAY_SIZE = %d\n", array_size, (int)ARRAY_SIZE(pmodclp_ctrl));
-
-       status = gpio_request_array(pmodclp_ctrl, ARRAY_SIZE(pmodclp_ctrl));
-       if (status) {
-               pr_info("!! gpio_request_array FAILED!\n");
-               pr_info(" status is: %d, array_size = %d, ARRAY_SIZE = %d\n", status, array_size, (int)ARRAY_SIZE(pmodclp_ctrl));
-               gpio_free_array(pmodclp_ctrl, 4);
-               goto gpio_invalid;
-       }
-
-gpio_invalid:
-/* gpio_direction_output_invalid: */
-       return status;
-}
-
-/**
- * pmodclp_of_remove - Remove method for ZED PmodCLP device.
- * @np: pointer to device tree node
- *
- * This function removes the PmodCLP device in the device tree. It frees the
- * PmodCLP driver data structure. It returns 0, if the driver is successfully
- * removed, or a negative value if there is an error.
- */
-static int pmodclp_of_remove(struct platform_device *pdev)
-{
-       struct pmodclp_device *pmodclp_dev;
-       struct device_node *np = pdev->dev.of_node;
-
-       if (np->data == NULL) {
-               dev_err(&pdev->dev, "pmodclp %s: ERROR: No pmodclp_device structure found!\n", np->name);
-               return -ENOSYS;
-       }
-       pmodclp_dev = (struct pmodclp_device *)(np->data);
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s : Free text buffer.\n", np->name);
-#endif
-
-       if (pmodclp_dev->txt_buf != NULL)
-               kfree(pmodclp_dev->txt_buf);
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s : Unregister gpio_spi Platform Devices.\n", np->name);
-#endif
-
-       np->data = NULL;
-       device_num--;
-
-       /* Destroy pmodclp class, Release device id Region after
-        * all pmodclp devices have been removed.
-        */
-       if (device_num == 0) {
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : Destroy pmodclp_gpio Class.\n");
-#endif
-
-               if (pmodclp_class)
-                       class_destroy(pmodclp_class);
-               pmodclp_class = NULL;
-
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : Release Char Device Region.\n");
-#endif
-
-               unregister_chrdev_region(pmodclp_dev_id, MAX_PMODCLP_DEV_NUM);
-               pmodclp_dev_id = 0;
-       }
-
-       return 0;
-}
-
-static struct platform_driver pmodclp_driver = {
-       .driver                 = {
-               .name           = DRIVER_NAME,
-               .owner          = THIS_MODULE,
-               .of_match_table = pmodclp_of_match,
-       },
-       .probe                  = pmodclp_of_probe,
-       .remove                 = pmodclp_of_remove,
-};
-
-module_platform_driver(pmodclp_driver);
-
-MODULE_AUTHOR("Digilent, Inc.");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION(DRIVER_NAME ": PmodCLP display driver");
-MODULE_ALIAS(DRIVER_NAME);
diff --git a/drivers/staging/pmods/pmodcls.c b/drivers/staging/pmods/pmodcls.c
deleted file mode 100644 (file)
index 324353a..0000000
+++ /dev/null
@@ -1,799 +0,0 @@
-/*
- * pmodcls.c - Digilent PmodCLS driver
- *
- * Copyright (c) 2012 Digilent. All right reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_gpio.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/spi_gpio.h>
-#include <linux/cdev.h>
-#include <linux/mutex.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/types.h>
-#include <linux/uaccess.h>
-
-#define DRIVER_NAME "pmodcls"
-#define SPI_DRIVER_NAME "pmodcls-spi"
-
-#define DEFAULT_SPI_SPEED 625000
-#define MAX_PMODCLS_DEV_NUM 16
-#define TXT_BUF_SIZE 1024
-#define MAX_NO_ROWS 2 /* The device has 2 rows */
-
-static dev_t pmodcls_dev_id;
-static unsigned int device_num;
-static unsigned int cur_minor;
-static unsigned int spi_drv_registered;
-static struct class *pmodcls_class;
-
-struct pmodcls_device {
-       char *name;
-       /* R/W Mutex Lock */
-       struct mutex mutex;
-       /* Text Buffer */
-       char *txt_buf;          /* Device Text buffer */
-       int cur_row;            /* Maintain current row */
-       int exceeded_rows;      /* Flag for situation where maximum number of rows is exceeded */
-       /* Pin Assignment */
-
-       unsigned long iSCLK;
-       unsigned long iSDIN;
-       unsigned long iCS;
-
-       /* SPI Info */
-       uint32_t spi_speed;
-       uint32_t spi_id;
-       /* platform device structures */
-       struct platform_device *pdev;
-       /* Char Device */
-       struct cdev cdev;
-       struct spi_device *spi;
-       dev_t dev_id;
-};
-
-/* Forward definitions */
-static int parse_text(char *txt_buf, int cnt, struct pmodcls_device *dev);
-static int txt_buf_to_display(char *txt_buf, int cnt, struct pmodcls_device *dev);
-
-/**
- * A basic open function.
- */
-static int pmodcls_open(struct inode *inode, struct file *fp)
-{
-       struct pmodcls_device *dev;
-
-       dev = container_of(inode->i_cdev, struct pmodcls_device, cdev);
-       fp->private_data = dev;
-
-       return 0;
-}
-
-/**
- * A basic close function, do nothing.
- */
-static int pmodcls_close(struct inode *inode, struct file *fp)
-{
-       return 0;
-}
-
-/*
- * Driver write function
- *
- * This function uses a generic SPI write to send values to the Pmod device.
- * It takes a string from the app in the buffer.
- * It sends the commands and the text to PmodCLS over the standard SPI interface.
- *
- */
-static ssize_t pmodcls_write(struct file *fp, const char __user *buffer, size_t length, loff_t *offset)
-{
-       ssize_t retval = 0;
-       int status; /* spi_write return value */
-       int cnt;
-       struct pmodcls_device *dev;
-
-       dev = fp->private_data;
-
-       if (mutex_lock_interruptible(&dev->mutex)) {
-               retval = -ERESTARTSYS;
-               goto write_lock_err;
-       }
-
-       cnt = length;
-
-       if (copy_from_user(dev->txt_buf, buffer, cnt)) {
-               retval = -EFAULT;
-               goto quit_write;
-       }
-       retval = cnt;
-
-       dev->txt_buf[cnt] = '\0';
-       status = parse_text(dev->txt_buf, cnt, dev);
-       dev_dbg(&dev->spi->dev, "cls_write: Writing \"%s\" to display\n",
-               dev->txt_buf);
-
-       if (status) {
-               dev_err(&dev->spi->dev, "cls_write: Error writing text to SPI device\n");
-               retval = -EFAULT;
-               goto quit_write;
-       }
-       dev_dbg(&dev->spi->dev, "cls_write: Writing to display complete\n");
-
-quit_write:
-       mutex_unlock(&dev->mutex);
-write_lock_err:
-       return retval;
-}
-
-/**
- * parse_text - This function builds the commands to be sent for each recognized escape sequence.
- *
- * Parameters
- * @char *txt_buf: the text array to be parsed
- * @int cnt the number of charcaters to be parsed in the text array
- * @struct pmodclp_device *dev pointer to device structure
- *
- *
- * This function parses a text array, containing a sequence of one or more text or commands to be sent to PmodCLS. Its purpose is:
- * - recognize, interpret the commands:
- * - maintain a shadow value of the current row (this is because PmodCLS is a "write only" device, the cursor position cannot be read)
- * - split the separate commands / text and send individually to the device.
- * - recognize LF character ('\n') inside a text to be sent to the device
- * - if current line is the first, move the cursor to the beginning of the next line
- * - if current line is the second, there is no room for new line. Text characters after LF are ignored, commands are still interpreted.
- *
- */
-static int parse_text(char *txt_buf, int cnt, struct pmodcls_device *dev)
-{
-       int status = 0; /* spi_write return value */
-       int is_ignore_txt;
-       int is_par1 = 0;
-       int is_cmd = 0;
-       int par1 = 0, par2;
-       char txt_LF_cmd[10];
-       char *parse_buf, *sent_buf;
-
-       parse_buf = txt_buf;
-       sent_buf = txt_buf - 1;
-       is_par1 = 0;
-       is_cmd = 0;
-       is_ignore_txt = dev->exceeded_rows;
-       while ((!status) && (parse_buf < (txt_buf + cnt))) {
-               /* recognize command - look for ESC code, followed by '[' */
-               if ((!is_cmd) && ((*parse_buf) == 0x1B) && (parse_buf[1] == '[')) {
-                       /* enter command mode */
-                       is_cmd = 1;
-                       is_par1 = 1;
-                       par1 = 0;
-                       /* send previous text (before the ESC sequence) */
-                       if ((parse_buf - sent_buf) > 1) {
-                               status = txt_buf_to_display(sent_buf + 1, parse_buf - 1 - sent_buf, dev);
-                               sent_buf = parse_buf - 1;
-                       }
-                       parse_buf++; /* skip '[' char */
-
-               } else {
-                       if (is_cmd) {
-                               if ((*parse_buf) >= '0' && (*parse_buf) <= '9') { /* numeric char, build parameters values */
-                                       if (is_par1)
-                                               par1 = 10 * par1 + (*parse_buf) - '0';
-                                       else
-                                               par2 = 10 * par2 + (*parse_buf) - '0';
-                               } else {
-                                       if ((*parse_buf) == ';') { /* parameters separator */
-                                               is_par1 = 0;
-                                               par2 = 0;
-                                       } else {
-                                               /* look for some commands */
-                                               switch (*parse_buf) {
-                                               case 'H': /* set cursor position */
-                                                       dev->cur_row = par1;
-                                                       if (dev->cur_row < MAX_NO_ROWS)
-                                                               is_ignore_txt = 0;
-                                                       else
-                                                               is_ignore_txt = 1;
-                                                       break;
-                                               case 'j':       /* clear display and home cursor */
-                                               case '*':       /* reset */
-                                                       dev->cur_row = 0;
-                                                       is_ignore_txt = 0;
-                                                       break;
-                                               case 's':       /* save cursor position */
-                                               case 'u':       /* restore saved cursor position */
-                                               case 'K':       /* erase within line */
-                                               case 'N':       /* erase field */
-                                               case '@':       /* scroll left */
-                                               case 'A':       /* scroll right */
-                                               case 'h':       /* set display mode (wrap line) */
-                                               case 'c':       /* set cursor mode */
-                                               case 'p':       /* program char table into LCD */
-                                               case 't':       /* save RAM character table to EEPROM */
-                                               case 'l':       /* load EEPROM character table to RAM */
-                                               case 'd':       /* define user programmable character */
-                                               case 'm':       /* save communication mode to EEPROM */
-                                               case 'w':       /* enable write to EEPROM */
-                                               case 'n':       /* save cursor mode to EEPROM */
-                                               case 'o':       /* save display mode to EEPROM */
-                                                               /* cursor is not affected */
-                                                       break;
-
-                                               default:
-                                                       /* no command was recognized */
-                                                       is_cmd = 0; /* comand mode is abandonned */
-                                               }
-                                               if (is_cmd) {
-                                                       /* send text including the command char */
-                                                       if ((parse_buf - sent_buf) > 1) {
-                                                               status = txt_buf_to_display(sent_buf + 1, parse_buf - sent_buf, dev);
-                                                               sent_buf = parse_buf;
-                                                               is_cmd = 0; /* comand mode is abandonned */
-                                                       }
-                                               }
-                                       }
-                               }
-                       } else {
-                               /* free text, not inside a command */
-                               if (is_ignore_txt) {
-                                       sent_buf = parse_buf;
-                               } else {
-                                       if ((*parse_buf) == '\n') { /* LF */
-                                               /* send text before the LF char */
-                                               if ((parse_buf - sent_buf) > 0)
-                                                       txt_buf_to_display(sent_buf + 1, parse_buf - 1 - sent_buf, dev);
-                                               /* position the cursor on the beginning of the next line */
-                                               if (dev->cur_row < (MAX_NO_ROWS - 1)) {
-                                                       dev->cur_row++;
-                                                       strcpy(txt_LF_cmd, "0[0;0H");
-                                                       txt_LF_cmd[0] = 0x1B; /* ESC */
-                                                       txt_LF_cmd[2] = '0' + (unsigned char)dev->cur_row;
-                                                       status = txt_buf_to_display(txt_LF_cmd, 6, dev);
-                                               } else {
-                                                       /* there is no room to place a third line. Ignore text (still look for the comands) */
-                                                       is_ignore_txt = 1;
-                                               }
-
-                                               /* advance the pointers so that LF char is skipped next time when chars are sent */
-                                               sent_buf = parse_buf;
-                                       }
-
-                               }
-                       }
-
-               }
-               parse_buf++; /* advance one character */
-       }
-       parse_buf--;
-       /* send remaining chars */
-
-       if ((!status) && ((parse_buf - sent_buf) > 0))
-               status = txt_buf_to_display(sent_buf + 1, parse_buf - sent_buf, dev);
-
-       dev->exceeded_rows = is_ignore_txt;
-
-       return status;
-}
-
-/**
- * txt_buf_to_display - This function breaks sends the string to the PmodCLS device over the SPI.
-        prior to .
- *
- * Parameters
- * @char *txt_buf: the text array to be parsed
- * @int cnt the number of charcaters to be parsed in the text array
- * @struct pmodclp_device *dev pointer to device structure
- *
- *
- * This function breaks sends the string to the PmodCLS device over the SPI.
- * It breaks the input string in chunks of 3 bytes in order to reduce the load on the receiving
- * PmodCLS.
- *
- */
-static int txt_buf_to_display(char *txt_buf, int cnt, struct pmodcls_device *dev)
-{
-       int status; /* spi_write return value */
-       int short_cnt;
-
-       /*
-        * Break writes into three byte chunks so that the microcontroller on
-        * the PmodCLS can keep up. Prior to breaking up writes to these
-        * smaller chunks, every 4th character would not be displayed.
-        *
-        * NOTE: The usleep_range delay is not needed, but allows the driver
-        *       to relinquish control to other tasks.
-        */
-       status = 0;
-       while ((cnt > 0) && (!status)) {
-               short_cnt = (cnt > 3) ? 3 : cnt;
-               status = spi_write(dev->spi, txt_buf, short_cnt);
-               cnt -= short_cnt;
-               txt_buf += short_cnt;
-               usleep_range(10, 100);
-       }
-       return status;
-
-}
-
-/**
- * Driver Read Function
- *
- * This function does not actually read the PmodCLP as it is a write-only device.
- */
-static ssize_t pmodcls_read(struct file *fp, char __user *buffer, size_t length, loff_t *offset)
-{
-       ssize_t retval = 0;
-
-       return retval;
-}
-
-static const struct file_operations pmodcls_cdev_fops = {
-       .owner          = THIS_MODULE,
-       .write          = pmodcls_write,
-       .read           = pmodcls_read,
-       .open           = pmodcls_open,
-       .release        = pmodcls_close,
-};
-
-/**
- * add_pmodcls_device_to_bus - Add device to SPI bus, initialize SPI data.
- * @dev: pointer to device tree node
- *
- * This function adds device to SPI bus, initialize SPI data.
- */
-static int add_pmodcls_device_to_bus(struct pmodcls_device *dev)
-{
-       struct spi_master *spi_master;
-       struct spi_device *spi_device;
-       int status = 0;
-
-       spi_master = spi_busnum_to_master(dev->spi_id);
-       if (!spi_master) {
-               dev_err(&dev->pdev->dev, "spi_busnum_to_master(%d) returned NULL\n", dev->spi_id);
-               return -ENOSYS;
-       }
-
-       spi_device = spi_alloc_device(spi_master);
-       if (!spi_device) {
-               put_device(&spi_master->dev);
-               dev_err(&dev->pdev->dev, "spi_alloc_device() failed\n");
-               return -ENOMEM;
-       }
-
-       spi_device->chip_select = 0;
-       spi_device->max_speed_hz = dev->spi_speed;
-       spi_device->mode = SPI_MODE_0;
-       spi_device->bits_per_word = 8;
-       spi_device->controller_data = (void *)dev->iCS;
-       spi_device->dev.platform_data = dev;
-       strlcpy(spi_device->modalias, SPI_DRIVER_NAME, sizeof(SPI_DRIVER_NAME));
-
-       status = spi_add_device(spi_device);
-       if (status < 0) {
-               spi_dev_put(spi_device);
-               dev_err(&dev->pdev->dev, "spi_add_device() failed %d\n", status);
-               return status;
-       }
-       dev->spi = spi_device;
-
-       put_device(&spi_master->dev);
-       pr_info(DRIVER_NAME " SPI initialized, max_speed_hz\t%d\n", spi_device->max_speed_hz);
-
-       return status;
-}
-
-/**
- * pmodcls_setup_cdev - Setup Char Device for ZED PmodCLP device.
- * @dev: pointer to device tree node
- * @dev_id: pointer to device major and minor number
- * @spi: pointer to spi_device structure
- *
- * This function initializes char device for PmodCLS device, and add it into
- * kernel device structure. It returns 0, if the cdev is successfully
- * initialized, or a negative value if there is an error.
- */
-static int pmodcls_setup_cdev(struct pmodcls_device *dev, dev_t *dev_id, struct spi_device *spi)
-{
-       int status = 0;
-       struct device *device;
-
-       cdev_init(&dev->cdev, &pmodcls_cdev_fops);
-       dev->cdev.owner = THIS_MODULE;
-       dev->cdev.ops = &pmodcls_cdev_fops;
-       dev->spi = spi;
-
-       *dev_id = MKDEV(MAJOR(pmodcls_dev_id), cur_minor++);
-       status = cdev_add(&dev->cdev, *dev_id, 1);
-       if (status < 0)
-               return status;
-
-       /* Add Device node in system */
-       device = device_create(pmodcls_class, NULL,
-                              *dev_id, NULL,
-                              "%s", dev->name);
-       if (IS_ERR(device)) {
-               status = PTR_ERR(device);
-               dev_err(&spi->dev, "failed to create device node %s, err %d\n",
-                       dev->name, status);
-               cdev_del(&dev->cdev);
-       }
-
-       return status;
-}
-
-/**
- * SPI hardware probe. Sets correct SPI mode, attempts
- * to obtain memory needed by the driver, and performs
- * a simple initialization of the device.
- */
-static int pmodcls_spi_probe(struct spi_device *spi)
-{
-       int status = 0;
-       struct pmodcls_device *pmodcls_dev;
-
-       /* We must use SPI_MODE_0 */
-       spi->mode = SPI_MODE_0;
-       spi->bits_per_word = 8;
-
-       status = spi_setup(spi);
-       if (status < 0) {
-               dev_err(&spi->dev, "needs SPI mode %02x, %d KHz; %d\n",
-                       spi->mode, spi->max_speed_hz / 1000,
-                       status);
-               goto spi_err;
-       }
-
-       /* Get pmodcls_device structure */
-       pmodcls_dev = (struct pmodcls_device *)spi->dev.platform_data;
-       if (pmodcls_dev == NULL) {
-               dev_err(&spi->dev, "Cannot get pmodcls_device.\n");
-               status = -EINVAL;
-               goto spi_platform_data_err;
-       }
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(SPI_DRIVER_NAME " [%s] spi_probe: setup char device\n", pmodcls_dev->name);
-#endif
-
-       /* Setup char driver */
-       status = pmodcls_setup_cdev(pmodcls_dev, &(pmodcls_dev->dev_id), spi);
-       if (status) {
-               pr_info(" spi_probe: Error adding %s device: %d\n", SPI_DRIVER_NAME, status);
-               dev_err(&spi->dev, "spi_probe: Error adding %s device: %d\n", SPI_DRIVER_NAME, status);
-               goto cdev_add_err;
-       }
-
-       /* Initialize Mutex */
-       mutex_init(&pmodcls_dev->mutex);
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(SPI_DRIVER_NAME " [%s] spi_probe: initialize device\n", pmodcls_dev->name);
-#endif
-
-       return status;
-
-cdev_add_err:
-spi_platform_data_err:
-spi_err:
-       return status;
-}
-
-static int pmodcls_spi_remove(struct spi_device *spi)
-{
-       int status;
-       struct pmodcls_device *dev;
-
-       dev = (struct pmodcls_device *)spi->dev.platform_data;
-
-       if (dev == NULL) {
-               dev_err(&spi->dev, "spi_remove: Error fetch pmodcls_device struct\n");
-               return -EINVAL;
-       }
-
-       if (&dev->cdev) {
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(SPI_DRIVER_NAME " [%s] spi_remove: Destroy Char Device\n", dev->name);
-#endif
-               device_destroy(pmodcls_class, dev->dev_id);
-               cdev_del(&dev->cdev);
-       }
-
-       cur_minor--;
-
-       return status;
-}
-
-static struct spi_driver pmodcls_spi_driver = {
-       .driver         = {
-               .name   = SPI_DRIVER_NAME,
-               .bus    = &spi_bus_type,
-               .owner  = THIS_MODULE,
-       },
-       .probe          = pmodcls_spi_probe,
-       .remove         = pmodcls_spi_remove,
-};
-
-static const struct of_device_id pmodcls_of_match[] = {
-       { .compatible = "dglnt,pmodcls", },
-       {},
-};
-MODULE_DEVICE_TABLE(of, pmodcls_of_match);
-
-/**
- * pmodcls_of_probe - Probe method for PmodCLS device (over GPIO).
- * @pdev: pointer to platform devices
- *
- * This function probes the PmodCLS device in the device tree. It initializes the
- * PmodCLS driver data structure. It returns 0, if the driver is bound to the PmodCLS
- * device, or a negative value if there is an error.
- */
-static int pmodcls_of_probe(struct platform_device *pdev)
-{
-       struct pmodcls_device *pmodcls_dev;
-       struct platform_device *pmodcls_pdev;
-       struct spi_gpio_platform_data *pmodcls_pdata;
-
-       struct device_node *np = pdev->dev.of_node;
-
-       const u32 *tree_info;
-       const u32 *spi_speed;
-       int status = 0;
-
-       /* Alloc Space for platform device structure */
-       pmodcls_dev = kzalloc(sizeof(*pmodcls_dev), GFP_KERNEL);
-       if (!pmodcls_dev) {
-               status = -ENOMEM;
-               goto dev_alloc_err;
-       }
-
-       /* Alloc Text Buffer for device */
-       pmodcls_dev->txt_buf = kmalloc(TXT_BUF_SIZE, GFP_KERNEL);
-       if (!pmodcls_dev->txt_buf) {
-               status = -ENOMEM;
-               dev_err(&pdev->dev, "Device Display data buffer allocation failed: %d\n", status);
-               goto txt_buf_alloc_err;
-       }
-
-       /* Get the GPIO Pins */
-
-       pmodcls_dev->iSCLK = of_get_named_gpio(np, "spi-sclk-gpio", 0);
-       pmodcls_dev->iSDIN = of_get_named_gpio(np, "spi-sdin-gpio", 0);
-       status = of_get_named_gpio(np, "spi-cs-gpio", 0);
-       pmodcls_dev->iCS = (status < 0) ? SPI_GPIO_NO_CHIPSELECT : status;
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s: iSCLK: 0x%lx\n", np->name, pmodcls_dev->iSCLK);
-       pr_info(DRIVER_NAME " %s: iSDIN: 0x%lx\n", np->name, pmodcls_dev->iSDIN);
-       pr_info(DRIVER_NAME " %s: iCS : 0x%lx\n", np->name, pmodcls_dev->iCS);
-#endif
-
-       /* Get SPI Related Params */
-       tree_info = of_get_property(np, "spi-bus-num", NULL);
-       if (tree_info) {
-               pmodcls_dev->spi_id = be32_to_cpup((tree_info));
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " %s: BUS_ID\t%x\n", np->name, pmodcls_dev->spi_id);
-#endif
-       }
-
-       spi_speed = of_get_property(np, "spi-speed-hz", NULL);
-       if (spi_speed) {
-               pmodcls_dev->spi_speed = be32_to_cpup((spi_speed));
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " %s: SPI_SPEED\t%x\n", np->name, pmodcls_dev->spi_speed);
-#endif
-       } else {
-               pmodcls_dev->spi_speed = DEFAULT_SPI_SPEED;
-       }
-       /* Alloc Space for platform data structure */
-       pmodcls_pdata = kzalloc(sizeof(*pmodcls_pdata), GFP_KERNEL);
-       if (!pmodcls_pdata) {
-               status = -ENOMEM;
-               goto pdata_alloc_err;
-       }
-
-       /* Fill up Platform Data Structure */
-       pmodcls_pdata->sck = pmodcls_dev->iSCLK;
-       pmodcls_pdata->miso = SPI_GPIO_NO_MISO;
-       pmodcls_pdata->mosi = pmodcls_dev->iSDIN;
-       pmodcls_pdata->num_chipselect = 1;
-
-       /* Alloc Space for platform data structure */
-       pmodcls_pdev = kzalloc(sizeof(*pmodcls_pdev), GFP_KERNEL);
-       if (!pmodcls_pdev) {
-               status = -ENOMEM;
-               goto pdev_alloc_err;
-       }
-
-       /* Fill up Platform Device Structure */
-       pmodcls_pdev->name = "spi_gpio";
-       pmodcls_pdev->id = pmodcls_dev->spi_id;
-       pmodcls_pdev->dev.platform_data = pmodcls_pdata;
-       pmodcls_dev->pdev = pmodcls_pdev;
-
-       /* Register spi_gpio master */
-       status = platform_device_register(pmodcls_dev->pdev);
-       if (status < 0) {
-               dev_err(&pdev->dev, "platform_device_register failed: %d\n", status);
-               goto pdev_reg_err;
-       }
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s: spi_gpio platform device registered.\n", np->name);
-#endif
-       pmodcls_dev->name = (char *)np->name;
-
-       /* Fill up Board Info for SPI device */
-       status = add_pmodcls_device_to_bus(pmodcls_dev);
-       if (status < 0) {
-               dev_err(&pdev->dev, "add_pmodcls_device_to_bus failed: %d\n", status);
-               goto spi_add_err;
-       }
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s: spi device registered.\n", np->name);
-#endif
-
-       /* Point device node data to pmodcls_device structure */
-       if (np->data == NULL)
-               np->data = pmodcls_dev;
-
-       if (pmodcls_dev_id == 0) {
-               /* Alloc Major & Minor number for char device */
-               status = alloc_chrdev_region(&pmodcls_dev_id, 0, MAX_PMODCLS_DEV_NUM, DRIVER_NAME);
-               if (status) {
-                       dev_err(&pdev->dev, "Character device region not allocated correctly: %d\n", status);
-                       goto err_alloc_chrdev_region;
-               }
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : Char Device Region Registered, with Major: %d.\n",
-                       MAJOR(pmodcls_dev_id));
-#endif
-       }
-
-       if (pmodcls_class == NULL) {
-               /* Create Pmodcls Device Class */
-               pmodcls_class = class_create(THIS_MODULE, DRIVER_NAME);
-               if (IS_ERR(pmodcls_class)) {
-                       status = PTR_ERR(pmodcls_class);
-                       goto err_create_class;
-               }
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : pmodcls device class registered.\n");
-#endif
-       }
-
-       if (spi_drv_registered == 0) {
-               /* Register SPI Driver for Pmodcls Device */
-               status = spi_register_driver(&pmodcls_spi_driver);
-               if (status < 0) {
-                       dev_err(&pdev->dev, "pmodcls_spi_driver register failed: %d\n", status);
-                       goto err_spi_register;
-               }
-               spi_drv_registered = 1;
-       }
-
-       device_num++;
-
-       return status;
-
-err_spi_register:
-       class_destroy(pmodcls_class);
-       pmodcls_class = NULL;
-err_create_class:
-       unregister_chrdev_region(pmodcls_dev_id, MAX_PMODCLS_DEV_NUM);
-       pmodcls_dev_id = 0;
-err_alloc_chrdev_region:
-       spi_unregister_device(pmodcls_dev->spi);
-spi_add_err:
-       platform_device_unregister(pmodcls_dev->pdev);
-pdev_reg_err:
-       kfree(pmodcls_pdev);
-pdev_alloc_err:
-       kfree(pmodcls_pdata);
-pdata_alloc_err:
-       kfree(pmodcls_dev->txt_buf);
-txt_buf_alloc_err:
-       kfree(pmodcls_dev);
-dev_alloc_err:
-       return status;
-}
-
-/**
- * pmodcls_of_remove - Remove method for ZED PmodCLS device.
- * @np: pointer to device tree node
- *
- * This function removes the PmodCLS device in the device tree. It frees the
- * PmodCLS driver data structure. It returns 0, if the driver is successfully
- * removed, or a negative value if there is an error.
- */
-static int pmodcls_of_remove(struct platform_device *pdev)
-{
-       struct pmodcls_device *pmodcls_dev;
-       struct device_node *np = pdev->dev.of_node;
-
-       if (np->data == NULL) {
-               dev_err(&pdev->dev, "pmodcls %s: ERROR: No pmodcls_device structure found!\n", np->name);
-               return -ENOSYS;
-       }
-       pmodcls_dev = (struct pmodcls_device *)(np->data);
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s : Free display buffer.\n", np->name);
-#endif
-
-       if (pmodcls_dev->txt_buf != NULL)
-               kfree(pmodcls_dev->txt_buf);
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s : Unregister gpio_spi Platform Devices.\n", np->name);
-#endif
-
-       if (pmodcls_dev->pdev != NULL)
-               platform_device_unregister(pmodcls_dev->pdev);
-
-       np->data = NULL;
-       device_num--;
-
-       /* Unregister SPI Driver, Destroy pmodcls class, Release device id Region after
-        * all pmodcls devices have been removed.
-        */
-       if (device_num == 0) {
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : Unregister SPI Driver.\n");
-#endif
-               spi_unregister_driver(&pmodcls_spi_driver);
-               spi_drv_registered = 0;
-
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : Destroy pmodcls_gpio Class.\n");
-#endif
-
-               if (pmodcls_class)
-                       class_destroy(pmodcls_class);
-               pmodcls_class = NULL;
-
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : Release Char Device Region.\n");
-#endif
-
-               unregister_chrdev_region(pmodcls_dev_id, MAX_PMODCLS_DEV_NUM);
-               pmodcls_dev_id = 0;
-       }
-
-       return 0;
-}
-
-static struct platform_driver pmodcls_driver = {
-       .driver                 = {
-               .name           = DRIVER_NAME,
-               .owner          = THIS_MODULE,
-               .of_match_table = pmodcls_of_match,
-       },
-       .probe                  = pmodcls_of_probe,
-       .remove                 = pmodcls_of_remove,
-};
-
-module_platform_driver(pmodcls_driver);
-
-MODULE_AUTHOR("Digilent, Inc.");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION(DRIVER_NAME ": PmodCLS display driver");
-MODULE_ALIAS(DRIVER_NAME);
diff --git a/drivers/staging/pmods/pmodda1.c b/drivers/staging/pmods/pmodda1.c
deleted file mode 100644 (file)
index a7d9ebf..0000000
+++ /dev/null
@@ -1,829 +0,0 @@
-/*
- * pmodda1.c - Digilent PmodDA1 driver
- *
- * Copyright (c) 2012 Digilent. All right reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_gpio.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/spi_gpio.h>
-#include <linux/cdev.h>
-#include <linux/mutex.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/uaccess.h>
-
-#define DRIVER_NAME "pmodda1"
-#define SPI_DRIVER_NAME "pmodda1-spi"
-
-#define DEFAULT_SPI_SPEED 625000
-/* only 2 channels as SPI does not allow write on Data In line. */
-#define PMODDA1_DEV_NUM 2
-
-#define DEFAULT_BUF_SZ 512
-/*
- * default size of the buffer for each DAC on the device. Can be
- * changed from the default during insmod.
- */
-static int buf_sz = DEFAULT_BUF_SZ;
-module_param(buf_sz, int, 0);
-
-static dev_t pmodda1_first_dev_id;
-static struct spi_device *spi_device;
-static unsigned int spi_drv_registered;
-static struct class *pmodda1_class;
-
-struct pmodda1_device {
-       char *name;
-
-       unsigned int minor_id;
-       /* Data Buffer */
-       unsigned char *buf;
-       /* Pin Assignment */
-
-       unsigned long iSCLK;
-       unsigned long iSDIN;
-       unsigned long iCS;
-
-       /* SPI Info */
-       uint32_t spi_speed;
-       uint32_t spi_id;
-       /* platform device structures */
-       struct platform_device *pdev;
-       /* Char Device */
-       struct cdev cdev;
-       struct spi_device *spi;
-       dev_t dev_id;
-};
-
-/*
- * create a shadow register to configure the devices using a
- * struct for the physical D to A parts used on the Pmod.
- * this is intended to hold the state for each D to A such
- * that a control word can be built for the device when a
- * write request comes for any of the channels.
- */
-struct ad7303 {
-       bool ext;
-       bool ldac;
-       bool pdb;
-       bool pda;
-       bool sel; /* !A/B in the datasheet for the AD7303, bit 10 in the control reg */
-       bool cr1;
-       bool cr0;
-       uint8_t a_val;
-       uint8_t b_val;
-       struct mutex mutex;
-};
-
-static struct pmodda1_device *rgpmodda1_devices[PMODDA1_DEV_NUM]; /* create pointer array to hold device info */
-
-static struct ad7303 dac1;
-/* Forward definitions */
-static uint16_t make_cmd_from_shadow_regs(struct ad7303 *dac);
-
-/* make_cmd_from_shadow_regs
- * @dac the ad7303 structure who's bits are used.
- * this function places the configuration bits in the proper
- * bit position to form the command word the AD73703 expects
- * to receive.
- */
-static uint16_t make_cmd_from_shadow_regs(struct ad7303 *dac)
-{
-       uint16_t cd = 0;
-
-       cd = ((dac->ext & 1) << 15);
-       cd |= ((dac->ldac & 1) << 13);
-       cd |= ((dac->pdb & 1) << 12);
-       cd |= ((dac->pda & 1) << 11);
-       cd |= ((dac->sel & 1) << 10);
-       cd |= ((dac->cr1 & 1) << 9);
-       cd |= ((dac->cr0 & 1) << 8);
-
-       return cd;
-}
-
-/**
- * write_spi_16 - Write a 16 bit variable to SPI in High - Low order.
- * @spi: pointer to spi_device structure
- * @cmd_data: the 16 bits variable containing data to be written to spi
- *
- * This function writes to spi the 16 bits of data, big endian (first High and then Low bytes), regardless of CPU representation.
- * It returns the spi write return value (0 on success).
- */
-static int write_spi_16(struct spi_device *spi, uint16_t cmd_data)
-{
-       int status; /* spi_write return value */
-       /* Change endianness of data, if necessary
-        * The data must be written to SPI in big endian,
-        * whereas some CPU architectures are little endian.
-        */
-       uint16_t write_cmd_data = cpu_to_be16(cmd_data);
-
-       status = spi_write(spi, &write_cmd_data, 2);
-       return status;
-}
-/**
- * A basic open function.
- */
-static int pmodda1_open(struct inode *inode, struct file *fp)
-{
-       struct pmodda1_device *dev;
-
-       dev = container_of(inode->i_cdev, struct pmodda1_device, cdev);
-       dev->minor_id = iminor(inode);
-       fp->private_data = dev;
-
-       return 0;
-}
-
-/**
- * A basic close function, do nothing.
- */
-static int pmodda1_close(struct inode *inode, struct file *fp)
-{
-       return 0;
-}
-
-/*
- * Driver write function
- *
- * This function uses a generic SPI write to send values to the Pmod device.
- * It takes a string from the app in the buffer.
- * It sends the commands and the text to PmodDA1 over the standard SPI interface.
- *
- */
-static ssize_t pmodda1_write(struct file *fp, const char __user *buffer, size_t length, loff_t *offset)
-{
-       ssize_t retval = 0;
-       int status; /* spi_write return value */
-       int cnt;
-       int i;
-       unsigned int minor_id;
-       struct mutex *mutex;
-       uint16_t cmd_data;
-       struct pmodda1_device *dev;
-
-       dev = fp->private_data;
-       minor_id = dev->minor_id;
-
-       if (minor_id > PMODDA1_DEV_NUM - 1) {
-               dev_err(&dev->spi->dev, "da1_write: ERROR: Attempt to read a non-existant device: %d\n", minor_id);
-               retval = -ENOTTY;
-               goto bad_device;
-       }
-       dev = rgpmodda1_devices[minor_id];
-       mutex = &dac1.mutex; /* get the mutex for the part we will be programming */
-
-       if (mutex_lock_interruptible(mutex)) {
-               retval = -ERESTARTSYS;
-               goto write_lock_err;
-       }
-
-       if (length > buf_sz)
-               cnt = buf_sz;
-       else
-               cnt = length;
-
-       if (copy_from_user(dev->buf, buffer, cnt)) {
-               retval = -EFAULT;
-               goto quit_write;
-       }
-       retval = cnt;
-
-       dev->buf[cnt] = '\0';
-       /* use the minor id number to select which channel to program */
-
-       /* the command word is constructed here */
-       if ((minor_id == 0)) {
-               dev_dbg(&dev->spi->dev, "da1_write: setting DAC_A (or even number DAC)\n");
-               dac1.pda = 0;   /* want DAC A powered up, don't touch DAC B's setting */
-               dac1.sel = 0;   /* this will indicate to load DAC A */
-       } else {
-               dev_dbg(&dev->spi->dev, "da1_write: setting DAC_B (or odd number DAC)\n");
-               dac1.pdb = 0;   /* want DAC B powered up, don't touch DAC A's setting */
-               dac1.sel = 1;   /* this will indicate to load DAC B */
-       }
-       dac1.ext = 0;           /* select internal reference for now */
-       dac1.ldac = 1;          /* will program DAC input reg from shift reg and update both DAC registers */
-
-       cmd_data = make_cmd_from_shadow_regs(&dac1);
-       for (i = 0; i < cnt; i++) {
-               cmd_data &= 0xFF00;
-               cmd_data |= dev->buf[i];
-
-               status = write_spi_16(dev->spi, cmd_data);
-
-               if (!status)            /* seems like spi_write returns 0 on success */
-                       retval = i + 1; /* but system write function expects to see number of bytes written */
-               else
-                       retval = -EIO;
-       }
-
-       /* save the last value written to the DAC */
-       switch (minor_id) {
-       case 0:
-               dac1.a_val = dev->buf[i - 1];
-               break;
-       case 1:
-               dac1.b_val = dev->buf[i - 1];
-               break;
-       }
-quit_write:
-       mutex_unlock(mutex);
-       dev_dbg(&dev->spi->dev, "da1_write: Writing to display complete\n");
-bad_device:
-write_lock_err:
-
-       return retval;
-}
-
-/*
- * Driver read function
- *
- * This function does not actually read the Pmod as it is a read-only device. Instead
- * it returns a shadowed copy of the value that was used when the DAC was last programmed.
- */
-static ssize_t pmodda1_read(struct file *fp, char __user *buffer, size_t length, loff_t *offset)
-{
-       ssize_t retval = 0;
-       int i;
-       struct pmodda1_device *dev;
-       unsigned int minor_id;
-       uint8_t rd_val;
-       struct mutex *mutex;
-       int cnt;
-
-       dev = fp->private_data;
-       minor_id = dev->minor_id;
-
-       if (length > buf_sz)
-               cnt = buf_sz;
-       else
-               cnt = length;
-       if (minor_id > PMODDA1_DEV_NUM - 1) {
-               dev_err(&dev->spi->dev, "da1_read: ERROR: Attempt to read a non-existant device: %d\n", minor_id);
-               retval = -ENOTTY;
-               goto bad_device;
-       }
-
-       if (minor_id < 2)
-               mutex = &dac1.mutex;
-
-       if (mutex_lock_interruptible(mutex)) {
-               retval = -ERESTARTSYS;
-               goto lock_err;
-       }
-
-       if (buffer == NULL) {
-               dev_err(&dev->spi->dev, "da1_read: ERROR: invalid buffer address: 0x%08lx\n", (__force unsigned long)buffer);
-               retval = -EINVAL;
-               goto quit_read;
-       }
-
-       /* ok, can use the minor id number to select which DAC value to return */
-       switch (minor_id) {
-       case 0:
-               rd_val = dac1.a_val;
-               break;
-       case 1:
-               rd_val = dac1.b_val;
-               break;
-       default:
-               rd_val = 0; /* git rid of warning about rd_val may be used uninitialized */
-       }
-/* tmp, read value from spi */
-       spi_read(dev->spi, &rd_val, 2);
-       pr_info(DRIVER_NAME "Read values Last Value\t%X\n", rd_val);
-       for (i = 0; i < cnt; i++)
-               dev->buf[i] = rd_val;
-
-       retval = copy_to_user(buffer, (void *)dev->buf, cnt);
-       if (!retval)
-               retval = cnt; /* copy success, return amount in buffer */
-
-quit_read:
-       mutex_unlock(mutex);
-lock_err:
-bad_device:
-       return retval;
-}
-
-static const struct file_operations pmodda1_cdev_fops = {
-       .owner          = THIS_MODULE,
-       .write          = pmodda1_write,
-       .read           = pmodda1_read,
-       .open           = pmodda1_open,
-       .release        = pmodda1_close,
-};
-
-/**
- * add_pmodda1_device_to_bus - Add device to SPI bus, initialize SPI data.
- * @dev: pointer to device tree node
- *
- * This function adds device to SPI bus, initialize SPI data.
- */
-static int add_pmodda1_device_to_bus(struct pmodda1_device *dev)
-{
-       struct spi_master *spi_master;
-       int status = 0;
-
-       spi_master = spi_busnum_to_master(dev->spi_id);
-       if (!spi_master) {
-               dev_err(&dev->pdev->dev, "spi_busnum_to_master(%d) returned NULL\n", dev->spi_id);
-               return -ENOSYS;
-       }
-
-       spi_device = spi_alloc_device(spi_master);
-       if (!spi_device) {
-               put_device(&spi_master->dev);
-               dev_err(&dev->pdev->dev, "spi_alloc_device() failed\n");
-               return -ENOMEM;
-       }
-
-       spi_device->chip_select = 0;
-       spi_device->max_speed_hz = dev->spi_speed;
-       spi_device->mode = SPI_MODE_0;
-       spi_device->bits_per_word = 8;
-       spi_device->controller_data = (void *)dev->iCS;
-       spi_device->dev.platform_data = dev;
-       strlcpy(spi_device->modalias, SPI_DRIVER_NAME, sizeof(SPI_DRIVER_NAME));
-
-       status = spi_add_device(spi_device);
-       if (status < 0) {
-               spi_dev_put(spi_device);
-               dev_err(&dev->pdev->dev, "spi_add_device() failed %d\n", status);
-               return status;
-       }
-       dev->spi = spi_device;
-
-       put_device(&spi_master->dev);
-       pr_info(DRIVER_NAME " SPI initialized, max_speed_hz\t%d\n", spi_device->max_speed_hz);
-
-       return status;
-}
-
-/**
- * pmodda1_setup_cdev - Setup Char Device for ZED PmodDA1 device.
- * @dev: pointer to device tree node
- * @dev_id: pointer to device major and minor number
- * @spi: pointer to spi_device structure
- *
- * This function initializes char device for PmodDA1 device, and add it into
- * kernel device structure. It returns 0, if the cdev is successfully
- * initialized, or a negative value if there is an error.
- */
-static int pmodda1_setup_cdev(struct pmodda1_device *dev, dev_t *dev_id, int idx, struct spi_device *spi)
-{
-       int status = 0;
-       struct device *device;
-       unsigned int major_id = MAJOR(pmodda1_first_dev_id);
-       unsigned int minor_id = MINOR(pmodda1_first_dev_id) + idx;
-       char min_name[50];
-
-       cdev_init(&dev->cdev, &pmodda1_cdev_fops);
-       dev->cdev.owner = THIS_MODULE;
-       dev->cdev.ops = &pmodda1_cdev_fops;
-       dev->spi = spi;
-
-       *dev_id = MKDEV(major_id, minor_id);
-       status = cdev_add(&dev->cdev, *dev_id, 1);
-       if (status < 0)
-               return status;
-
-       /* Add Device node in system */
-       sprintf(min_name, "%s_%d", dev->name, idx);
-       device = device_create(pmodda1_class, NULL,
-                              *dev_id, NULL,
-                              min_name);
-       if (IS_ERR(device)) {
-               status = PTR_ERR(device);
-               dev_err(&spi->dev, "failed to create device node %s, err %d\n",
-                       dev->name, status);
-               cdev_del(&dev->cdev);
-       }
-       pr_info(SPI_DRIVER_NAME "pmodda1_setup_cdev: Create device %s, major %d, minor %d\n",
-               min_name, major_id, minor_id);
-       return status;
-}
-
-/**
- * SPI hardware probe. Sets correct SPI mode, attempts
- * to obtain memory needed by the driver and, for each
- * desired minor number device, it performs a simple
- * initialization of the corresponding device.
- */
-static int pmodda1_spi_probe(struct spi_device *spi)
-{
-       int status = 0;
-       struct pmodda1_device *pmodda1_dev;
-       int i;
-
-       /* We must use SPI_MODE_0 */
-       spi->mode = SPI_MODE_0;
-       spi->bits_per_word = 8;
-
-       status = spi_setup(spi);
-       if (status < 0) {
-               dev_err(&spi->dev, "needs SPI mode %02x, %d KHz; %d\n",
-                       spi->mode, spi->max_speed_hz / 1000,
-                       status);
-               goto spi_err;
-       }
-
-       /* Get pmodda1_device structure */
-       pmodda1_dev = (struct pmodda1_device *)spi->dev.platform_data;
-       if (pmodda1_dev == NULL) {
-               dev_err(&spi->dev, "Cannot get pmodda1_device.\n");
-               status = -EINVAL;
-               goto spi_platform_data_err;
-       }
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(SPI_DRIVER_NAME " [%s] spi_probe: setup char device\n", pmodda1_dev->name);
-#endif
-       for (i = 0; i < PMODDA1_DEV_NUM; i++) {
-               rgpmodda1_devices[i] = kmalloc(sizeof(struct pmodda1_device), GFP_KERNEL);
-               if (!rgpmodda1_devices[i]) {
-                       status = -ENOMEM;
-                       dev_err(&spi->dev, "da1_spi_probe: Device structure allocation failed: %d for device %d\n", status, i);
-                       goto dev_alloc_err;
-               }
-               rgpmodda1_devices[i]->buf = NULL;
-       }
-
-       for (i = 0; i < PMODDA1_DEV_NUM; i++) {
-               rgpmodda1_devices[i]->buf = kmalloc(buf_sz, GFP_KERNEL);
-               if (!rgpmodda1_devices[i]->buf) {
-                       status = -ENOMEM;
-                       dev_err(&spi->dev, "Device value buffer allocation failed: %d\n", status);
-                       goto buf_alloc_err;
-               }
-               rgpmodda1_devices[i]->spi = spi_device;
-       }
-
-       /* Setup char driver for each device*/
-       for (i = 0; i < PMODDA1_DEV_NUM; i++) {
-               status = pmodda1_setup_cdev(pmodda1_dev, &(pmodda1_dev->dev_id), i, spi);
-               if (status) {
-                       dev_err(&spi->dev, "pmodda1_spi_probe: Error adding da1_spi device: %d for device %d\n", status, i);
-                       goto cdev_add_err;
-               }
-       }
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(SPI_DRIVER_NAME " [%s] spi_probe: initialize device\n", pmodda1_dev->name);
-#endif
-
-       return status;
-buf_alloc_err:
-       for (i = 0; i < PMODDA1_DEV_NUM; i++)
-               kfree(rgpmodda1_devices[i]->buf);
-dev_alloc_err:
-       for (i = 0; i < PMODDA1_DEV_NUM; i++)
-               kfree(rgpmodda1_devices[i]);
-cdev_add_err:
-spi_platform_data_err:
-spi_err:
-       return status;
-}
-
-/**
- * pmodda1_spi_remove - SPI hardware remove.
- * Performs tasks required when SPI is removed.
- */
-static int pmodda1_spi_remove(struct spi_device *spi)
-{
-       int status;
-       struct pmodda1_device *dev;
-
-       dev = (struct pmodda1_device *)spi->dev.platform_data;
-
-       if (dev == NULL) {
-               dev_err(&spi->dev, "spi_remove: Error fetch pmodda1_device struct\n");
-               return -EINVAL;
-       }
-
-       if (&dev->cdev) {
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(SPI_DRIVER_NAME " [%s] spi_remove: Destroy Char Device\n", dev->name);
-#endif
-               device_destroy(pmodda1_class, dev->dev_id);
-               cdev_del(&dev->cdev);
-       }
-
-       return status;
-}
-
-static struct spi_driver pmodda1_spi_driver = {
-       .driver         = {
-               .name   = SPI_DRIVER_NAME,
-               .bus    = &spi_bus_type,
-               .owner  = THIS_MODULE,
-       },
-       .probe          = pmodda1_spi_probe,
-       .remove         = pmodda1_spi_remove,
-};
-
-static const struct of_device_id pmodda1_of_match[] = {
-       { .compatible = "dglnt,pmodda1", },
-       {},
-};
-MODULE_DEVICE_TABLE(of, pmodda1_of_match);
-
-/**
- * pmodda1_of_probe - Probe method for PmodDA1 device (over GPIO).
- * @pdev: pointer to platform devices
- *
- * This function probes the PmodDA1 device in the device tree. It initializes the
- * PmodDA1 driver data structure. It returns 0, if the driver is bound to the PmodDA1
- * device, or a negative value if there is an error.
- */
-static int pmodda1_of_probe(struct platform_device *pdev)
-{
-       struct pmodda1_device *pmodda1_dev;
-       struct platform_device *pmodda1_pdev;
-       struct spi_gpio_platform_data *pmodda1_pdata;
-
-       struct device_node *np = pdev->dev.of_node;
-
-       const u32 *tree_info;
-       const u32 *spi_speed;
-       int status = 0;
-       uint16_t cmd_data;
-
-       /* Alloc Space for platform device structure */
-       pmodda1_dev = kzalloc(sizeof(*pmodda1_dev), GFP_KERNEL);
-       if (!pmodda1_dev) {
-               status = -ENOMEM;
-               goto dev_alloc_err;
-       }
-
-       pmodda1_dev->buf = kmalloc(buf_sz, GFP_KERNEL);
-       if (!pmodda1_dev->buf) {
-               status = -ENOMEM;
-               pr_info(DRIVER_NAME "Device value buffer allocation failed: %d\n", status);
-               goto buf_alloc_err;
-       }
-
-       /* Get the GPIO Pins */
-
-       pmodda1_dev->iSCLK = of_get_named_gpio(np, "spi-sclk-gpio", 0);
-       pmodda1_dev->iSDIN = of_get_named_gpio(np, "spi-sdin-gpio", 0);
-       status = of_get_named_gpio(np, "spi-cs-gpio", 0);
-       pmodda1_dev->iCS = (status < 0) ? SPI_GPIO_NO_CHIPSELECT : status;
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s: iSCLK: 0x%lx\n", np->name, pmodda1_dev->iSCLK);
-       pr_info(DRIVER_NAME " %s: iSDIN: 0x%lx\n", np->name, pmodda1_dev->iSDIN);
-       pr_info(DRIVER_NAME " %s: iCS : 0x%lx\n", np->name, pmodda1_dev->iCS);
-#endif
-
-       /* Get SPI Related Params */
-       tree_info = of_get_property(np, "spi-bus-num", NULL);
-       if (tree_info) {
-               pmodda1_dev->spi_id = be32_to_cpup((tree_info));
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " %s: BUS_ID\t%x\n", np->name, pmodda1_dev->spi_id);
-#endif
-       }
-
-       spi_speed = of_get_property(np, "spi-speed-hz", NULL);
-       if (spi_speed) {
-               pmodda1_dev->spi_speed = be32_to_cpup((spi_speed));
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " %s: SPI_SPEED\t%x\n", np->name, pmodda1_dev->spi_speed);
-#endif
-       } else {
-               pmodda1_dev->spi_speed = DEFAULT_SPI_SPEED;
-       }
-       /* Alloc Space for platform data structure */
-       pmodda1_pdata = kzalloc(sizeof(*pmodda1_pdata), GFP_KERNEL);
-       if (!pmodda1_pdata) {
-               status = -ENOMEM;
-               goto pdata_alloc_err;
-       }
-
-       /* Fill up Platform Data Structure */
-       pmodda1_pdata->sck = pmodda1_dev->iSCLK;
-       pmodda1_pdata->miso = SPI_GPIO_NO_MISO;
-       pmodda1_pdata->mosi = pmodda1_dev->iSDIN;
-       pmodda1_pdata->num_chipselect = 1;
-
-       /* Alloc Space for platform data structure */
-       pmodda1_pdev = kzalloc(sizeof(*pmodda1_pdev), GFP_KERNEL);
-       if (!pmodda1_pdev) {
-               status = -ENOMEM;
-               goto pdev_alloc_err;
-       }
-
-       /* Fill up Platform Device Structure */
-       pmodda1_pdev->name = "spi_gpio";
-       pmodda1_pdev->id = pmodda1_dev->spi_id;
-       pmodda1_pdev->dev.platform_data = pmodda1_pdata;
-       pmodda1_dev->pdev = pmodda1_pdev;
-
-       /* Register spi_gpio master */
-       status = platform_device_register(pmodda1_dev->pdev);
-       if (status < 0) {
-               dev_err(&pdev->dev, "platform_device_register failed: %d\n", status);
-               goto pdev_reg_err;
-       }
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s: spi_gpio platform device registered.\n", np->name);
-#endif
-       pmodda1_dev->name = (char *)np->name;
-
-       if (pmodda1_first_dev_id == 0) {
-               /* Alloc Major & Minor number for char device */
-               status = alloc_chrdev_region(&pmodda1_first_dev_id, 0, PMODDA1_DEV_NUM, DRIVER_NAME);
-               if (status) {
-                       dev_err(&pdev->dev, "Character device region not allocated correctly: %d\n", status);
-                       goto err_alloc_chrdev_region;
-               }
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : Char Device Region Registered, with Major: %d.\n",
-                       MAJOR(pmodda1_first_dev_id));
-#endif
-       }
-
-       /* Point device node data to pmodda1_device structure */
-       if (np->data == NULL)
-               np->data = pmodda1_dev;
-
-       if (pmodda1_class == NULL) {
-               /* Create Pmodda1 Device Class */
-               pmodda1_class = class_create(THIS_MODULE, DRIVER_NAME);
-               if (IS_ERR(pmodda1_class)) {
-                       status = PTR_ERR(pmodda1_class);
-                       goto err_create_class;
-               }
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : pmodda1 device class registered.\n");
-#endif
-       }
-
-       /* Fill up Board Info for SPI device */
-       status = add_pmodda1_device_to_bus(pmodda1_dev);
-       if (status < 0) {
-               dev_err(&pdev->dev, "add_pmodda1_device_to_bus failed: %d\n", status);
-               goto spi_add_err;
-       }
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s: spi device registered.\n", np->name);
-#endif
-
-       if (spi_drv_registered == 0) {
-               /* Register SPI Driver for Pmodda1 Device */
-               status = spi_register_driver(&pmodda1_spi_driver);
-               if (status < 0) {
-                       dev_err(&pdev->dev, "pmodda1_spi_driver register failed: %d\n", status);
-                       goto err_spi_register;
-               }
-               spi_drv_registered = 1;
-       }
-
-       /*
-        * although a well-designed part will power-up into a known good state, this is
-        * a good time to force it into a known good state just to be sure. In this case,
-        * the desired known good state is both DACs powered down.
-        */
-       dac1.ext = 0;   /* select internal reference for now */
-       dac1.ldac = 0;  /* want to be able to load both DACs together */
-       dac1.pda = 1;   /* want DAC A powered down */
-       dac1.pdb = 1;   /* want DAC B powered down */
-       dac1.sel = 0;   /* this won't matter this time since both devices will be loaded from the shift register */
-       dac1.cr0 = 0;   /* in conjunction with cr1 will load both devices from the shift register */
-       dac1.cr1 = 0;   /* in conjunction with cr0 will load both devices from the shift register */
-       mutex_init(&dac1.mutex);
-       cmd_data = make_cmd_from_shadow_regs(&dac1);
-       /* cmd_data &= 0xFFFF0000; *//* zeroes out the low order bits so that the DAC could be powered up and */
-       /* the output would still be zero. */
-       status = write_spi_16(rgpmodda1_devices[0]->spi, cmd_data);
-       if (status) {
-               dev_err(&pdev->dev, "da1_spi_probe: Error writing to device to initally power down: %d\n", status);
-               goto initial_state_err;
-       }
-
-       return status;
-initial_state_err:
-err_spi_register:
-       class_destroy(pmodda1_class);
-       pmodda1_class = NULL;
-err_create_class:
-       unregister_chrdev_region(pmodda1_first_dev_id, PMODDA1_DEV_NUM);
-       pmodda1_first_dev_id = 0;
-err_alloc_chrdev_region:
-       spi_unregister_device(pmodda1_dev->spi);
-spi_add_err:
-       platform_device_unregister(pmodda1_dev->pdev);
-pdev_reg_err:
-       kfree(pmodda1_pdev);
-pdev_alloc_err:
-       kfree(pmodda1_pdata);
-buf_alloc_err:
-pdata_alloc_err:
-       kfree(pmodda1_dev->buf);
-       kfree(pmodda1_dev);
-dev_alloc_err:
-       return status;
-}
-
-/**
- * pmodda1_of_remove - Remove method for ZED PmodDA1 device.
- * @np: pointer to device tree node
- *
- * This function removes the PmodDA1 device in the device tree. It frees the
- * PmodDA1 driver data structure. It returns 0, if the driver is successfully
- * removed, or a negative value if there is an error.
- */
-static int pmodda1_of_remove(struct platform_device *pdev)
-{
-       struct pmodda1_device *pmodda1_dev;
-       struct device_node *np = pdev->dev.of_node;
-
-       if (np->data == NULL) {
-               dev_err(&pdev->dev, "pmodda1 %s: ERROR: No pmodda1_device structure found!\n", np->name);
-               return -ENOSYS;
-       }
-       pmodda1_dev = (struct pmodda1_device *)(np->data);
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s : Free display buffer.\n", np->name);
-#endif
-
-       if (pmodda1_dev->buf != NULL)
-               kfree(pmodda1_dev->buf);
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s : Unregister gpio_spi Platform Devices.\n", np->name);
-#endif
-
-       if (pmodda1_dev->pdev != NULL)
-               platform_device_unregister(pmodda1_dev->pdev);
-
-       np->data = NULL;
-
-       /* Unregister SPI Driver, Destroy pmodda1 class, Release device id Region
-        */
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " : Unregister SPI Driver.\n");
-#endif
-       spi_unregister_driver(&pmodda1_spi_driver);
-       spi_drv_registered = 0;
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " : Destroy pmodda1_gpio Class.\n");
-#endif
-
-       if (pmodda1_class)
-               class_destroy(pmodda1_class);
-       pmodda1_class = NULL;
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " : Release Char Device Region.\n");
-#endif
-
-       unregister_chrdev_region(pmodda1_first_dev_id, PMODDA1_DEV_NUM);
-       pmodda1_first_dev_id = 0;
-
-       return 0;
-}
-
-static struct platform_driver pmodda1_driver = {
-       .driver                 = {
-               .name           = DRIVER_NAME,
-               .owner          = THIS_MODULE,
-               .of_match_table = pmodda1_of_match,
-       },
-       .probe                  = pmodda1_of_probe,
-       .remove                 = pmodda1_of_remove,
-};
-
-module_platform_driver(pmodda1_driver);
-
-MODULE_AUTHOR("Digilent, Inc.");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION(DRIVER_NAME ": PmodDA1 display driver");
-MODULE_ALIAS(DRIVER_NAME);
diff --git a/drivers/staging/pmods/pmodoled-gpio.c b/drivers/staging/pmods/pmodoled-gpio.c
deleted file mode 100644 (file)
index 64ccba9..0000000
+++ /dev/null
@@ -1,862 +0,0 @@
-/*
- * pmodolde-gpio.c - PmodOLED-GPIO driver
- *
- * Copyright (c) 2012 Digilent. All right reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_gpio.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/spi_gpio.h>
-#include <linux/cdev.h>
-#include <linux/mutex.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/types.h>
-#include <asm/uaccess.h>
-
-#define DRIVER_NAME "pmodoled-gpio"
-#define SPI_DRIVER_NAME "pmodoled-gpio-spi"
-#define MAX_PMODOLED_GPIO_DEV_NUM 16
-#define DISPLAY_BUF_SZ 512      /* 32 x 128 bit monochrome == 512 bytes */
-#define MAX_LINE_LEN 16         /* 128 bits wide and current char width is 8 bit */
-#define MAX_ROW 4
-#define OLED_MAX_PG_CNT 4       /* number of display pages in OLED controller */
-#define OLED_CONTROLLER_PG_SZ 128
-#define OLED_CONTROLLER_CMD 0
-#define OLED_CONTROLLER_DATA 1
-
-/* commands for the OLED display controller    */
-#define OLED_SET_PG_ADDR 0x22
-#define OLED_DISPLAY_OFF 0xAE
-#define OLED_DISPLAY_ON 0xAF
-#define OLED_CONTRAST_CTRL 0x81
-#define OLED_SET_PRECHARGE_PERIOD 0xD9
-#define OLED_SET_SEGMENT_REMAP 0xA1
-#define OLED_SET_COM_DIR 0xC8
-#define OLED_SET_COM_PINS 0xDA
-
-static dev_t gpio_pmodoled_dev_id;
-static unsigned int device_num;
-static unsigned int cur_minor;
-static unsigned int spi_drv_registered;
-/* struct mutex minor_mutex; */
-static struct class *gpio_pmodoled_class;
-
-struct gpio_pmodoled_device {
-       const char *name;
-       /* R/W Mutex Lock */
-       struct mutex mutex;
-       /* Display Buffers */
-       uint8_t disp_on;
-       uint8_t *disp_buf;
-       /* Pin Assignment */
-       unsigned long iVBAT;
-       unsigned long iVDD;
-       unsigned long iRES;
-       unsigned long iDC;
-       unsigned long iSCLK;
-       unsigned long iSDIN;
-       unsigned long iCS;
-       /* SPI Info */
-       uint32_t spi_id;
-       /* platform device structures */
-       struct platform_device *pdev;
-       /* Char Device */
-       struct cdev cdev;
-       struct spi_device *spi;
-       dev_t dev_id;
-};
-
-/**
- * screen_buf_to_display -
- * @screen_buf -
- * @dev -
- *
- */
-static int screen_buf_to_display(uint8_t *screen_buf, struct gpio_pmodoled_device *dev)
-{
-       uint32_t pg;
-       int status;
-       uint8_t lower_start_column = 0x00;
-       uint8_t upper_start_column = 0x10;
-       uint8_t wr_buf[10];
-
-       for (pg = 0; pg < OLED_MAX_PG_CNT; pg++) {
-               wr_buf[0] = OLED_SET_PG_ADDR;
-               wr_buf[1] = pg;
-               wr_buf[2] = lower_start_column;
-               wr_buf[3] = upper_start_column;
-               gpio_set_value(dev->iDC, OLED_CONTROLLER_CMD);
-               status = spi_write(dev->spi, wr_buf, 4);
-               if (status) {
-                       dev_err(&dev->spi->dev, "screen_buf_to_display: Error writing to SPI\n");
-                       break;
-               }
-
-               gpio_set_value(dev->iDC, OLED_CONTROLLER_DATA);
-               status = spi_write(dev->spi, (uint8_t *)(screen_buf +
-                                                        (pg * OLED_CONTROLLER_PG_SZ)), OLED_CONTROLLER_PG_SZ);
-               if (status) {
-                       dev_err(&dev->spi->dev, "screen_buf_to_display: Error writing to SPI\n");
-                       break;
-               }
-       }
-       return status;
-}
-
-/**
- * A basic open function. It exists mainly to save the id of
- * the OLED and some other basic information.
- */
-static int gpio_pmodoled_open(struct inode *inode, struct file *fp)
-{
-       struct gpio_pmodoled_device *dev;
-
-       dev = container_of(inode->i_cdev, struct gpio_pmodoled_device, cdev);
-       fp->private_data = dev;
-
-       return 0;
-}
-
-static int gpio_pmodoled_close(struct inode *inode, struct file *fp)
-{
-       return 0;
-}
-
-/**
- * Driver write function
- *
- * This function uses a generic SPI write to send values to the Pmod device
- * It takes a raw data array from the app in the buffer, copied it into
- * device dispay buffer, and finally sends the buffer to the OLED using SPI
- */
-static ssize_t gpio_pmodoled_write(struct file *fp, const char __user *buffer, size_t length, loff_t *offset)
-{
-       ssize_t retval = 0;
-       struct gpio_pmodoled_device *dev;
-       unsigned int minor_id;
-       int cnt;
-       int status;
-
-       dev = fp->private_data;
-       minor_id = MINOR(dev->dev_id);
-
-       if (mutex_lock_interruptible(&dev->mutex)) {
-               retval = -ERESTARTSYS;
-               goto write_lock_err;
-       }
-
-       if (buffer == NULL) {
-               dev_err(&dev->spi->dev, "oled_write: ERROR: invalid buffer address: 0x%08lx\n",
-                       (__force unsigned long)buffer);
-               retval = -EINVAL;
-               goto quit_write;
-       }
-
-       if (length > DISPLAY_BUF_SZ)
-               cnt = DISPLAY_BUF_SZ;
-       else
-               cnt = length;
-
-       if (copy_from_user(dev->disp_buf, buffer, cnt)) {
-               dev_err(&dev->spi->dev, "oled_write: copy_from_user failed\n");
-               retval = -EFAULT;
-               goto quit_write;
-       } else
-               retval = cnt;
-
-       status = screen_buf_to_display(dev->disp_buf, dev);
-       if (status) {
-               dev_err(&dev->spi->dev, "oled_write: Error sending string to display\n");
-               retval = -EFAULT;
-               goto quit_write;
-       }
-
-quit_write:
-       mutex_unlock(&dev->mutex);
-write_lock_err:
-       return retval;
-}
-
-/**
- * Driver Read Function
- *
- * This function does not actually read the Pmod as it is a write-only device. Instead
- * It returns data in the buffer generated for the display that was used when the OLED
- * was last programmed.
- */
-static ssize_t gpio_pmodoled_read(struct file *fp, char __user *buffer, size_t length, loff_t *offset)
-{
-       ssize_t retval = 0;
-       struct gpio_pmodoled_device *dev;
-       unsigned int minor_id;
-       int cnt;
-
-       dev = fp->private_data;
-       minor_id = MINOR(dev->dev_id);
-
-       if (mutex_lock_interruptible(&dev->mutex)) {
-               retval = -ERESTARTSYS;
-               goto read_lock_err;
-       }
-
-       if (buffer == NULL) {
-               dev_err(&dev->spi->dev, "OLED_read: ERROR: invalid buffer "
-                       "address: 0x%08lx\n", (__force unsigned long)buffer);
-               retval = -EINVAL;
-               goto quit_read;
-       }
-
-       if (length > DISPLAY_BUF_SZ)
-               cnt = DISPLAY_BUF_SZ;
-       else
-               cnt = length;
-       retval = copy_to_user((void __user *)buffer, dev->disp_buf, cnt);
-       if (!retval)
-               retval = cnt; /* copy success, return amount in buffer */
-
-quit_read:
-       mutex_unlock(&dev->mutex);
-read_lock_err:
-       return retval;
-}
-
-static struct file_operations gpio_pmodoled_cdev_fops = {
-       .owner          = THIS_MODULE,
-       .write          = gpio_pmodoled_write,
-       .read           = gpio_pmodoled_read,
-       .open           = gpio_pmodoled_open,
-       .release        = gpio_pmodoled_close,
-};
-
-static int add_gpio_pmodoled_device_to_bus(struct gpio_pmodoled_device *dev)
-{
-       struct spi_master *spi_master;
-       struct spi_device *spi_device;
-       int status = 0;
-
-       spi_master = spi_busnum_to_master(dev->spi_id);
-       if (!spi_master) {
-               dev_err(&dev->pdev->dev, "spi_busnum_to_master(%d) returned NULL\n", dev->spi_id);
-               return -ENOSYS;
-       }
-
-       spi_device = spi_alloc_device(spi_master);
-       if (!spi_device) {
-               put_device(&spi_master->dev);
-               dev_err(&dev->pdev->dev, "spi_alloc_device() failed\n");
-               return -ENOMEM;
-       }
-
-       spi_device->chip_select = 0;
-       spi_device->max_speed_hz = 4000000;
-       spi_device->mode = SPI_MODE_0;
-       spi_device->bits_per_word = 8;
-       spi_device->controller_data = (void *)dev->iCS;
-       spi_device->dev.platform_data = dev;
-       strlcpy(spi_device->modalias, SPI_DRIVER_NAME, sizeof(SPI_DRIVER_NAME));
-
-       status = spi_add_device(spi_device);
-       if (status < 0) {
-               spi_dev_put(spi_device);
-               dev_err(&dev->pdev->dev, "spi_add_device() failed %d\n", status);
-               return status;
-       }
-       dev->spi = spi_device;
-
-       put_device(&spi_master->dev);
-
-       return status;
-}
-
-/**
- * gpio_pmodoled_setup_cdev - Setup Char Device for ZED on-board OLED device.
- * @dev: pointer to device tree node
- * @dev_id: pointer to device major and minor number
- * @spi: pointer to spi_device structure
- *
- * This function initializes char device for OLED device, and add it into
- * kernel device structure. It returns 0, if the cdev is successfully
- * initialized, or a negative value if there is an error.
- */
-static int gpio_pmodoled_setup_cdev(struct gpio_pmodoled_device *dev, dev_t *dev_id, struct spi_device *spi)
-{
-       int status = 0;
-       struct device *device;
-
-       cdev_init(&dev->cdev, &gpio_pmodoled_cdev_fops);
-       dev->cdev.owner = THIS_MODULE;
-       dev->cdev.ops = &gpio_pmodoled_cdev_fops;
-       dev->spi = spi;
-
-       *dev_id = MKDEV(MAJOR(gpio_pmodoled_dev_id), cur_minor++);
-       status = cdev_add(&dev->cdev, *dev_id, 1);
-       if (status < 0)
-               return status;
-
-       /* Add Device node in system */
-       device = device_create(gpio_pmodoled_class, NULL,
-                              *dev_id, NULL,
-                              "%s", dev->name);
-       if (IS_ERR(device)) {
-               status = PTR_ERR(device);
-               dev_err(&spi->dev, "failed to create device node %s, err %d\n",
-                       dev->name, status);
-               cdev_del(&dev->cdev);
-       }
-
-       return status;
-}
-
-/**
- * gpio_pmodoled_init_gpio - Initialize GPIO for ZED Onboard OLED
- * @dev - gpio_pmodoled_device
- *
- * Initializes OLED GPIO Control Pins.
- * It returns 0, if the gpio pins are successfully
- * initialized, or a negative value if there is an error.
- */
-static int gpio_pmodoled_init_gpio(struct gpio_pmodoled_device *dev)
-{
-       struct gpio gpio_pmodoled_ctrl[] = {
-               { dev->iVBAT, GPIOF_OUT_INIT_HIGH, "OLED VBat"  },
-               { dev->iVDD,  GPIOF_OUT_INIT_HIGH, "OLED VDD"   },
-               { dev->iRES,  GPIOF_OUT_INIT_HIGH, "OLED_RESET" },
-               { dev->iDC,   GPIOF_OUT_INIT_HIGH, "OLED_D/C"   },
-       };
-       int status;
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(gpio_pmodoled_ctrl); i++) {
-               status = gpio_is_valid(gpio_pmodoled_ctrl[i].gpio);
-               if (!status) {
-                       dev_err(&dev->spi->dev, "!! gpio_is_valid for GPIO %d, %s FAILED!, status: %d\n",
-                               gpio_pmodoled_ctrl[i].gpio, gpio_pmodoled_ctrl[i].label, status);
-                       goto gpio_invalid;
-               }
-       }
-
-       status = gpio_request_array(gpio_pmodoled_ctrl, ARRAY_SIZE(gpio_pmodoled_ctrl));
-       if (status) {
-               dev_err(&dev->spi->dev, "!! gpio_request_array FAILED!\n");
-               dev_err(&dev->spi->dev, " status is: %d\n", status);
-               gpio_free_array(gpio_pmodoled_ctrl, 4);
-               goto gpio_invalid;
-       }
-
-gpio_invalid:
-       return status;
-}
-
-/**
- * gpio_pmodoled_disp_init -
- * @dev:
- *
- */
-static void gpio_pmodoled_disp_init(struct gpio_pmodoled_device *dev)
-{
-       int status;
-       uint8_t wr_buf[20];
-
-       /* We are going to be sending commands
-        * so clear the data/cmd bit */
-       gpio_set_value(dev->iDC, OLED_CONTROLLER_CMD);
-
-       /* Start by turning VDD on and wait for the power to come up */
-       gpio_set_value(dev->iVDD, 0);
-       msleep(1);
-
-       /* Display off Command */
-       wr_buf[0] = OLED_DISPLAY_OFF;
-       status = spi_write(dev->spi, wr_buf, 1);
-
-       /* Bring Reset Low and then High */
-       gpio_set_value(dev->iRES, 1);
-       msleep(1);
-       gpio_set_value(dev->iRES, 0);
-       msleep(1);
-       gpio_set_value(dev->iRES, 1);
-
-       /* Send the set charge pump and set precharge period commands */
-       wr_buf[0] = 0x8D;
-       wr_buf[1] = 0x14;
-       wr_buf[2] = OLED_SET_PRECHARGE_PERIOD;
-       wr_buf[3] = 0xF1;
-
-       status = spi_write(dev->spi, wr_buf, 4);
-
-       /* Turn on VCC and wait 100ms */
-       gpio_set_value(dev->iVBAT, 0);
-       msleep(100);
-
-       /* Set Display COntrast */
-       wr_buf[0] = OLED_CONTRAST_CTRL;
-       wr_buf[1] = 0x0F;
-
-       /* Invert the display */
-       wr_buf[2] = OLED_SET_SEGMENT_REMAP;     /* Remap Columns */
-       wr_buf[3] = OLED_SET_COM_DIR;           /* Remap Rows */
-
-       /* Select sequential COM configuration */
-       wr_buf[4] = OLED_SET_COM_PINS;
-       wr_buf[5] = 0x00;
-       wr_buf[6] = 0xC0;
-       wr_buf[7] = 0x20;
-       wr_buf[8] = 0x00;
-
-       /* Turn on Display */
-       wr_buf[9] = OLED_DISPLAY_ON;
-
-       status = spi_write(dev->spi, wr_buf, 10);
-}
-
-/**
- * SPI hardware probe. Sets correct SPI mode, attempts
- * to obtain memory needed by the driver, and performs
- * a simple initialization of the device.
- */
-static int gpio_pmodoled_spi_probe(struct spi_device *spi)
-{
-       int status = 0;
-       struct gpio_pmodoled_device *gpio_pmodoled_dev;
-
-       /* We rely on full duplex transfers, mostly to reduce
-        * per transfer overheads (by making few transfers).
-        */
-       if (spi->master->flags & SPI_MASTER_HALF_DUPLEX) {
-               status = -EINVAL;
-               dev_err(&spi->dev, "SPI settings incorrect: %d\n", status);
-               goto spi_err;
-       }
-
-       /* We must use SPI_MODE_0 */
-       spi->mode = SPI_MODE_0;
-       spi->bits_per_word = 8;
-
-       status = spi_setup(spi);
-       if (status < 0) {
-               dev_err(&spi->dev, "needs SPI mode %02x, %d KHz; %d\n",
-                       spi->mode, spi->max_speed_hz / 1000,
-                       status);
-               goto spi_err;
-       }
-
-       /* Get gpio_pmodoled_device structure */
-       gpio_pmodoled_dev = (struct gpio_pmodoled_device *)spi->dev.platform_data;
-       if (gpio_pmodoled_dev == NULL) {
-               dev_err(&spi->dev, "Cannot get gpio_pmodoled_device.\n");
-               status = -EINVAL;
-               goto spi_platform_data_err;
-       }
-
-       pr_info(SPI_DRIVER_NAME " [%s] SPI Probing\n", gpio_pmodoled_dev->name);
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(SPI_DRIVER_NAME " [%s] spi_probe: setup char device\n", gpio_pmodoled_dev->name);
-#endif
-
-       /* Setup char driver */
-       status = gpio_pmodoled_setup_cdev(gpio_pmodoled_dev, &(gpio_pmodoled_dev->dev_id), spi);
-       if (status) {
-               dev_err(&spi->dev, "spi_probe: Error adding %s device: %d\n", SPI_DRIVER_NAME, status);
-               goto cdev_add_err;
-       }
-
-       /* Initialize Mutex */
-       mutex_init(&gpio_pmodoled_dev->mutex);
-
-       /**
-        * It is important to the OLED's longevity that the lines that
-        * control it's power are carefully controlled. This is a good
-        * time to ensure that the device is ot turned on until it is
-        * instructed to do so.
-        */
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(SPI_DRIVER_NAME " [%s] spi_probe: initialize device\n", gpio_pmodoled_dev->name);
-#endif
-
-       status = gpio_pmodoled_init_gpio(gpio_pmodoled_dev);
-       if (status) {
-               dev_err(&spi->dev, "spi_probe: Error initializing GPIO\n");
-               goto oled_init_error;
-       }
-
-       gpio_pmodoled_disp_init(gpio_pmodoled_dev);
-
-       memset(gpio_pmodoled_dev->disp_buf, 0x00, DISPLAY_BUF_SZ);
-
-       status = screen_buf_to_display(gpio_pmodoled_dev->disp_buf, gpio_pmodoled_dev);
-       if (status) {
-               dev_err(&spi->dev, "spi_probe: Error sending initial Display String\n");
-               goto oled_init_error;
-       }
-       return status;
-
-oled_init_error:
-       if (&gpio_pmodoled_dev->cdev)
-               cdev_del(&gpio_pmodoled_dev->cdev);
-cdev_add_err:
-spi_platform_data_err:
-spi_err:
-       return status;
-}
-
-static int gpio_pmodoled_spi_remove(struct spi_device *spi)
-{
-       int status;
-       struct gpio_pmodoled_device *dev;
-       uint8_t wr_buf[10];
-
-       dev = (struct gpio_pmodoled_device *)spi->dev.platform_data;
-
-       if (dev == NULL) {
-               dev_err(&spi->dev, "spi_remove: Error fetch gpio_pmodoled_device struct\n");
-               return -EINVAL;
-       }
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(SPI_DRIVER_NAME " [%s] spi_remove: Clearing Display\n", dev->name);
-#endif
-
-       /* Clear Display */
-       memset(dev->disp_buf, 0, DISPLAY_BUF_SZ);
-       status = screen_buf_to_display(dev->disp_buf, dev);
-
-       /* Turn off display */
-       wr_buf[0] = OLED_DISPLAY_OFF;
-       status = spi_write(spi, wr_buf, 1);
-       if (status)
-               dev_err(&spi->dev, "oled_spi_remove: Error writing to SPI device\n");
-
-       /* Turn off VCC (VBAT) */
-       gpio_set_value(dev->iVBAT, 1);
-       msleep(100);
-       /* TUrn off VDD Power */
-       gpio_set_value(dev->iVDD, 1);
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(SPI_DRIVER_NAME " [%s] spi_remove: Free GPIOs\n", dev->name);
-#endif
-
-       {
-               struct gpio gpio_pmodoled_ctrl[] = {
-                       { dev->iVBAT, GPIOF_OUT_INIT_HIGH, "OLED VBat"  },
-                       { dev->iVDD,  GPIOF_OUT_INIT_HIGH, "OLED VDD"   },
-                       { dev->iRES,  GPIOF_OUT_INIT_HIGH, "OLED_RESET" },
-                       { dev->iDC,   GPIOF_OUT_INIT_HIGH, "OLED_D/C"   },
-               };
-
-               gpio_free_array(gpio_pmodoled_ctrl, 4);
-       }
-
-       if (&dev->cdev) {
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(SPI_DRIVER_NAME " [%s] spi_remove: Destroy Char Device\n", dev->name);
-#endif
-               device_destroy(gpio_pmodoled_class, dev->dev_id);
-               cdev_del(&dev->cdev);
-       }
-
-       cur_minor--;
-
-       pr_info(SPI_DRIVER_NAME " [%s] spi_remove: Device Removed\n", dev->name);
-
-       return status;
-}
-
-static struct spi_driver gpio_pmodoled_spi_driver = {
-       .driver         = {
-               .name   = SPI_DRIVER_NAME,
-               .bus    = &spi_bus_type,
-               .owner  = THIS_MODULE,
-       },
-       .probe          = gpio_pmodoled_spi_probe,
-       .remove         = gpio_pmodoled_spi_remove,
-};
-
-static const struct of_device_id gpio_pmodoled_of_match[] = {
-       { .compatible = "dglnt,pmodoled-gpio", },
-       {},
-};
-MODULE_DEVICE_TABLE(of, gpio_pmodoled_of_match);
-
-/**
- * gpio_pmodoled_of_probe - Probe method for PmodOLED device (over GPIO).
- * @pdev: pointer to platform devices
- *
- * This function probes the OLED device in the device tree. It initializes the
- * OLED driver data structure. It returns 0, if the driver is bound to the OLED
- * device, or a negative value if there is an error.
- */
-static int gpio_pmodoled_of_probe(struct platform_device *pdev)
-{
-       struct gpio_pmodoled_device *gpio_pmodoled_dev;
-       struct platform_device *gpio_pmodoled_pdev;
-       struct spi_gpio_platform_data *gpio_pmodoled_pdata;
-
-       struct device_node *np = pdev->dev.of_node;
-
-       const u32 *tree_info;
-       int status = 0;
-
-       /* Alloc Space for platform device structure */
-       gpio_pmodoled_dev = kzalloc(sizeof(*gpio_pmodoled_dev), GFP_KERNEL);
-       if (!gpio_pmodoled_dev) {
-               status = -ENOMEM;
-               goto dev_alloc_err;
-       }
-
-       /* Alloc Graphic Buffer for device */
-       gpio_pmodoled_dev->disp_buf = kmalloc(DISPLAY_BUF_SZ, GFP_KERNEL);
-       if (!gpio_pmodoled_dev->disp_buf) {
-               status = -ENOMEM;
-               dev_err(&pdev->dev, "Device Display data buffer allocation failed: %d\n", status);
-               goto disp_buf_alloc_err;
-       }
-
-       /* Get the GPIO Pins */
-       gpio_pmodoled_dev->iVBAT = of_get_named_gpio(np, "vbat-gpio", 0);
-       gpio_pmodoled_dev->iVDD = of_get_named_gpio(np, "vdd-gpio", 0);
-       gpio_pmodoled_dev->iRES = of_get_named_gpio(np, "res-gpio", 0);
-       gpio_pmodoled_dev->iDC = of_get_named_gpio(np, "dc-gpio", 0);
-       gpio_pmodoled_dev->iSCLK = of_get_named_gpio(np, "spi-sclk-gpio", 0);
-       gpio_pmodoled_dev->iSDIN = of_get_named_gpio(np, "spi-sdin-gpio", 0);
-       status = of_get_named_gpio(np, "spi-cs-gpio", 0);
-       gpio_pmodoled_dev->iCS = (status < 0) ? SPI_GPIO_NO_CHIPSELECT : status;
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s: iVBAT: 0x%lx\n", np->name, gpio_pmodoled_dev->iVBAT);
-       pr_info(DRIVER_NAME " %s: iVDD : 0x%lx\n", np->name, gpio_pmodoled_dev->iVDD);
-       pr_info(DRIVER_NAME " %s: iRES : 0x%lx\n", np->name, gpio_pmodoled_dev->iRES);
-       pr_info(DRIVER_NAME " %s: iDC : 0x%lx\n", np->name, gpio_pmodoled_dev->iDC);
-       pr_info(DRIVER_NAME " %s: iSCLK: 0x%lx\n", np->name, gpio_pmodoled_dev->iSCLK);
-       pr_info(DRIVER_NAME " %s: iSDIN: 0x%lx\n", np->name, gpio_pmodoled_dev->iSDIN);
-       pr_info(DRIVER_NAME " %s: iCS : 0x%lx\n", np->name, gpio_pmodoled_dev->iCS);
-#endif
-
-       /* Get SPI Related Params */
-       tree_info = of_get_property(np, "spi-bus-num", NULL);
-       if (tree_info) {
-               gpio_pmodoled_dev->spi_id = be32_to_cpup((tree_info));
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " %s: BUS_ID\t%x\n", np->name, gpio_pmodoled_dev->spi_id);
-#endif
-       }
-
-       /* Alloc Space for platform data structure */
-       gpio_pmodoled_pdata = kzalloc(sizeof(*gpio_pmodoled_pdata), GFP_KERNEL);
-       if (!gpio_pmodoled_pdata) {
-               status = -ENOMEM;
-               goto pdata_alloc_err;
-       }
-
-       /* Fill up Platform Data Structure */
-       gpio_pmodoled_pdata->sck = gpio_pmodoled_dev->iSCLK;
-       gpio_pmodoled_pdata->miso = SPI_GPIO_NO_MISO;
-       gpio_pmodoled_pdata->mosi = gpio_pmodoled_dev->iSDIN;
-       gpio_pmodoled_pdata->num_chipselect = 1;
-
-       /* Alloc Space for platform data structure */
-       gpio_pmodoled_pdev = kzalloc(sizeof(*gpio_pmodoled_pdev), GFP_KERNEL);
-       if (!gpio_pmodoled_pdev) {
-               status = -ENOMEM;
-               goto pdev_alloc_err;
-       }
-
-       /* Fill up Platform Device Structure */
-       gpio_pmodoled_pdev->name = "spi_gpio";
-       gpio_pmodoled_pdev->id = gpio_pmodoled_dev->spi_id;
-       gpio_pmodoled_pdev->dev.platform_data = gpio_pmodoled_pdata;
-       gpio_pmodoled_dev->pdev = gpio_pmodoled_pdev;
-
-       /* Register spi_gpio master */
-       status = platform_device_register(gpio_pmodoled_dev->pdev);
-       if (status < 0) {
-               dev_err(&pdev->dev, "platform_device_register failed: %d\n", status);
-               goto pdev_reg_err;
-       }
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s: spi_gpio platform device registered.\n", np->name);
-#endif
-       gpio_pmodoled_dev->name = np->name;
-
-       /* Fill up Board Info for SPI device */
-       status = add_gpio_pmodoled_device_to_bus(gpio_pmodoled_dev);
-       if (status < 0) {
-               dev_err(&pdev->dev, "add_gpio_pmodoled_device_to_bus failed: %d\n", status);
-               goto spi_add_err;
-       }
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s: spi device registered.\n", np->name);
-#endif
-
-       /* Point device node data to gpio_pmodoled_device structure */
-       if (np->data == NULL)
-               np->data = gpio_pmodoled_dev;
-
-       if (gpio_pmodoled_dev_id == 0) {
-               /* Alloc Major & Minor number for char device */
-               status = alloc_chrdev_region(&gpio_pmodoled_dev_id, 0, MAX_PMODOLED_GPIO_DEV_NUM, DRIVER_NAME);
-               if (status) {
-                       dev_err(&pdev->dev, "Character device region not allocated correctly: %d\n", status);
-                       goto err_alloc_chrdev_region;
-               }
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : Char Device Region Registered, with Major: %d.\n",
-                       MAJOR(gpio_pmodoled_dev_id));
-#endif
-       }
-
-       if (gpio_pmodoled_class == NULL) {
-               /* Create Pmodoled-gpio Device Class */
-               gpio_pmodoled_class = class_create(THIS_MODULE, DRIVER_NAME);
-               if (IS_ERR(gpio_pmodoled_class)) {
-                       status = PTR_ERR(gpio_pmodoled_class);
-                       goto err_create_class;
-               }
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : pmodoled_gpio device class registered.\n");
-#endif
-       }
-
-       if (spi_drv_registered == 0) {
-               /* Register SPI Driver for Pmodoled Device */
-               status = spi_register_driver(&gpio_pmodoled_spi_driver);
-               if (status < 0) {
-                       dev_err(&pdev->dev, "gpio_pmodoled_spi_driver register failed: %d\n", status);
-                       goto err_spi_register;
-               }
-               spi_drv_registered = 1;
-       }
-
-       device_num++;
-
-       return status;
-
-err_spi_register:
-       class_destroy(gpio_pmodoled_class);
-       gpio_pmodoled_class = NULL;
-err_create_class:
-       unregister_chrdev_region(gpio_pmodoled_dev_id, MAX_PMODOLED_GPIO_DEV_NUM);
-       gpio_pmodoled_dev_id = 0;
-err_alloc_chrdev_region:
-       spi_unregister_device(gpio_pmodoled_dev->spi);
-spi_add_err:
-       platform_device_unregister(gpio_pmodoled_dev->pdev);
-pdev_reg_err:
-       kfree(gpio_pmodoled_pdev);
-pdev_alloc_err:
-       kfree(gpio_pmodoled_pdata);
-pdata_alloc_err:
-       kfree(gpio_pmodoled_dev->disp_buf);
-disp_buf_alloc_err:
-       kfree(gpio_pmodoled_dev);
-dev_alloc_err:
-       return status;
-}
-
-/**
- * gpio_pmodoled_of_remove - Remove method for ZED on-board OLED device.
- * @np: pointer to device tree node
- *
- * This function removes the OLED device in the device tree. It frees the
- * OLED driver data structure. It returns 0, if the driver is successfully
- * removed, or a negative value if there is an error.
- */
-static int gpio_pmodoled_of_remove(struct platform_device *pdev)
-{
-       struct gpio_pmodoled_device *gpio_pmodoled_dev;
-       struct device_node *np = pdev->dev.of_node;
-
-       if (np->data == NULL) {
-               dev_err(&pdev->dev, "pmodoled %s: ERROR: No gpio_pmodoled_device structure found!\n", np->name);
-               return -ENOSYS;
-       }
-       gpio_pmodoled_dev = (struct gpio_pmodoled_device *)(np->data);
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s : Free display buffer.\n", np->name);
-#endif
-
-       if (gpio_pmodoled_dev->disp_buf != NULL)
-               kfree(gpio_pmodoled_dev->disp_buf);
-
-#ifdef CONFIG_PMODS_DEBUG
-       pr_info(DRIVER_NAME " %s : Unregister gpio_spi Platform Devices.\n", np->name);
-#endif
-
-       if (gpio_pmodoled_dev->pdev != NULL)
-               platform_device_unregister(gpio_pmodoled_dev->pdev);
-
-       np->data = NULL;
-       device_num--;
-
-       /* Unregister SPI Driver, Destroy pmodoled-gpio class, Release device id Region after
-        * all pmodoled-gpio devices have been removed.
-        */
-       if (device_num == 0) {
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : Unregister SPI Driver.\n");
-#endif
-               spi_unregister_driver(&gpio_pmodoled_spi_driver);
-               spi_drv_registered = 0;
-
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : Destroy pmodoled_gpio Class.\n");
-#endif
-
-               if (gpio_pmodoled_class)
-                       class_destroy(gpio_pmodoled_class);
-
-               gpio_pmodoled_class = NULL;
-
-#ifdef CONFIG_PMODS_DEBUG
-               pr_info(DRIVER_NAME " : Release Char Device Region.\n");
-#endif
-
-               unregister_chrdev_region(gpio_pmodoled_dev_id, MAX_PMODOLED_GPIO_DEV_NUM);
-               gpio_pmodoled_dev_id = 0;
-       }
-
-       return 0;
-}
-
-static struct platform_driver gpio_pmodoled_driver = {
-       .driver                 = {
-               .name           = DRIVER_NAME,
-               .owner          = THIS_MODULE,
-               .of_match_table = gpio_pmodoled_of_match,
-       },
-       .probe                  = gpio_pmodoled_of_probe,
-       .remove                 = gpio_pmodoled_of_remove,
-};
-
-module_platform_driver(gpio_pmodoled_driver);
-
-MODULE_AUTHOR("Digilent, Inc.");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION(DRIVER_NAME ": PmodOLED display driver");
-MODULE_ALIAS(DRIVER_NAME);