diff --git a/Documentation/devicetree/bindings/dma/xilinx/axi-cdma.txt b/Documentation/devicetree/bindings/dma/xilinx/axi-cdma.txt deleted file mode 100644 index 903562647710c..0000000000000 --- a/Documentation/devicetree/bindings/dma/xilinx/axi-cdma.txt +++ /dev/null @@ -1,18 +0,0 @@ -Xilinx AXI CDMA engine, it does transfers between memory and memory - -Required properties: -- compatible: Should be "xlnx,axi-cdma" -- reg: Should contain CDMA registers location and length. -- interrupts: Should contain channel CDMA interrupts. - -Example: -++++++++ - -axi_cdma_0: axicdma@40030000 { - compatible = "xlnx,axi-cdma"; - reg = < 0x40030000 0x10000 >; - dma-channel@40030000 { - interrupts = < 0 59 4 >; - } ; -} ; - diff --git a/Documentation/devicetree/bindings/dma/xilinx/axi-dma.txt b/Documentation/devicetree/bindings/dma/xilinx/axi-dma.txt deleted file mode 100644 index 4b474a2d494e6..0000000000000 --- a/Documentation/devicetree/bindings/dma/xilinx/axi-dma.txt +++ /dev/null @@ -1,28 +0,0 @@ -Xilinx AXI DMA engine, it does transfers between memory and device. It can be -configured to have one channel or two channels. If configured as two -channels, one is to transmit to device and another is to receive from -device. - -Required properties: -- compatible: Should be "xlnx,axi-dma" -- reg: Should contain DMA registers location and length. -- interrupts: Should contain per channel DMA interrupts. -- compatible (child node): It should be either "xlnx,axi-dma-mm2s-channel" or - "xlnx,axi-dma-s2mm-channel". It depends on the hardware design and it - can also have both channels. - -Example: -++++++++ - -axi_dma_0: axidma@40400000 { - compatible = "xlnx,axi-dma"; - reg = < 0x40400000 0x10000 >; - dma-channel@40400000 { - compatible = "xlnx,axi-dma-mm2s-channel"; - interrupts = < 0 59 4 >; - } ; - dma-channel@40030030 { - compatible = "xlnx,axi-dma-s2mm-channel"; - interrupts = < 0 58 4 >; - } ; -} ; diff --git a/Documentation/devicetree/bindings/dma/xilinx/axi-vdma.txt b/Documentation/devicetree/bindings/dma/xilinx/axi-vdma.txt deleted file mode 100644 index a9cccf173fa45..0000000000000 --- a/Documentation/devicetree/bindings/dma/xilinx/axi-vdma.txt +++ /dev/null @@ -1,28 +0,0 @@ -Xilinx AXI VDMA engine, it does transfers between memory and video devices. -It can be configured to have one channel or two channels. If configured -as two channels, one is to transmit to the video device and another is -to receive from the video device. - -Required properties: -- compatible: Should be "xlnx,axi-vdma" -- reg: Should contain VDMA registers location and length. -- interrupts: Should contain per channel VDMA interrupts. -- compatible (child node): It should be either "xlnx,axi-vdma-mm2s-channel" or - "xlnx,axi-vdma-s2mm-channel". It depends on the hardware design and it - can also have both channels. - -Example: -++++++++ - -axi_vdma_0: axivdma@40030000 { - compatible = "xlnx,axi-vdma"; - reg = < 0x40030000 0x10000 >; - dma-channel@40030000 { - compatible = "xlnx,axi-vdma-mm2s-channel"; - interrupts = < 0 54 4 >; - } ; - dma-channel@40030030 { - compatible = "xlnx,axi-vdma-s2mm-channel"; - interrupts = < 0 53 4 >; - } ; -} ; diff --git a/Documentation/devicetree/bindings/gpio/gpio_i2c.txt b/Documentation/devicetree/bindings/gpio/gpio_i2c.txt new file mode 100644 index 0000000000000..4f8ec947c6bd9 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio_i2c.txt @@ -0,0 +1,32 @@ +Device-Tree bindings for i2c gpio driver + +Required properties: + - compatible = "i2c-gpio"; + - gpios: sda and scl gpio + + +Optional properties: + - i2c-gpio,sda-open-drain: sda as open drain + - i2c-gpio,scl-open-drain: scl as open drain + - i2c-gpio,scl-output-only: scl as output only + - i2c-gpio,delay-us: delay between GPIO operations (may depend on each platform) + - i2c-gpio,timeout-ms: timeout to get data + +Example nodes: + +i2c@0 { + compatible = "i2c-gpio"; + gpios = <&pioA 23 0 /* sda */ + &pioA 24 0 /* scl */ + >; + i2c-gpio,sda-open-drain; + i2c-gpio,scl-open-drain; + i2c-gpio,delay-us = <2>; /* ~100 kHz */ + #address-cells = <1>; + #size-cells = <0>; + + rv3029c2@56 { + compatible = "rv3029c2"; + reg = <0x56>; + }; +}; diff --git a/Documentation/devicetree/bindings/i2c/xiic.txt b/Documentation/devicetree/bindings/i2c/xiic.txt index ceabbe91ae449..5198404577a51 100644 --- a/Documentation/devicetree/bindings/i2c/xiic.txt +++ b/Documentation/devicetree/bindings/i2c/xiic.txt @@ -2,8 +2,8 @@ Xilinx IIC controller: Required properties: - compatible : Must be "xlnx,xps-iic-2.00.a" -- reg : IIC register location and length -- interrupts : IIC controller unterrupt +- reg : IIC Register location and length +- interrupts : IIC controller interrupt - #address-cells = <1> - #size-cells = <0> diff --git a/Documentation/pmods/pmodad1.txt b/Documentation/pmods/pmodad1.txt new file mode 100644 index 0000000000000..7b575e54d4db7 --- /dev/null +++ b/Documentation/pmods/pmodad1.txt @@ -0,0 +1,99 @@ +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 new file mode 100644 index 0000000000000..5ec04680fb61b --- /dev/null +++ b/Documentation/pmods/pmodclp.txt @@ -0,0 +1,198 @@ +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: + +;H - set cursor position to row and col + +@ - scroll left columns + +A - scroll right columns + +e - enable/disable display + 0 = display off, + backlight off + 1 = display on, + backlight off + 2 = display off, + backlight on + 3 = display on, + backlight on + +c - set cursor mode + 0 = cursor off + 1 = cursor on, + blink off + 2 = cursor on, + blink on + +j - clear display and home cursor + + +;…;d - define user programmable character +Be aware that after defining a user character you must issue a +set position command. + +Notations: + row number (0 - 1) + column number (0 – 39) + numeric parameter + - decimal: 122 for ex. + - hex: 0x7A for ex. + - binary: 0b01111010 for ex. + 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 new file mode 100644 index 0000000000000..6ca28fafed794 --- /dev/null +++ b/Documentation/pmods/pmodcls.txt @@ -0,0 +1,174 @@ +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): + +;H - set cursor position to row and col +s - save cursor position +u - restore saved cursor position +j - clear display and home cursor +K - erase within line + 0 = current position to end of line + 1 = start of line to current position + 2 = entire line +N erase field in current line + = number of chars starting at current position +@ - scroll left columns +A - scroll right columns +* - reset; equivalent to cycling power of PmodCLS +e - enable/disable display + 0 = display off, + backlight off + 1 = display on, + backlight off + 2 = display off, + backlight on + 3 = display on, + backlight on +h - set display mode + 0 = wrap line at 16 characters + 1 = wrap line at 40 characters +c - set cursor mode + 0 = cursor off + 1 = cursor on, + blink off + 2 = cursor on, + blink on +a - save TWI address in EEPROM to +b - save baud rate value in EEPROM to +p - program character table into LCD +t - save RAM character table to EEPROM +l - load EEPROM character table to RAM +;…;d- define user programmable character + Be aware that after defining a user character you must + program the character table into LCD (command 'p'). +m - save communication mode to EEPROM +w - enable write to EEPROM +n - save cursor mode to EEPROM +o - save display mode to EEPROM + +Notations: + row number (0 - 1) + column number (0 – 39) + numeric parameter + - decimal: 122 for ex. + - hex: 0x7A for ex. + - binary: 0b01111010 for ex. + decimal selection parameter + 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 new file mode 100644 index 0000000000000..82547d5c7d01a --- /dev/null +++ b/Documentation/pmods/pmodda1.txt @@ -0,0 +1,120 @@ +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/Makefile b/Makefile index bb9fff26f0780..39cf140900245 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 6 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = -digilent-13.01 NAME = Terrified Chipmunk # *DOCUMENTATION* diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index bfd2dcdceb8b2..d78f67eca067d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1779,7 +1779,7 @@ config FORCE_MAX_ZONEORDER int "Maximum zone order" if ARCH_SHMOBILE range 11 64 if ARCH_SHMOBILE default "9" if SA1111 - default "11" + default "15" help The kernel memory allocator divides physically contiguous memory blocks into "zones", where each zone is a power of two number of diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 7a7bd8c163a38..b64b568737264 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -293,7 +293,10 @@ archprepare: bzImage: zImage #zImage Image xipImage bootpImage uImage: vmlinux -$(BOOT_TARGETS1) $(BOOT_TARGETS2) : vmlinux +$(BOOT_TARGETS1) : vmlinux + $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ + +$(BOOT_TARGETS2) : vmlinux $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ zinstall uinstall install: vmlinux diff --git a/arch/arm/boot/dts/digilent-zed.dts b/arch/arm/boot/dts/digilent-zed.dts new file mode 100644 index 0000000000000..cbea708dc6eb2 --- /dev/null +++ b/arch/arm/boot/dts/digilent-zed.dts @@ -0,0 +1,554 @@ +/* + * digilent-zed.dts - Default Device Tree for ZedBoard + * + * (C) Copyright 2012 Digilent, Inc. + * + * Code based on Device Tree Generator version: 1.1 + * + * (C) Copyright 2007-2012 Xilinx, Inc. + * (C) Copyright 2007-2012 Michal Simek + * (C) Copyright 2007-2012 PetaLogix Qld Pty Ltd + * + * Michal SIMEK + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * CAUTION: This file is automatically generated by libgen. + * Version: Xilinx EDK 14.4 EDK_P.49d + * Today is: Wednesday, the 26 of December, 2012; 15:18:18 + * + * XPS project directory: device-tree_bsp_0 + */ + +/dts-v1/; +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,zynq-zed"; + model = "Xilinx Zynq ZED"; + + aliases { + ethernet0 = &ps7_ethernet_0; + serial0 = &ps7_uart_1; + }; + + chosen { + bootargs = "console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait devtmpfs.mount=1"; + /* bootargs = "console=ttyPS0,115200 root=/dev/ram rw initrd=0x800000,8M init=/init earlyprintk rootwait devtmpfs.mount=1"; */ + linux,stdout-path = "/axi@0/serial@e0001000"; + }; + + cpus { + #address-cells = <1>; + #cpus = <0x2>; + #size-cells = <0>; + ps7_cortexa9_0: cpu@0 { + clock-frequency = <666666687>; + compatible = "xlnx,ps7-cortexa9-1.00.a"; + d-cache-line-size = <0x20>; + d-cache-size = <0x8000>; + device_type = "cpu"; + i-cache-line-size = <0x20>; + i-cache-size = <0x8000>; + model = "ps7_cortexa9,1.00.a"; + reg = <0>; + timebase-frequency = <333333343>; + xlnx,cpu-1x-clk-freq-hz = <0x69f6bcb>; + xlnx,cpu-clk-freq-hz = <0x27bc86bf>; + }; + ps7_cortexa9_1: cpu@1 { + clock-frequency = <666666687>; + compatible = "xlnx,ps7-cortexa9-1.00.a"; + d-cache-line-size = <0x20>; + d-cache-size = <0x8000>; + device_type = "cpu"; + i-cache-line-size = <0x20>; + i-cache-size = <0x8000>; + model = "ps7_cortexa9,1.00.a"; + reg = <1>; + timebase-frequency = <333333343>; + xlnx,cpu-1x-clk-freq-hz = <0x69f6bcb>; + xlnx,cpu-clk-freq-hz = <0x27bc86bf>; + }; + }; + + ps7_ddr_0: memory@0 { + device_type = "memory"; + reg = < 0x0 0x20000000 >; + }; + + ps7_axi_interconnect_0: axi@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,ps7-axi-interconnect-1.00.a", "simple-bus"; + ranges; + + /* ADAU 1761 IP Part */ + /* Support for ADAU1761 is broken, will be fixed soon */ +/* axi_dma_i2s: axi-dma@40420000 { + axistream-connected = <&axi_i2s_adi_0>; + compatible = "xlnx,axi-dma-6.03.a", "xlnx,axi-dma-1.00.a"; + interrupt-parent = <&ps7_scugic_0>; + reg = < 0x40420000 0x10000 >; + xlnx,dlytmr-resolution = <0x7d>; + xlnx,enable-multi-channel = <0x0>; + xlnx,family = "zynq"; + xlnx,generic = <0x0>; + xlnx,include-mm2s = <0x1>; + xlnx,include-mm2s-dre = <0x0>; + xlnx,include-mm2s-sf = <0x1>; + xlnx,include-s2mm = <0x1>; + xlnx,include-s2mm-dre = <0x0>; + xlnx,include-s2mm-sf = <0x1>; + xlnx,include-sg = <0x1>; + xlnx,instance = "axi_dma_i2s"; + xlnx,mm2s-burst-size = <0x10>; + xlnx,num-mm2s-channels = <0x1>; + xlnx,num-s2mm-channels = <0x1>; + xlnx,prmry-is-aclk-async = <0x0>; + xlnx,s2mm-burst-size = <0x10>; + xlnx,sg-include-desc-queue = <0x0>; + xlnx,sg-include-stscntrl-strm = <0x0>; + xlnx,sg-length-width = <0x14>; + xlnx,sg-use-stsapp-length = <0x1>; + + dma-channel@40420000 { + compatible = "xlnx,axi-dma-mm2s-channel"; + xlnx,datawidth = <0x20>; + interrupts = < 0 54 4 >; + xlnx,include-dre = <0x0>; + }; + dma-channel@40420030 { + compatible = "xlnx,axi-dma-s2mm-channel"; + xlnx,datawidth = <0x20>; + interrupts = < 0 55 4 >; + xlnx,include-dre = <0x0>; + }; + }; + + axi_gpio_i2s: gpio@41200000 { + #gpio-cells = <2>; + compatible = "xlnx,axi-gpio-1.01.b", "xlnx,xps-gpio-1.00.a"; + gpio-controller; + reg = < 0x41200000 0x10000 >; + xlnx,all-inputs = <0x0>; + xlnx,all-inputs-2 = <0x0>; + xlnx,dout-default = <0x0>; + xlnx,dout-default-2 = <0x0>; + xlnx,family = "zynq"; + xlnx,gpio-width = <0x2>; + xlnx,gpio2-width = <0x20>; + xlnx,instance = "axi_gpio_i2s"; + xlnx,interrupt-present = <0x0>; + xlnx,is-dual = <0x0>; + xlnx,tri-default = <0xffffffff>; + xlnx,tri-default-2 = <0xffffffff>; + }; + + axi_i2s_adi_0: axi-i2s-adi@77600000 { + compatible = "adi,axi-i2s-1.00.a"; + reg = < 0x77600000 0x10000 >; + clock-frequency = <12288000>; + }; + + axi_iic_i2s: i2c@41640000 { + compatible = "xlnx,axi-iic-1.02.a", "xlnx,xps-iic-2.00.a"; + interrupt-parent = <&ps7_scugic_0>; + interrupts = < 0 53 4 >; + reg = < 0x41640000 0x10000 >; + xlnx,family = "zynq"; + xlnx,gpo-width = <0x1>; + xlnx,iic-freq = <0x186a0>; + xlnx,instance = "axi_iic_i2s"; + xlnx,scl-inertial-delay = <0x0>; + xlnx,sda-inertial-delay = <0x0>; + xlnx,sda-level = <0x1>; + xlnx,ten-bit-adr = <0x0>; + + #size-cells = <0>; + #address-cells = <1>; + + adau1761: adau1761@3b { + compatible = "adi,adau1761"; + reg = <0x3b>; + }; + }; + + xilinx_pcm_audio_i2s: xilinx_pcm_audio_i2s { + compatible = "xilinx-pcm-audio"; + #size-cells = <0>; + #address-cells = <1>; + + stream@0{ + reg = <0>; + dma-request = <&axi_dma_i2s 0>; + }; + stream@1{ + reg = <1>; + dma-request = <&axi_dma_i2s 1>; + }; + }; + + zed_adau1761_snd: zed_adau1761_snd { + compatible = "zed-adau1761-snd"; + audio-codec = <&adau1761>; + cpu-dai = <&axi_i2s_adi_0>; + pcm = <&xilinx_pcm_audio_i2s>; + }; +*/ + /* ADV7511 Part (HDMI SPDIF Sound Supported) */ + axi_vdma_0: axivdma@43000000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-vdma"; + ranges = < 0x43000000 0x43000000 0x10000 >; + reg = < 0x43000000 0x10000 >; + xlnx,flush-fsync = <0x1>; + xlnx,include-sg = <0x0>; + xlnx,num-fstores = <0x3>; + dma-channel@43000000 { + compatible = "xlnx,axi-vdma-mm2s-channel"; + interrupt-parent = <&ps7_scugic_0>; + interrupts = < 0 59 4 >; + xlnx,datawidth = <0x40>; + xlnx,device-id = <0x0>; + xlnx,genlock-mode = <0x0>; + xlnx,include-dre = <0x0>; + }; + }; + + axi_iic_hdmi: i2c@41600000 { + compatible = "xlnx,axi-iic-1.02.a", "xlnx,xps-iic-2.00.a"; + interrupt-parent = <&ps7_scugic_0>; + interrupts = < 0 56 4 >; + reg = < 0x41600000 0x10000 >; + xlnx,family = "zynq"; + xlnx,gpo-width = <0x1>; + xlnx,iic-freq = <0x186a0>; + xlnx,instance = "axi_iic_hdmi"; + xlnx,scl-inertial-delay = <0x0>; + xlnx,sda-inertial-delay = <0x0>; + xlnx,sda-level = <0x1>; + xlnx,ten-bit-adr = <0x0>; + }; + + axi_hdmi_tx_16b_0: axi-hdmi-tx-16b@70e00000 { + compatible = "adi,cf-adv7x11-core-1.00.a"; + reg = < 0x70e00000 0x10000 0x79000000 0x10000 >; + slave_adapter = <&axi_iic_hdmi>; + dma-request = <&axi_vdma_0 0x0>; + }; + + axi_dma_spdif: axi-dma@40400000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + axistream-connected = <&axi_spdif_tx_0>; + compatible = "xlnx,axi-dma-6.03.a", "xlnx,axi-dma-1.00.a", "xlnx,axi-dma"; + interrupt-parent = <&ps7_scugic_0>; + reg = < 0x40400000 0x10000 >; + xlnx,sg-include-stscntrl-strm = <0x0>; + xlnx,dlytmr-resolution = <0x7d>; + xlnx,enable-multi-channel = <0x0>; + xlnx,family = "zynq"; + xlnx,generic = <0x0>; + xlnx,include-mm2s = <0x1>; + xlnx,include-mm2s-dre = <0x0>; + xlnx,include-mm2s-sf = <0x1>; + xlnx,include-s2mm = <0x0>; + xlnx,include-s2mm-dre = <0x0>; + xlnx,include-s2mm-sf = <0x1>; + xlnx,include-sg = <0x1>; + xlnx,instance = "axi_dma_spdif"; + xlnx,mm2s-burst-size = <0x10>; + xlnx,num-mm2s-channels = <0x1>; + xlnx,num-s2mm-channels = <0x1>; + xlnx,prmry-is-aclk-async = <0x0>; + xlnx,s2mm-burst-size = <0x10>; + xlnx,sg-include-desc-queue = <0x0>; + xlnx,sg-length-width = <0x14>; + xlnx,sg-use-stsapp-length = <0x1>; + + dma-channel@40400000 { + compatible = "xlnx,axi-dma-mm2s-channel"; + interrupts = < 0 58 4 >; + xlnx,datawidth = <0x20>; + xlnx,include-dre = <0x0>; + }; + }; + + axi_spdif_tx_0: axi-spdif-tx@75c00000 { + compatible = "adi,axi-spdif-tx-1.00.a"; + reg = < 0x75c00000 0x10000 >; + clock-frequency = <12288000>; + }; + + xlnx_pcm_spdif: xilinx_pcm_spdif_audio { + compatible = "xilinx-pcm-audio"; + dma-request = <&axi_dma_spdif 0x0>; + }; + + adv7511_hdmi_snd { + compatible = "adv7511-hdmi-snd"; + audio-codec-adapter = <&axi_iic_hdmi>; + cpu-dai = <&axi_spdif_tx_0>; + pcm = <&xlnx_pcm_spdif>; + }; + + /* PS system internal devices */ + ps7_afi_0: ps7-afi@f8008000 { + compatible = "xlnx,ps7-afi-1.00.a"; + reg = < 0xf8008000 0x1000 >; + }; + ps7_afi_1: ps7-afi@f8009000 { + compatible = "xlnx,ps7-afi-1.00.a"; + reg = < 0xf8009000 0x1000 >; + }; + ps7_afi_2: ps7-afi@f800a000 { + compatible = "xlnx,ps7-afi-1.00.a"; + reg = < 0xf800a000 0x1000 >; + }; + ps7_afi_3: ps7-afi@f800b000 { + compatible = "xlnx,ps7-afi-1.00.a"; + reg = < 0xf800b000 0x1000 >; + }; + + ps7_ddrc_0: ps7-ddrc@f8006000 { + compatible = "xlnx,ps7-ddrc-1.00.a"; + reg = < 0xf8006000 0x1000 >; + xlnx,has-ecc = <0x0>; + }; + + ps7_dev_cfg_0: ps7-dev-cfg@f8007000 { + compatible = "xlnx,ps7-dev-cfg-1.00.a"; + interrupt-parent = <&ps7_scugic_0>; + interrupts = < 0 8 4 >; + reg = < 0xf8007000 0x1000 >; + }; + + ps7_dma_ns: ps7-dma@f8004000 { + compatible = "xlnx,ps7-dma-1.00.a", "arm,pl330"; + interrupt-parent = <&ps7_scugic_0>; + interrupts = < 0 13 4 0 14 4 0 15 4 0 16 4 0 17 4 0 40 4 0 41 4 0 42 4 0 43 4 >; + reg = < 0xf8004000 0x1000 >; + }; + + ps7_dma_s: ps7-dma@f8003000 { + compatible = "xlnx,ps7-dma-1.00.a", "arm,pl330"; + interrupt-parent = <&ps7_scugic_0>; + interrupts = < 0 13 4 0 14 4 0 15 4 0 16 4 0 17 4 0 40 4 0 41 4 0 42 4 0 43 4 >; + reg = < 0xf8003000 0x1000 >; + }; + + ps7_ethernet_0: ps7-ethernet@e000b000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "xlnx,ps7-ethernet-1.00.a"; + interrupt-parent = <&ps7_scugic_0>; + interrupts = < 0 22 4 >; + local-mac-address = [ 00 0a 35 00 00 00 ]; + phy-handle = <&phy0>; + reg = < 0xe000b000 0x1000 >; + xlnx,enet-clk-freq-hz = <0x7735940>; + xlnx,enet-reset = <0xffffffff>; + xlnx,enet-slcr-1000mbps-div0 = <0x8>; + xlnx,enet-slcr-1000mbps-div1 = <0x1>; + xlnx,enet-slcr-100mbps-div0 = <0x8>; + xlnx,enet-slcr-100mbps-div1 = <0x5>; + xlnx,enet-slcr-10mbps-div0 = <0x8>; + xlnx,enet-slcr-10mbps-div1 = <0x32>; + xlnx,eth-mode = <0x1>; + xlnx,has-mdio = <0x1>; + xlnx,ptp-enet-clock = <111111115>; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: phy@0 { + compatible = "marvell,88e1510"; + device_type = "ethernet-phy"; + reg = <0>; + marvell,reg-init = <0x3 0x10 0xff00 0x1e 0x3 0x11 0xfff0 0xa>; + }; + }; + }; + + ps7_gpio_0: ps7-gpio@e000a000 { + #gpio-cells = <2>; + compatible = "xlnx,ps7-gpio-1.00.a"; + emio-gpio-width = <60>; + gpio-controller; + gpio-mask-high = <0xc0000>; + gpio-mask-low = <0xfe81>; + interrupt-parent = <&ps7_scugic_0>; + interrupts = < 0 20 4 >; + reg = < 0xe000a000 0x1000 >; + }; + + ps7_iop_bus_config_0: ps7-iop-bus-config@e0200000 { + compatible = "xlnx,ps7-iop-bus-config-1.00.a"; + reg = < 0xe0200000 0x1000 >; + }; + + ps7_pl310_0: ps7-pl310@f8f02000 { + arm,data-latency = < 3 2 2 >; + arm,tag-latency = < 2 2 2 >; + cache-level = < 2 >; + cache-unified; + compatible = "xlnx,ps7-pl310-1.00.a", "arm,pl310-cache"; + reg = < 0xf8f02000 0x1000 >; + }; + + ps7_qspi_0: ps7-qspi@e000d000 { + bus-num = <0>; + compatible = "xlnx,ps7-qspi-1.00.a"; + interrupt-parent = <&ps7_scugic_0>; + interrupts = < 0 19 4 >; + is-dual = <0>; + num-chip-select = <1>; + reg = < 0xe000d000 0x1000 >; + speed-hz = <200000000>; + xlnx,fb-clk = <0x1>; + xlnx,qspi-clk-freq-hz = <0xbebc200>; + xlnx,qspi-mode = <0x0>; + }; + + ps7_qspi_linear_0: ps7-qspi-linear@fc000000 { + compatible = "xlnx,ps7-qspi-linear-1.00.a"; + reg = < 0xfc000000 0x1000000 >; + xlnx,qspi-clk-freq-hz = <0xe4e1c0>; + }; + + ps7_scugic_0: ps7-scugic@f8f01000 { + #address-cells = < 2 >; + #interrupt-cells = < 3 >; + #size-cells = < 1 >; + compatible = "xlnx,ps7-scugic-1.00.a", "arm,cortex-a9-gic", "arm,gic"; + interrupt-controller; + linux,phandle = < 0x1 >; + phandle = < 0x1 >; + reg = < 0xf8f01000 0x1000 0xf8f00100 0x100 >; + }; + + ps7_scutimer_0: ps7-scutimer@f8f00600 { + clock-frequency = <333333343>; + compatible = "xlnx,ps7-scutimer-1.00.a", "arm,cortex-a9-twd-timer"; + interrupt-parent = <&ps7_scugic_0>; + interrupts = < 1 13 769 >; + reg = < 0xf8f00600 0x20 >; + }; + + ps7_scuwdt_0: ps7-scuwdt@f8f00620 { + clock-frequency = <333333343>; + /* clock-frequency = <111111111>; */ + compatible = "xlnx,ps7-scuwdt-1.00.a"; + device_type = "watchdog"; + interrupt-parent = <&ps7_scugic_0>; + interrupts = < 1 14 769 >; + reg = < 0xf8f00620 0xe0 >; + }; + + ps7_sd_0: ps7-sdio@e0100000 { + clock-frequency = <50000000>; + compatible = "xlnx,ps7-sdio-1.00.a", "generic-sdhci"; + interrupt-parent = <&ps7_scugic_0>; + interrupts = < 0 24 4 >; + reg = < 0xe0100000 0x1000 >; + xlnx,has-cd = <0x1>; + xlnx,has-power = <0x0>; + xlnx,has-wp = <0x1>; + xlnx,sdio-clk-freq-hz = <0x2faf080>; + /* clock-frequency = <0x1fc9f08>; */ + }; + + ps7_slcr_0: ps7-slcr@f8000000 { + compatible = "xlnx,ps7-slcr-1.00.a"; + reg = < 0xf8000000 0x1000 >; + }; + + ps7_ttc_0: ps7-ttc@f8001000 { + clock-frequency = <111111115>; + clock-frequency-timer0 = <111111115>; + clock-frequency-timer1 = <111111115>; + clock-frequency-timer2 = <111111115>; + compatible = "xlnx,ps7-ttc-1.00.a"; + interrupt-parent = <&ps7_scugic_0>; + interrupts = < 0 10 4 0 11 4 0 12 4 >; + reg = < 0xf8001000 0x1000 >; + xlnx,ttc-clk0-clksrc = <0x0>; + xlnx,ttc-clk0-freq-hz = <0x69f6bcb>; + xlnx,ttc-clk1-clksrc = <0x0>; + xlnx,ttc-clk1-freq-hz = <0x69f6bcb>; + xlnx,ttc-clk2-clksrc = <0x0>; + xlnx,ttc-clk2-freq-hz = <0x69f6bcb>; + }; + + ps7_uart_1: serial@e0001000 { + clock = <50000000>; + clock-frequency = <50000000>; + compatible = "xlnx,ps7-uart-1.00.a", "xlnx,xuartps"; + current-speed = <115200>; + device_type = "serial"; + interrupt-parent = <&ps7_scugic_0>; + interrupts = < 0 50 4 >; + port-number = <0>; + reg = < 0xe0001000 0x1000 >; + xlnx,has-modem = <0x0>; + xlnx,uart-clk-freq-hz = <0x2faf080>; + }; + + ps7_usb_0: ps7-usb@e0002000 { + compatible = "xlnx,ps7-usb-1.00.a"; + dr_mode = "host"; + interrupt-parent = <&ps7_scugic_0>; + interrupts = < 0 21 4 >; + phy_type = "ulpi"; + reg = < 0xe0002000 0x1000 >; + xlnx,usb-reset = <0xffffffff>; + }; + + ps7_xadc: ps7_xadc@f8007100 { + compatible = "xlnx,ps7-xadc-1.00.a"; + interrupts = < 0 7 4 >; + reg = < 0xf8007100 0x20 >; + }; + + leds { + compatible = "gpio-leds"; + + mmc_led { + label = "mmc_led"; + gpios = <&ps7_gpio_0 7 0>; + linux,default-trigger = "mmc0"; + }; + }; + + zed_oled { + compatible = "dglnt,pmodoled-gpio"; + /* GPIO Pins */ + vbat-gpio = <&ps7_gpio_0 55 0>; + vdd-gpio = <&ps7_gpio_0 56 0>; + res-gpio = <&ps7_gpio_0 57 0>; + dc-gpio = <&ps7_gpio_0 58 0>; + /* SPI-GPIOs */ + spi-bus-num = <2>; + spi-speed-hz = <4000000>; + spi-sclk-gpio = <&ps7_gpio_0 59 0>; + spi-sdin-gpio = <&ps7_gpio_0 60 0>; + }; + }; +}; diff --git a/arch/arm/boot/dts/zynq-zc702-adv7511-xcomm.dts b/arch/arm/boot/dts/zynq-zc702-adv7511-xcomm.dts new file mode 100644 index 0000000000000..9c9a06b47e1ad --- /dev/null +++ b/arch/arm/boot/dts/zynq-zc702-adv7511-xcomm.dts @@ -0,0 +1,303 @@ +/dts-v1/; + +/ { + model = "Xilinx Zynq ZC702"; + compatible = "xlnx,zynq-zc702"; + #address-cells = <0x1>; + #size-cells = <0x1>; + interrupt-parent = <0x1>; + + memory { + device_type = "memory"; + reg = <0x000000000 0x40000000>; + }; + chosen { +// bootargs = "console=ttyPS0,115200 root=/dev/ram rw initrd=0x1100000,33M ip=:::::eth0:dhcp earlyprintk"; + bootargs = "console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait devtmpfs.mount=0 --no-log"; + linux,stdout-path = "/amba@0/uart@E0001000"; + }; + + amba@0 { + compatible = "simple-bus"; + #address-cells = <0x1>; + #size-cells = <0x1>; + ranges; + + gic: intc@f8f01000 { + interrupt-controller; + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + reg = < 0xf8f01000 0x1000 >, + < 0xf8f00100 0x0100 >; + }; + + uart@e0001000 { + compatible = "xlnx,ps7-uart-1.00.a"; + reg = <0xe0001000 0x1000>; + interrupts = < 0 50 0 >; + interrupt-parent = <&gic>; + clock = <50000000>; + }; + + timer@0xf8001000 { + compatible = "xlnx,ps7-ttc-1.00.a"; + reg = <0xf8001000 0x1000>; + interrupts = <0 10 0>,<0 11 0>,<0 12 0>; + interrupt-parent = <&gic>; +/* clock-frequency = <111111111>;*/ + clock-frequency-timer0 = <133000000>; + clock-frequency-timer1 = <133000000>; + clock-frequency-timer2 = <133000000>; + }; + + swdt@f8005000 { + device_type = "watchdog"; + compatible = "xlnx,ps7-wdt-1.00.a"; + reg = <0xf8005000 0x100>; + }; + + eth@e000b000 { + compatible = "xlnx,ps7-ethernet-1.00.a"; + reg = <0xe000b000 0x1000>; + interrupts = <0 22 0>; + interrupt-parent = <&gic>; + phy-handle = <&phy0>; + #address-cells = <0x1>; + #size-cells = <0x0>; + + phy0: phy@7 { + compatible = "marvell,88e1116r"; + device_type = "ethernet-phy"; + reg = <0x7>; + }; + }; + + gpio: gpio@e000a000 { + compatible = "xlnx,ps7-gpio-1.00.a"; + reg = <0xe000a000 0x1000>; + interrupts = <0 20 0>; + interrupt-parent = <&gic>; + gpio-controller; + #gpio-cells = <2>; + }; + +/* + i2c0: i2c@e0004000 { + compatible = "xlnx,ps7-i2c-1.00.a"; + reg = <0xe0004000 0x1000>; + interrupts = <0 25 0>; + interrupt-parent = <&gic>; + bus-id = <0>; + input-clk = <111111111>; + i2c-clk = <100000>; +*/ + + i2c0: i2c@0 { + compatible = "i2c-gpio"; + gpios = <&gpio 51 0 &gpio 50 0>; + i2c-gpio,delay-us = <5>; + #address-cells = <1>; + #size-cells = <0>; + + mux@74 { + compatible = "pca9548"; + reg = <0x74>; + #address-cells = <1>; + #size-cells = <0>; + i2c_adv7511: i2c@1 { + #size-cells = <0>; + #address-cells = <1>; + reg = <1>; + }; + + i2c@4 { + #size-cells = <0>; + #address-cells = <1>; + reg = <4>; + rtc@51 { + compatible = "rtc8564"; + reg = <0x51>; + }; + }; + i2c@5 { + #size-cells = <0>; + #address-cells = <1>; + reg = <5>; + spi_xcomm0: spi_xcomm0@58 { + #size-cells = <0>; + #address-cells = <1>; + compatible = "spi-xcomm"; + reg = <0x58>; + dac0_ad9122: ad9122@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "ad9122"; + reg = <0>; + spi-max-frequency = <10000000>; + }; + adc0_ad9467: ad9467@1 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "ad9643"; + reg = <1>; + spi-3wire; + spi-max-frequency = <10000000>; + }; + + }; + eeprom@50 { + compatible = "at24,24c02"; + reg = <0x50>; + }; + eeprom@55 { + compatible = "at24,24c02"; + reg = <0x55>; + }; + }; + }; + + }; + + sdhci@e0100000 { + compatible = "xlnx,ps7-sdhci-1.00.a"; + reg = <0xe0100000 0x1000>; + interrupts = <0 24 0>; + interrupt-parent = <&gic>; + clock-frequency = <50000000>; + }; + + usb@e0002000 { + compatible = "xlnx,ps7-usb-1.00.a"; + reg = <0xe0002000 0x1000>; + interrupts = <0 21 0>; + interrupt-parent = <&gic>; + dr_mode = "host"; + phy_type = "ulpi"; + }; + + devcfg@f8007000 { + compatible = "xlnx,ps7-dev-cfg-1.00.a"; + reg = <0xf8007000 0x1000>; + interrupts = <0 8 0>; + interrupt-parent = <&gic>; + }; + + axi_dma_0: axidma@40440000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-dma"; + reg = < 0x40440000 0x1000 >; + xlnx,sg-include-stscntrl-strm = <0x0>; + dma-channel@40440000 { + compatible = "xlnx,axi-dma-mm2s-channel"; + interrupts = < 0 56 0x4 >; + xlnx,datawidth = <0x20>; + xlnx,include-dre = <0x0>; + }; + }; + + axi_spdif_tx_0: axi-spdif-tx@0x75c00000 { + compatible = "adi,axi-spdif-tx-1.00.a"; + reg = < 0x75c00000 0x1000 >; + clock-frequency = <12288000>; + }; + + axi_vdma_0: axivdma@43200000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-vdma"; + reg = <0x43020000 0x1000>; + xlnx,include-sg = <0x0>; + xlnx,num-fstores = <0x3>; + dma-channel@43000000 { + compatible = "xlnx,axi-vdma-mm2s-channel"; + interrupts = <0 57 0x4>; + xlnx,datawidth = <0x40>; + xlnx,genlock-mode = <0x0>; + xlnx,include-dre = <0x0>; + }; + }; + + axi_vdma_1: axivdma@43000000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-vdma"; + reg = <0x43000000 0x1000>; + xlnx,include-sg = <0x0>; + xlnx,num-fstores = <0x3>; + dma-channel@43000000 { + compatible = "xlnx,axi-vdma-mm2s-channel"; + interrupts = <0 59 0x4>; + xlnx,datawidth = <0x40>; + xlnx,genlock-mode = <0x0>; + xlnx,include-dre = <0x0>; + }; + }; + + cf_adv7x11_core_0: cf-adv7x11-core@6c000000 { + compatible = "adi,cf-adv7x11-core-1.00.a"; + reg = <0x70e00000 0x10000 + 0x79000000 0x10000>; + slave_adapter = <&i2c_adv7511>; + dma-request = <&axi_vdma_0 0>; + }; + + xilinx_pcm_audio: xilinx_pcm_audio { + compatible = "xilinx-pcm-audio"; + dma-request = <&axi_dma_0 0>; + }; + + adv7511_hdmi_snd: adv7511_hdmi_snd { + compatible = "adv7511-hdmi-snd"; + audio-codec-adapter = <&i2c_adv7511>; + cpu-dai = <&axi_spdif_tx_0>; + pcm = <&xilinx_pcm_audio>; + }; + + axi_dma_1: axidma@40420000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-dma"; + reg = < 0x40420000 0x10000 >; + dma-channel@40420000 { + compatible = "xlnx,axi-dma-s2mm-channel"; + interrupts = < 0 58 0x4 >; + xlnx,datawidth = <0x40>; + xlnx,include-dre = <0x0>; + } ; + } ; + + cf_ad9643_core_0: cf-ad9643-core-lpc@79020000 { + compatible = "xlnx,axi-adc-2c-1.00.a"; + reg = < 0x79020000 0x10000 >; + dma-request = <&axi_dma_1 0>; + spibus-connected = <&adc0_ad9467>; + xlnx,dphase-timeout = <0x8>; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; + + cf_ad9122_core_0: cf-ad9122-core-lpc@74200000 { + compatible = "xlnx,axi-dac-4d-2c-1.00.a"; + reg = < 0x74200000 0x10000 >; + spibus-connected = <&dac0_ad9122>; + dma-request = <&axi_vdma_1 0>; + dac-sample-frequency = <491520000>; + xlnx,dphase-timeout = <0x8>; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; + }; +}; diff --git a/arch/arm/boot/dts/zynq-zc702-adv7511.dts b/arch/arm/boot/dts/zynq-zc702-adv7511.dts new file mode 100644 index 0000000000000..1f61c2b9f2985 --- /dev/null +++ b/arch/arm/boot/dts/zynq-zc702-adv7511.dts @@ -0,0 +1,219 @@ +/dts-v1/; + +/ { + model = "Xilinx Zynq ZC702"; + compatible = "xlnx,zynq-zc702"; + #address-cells = <0x1>; + #size-cells = <0x1>; + interrupt-parent = <0x1>; + + memory { + device_type = "memory"; + reg = <0x000000000 0x40000000>; + }; + chosen { +// bootargs = "console=ttyPS0,115200 root=/dev/ram rw initrd=0x1100000,33M ip=:::::eth0:dhcp earlyprintk"; + bootargs = "console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait devtmpfs.mount=0"; + linux,stdout-path = "/amba@0/uart@E0001000"; + }; + + amba@0 { + compatible = "simple-bus"; + #address-cells = <0x1>; + #size-cells = <0x1>; + ranges; + + gic: intc@f8f01000 { + interrupt-controller; + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + reg = < 0xf8f01000 0x1000 >, + < 0xf8f00100 0x0100 >; + }; + + uart@e0001000 { + compatible = "xlnx,ps7-uart-1.00.a"; + reg = <0xe0001000 0x1000>; + interrupts = < 0 50 0 >; + interrupt-parent = <&gic>; + clock = <50000000>; + }; + + timer@0xf8001000 { + compatible = "xlnx,ps7-ttc-1.00.a"; + reg = <0xf8001000 0x1000>; + interrupts = <0 10 0>,<0 11 0>,<0 12 0>; + interrupt-parent = <&gic>; +/* clock-frequency = <111111111>;*/ + clock-frequency-timer0 = <133000000>; + clock-frequency-timer1 = <133000000>; + clock-frequency-timer2 = <133000000>; + }; + + swdt@f8005000 { + device_type = "watchdog"; + compatible = "xlnx,ps7-wdt-1.00.a"; + reg = <0xf8005000 0x100>; + }; + + eth@e000b000 { + compatible = "xlnx,ps7-ethernet-1.00.a"; + reg = <0xe000b000 0x1000>; + interrupts = <0 22 0>; + interrupt-parent = <&gic>; + phy-handle = <&phy0>; + #address-cells = <0x1>; + #size-cells = <0x0>; + + phy0: phy@7 { + compatible = "marvell,88e1116r"; + device_type = "ethernet-phy"; + reg = <0x7>; + }; + }; + + gpio: gpio@e000a000 { + compatible = "xlnx,ps7-gpio-1.00.a"; + reg = <0xe000a000 0x1000>; + interrupts = <0 20 0>; + interrupt-parent = <&gic>; + gpio-controller; + #gpio-cells = <2>; + }; + +/* + i2c0: i2c@e0004000 { + compatible = "xlnx,ps7-i2c-1.00.a"; + reg = <0xe0004000 0x1000>; + interrupts = <0 25 0>; + interrupt-parent = <&gic>; + bus-id = <0>; + input-clk = <111111111>; + i2c-clk = <100000>; +*/ + + i2c0: i2c@0 { + compatible = "i2c-gpio"; + gpios = <&gpio 51 0 &gpio 50 0>; + i2c-gpio,delay-us = <2>; + #address-cells = <1>; + #size-cells = <0>; + + mux@74 { + compatible = "pca9548"; + reg = <0x74>; + #address-cells = <1>; + #size-cells = <0>; + i2c_adv7511: i2c@1 { + #size-cells = <0>; + #address-cells = <1>; + reg = <1>; + }; + + i2c@4 { + #size-cells = <0>; + #address-cells = <1>; + reg = <4>; + rtc@51 { + compatible = "rtc8564"; + reg = <0x51>; + }; + }; + }; + + }; + + sdhci@e0100000 { + compatible = "xlnx,ps7-sdhci-1.00.a"; + reg = <0xe0100000 0x1000>; + interrupts = <0 24 0>; + interrupt-parent = <&gic>; + clock-frequency = <33333000>; + }; + + usb@e0002000 { + compatible = "xlnx,ps7-usb-1.00.a"; + reg = <0xe0002000 0x1000>; + interrupts = <0 21 0>; + interrupt-parent = <&gic>; + dr_mode = "host"; + phy_type = "ulpi"; + }; + + qspi0: spi@e000d000 { + compatible = "xlnx,ps7-qspi-1.00.a"; + reg = <0xE000D000 0x1000>; + interrupts = <0 19 0>; + interrupt-parent = <&gic>; + speed-hz = <200000000>; + bus-num = <1>; + num-chip-select = <1>; + is-dual = <0>; + }; + + devcfg@f8007000 { + compatible = "xlnx,ps7-dev-cfg-1.00.a"; + reg = <0xf8007000 0x1000>; + interrupts = <0 8 0>; + interrupt-parent = <&gic>; + }; + + axi_dma_0: axidma@40400000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-dma"; + reg = < 0x40400000 0x1000 >; + xlnx,sg-include-stscntrl-strm = <0x0>; + dma-channel@40400000 { + compatible = "xlnx,axi-dma-mm2s-channel"; + interrupts = < 0 58 0x4 >; + xlnx,datawidth = <0x20>; + xlnx,include-dre = <0x0>; + }; + }; + + axi_spdif_tx_0: axi-spdif-tx@0x75c00000 { + compatible = "adi,axi-spdif-tx-1.00.a"; + reg = < 0x75c00000 0x1000 >; + clock-frequency = <12288000>; + }; + + axi_vdma_0: axivdma@43000000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-vdma"; + reg = <0x43000000 0x1000>; + xlnx,include-sg = <0x0>; + xlnx,num-fstores = <0x3>; + dma-channel@7e200000 { + compatible = "xlnx,axi-vdma-mm2s-channel"; + interrupts = <0 59 0x4>; + xlnx,datawidth = <0x40>; + xlnx,genlock-mode = <0x0>; + xlnx,include-dre = <0x0>; + }; + }; + + cf_adv7x11_core_0: cf-adv7x11-core@6c000000 { + compatible = "adi,cf-adv7x11-core-1.00.a"; + reg = <0x6c000000 0x10000 + 0x66000000 0x10000>; + slave_adapter = <&i2c_adv7511>; + dma-request = <&axi_vdma_0 0>; + }; + + xilinx_pcm_audio: xilinx_pcm_audio { + compatible = "xilinx-pcm-audio"; + dma-request = <&axi_dma_0 0>; + }; + + adv7511_hdmi_snd: adv7511_hdmi_snd { + compatible = "adv7511-hdmi-snd"; + audio-codec-adapter = <&i2c_adv7511>; + cpu-dai = <&axi_spdif_tx_0>; + pcm = <&xilinx_pcm_audio>; + }; + }; +}; diff --git a/arch/arm/boot/dts/zynq-zed.dts b/arch/arm/boot/dts/zynq-zed.dts deleted file mode 100644 index bc9f168f34bb3..0000000000000 --- a/arch/arm/boot/dts/zynq-zed.dts +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Device Tree Generator version: 1.1 - * - * (C) Copyright 2007-2012 Xilinx, Inc. - * (C) Copyright 2007-2012 Michal Simek - * (C) Copyright 2007-2012 PetaLogix Qld Pty Ltd - * - * Michal SIMEK - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - * CAUTION: This file is automatically generated by libgen. - * Version: Xilinx EDK 14.3 EDK_P.40xd - * Today is: Tuesday, the 27 of November, 2012; 12:29:21 - * - * XPS project directory: device-tree_bsp_0 - */ - -/dts-v1/; -/ { - #address-cells = <1>; - #size-cells = <1>; - compatible = "xlnx,zynq-zc770"; - model = "Xilinx Zynq"; - aliases { - ethernet0 = &ps7_ethernet_0; - serial0 = &ps7_uart_1; - } ; - chosen { - bootargs = "console=ttyPS0,115200 root=/dev/ram rw ip=:::::eth0:dhcp earlyprintk"; - linux,stdout-path = "/axi@0/serial@e0001000"; - } ; - cpus { - #address-cells = <1>; - #cpus = <0x2>; - #size-cells = <0>; - ps7_cortexa9_0: cpu@0 { - clock-frequency = <666666687>; - compatible = "xlnx,ps7-cortexa9-1.00.a"; - d-cache-line-size = <0x20>; - d-cache-size = <0x8000>; - device_type = "cpu"; - i-cache-line-size = <0x20>; - i-cache-size = <0x8000>; - model = "ps7_cortexa9,1.00.a"; - reg = <0>; - timebase-frequency = <333333343>; - xlnx,cpu-1x-clk-freq-hz = <0x69f6bcb>; - xlnx,cpu-clk-freq-hz = <0x27bc86bf>; - } ; - ps7_cortexa9_1: cpu@1 { - clock-frequency = <666666687>; - compatible = "xlnx,ps7-cortexa9-1.00.a"; - d-cache-line-size = <0x20>; - d-cache-size = <0x8000>; - device_type = "cpu"; - i-cache-line-size = <0x20>; - i-cache-size = <0x8000>; - model = "ps7_cortexa9,1.00.a"; - reg = <1>; - timebase-frequency = <333333343>; - xlnx,cpu-1x-clk-freq-hz = <0x69f6bcb>; - xlnx,cpu-clk-freq-hz = <0x27bc86bf>; - } ; - } ; - ps7_ddr_0: memory@0 { - device_type = "memory"; - reg = < 0x0 0x20000000 >; - } ; - ps7_axi_interconnect_0: axi@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "xlnx,ps7-axi-interconnect-1.00.a", "simple-bus"; - ranges ; - ps7_afi_0: ps7-afi@f8008000 { - compatible = "xlnx,ps7-afi-1.00.a"; - reg = < 0xf8008000 0x1000 >; - } ; - ps7_afi_1: ps7-afi@f8009000 { - compatible = "xlnx,ps7-afi-1.00.a"; - reg = < 0xf8009000 0x1000 >; - } ; - ps7_afi_2: ps7-afi@f800a000 { - compatible = "xlnx,ps7-afi-1.00.a"; - reg = < 0xf800a000 0x1000 >; - } ; - ps7_afi_3: ps7-afi@f800b000 { - compatible = "xlnx,ps7-afi-1.00.a"; - reg = < 0xf800b000 0x1000 >; - } ; - ps7_ddrc_0: ps7-ddrc@f8006000 { - compatible = "xlnx,ps7-ddrc-1.00.a"; - reg = < 0xf8006000 0x1000 >; - xlnx,has-ecc = <0x0>; - } ; - ps7_dev_cfg_0: ps7-dev-cfg@f8007000 { - compatible = "xlnx,ps7-dev-cfg-1.00.a"; - interrupt-parent = <&ps7_scugic_0>; - interrupts = < 0 8 0 >; - reg = < 0xf8007000 0x1000 >; - } ; - ps7_dma_ns: ps7-dma@f8004000 { - compatible = "xlnx,ps7-dma-1.00.a"; - reg = < 0xf8004000 0x1000 >; - } ; - ps7_dma_s: ps7-dma@f8003000 { - compatible = "xlnx,ps7-dma-1.00.a"; - reg = < 0xf8003000 0x1000 >; - } ; - ps7_ethernet_0: ps7-ethernet@e000b000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "xlnx,ps7-ethernet-1.00.a"; - interrupt-parent = <&ps7_scugic_0>; - interrupts = < 0 22 0 >; - local-mac-address = [ 00 0a 35 00 00 00 ]; - phy-handle = <&phy0>; - reg = < 0xe000b000 0x1000 >; - xlnx,enet-clk-freq-hz = <0x7735940>; - xlnx,enet-reset = <0xffffffff>; - xlnx,enet-slcr-1000mbps-div0 = <0x8>; - xlnx,enet-slcr-1000mbps-div1 = <0x1>; - xlnx,enet-slcr-100mbps-div0 = <0x8>; - xlnx,enet-slcr-100mbps-div1 = <0x5>; - xlnx,enet-slcr-10mbps-div0 = <0x8>; - xlnx,enet-slcr-10mbps-div1 = <0x32>; - xlnx,eth-mode = <0x1>; - xlnx,has-mdio = <0x1>; - xlnx,ptp-enet-clock = <111111115>; - mdio { - #address-cells = <1>; - #size-cells = <0>; - phy0: phy@7 { - compatible = "marvell,88e1510"; - device_type = "ethernet-phy"; - reg = <7>; - } ; - } ; - } ; - ps7_gpio_0: ps7-gpio@e000a000 { - #gpio-cells = <2>; - compatible = "xlnx,ps7-gpio-1.00.a"; - emio-gpio-width = <64>; - gpio-controller ; - gpio-mask-high = <0xc0000>; - gpio-mask-low = <0xfe81>; - interrupt-parent = <&ps7_scugic_0>; - interrupts = < 0 20 0 >; - reg = < 0xe000a000 0x1000 >; - } ; - ps7_iop_bus_config_0: ps7-iop-bus-config@e0200000 { - compatible = "xlnx,ps7-iop-bus-config-1.00.a"; - reg = < 0xe0200000 0x1000 >; - } ; - ps7_pl310_0: ps7-pl310@f8f02000 { - arm,data-latency = < 3 2 2 >; - arm,tag-latency = < 2 2 2 >; - cache-level = < 2 >; - cache-unified ; - compatible = "xlnx,ps7-pl310-1.00.a", "arm,pl310-cache"; - reg = < 0xf8f02000 0x1000 >; - } ; - ps7_qspi_0: ps7-qspi@e000d000 { - bus-num = <0>; - compatible = "xlnx,ps7-qspi-1.00.a"; - interrupt-parent = <&ps7_scugic_0>; - interrupts = < 0 19 0 >; - is-dual = <0>; - num-chip-select = <1>; - reg = < 0xe000d000 0x1000 >; - speed-hz = <200000000>; - xlnx,fb-clk = <0x1>; - xlnx,qspi-clk-freq-hz = <0xbebc200>; - xlnx,qspi-mode = <0x0>; - #address-cells = <1>; - #size-cells = <0>; - flash@0 { - compatible = "n25q128"; - reg = <0x0>; - spi-max-frequency = <50000000>; - #address-cells = <1>; - #size-cells = <1>; - partition@qspi-fsbl-uboot { - label = "qspi-fsbl-uboot"; - reg = <0x0 0x100000>; - }; - partition@qspi-linux { - label = "qspi-linux"; - reg = <0x100000 0x500000>; - }; - partition@qspi-device-tree { - label = "qspi-device-tree"; - reg = <0x600000 0x20000>; - }; - partition@qspi-rootfs { - label = "qspi-rootfs"; - reg = <0x620000 0x9D0000>; - }; - }; - } ; - ps7_qspi_linear_0: ps7-qspi-linear@fc000000 { - compatible = "xlnx,ps7-qspi-linear-1.00.a"; - reg = < 0xfc000000 0x1000000 >; - xlnx,qspi-clk-freq-hz = <0xe4e1c0>; - } ; - ps7_ram_0: ps7-ram@0 { - compatible = "xlnx,ps7-ram-1.00.a"; - reg = < 0x0 0x30000 >; - } ; - ps7_ram_1: ps7-ram@ffff0000 { - compatible = "xlnx,ps7-ram-1.00.a"; - reg = < 0xffff0000 0xfe00 >; - } ; - ps7_scugic_0: ps7-scugic@f8f01000 { - #address-cells = < 2 >; - #interrupt-cells = < 3 >; - #size-cells = < 1 >; - compatible = "xlnx,ps7-scugic-1.00.a", "arm,cortex-a9-gic", "arm,gic"; - interrupt-controller ; - linux,phandle = < 0x1 >; - phandle = < 0x1 >; - reg = < 0xf8f01000 0x1000 0xf8f00100 0x100 >; - } ; - ps7_scutimer_0: ps7-scutimer@f8f00600 { - clock-frequency = <333333343>; - compatible = "xlnx,ps7-scutimer-1.00.a", "arm,cortex-a9-twd-timer"; - interrupt-parent = <&ps7_scugic_0>; - interrupts = < 1 13 0 >; - reg = < 0xf8f00600 0x20 >; - } ; - ps7_scuwdt_0: ps7-scuwdt@f8f00620 { - clock-frequency = <333333343>; - compatible = "xlnx,ps7-scuwdt-1.00.a"; - device_type = "watchdog"; - interrupt-parent = <&ps7_scugic_0>; - interrupts = < 1 14 0 >; - reg = < 0xf8f00620 0xe0 >; - } ; - ps7_sd_0: ps7-sdio@e0100000 { - clock-frequency = <50000000>; - compatible = "xlnx,ps7-sdio-1.00.a", "generic-sdhci"; - interrupt-parent = <&ps7_scugic_0>; - interrupts = < 0 24 0 >; - reg = < 0xe0100000 0x1000 >; - xlnx,has-cd = <0x1>; - xlnx,has-power = <0x0>; - xlnx,has-wp = <0x1>; - xlnx,sdio-clk-freq-hz = <0x2faf080>; - } ; - ps7_slcr_0: ps7-slcr@f8000000 { - compatible = "xlnx,ps7-slcr-1.00.a"; - reg = < 0xf8000000 0x1000 >; - } ; - ps7_ttc_0: ps7-ttc@f8001000 { - clock-frequency = <111111115>; - clock-frequency-timer0 = <111111115>; - clock-frequency-timer1 = <111111115>; - clock-frequency-timer2 = <111111115>; - compatible = "xlnx,ps7-ttc-1.00.a"; - interrupt-parent = <&ps7_scugic_0>; - interrupts = < 0 10 0 0 11 0 0 12 0 >; - reg = < 0xf8001000 0x1000 >; - xlnx,ttc-clk0-clksrc = <0x0>; - xlnx,ttc-clk0-freq-hz = <0x69f6bcb>; - xlnx,ttc-clk1-clksrc = <0x0>; - xlnx,ttc-clk1-freq-hz = <0x69f6bcb>; - xlnx,ttc-clk2-clksrc = <0x0>; - xlnx,ttc-clk2-freq-hz = <0x69f6bcb>; - } ; - ps7_uart_1: serial@e0001000 { - clock = <50000000>; - clock-frequency = <50000000>; - compatible = "xlnx,ps7-uart-1.00.a", "xlnx,xuartps"; - current-speed = <115200>; - device_type = "serial"; - interrupt-parent = <&ps7_scugic_0>; - interrupts = < 0 50 0 >; - port-number = <0>; - reg = < 0xe0001000 0x1000 >; - xlnx,has-modem = <0x0>; - xlnx,uart-clk-freq-hz = <0x2faf080>; - } ; - ps7_usb_0: ps7-usb@e0002000 { - compatible = "xlnx,ps7-usb-1.00.a"; - dr_mode = "host"; - interrupt-parent = <&ps7_scugic_0>; - interrupts = < 0 21 0 >; - phy_type = "ulpi"; - reg = < 0xe0002000 0x1000 >; - xlnx,usb-reset = <0xffffffff>; - } ; - ps7_xadc: ps7_xadc@f8007100 { - compatible = "xlnx,ps7-xadc-1.00.a"; - interrupts = < 0 7 4 >; - reg = < 0xf8007100 0x20 >; - } ; - } ; -} ; diff --git a/arch/arm/configs/digilent_zed_defconfig b/arch/arm/configs/digilent_zed_defconfig new file mode 100755 index 0000000000000..846507d078f64 --- /dev/null +++ b/arch/arm/configs/digilent_zed_defconfig @@ -0,0 +1,2238 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm 3.6.0-digilent-13.01 Kernel Configuration +# +CONFIG_ARM=y +CONFIG_MIGHT_HAVE_PCI=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_ARCH_HAS_CPUFREQ=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_VECTORS_BASE=0xffff0000 +# CONFIG_ARM_PATCH_PHYS_VIRT is not set +CONFIG_PHYS_OFFSET=0x0 +CONFIG_GENERIC_BUG=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_HAVE_IRQ_WORK=y +CONFIG_IRQ_WORK=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_XZ is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_DEFAULT_HOSTNAME="(none)" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_FHANDLE is not set +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +# CONFIG_AUDIT is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_IRQ_DOMAIN=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set +CONFIG_KTIME_SCALAR=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +# CONFIG_NO_HZ is not set +CONFIG_HIGH_RES_TIMERS=y + +# +# RCU Subsystem +# +CONFIG_TREE_PREEMPT_RCU=y +CONFIG_PREEMPT_RCU=y +CONFIG_RCU_FANOUT=32 +CONFIG_RCU_FANOUT_LEAF=16 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_RCU_BOOST is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_CHECKPOINT_RESTORE is not set +# CONFIG_NAMESPACES is not set +# CONFIG_SCHED_AUTOGROUP is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EXPERT=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +# CONFIG_JUMP_LABEL is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_BSGLIB is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_UNINLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y +# CONFIG_FREEZER is not set + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_SOCFPGA is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_HIGHBANK is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CNS3XXX is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_PRIMA2 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_MXS is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_MVEBU is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LPC32XX is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_PICOXCELL is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C24XX is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P64X0 is not set +# CONFIG_ARCH_S5PC100 is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_PLAT_SPEAR is not set +# CONFIG_ARCH_VT8500 is not set +CONFIG_ARCH_ZYNQ=y +# CONFIG_GPIO_PCA953X is not set +# CONFIG_KEYBOARD_GPIO_POLLED is not set + +# +# Xilinx Specific Options +# +CONFIG_ZYNQ_EARLY_UART1=y +# CONFIG_ZYNQ_EARLY_UART_EP107 is not set +CONFIG_XILINX_FIXED_DEVTREE_ADDR=y +CONFIG_XILINX_L1_PREFETCH=y +CONFIG_XILINX_L2_PREFETCH=y +CONFIG_XILINX_ZED=y +# CONFIG_XILINX_TEST is not set +# CONFIG_XILINX_AXIPCIE is not set + +# +# Processor Type +# +CONFIG_CPU_V7=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +# CONFIG_ARM_LPAE is not set +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +CONFIG_ARM_THUMB=y +# CONFIG_ARM_THUMBEE is not set +CONFIG_SWP_EMULATE=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_OUTER_CACHE=y +CONFIG_OUTER_CACHE_SYNC=y +CONFIG_CACHE_L2X0=y +CONFIG_CACHE_PL310=y +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_DMA_MEM_BUFFERABLE=y +CONFIG_ARM_NR_BANKS=8 +CONFIG_CPU_HAS_PMU=y +CONFIG_MULTI_IRQ_HANDLER=y +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_458693 is not set +# CONFIG_ARM_ERRATA_460075 is not set +# CONFIG_ARM_ERRATA_742230 is not set +# CONFIG_ARM_ERRATA_742231 is not set +# CONFIG_PL310_ERRATA_588369 is not set +# CONFIG_ARM_ERRATA_720789 is not set +# CONFIG_PL310_ERRATA_727915 is not set +# CONFIG_ARM_ERRATA_743622 is not set +# CONFIG_ARM_ERRATA_751472 is not set +# CONFIG_PL310_ERRATA_753970 is not set +# CONFIG_ARM_ERRATA_754322 is not set +# CONFIG_ARM_ERRATA_754327 is not set +# CONFIG_ARM_ERRATA_764369 is not set +# CONFIG_PL310_ERRATA_769419 is not set +CONFIG_ARM_GIC=y +CONFIG_ICST=y + +# +# Bus support +# +CONFIG_ARM_AMBA=y +CONFIG_ISA_DMA_API=y +# CONFIG_PCI is not set +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_HAVE_SMP=y +CONFIG_SMP=y +CONFIG_SMP_ON_UP=y +CONFIG_ARM_CPU_TOPOLOGY=y +# CONFIG_SCHED_MC is not set +# CONFIG_SCHED_SMT is not set +CONFIG_HAVE_ARM_SCU=y +# CONFIG_ARM_ARCH_TIMER is not set +CONFIG_HAVE_ARM_TWD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_NR_CPUS=4 +CONFIG_HOTPLUG_CPU=y +CONFIG_LOCAL_TIMERS=y +CONFIG_ARCH_NR_GPIO=0 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +CONFIG_HZ=100 +# CONFIG_THUMB2_KERNEL is not set +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HIGHMEM=y +# CONFIG_HIGHPTE is not set +CONFIG_HW_PERF_EVENTS=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_COMPACTION is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_CROSS_MEMORY_ATTACH=y +# CONFIG_CLEANCACHE is not set +# CONFIG_FRONTSWAP is not set +CONFIG_FORCE_MAX_ZONEORDER=15 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set +# CONFIG_SECCOMP is not set +# CONFIG_CC_STACKPROTECTOR is not set +# CONFIG_DEPRECATED_PARAM_STRUCT is not set + +# +# Boot options +# +CONFIG_USE_OF=y +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +# CONFIG_ARM_APPENDED_DTB is not set +CONFIG_CMDLINE="console=ttyPS0,115200n8 root=/dev/ram rw initrd=0x00800000,16M earlyprintk mtdparts=physmap-flash.0:512K(nor-fsbl),512K(nor-u-boot),5M(nor-linux),9M(nor-user),1M(nor-scratch),-(nor-rootfs)" +CONFIG_CMDLINE_FROM_BOOTLOADER=y +# CONFIG_CMDLINE_EXTEND is not set +# CONFIG_CMDLINE_FORCE is not set +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set +# CONFIG_CRASH_DUMP is not set +# CONFIG_AUTO_ZRELADDR is not set + +# +# CPU Power Management +# + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set +# CONFIG_CPU_IDLE is not set +# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_SUSPEND is not set +CONFIG_PM_RUNTIME=y +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +# CONFIG_APM_EMULATION is not set +CONFIG_ARCH_HAS_OPP=y +# CONFIG_PM_OPP is not set +CONFIG_PM_CLK=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# CONFIG_ARM_CPU_SUSPEND is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +# CONFIG_NET_IPGRE_DEMUX is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_NET_IPVTI is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_INET_UDP_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_XPS=y +CONFIG_BQL=y +# CONFIG_BPF_JIT is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set +CONFIG_HAVE_BPF_JIT=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_GENERIC_CPU_DEVICES is not set +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=y +CONFIG_DMA_SHARED_BUFFER=y +# CONFIG_CMA is not set +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +CONFIG_MTD=y +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_SM_FTL is not set +# CONFIG_MTD_OOPS is not set +# CONFIG_MTD_SWAP is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +CONFIG_MTD_PHYSMAP_OF=y +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_DOCG3 is not set +CONFIG_MTD_NAND_ECC=y +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_BCH is not set +# CONFIG_MTD_SM_COMMON is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_DOCG4 is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_NAND_XILINX_PS is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set +# CONFIG_MTD_UBI is not set +CONFIG_DTC=y +CONFIG_OF=y + +# +# Device Tree and Open Firmware support +# +CONFIG_PROC_DEVICETREE=y +# CONFIG_OF_SELFTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_IRQ=y +CONFIG_OF_DEVICE=y +CONFIG_OF_I2C=y +CONFIG_OF_NET=y +CONFIG_OF_MDIO=y +CONFIG_OF_MTD=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=35384 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +# CONFIG_VIRTIO_BLK is not set +# CONFIG_BLK_DEV_RBD is not set + +# +# Misc devices +# +# CONFIG_SENSORS_LIS3LV02D is not set +# CONFIG_AD525X_DPOT is not set +# CONFIG_ATMEL_PWM is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_BMP085_I2C is not set +# CONFIG_BMP085_SPI is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_SI570 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=y +CONFIG_EEPROM_AT25=y +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_EEPROM_93XX46 is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set +# CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LIS3_I2C is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_ISCSI_BOOT_SYSFS is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_VIRTIO is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_TARGET_CORE is not set +CONFIG_NETDEVICES=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +# CONFIG_DUMMY is not set +# CONFIG_EQUALIZER is not set +# CONFIG_MII is not set +# CONFIG_NET_TEAM is not set +# CONFIG_MACVLAN is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_VIRTIO_NET is not set + +# +# CAIF transport drivers +# +CONFIG_ETHERNET=y +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_CALXEDA_XGMAC is not set +# CONFIG_NET_VENDOR_CHELSIO is not set +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_DM9000 is not set +# CONFIG_DNET is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_ETHOC is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_NET_VENDOR_XILINX=y +# CONFIG_XILINX_EMACLITE is not set +# CONFIG_XILINX_AXI_EMAC is not set +# CONFIG_XILINX_LLTEMAC_MARVELL_88E1111_RGMII is not set +CONFIG_XILINX_LLTEMAC_MARVELL_88E1111_GMII=y +# CONFIG_XILINX_LLTEMAC_MARVELL_88E1111_MII is not set +# CONFIG_XILINX_LLTEMAC_XILINX_1000BASEX is not set +CONFIG_XILINX_PS_EMAC=y +CONFIG_XILINX_PS_EMAC_HWTSTAMP=y +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_AMD_PHY is not set +CONFIG_MARVELL_PHY=y +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BCM87XX_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +CONFIG_MDIO_BITBANG=y +# CONFIG_MDIO_GPIO is not set +# CONFIG_MDIO_BUS_MUX_GPIO is not set +# CONFIG_MICREL_KS8995MA is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_WLAN is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +CONFIG_INPUT_SPARSEKMAP=y +# CONFIG_INPUT_MATRIXKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_LM8333 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_OMAP4 is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_SENTELIC is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_GPIO is not set +# CONFIG_MOUSE_SYNAPTICS_I2C is not set +# CONFIG_MOUSE_SYNAPTICS_USB is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +# CONFIG_DEVKMEM is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX3107 is not set +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +CONFIG_SERIAL_XILINX_PS_UART=y +CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +# CONFIG_TTY_PRINTK is not set +# CONFIG_HVC_DCC is not set +# CONFIG_VIRTIO_CONSOLE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +CONFIG_XILINX_DEVCFG=y +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +# CONFIG_I2C_CHARDEV is not set +CONFIG_I2C_MUX=y + +# +# Multiplexer I2C Chip support +# +# CONFIG_I2C_MUX_GPIO is not set +# CONFIG_I2C_MUX_PCA9541 is not set +# CONFIG_I2C_MUX_PCA954x is not set +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +CONFIG_I2C_GPIO=y +# CONFIG_I2C_NOMADIK is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +# CONFIG_I2C_SIMTEC is not set +CONFIG_I2C_XILINX_PS=y +CONFIG_I2C_XILINX=y + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +CONFIG_SPI_BITBANG=y +CONFIG_SPI_GPIO=y +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PL022 is not set +# CONFIG_SPI_PXA2XX_PCI is not set +# CONFIG_SPI_XCOMM is not set +# CONFIG_SPI_AD9250FMC is not set +# CONFIG_SPI_XILINX is not set +CONFIG_SPI_XILINX_PS_QSPI=y +CONFIG_SPI_XILINX_PS_SPI=y +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_HSI is not set + +# +# PPS support +# +# CONFIG_PPS is not set + +# +# PPS generators support +# + +# +# PTP clock support +# + +# +# Enable Device Drivers -> PPS to see the PTP clock options. +# +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_OF_GPIO=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO drivers: +# +# CONFIG_GPIO_GENERIC_PLATFORM is not set +# CONFIG_GPIO_EM is not set +# CONFIG_GPIO_PL061 is not set +# CONFIG_GPIO_XILINX is not set +CONFIG_GPIO_XILINX_PS=y + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_SX150X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_74X164 is not set + +# +# AC97 GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_POWER_AVS is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_CORE=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_ARM_SP805_WATCHDOG is not set +# CONFIG_DW_WATCHDOG is not set +# CONFIG_MPCORE_WATCHDOG is not set +CONFIG_XILINX_PS_WATCHDOG=y +# CONFIG_MAX63XX_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_88PM800 is not set +# CONFIG_MFD_88PM805 is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_MFD_LM3533 is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_STMPE is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX77686 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_SEC_CORE is not set +# CONFIG_MFD_ARIZONA_I2C is not set +# CONFIG_MFD_ARIZONA_SPI is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_REGULATOR is not set +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +# CONFIG_MEDIA_CAMERA_SUPPORT is not set +# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set +# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set +# CONFIG_MEDIA_RADIO_SUPPORT is not set +# CONFIG_MEDIA_RC_SUPPORT is not set + +# +# Media drivers +# + +# +# Graphics support +# +CONFIG_DRM=y +CONFIG_DRM_KMS_HELPER=y +# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set +CONFIG_DRM_GEM_CMA_HELPER=y +CONFIG_DRM_KMS_CMA_HELPER=y + +# +# I2C encoder or helper chips +# +# CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_SIL164 is not set +CONFIG_DRM_ENCODER_ADV7511=y +CONFIG_DRM_ANALOG=y +# CONFIG_DRM_UDL is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_WMT_GE_ROPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_ARMCLCD is not set +# CONFIG_FB_UVESA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_XILINX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_AUO_K190X is not set +# CONFIG_FB_XYLON is not set +# CONFIG_EXYNOS_VIDEO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_JACK=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +# CONFIG_SND_SUPPORT_OLD_API is not set +# CONFIG_SND_VERBOSE_PROCFS is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +# CONFIG_SND_DRIVERS is not set +# CONFIG_SND_ARM is not set +# CONFIG_SND_SPI is not set +# CONFIG_SND_USB is not set +CONFIG_SND_SOC=y +CONFIG_SND_SOC_DMAENGINE_PCM=y +# CONFIG_SND_DESIGNWARE_I2S is not set +CONFIG_SND_SOC_XILINX=y +CONFIG_SND_SOC_AXI_SPDIF=y +CONFIG_SND_SOC_ADV7511_HDMI=y +# CONFIG_SND_SOC_ZED_ADAU1761 is not set +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +# CONFIG_SND_SIMPLE_CARD is not set +# CONFIG_SOUND_PRIME is not set + +# +# HID support +# +CONFIG_HID=y +# CONFIG_HIDRAW is not set +# CONFIG_UHID is not set +CONFIG_HID_GENERIC=y + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_ACRUX is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_AUREAL is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_PRODIKEYS is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EMS_FF is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_HOLTEK is not set +# CONFIG_HID_KEYTOUCH is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_WALTOP is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LCPOWER is not set +# CONFIG_HID_LENOVO_TPKBD is not set +# CONFIG_HID_LOGITECH is not set +CONFIG_HID_MICROSOFT=y +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_MULTITOUCH is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_PRIMAX is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_SAITEK is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SPEEDLINK is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TIVO is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set + +# +# USB HID support +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +CONFIG_USB_ARCH_HAS_EHCI=y +# CONFIG_USB_ARCH_HAS_XHCI is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y +CONFIG_USB_OTG=y +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_DWC3 is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +CONFIG_USB_XUSBPS_DR_OF=y +CONFIG_USB_EHCI_XUSBPS=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_EHCI_HCD_PLATFORM is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_CHIPIDEA is not set +# CONFIG_USB_RENESAS_USBHS is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_REALTEK is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +# CONFIG_USB_UAS is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set + +# +# USB Physical Layer drivers +# +# CONFIG_USB_ISP1301 is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 + +# +# USB Peripheral Controller +# +CONFIG_USB_GADGET_XUSBPS=y +# CONFIG_XUSBPS_ERRATA_DT654401 is not set +CONFIG_USB_XUSBPS=y +# CONFIG_USB_FUSB300 is not set +# CONFIG_USB_R8A66597 is not set +# CONFIG_USB_MV_UDC is not set +# CONFIG_USB_M66592 is not set +# CONFIG_USB_NET2272 is not set +# CONFIG_USB_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_ZERO=m +# CONFIG_USB_ZERO_HNPTEST is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_G_NCM is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FUNCTIONFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_ACM_MS is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_DBGP is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +# CONFIG_USB_GPIO_VBUS is not set +CONFIG_USB_ULPI=y +CONFIG_USB_ULPI_VIEWPORT=y +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_USB_XUSBPS_OTG=y +CONFIG_XILINX_ZED_USB_OTG=y +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set +# CONFIG_MMC_CLKGATE is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=8 +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_ARMMMCI is not set +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_XILINX_PS=y +# CONFIG_MMC_SDHCI_PXAV3 is not set +# CONFIG_MMC_SDHCI_PXAV2 is not set +# CONFIG_MMC_WBSD is not set +# CONFIG_MMC_DW is not set +# CONFIG_MMC_VUB300 is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_PCA9633 is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_RENESAS_TPU is not set +# CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_LM3556 is not set +# CONFIG_LEDS_OT200 is not set +# CONFIG_LEDS_BLINKM is not set +CONFIG_LEDS_TRIGGERS=y + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGER_TIMER=y +# CONFIG_LEDS_TRIGGER_ONESHOT is not set +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_GPIO=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_LEDS_TRIGGER_TRANSIENT is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_EDAC is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_XILINX_DMA=y +# CONFIG_AMBA_PL08X is not set +# CONFIG_DW_DMAC is not set +# CONFIG_TIMB_DMA is not set +CONFIG_PL330_DMA=y +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +CONFIG_VIRTIO=m +CONFIG_VIRTIO_RING=m + +# +# Virtio drivers +# +# CONFIG_VIRTIO_BALLOON is not set +# CONFIG_VIRTIO_MMIO is not set + +# +# Microsoft Hyper-V guest support +# +# CONFIG_STAGING is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y + +# +# Common Clock Framework +# +# CONFIG_COMMON_CLK_DEBUG is not set + +# +# Hardware Spinlock drivers +# +# CONFIG_IOMMU_SUPPORT is not set + +# +# Remoteproc drivers (EXPERIMENTAL) +# +CONFIG_REMOTEPROC=m +CONFIG_ZYNQ_REMOTEPROC=m +CONFIG_MB_REMOTEPROC=m + +# +# Rpmsg drivers (EXPERIMENTAL) +# +CONFIG_RPMSG=m +# CONFIG_RPMSG_SERVER_SAMPLE is not set +# CONFIG_RPMSG_OMX is not set +# CONFIG_RPMSG_FREERTOS_STAT is not set +# CONFIG_VIRT_DRIVERS is not set +# CONFIG_PM_DEVFREQ is not set +# CONFIG_EXTCON is not set +# CONFIG_MEMORY is not set +# CONFIG_IIO is not set +# CONFIG_PWM is not set +CONFIG_PMODS=y +# CONFIG_PMODS_DEBUG is not set +CONFIG_PMODOLED=y +# CONFIG_PMODCLS is not set +# CONFIG_PMODCLP is not set +# CONFIG_PMODDA1 is not set +# CONFIG_PMODAD1 is not set + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT23=y +CONFIG_EXT4_FS_XATTR=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +# CONFIG_EXT4_FS_SECURITY is not set +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +# CONFIG_FS_POSIX_ACL is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_PSTORE is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_MAC_ROMAN is not set +# CONFIG_NLS_MAC_CELTIC is not set +# CONFIG_NLS_MAC_CENTEURO is not set +# CONFIG_NLS_MAC_CROATIAN is not set +# CONFIG_NLS_MAC_CYRILLIC is not set +# CONFIG_NLS_MAC_GAELIC is not set +# CONFIG_NLS_MAC_GREEK is not set +# CONFIG_NLS_MAC_ICELAND is not set +# CONFIG_NLS_MAC_INUIT is not set +# CONFIG_NLS_MAC_ROMANIAN is not set +# CONFIG_NLS_MAC_TURKISH is not set +# CONFIG_NLS_UTF8 is not set + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_LOCKUP_DETECTOR is not set +# CONFIG_HARDLOCKUP_DETECTOR is not set +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +# CONFIG_RCU_CPU_STALL_VERBOSE is not set +# CONFIG_RCU_CPU_STALL_INFO is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_LKDTM is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_TEST_KSTRTOX is not set +# CONFIG_STRICT_DEVMEM is not set +CONFIG_ARM_UNWIND=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_LL is not set +# CONFIG_OC_ETM is not set +# CONFIG_PID_IN_CONTEXTIDR is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=m +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set +# CONFIG_CRYPTO_USER is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_PCRYPT is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=m +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IO=y +# CONFIG_CRC_CCITT is not set +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +# CONFIG_CRC8 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +# CONFIG_XZ_DEC is not set +# CONFIG_XZ_DEC_BCJ is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y +# CONFIG_AVERAGE is not set +# CONFIG_CORDIC is not set +# CONFIG_DDR is not set diff --git a/arch/arm/configs/zed_adv7511_config b/arch/arm/configs/zed_adv7511_config new file mode 100644 index 0000000000000..c1eebd4a76b91 --- /dev/null +++ b/arch/arm/configs/zed_adv7511_config @@ -0,0 +1,2233 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm 3.3.0 Kernel Configuration +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +# CONFIG_ARCH_USES_GETTIMEOFFSET is not set +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_KTIME_SCALAR=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_LOCKBREAK=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_VECTORS_BASE=0xffff0000 +# CONFIG_ARM_PATCH_PHYS_VIRT is not set +CONFIG_PHYS_OFFSET=0x0 +CONFIG_GENERIC_BUG=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_HAVE_IRQ_WORK=y +CONFIG_IRQ_WORK=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_DEFAULT_HOSTNAME="(none)" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_FHANDLE is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_HAVE_SPARSE_IRQ=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_IRQ_DOMAIN=y +# CONFIG_SPARSE_IRQ is not set + +# +# RCU Subsystem +# +CONFIG_TREE_PREEMPT_RCU=y +CONFIG_PREEMPT_RCU=y +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_RCU_BOOST is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_CHECKPOINT_RESTORE is not set +# CONFIG_NAMESPACES is not set +# CONFIG_SCHED_AUTOGROUP is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EXPERT=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_BSGLIB is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +# CONFIG_FREEZER is not set + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_HIGHBANK is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CNS3XXX is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_PRIMA2 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_MXS is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LPC32XX is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_PICOXCELL is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P64X0 is not set +# CONFIG_ARCH_S5PC100 is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_PLAT_SPEAR is not set +# CONFIG_ARCH_VT8500 is not set +CONFIG_ARCH_ZYNQ=y +# CONFIG_GPIO_PCA953X is not set +# CONFIG_KEYBOARD_GPIO_POLLED is not set + +# +# System MMU +# + +# +# Xilinx Specific Options +# +CONFIG_ZYNQ_EARLY_UART1=y +# CONFIG_ZYNQ_EARLY_UART_EP107 is not set +CONFIG_XILINX_FIXED_DEVTREE_ADDR=y +CONFIG_XILINX_L1_PREFETCH=y +CONFIG_XILINX_L2_PREFETCH=y +CONFIG_XILINX_ZED=y +# CONFIG_XILINX_TEST is not set +CONFIG_ZYNQ_DEFAULT_KERNEL=y +# CONFIG_ZYNQ_AMP_CPU0_MASTER is not set +# CONFIG_ZYNQ_AMP_CPU1_SLAVE is not set +# CONFIG_ZYNQ_CPU1_TEST is not set + +# +# Processor Type +# +CONFIG_CPU_V7=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +# CONFIG_ARM_LPAE is not set +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +CONFIG_ARM_THUMB=y +# CONFIG_ARM_THUMBEE is not set +CONFIG_SWP_EMULATE=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_OUTER_CACHE=y +CONFIG_OUTER_CACHE_SYNC=y +CONFIG_CACHE_L2X0=y +CONFIG_CACHE_PL310=y +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_DMA_MEM_BUFFERABLE=y +CONFIG_ARM_NR_BANKS=8 +CONFIG_CPU_HAS_PMU=y +CONFIG_MULTI_IRQ_HANDLER=y +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_458693 is not set +# CONFIG_ARM_ERRATA_460075 is not set +# CONFIG_ARM_ERRATA_742230 is not set +# CONFIG_ARM_ERRATA_742231 is not set +# CONFIG_PL310_ERRATA_588369 is not set +# CONFIG_ARM_ERRATA_720789 is not set +# CONFIG_PL310_ERRATA_727915 is not set +# CONFIG_ARM_ERRATA_743622 is not set +# CONFIG_ARM_ERRATA_751472 is not set +# CONFIG_PL310_ERRATA_753970 is not set +# CONFIG_ARM_ERRATA_754322 is not set +# CONFIG_ARM_ERRATA_754327 is not set +# CONFIG_ARM_ERRATA_764369 is not set +# CONFIG_PL310_ERRATA_769419 is not set +CONFIG_ARM_GIC=y +CONFIG_ICST=y + +# +# Bus support +# +CONFIG_ARM_AMBA=y +CONFIG_ISA_DMA_API=y +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +# CONFIG_NO_HZ is not set +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_HAVE_SMP=y +CONFIG_SMP=y +CONFIG_SMP_ON_UP=y +CONFIG_ARM_CPU_TOPOLOGY=y +# CONFIG_SCHED_MC is not set +# CONFIG_SCHED_SMT is not set +CONFIG_HAVE_ARM_SCU=y +CONFIG_HAVE_ARM_TWD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_NR_CPUS=4 +# CONFIG_HOTPLUG_CPU is not set +CONFIG_LOCAL_TIMERS=y +CONFIG_ARCH_NR_GPIO=0 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +CONFIG_HZ=100 +# CONFIG_THUMB2_KERNEL is not set +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HIGHMEM=y +# CONFIG_HIGHPTE is not set +CONFIG_HW_PERF_EVENTS=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=999999 +# CONFIG_COMPACTION is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_CLEANCACHE is not set +CONFIG_FORCE_MAX_ZONEORDER=15 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set +# CONFIG_SECCOMP is not set +# CONFIG_CC_STACKPROTECTOR is not set +# CONFIG_DEPRECATED_PARAM_STRUCT is not set + +# +# Boot options +# +CONFIG_USE_OF=y +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +# CONFIG_ARM_APPENDED_DTB is not set +CONFIG_CMDLINE="console=ttyPS0,115200n8 root=/dev/ram rw initrd=0x00800000,16M earlyprintk mtdparts=physmap-flash.0:512K(nor-fsbl),512K(nor-u-boot),5M(nor-linux),9M(nor-user),1M(nor-scratch),-(nor-rootfs)" +CONFIG_CMDLINE_FROM_BOOTLOADER=y +# CONFIG_CMDLINE_EXTEND is not set +# CONFIG_CMDLINE_FORCE is not set +# CONFIG_XIP_KERNEL is not set +# CONFIG_CRASH_DUMP is not set +# CONFIG_AUTO_ZRELADDR is not set + +# +# CPU Power Management +# +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_SUSPEND is not set +CONFIG_PM_RUNTIME=y +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +# CONFIG_APM_EMULATION is not set +CONFIG_PM_CLK=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# CONFIG_ARM_CPU_SUSPEND is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +# CONFIG_NET_IPGRE_DEMUX is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_INET_UDP_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_XPS=y +CONFIG_BQL=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_GENERIC_CPU_DEVICES is not set +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=y +# CONFIG_DMA_SHARED_BUFFER is not set +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +CONFIG_MTD=y +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_SM_FTL is not set +# CONFIG_MTD_OOPS is not set +# CONFIG_MTD_SWAP is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +CONFIG_MTD_PHYSMAP_OF=y +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +CONFIG_MTD_M25P80=y +# CONFIG_M25PXX_USE_FAST_READ is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_DOCG3 is not set +CONFIG_MTD_NAND_ECC=y +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_BCH is not set +# CONFIG_MTD_SM_COMMON is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +CONFIG_MTD_NAND_XILINX_PSS=y +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set +# CONFIG_MTD_UBI is not set +CONFIG_DTC=y +CONFIG_OF=y + +# +# Device Tree and Open Firmware support +# +CONFIG_PROC_DEVICETREE=y +# CONFIG_OF_SELFTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_IRQ=y +CONFIG_OF_DEVICE=y +CONFIG_OF_GPIO=y +CONFIG_OF_I2C=y +CONFIG_OF_NET=y +CONFIG_OF_SPI=y +CONFIG_OF_MDIO=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=35384 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +# CONFIG_BLK_DEV_RBD is not set + +# +# Misc devices +# +# CONFIG_SENSORS_LIS3LV02D is not set +# CONFIG_AD525X_DPOT is not set +# CONFIG_ATMEL_PWM is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_BMP085 is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_SI570 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=y +CONFIG_EEPROM_AT25=y +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_EEPROM_93XX46 is not set +# CONFIG_IWMC3200TOP is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set +# CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LIS3_I2C is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_ISCSI_BOOT_SYSFS is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_TARGET_CORE is not set +CONFIG_NETDEVICES=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +# CONFIG_DUMMY is not set +# CONFIG_EQUALIZER is not set +# CONFIG_MII is not set +# CONFIG_NET_TEAM is not set +# CONFIG_MACVLAN is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set + +# +# CAIF transport drivers +# +CONFIG_ETHERNET=y +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_CALXEDA_XGMAC is not set +# CONFIG_NET_VENDOR_CHELSIO is not set +# CONFIG_DM9000 is not set +# CONFIG_DNET is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_ETHOC is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +CONFIG_NET_VENDOR_XILINX=y +CONFIG_XILINX_PS_EMAC=y +CONFIG_XILINX_PS_EMAC_HWTSTAMP=y +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +CONFIG_MARVELL_PHY=y +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +CONFIG_MDIO_BITBANG=y +# CONFIG_MDIO_GPIO is not set +# CONFIG_MICREL_KS8995MA is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_WLAN is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +CONFIG_INPUT_SPARSEKMAP=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_SENTELIC is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_GPIO is not set +# CONFIG_MOUSE_SYNAPTICS_I2C is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +# CONFIG_DEVKMEM is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX3107 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +CONFIG_SERIAL_XILINX_PS_UART=y +CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +# CONFIG_TTY_PRINTK is not set +# CONFIG_HVC_DCC is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +CONFIG_XILINX_DEVCFG=y +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_RAMOOPS is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +# CONFIG_I2C_CHARDEV is not set +CONFIG_I2C_MUX=y + +# +# Multiplexer I2C Chip support +# +# CONFIG_I2C_MUX_GPIO is not set +# CONFIG_I2C_MUX_PCA9541 is not set +CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +CONFIG_I2C_GPIO=y +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX_PS is not set +CONFIG_I2C_XILINX=y + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PL022 is not set +# CONFIG_SPI_PXA2XX_PCI is not set +# CONFIG_SPI_XILINX is not set +CONFIG_SPI_XILINX_PS_QSPI=y +# CONFIG_XILINX_PS_QSPI_USE_DUAL_FLASH is not set +CONFIG_SPI_XILINX_PS_SPI=y +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set + +# +# PPS generators support +# + +# +# PTP clock support +# + +# +# Enable Device Drivers -> PPS to see the PTP clock options. +# +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO drivers: +# +# CONFIG_GPIO_GENERIC_PLATFORM is not set +# CONFIG_GPIO_PL061 is not set +# CONFIG_GPIO_XILINX is not set +CONFIG_GPIO_XILINX_PS=y + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_SX150X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_74X164 is not set + +# +# AC97 GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_CORE is not set +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_ARM_SP805_WATCHDOG is not set +# CONFIG_DW_WATCHDOG is not set +# CONFIG_MPCORE_WATCHDOG is not set +# CONFIG_XILINX_PS_WATCHDOG is not set +# CONFIG_XILINX_SCU_WATCHDOG is not set +# CONFIG_MAX63XX_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_STMPE is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_S5M_CORE is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13XXX is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_REGULATOR is not set +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +# CONFIG_MEDIA_CONTROLLER is not set +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +# CONFIG_RC_CORE is not set +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=y +# CONFIG_MEDIA_TUNER_CUSTOMISE is not set +CONFIG_MEDIA_TUNER_SIMPLE=y +CONFIG_MEDIA_TUNER_TDA8290=y +CONFIG_MEDIA_TUNER_TDA827X=y +CONFIG_MEDIA_TUNER_TDA18271=y +CONFIG_MEDIA_TUNER_TDA9887=y +CONFIG_MEDIA_TUNER_TEA5761=y +CONFIG_MEDIA_TUNER_TEA5767=y +CONFIG_MEDIA_TUNER_MT20XX=y +CONFIG_MEDIA_TUNER_XC2028=y +CONFIG_MEDIA_TUNER_XC5000=y +CONFIG_MEDIA_TUNER_XC4000=y +CONFIG_MEDIA_TUNER_MC44S803=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEOBUF2_CORE=y +CONFIG_VIDEOBUF2_MEMOPS=y +CONFIG_VIDEOBUF2_VMALLOC=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set + +# +# Encoders, decoders, sensors and other helper chips +# + +# +# Audio decoders, processors and mixers +# +# CONFIG_VIDEO_TVAUDIO is not set +# CONFIG_VIDEO_TDA7432 is not set +# CONFIG_VIDEO_TDA9840 is not set +# CONFIG_VIDEO_TEA6415C is not set +# CONFIG_VIDEO_TEA6420 is not set +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_CS5345 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_TLV320AIC23B is not set +# CONFIG_VIDEO_WM8775 is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_VP27SMPX is not set + +# +# RDS decoders +# +# CONFIG_VIDEO_SAA6588 is not set + +# +# Video decoders +# +# CONFIG_VIDEO_ADV7180 is not set +# CONFIG_VIDEO_BT819 is not set +# CONFIG_VIDEO_BT856 is not set +# CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_KS0127 is not set +# CONFIG_VIDEO_SAA7110 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_SAA7191 is not set +# CONFIG_VIDEO_TVP514X is not set +# CONFIG_VIDEO_TVP5150 is not set +# CONFIG_VIDEO_TVP7002 is not set +# CONFIG_VIDEO_VPX3220 is not set + +# +# Video and audio decoders +# +# CONFIG_VIDEO_SAA717X is not set +# CONFIG_VIDEO_CX25840 is not set + +# +# MPEG video encoders +# +# CONFIG_VIDEO_CX2341X is not set + +# +# Video encoders +# +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_SAA7185 is not set +# CONFIG_VIDEO_ADV7170 is not set +# CONFIG_VIDEO_ADV7175 is not set +# CONFIG_VIDEO_ADV7343 is not set +# CONFIG_VIDEO_AK881X is not set + +# +# Camera sensor devices +# +# CONFIG_VIDEO_OV7670 is not set +# CONFIG_VIDEO_MT9V011 is not set +# CONFIG_VIDEO_TCM825X is not set +# CONFIG_VIDEO_SR030PC30 is not set + +# +# Flash devices +# + +# +# Video improvement chips +# +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set + +# +# Miscelaneous helper chips +# +# CONFIG_VIDEO_THS7303 is not set +# CONFIG_VIDEO_M52790 is not set +# CONFIG_VIDEO_VIVI is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_USB_VIDEO_CLASS=y +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=y +# CONFIG_USB_M5602 is not set +# CONFIG_USB_STV06XX is not set +# CONFIG_USB_GL860 is not set +# CONFIG_USB_GSPCA_BENQ is not set +# CONFIG_USB_GSPCA_CONEX is not set +# CONFIG_USB_GSPCA_CPIA1 is not set +# CONFIG_USB_GSPCA_ETOMS is not set +# CONFIG_USB_GSPCA_FINEPIX is not set +# CONFIG_USB_GSPCA_JEILINJ is not set +# CONFIG_USB_GSPCA_JL2005BCD is not set +# CONFIG_USB_GSPCA_KINECT is not set +# CONFIG_USB_GSPCA_KONICA is not set +# CONFIG_USB_GSPCA_MARS is not set +# CONFIG_USB_GSPCA_MR97310A is not set +# CONFIG_USB_GSPCA_NW80X is not set +# CONFIG_USB_GSPCA_OV519 is not set +# CONFIG_USB_GSPCA_OV534 is not set +# CONFIG_USB_GSPCA_OV534_9 is not set +# CONFIG_USB_GSPCA_PAC207 is not set +# CONFIG_USB_GSPCA_PAC7302 is not set +# CONFIG_USB_GSPCA_PAC7311 is not set +# CONFIG_USB_GSPCA_SE401 is not set +# CONFIG_USB_GSPCA_SN9C2028 is not set +# CONFIG_USB_GSPCA_SN9C20X is not set +# CONFIG_USB_GSPCA_SONIXB is not set +# CONFIG_USB_GSPCA_SONIXJ is not set +# CONFIG_USB_GSPCA_SPCA500 is not set +# CONFIG_USB_GSPCA_SPCA501 is not set +# CONFIG_USB_GSPCA_SPCA505 is not set +# CONFIG_USB_GSPCA_SPCA506 is not set +# CONFIG_USB_GSPCA_SPCA508 is not set +# CONFIG_USB_GSPCA_SPCA561 is not set +# CONFIG_USB_GSPCA_SPCA1528 is not set +# CONFIG_USB_GSPCA_SQ905 is not set +# CONFIG_USB_GSPCA_SQ905C is not set +# CONFIG_USB_GSPCA_SQ930X is not set +# CONFIG_USB_GSPCA_STK014 is not set +# CONFIG_USB_GSPCA_STV0680 is not set +# CONFIG_USB_GSPCA_SUNPLUS is not set +# CONFIG_USB_GSPCA_T613 is not set +# CONFIG_USB_GSPCA_TOPRO is not set +# CONFIG_USB_GSPCA_TV8532 is not set +# CONFIG_USB_GSPCA_VC032X is not set +# CONFIG_USB_GSPCA_VICAM is not set +# CONFIG_USB_GSPCA_XIRLINK_CIT is not set +# CONFIG_USB_GSPCA_ZC3XX is not set +# CONFIG_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_HDPVR is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_USBVISION is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_PWC is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +# CONFIG_V4L_PLATFORM_DRIVERS is not set +# CONFIG_V4L_MEM2MEM_DRIVERS is not set +# CONFIG_RADIO_ADAPTERS is not set + +# +# Graphics support +# +CONFIG_DRM=y +CONFIG_DRM_KMS_HELPER=y +CONFIG_DRM_ENCODER_ADV7511=y +CONFIG_DRM_ANALOG=y +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_WMT_GE_ROPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_ARMCLCD is not set +# CONFIG_FB_UVESA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_XILINX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_XYLON is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_JACK=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +# CONFIG_SND_SUPPORT_OLD_API is not set +# CONFIG_SND_VERBOSE_PROCFS is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +# CONFIG_SND_DRIVERS is not set +# CONFIG_SND_ARM is not set +# CONFIG_SND_SPI is not set +# CONFIG_SND_USB is not set +CONFIG_SND_SOC=y +CONFIG_SND_SOC_DMAENGINE_PCM=y +CONFIG_SND_SOC_XILINX=y +CONFIG_SND_SOC_AXI_SPDIF=y +CONFIG_SND_SOC_ADV7511_HDMI=y +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +# CONFIG_SOUND_PRIME is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_ACRUX is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_PRODIKEYS is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EMS_FF is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_HOLTEK is not set +# CONFIG_HID_KEYTOUCH is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_WALTOP is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LCPOWER is not set +# CONFIG_HID_LOGITECH is not set +CONFIG_HID_MICROSOFT=y +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_MULTITOUCH is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_PRIMAX is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SPEEDLINK is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +CONFIG_USB_ARCH_HAS_EHCI=y +# CONFIG_USB_ARCH_HAS_XHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y +CONFIG_USB_OTG=y +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_DWC3 is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +CONFIG_USB_XUSBPS_DR_OF=y +CONFIG_USB_EHCI_XUSBPS=y +# CONFIG_USB_EHCI_MV is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_RENESAS_USBHS is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_REALTEK is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +# CONFIG_USB_UAS is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 +CONFIG_USB_GADGET_XUSBPS=y +CONFIG_USB_XUSBPS=y +# CONFIG_USB_FUSB300 is not set +# CONFIG_USB_R8A66597 is not set +# CONFIG_USB_GADGET_XILINX is not set +# CONFIG_USB_MV_UDC is not set +# CONFIG_USB_M66592 is not set +# CONFIG_USB_NET2272 is not set +# CONFIG_USB_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_ZERO=m +# CONFIG_USB_ZERO_HNPTEST is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_G_NCM is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FUNCTIONFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_ACM_MS is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_DBGP is not set +# CONFIG_USB_G_WEBCAM is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +# CONFIG_USB_GPIO_VBUS is not set +CONFIG_USB_ULPI=y +CONFIG_USB_ULPI_VIEWPORT=y +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_USB_XUSBPS_OTG=y +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set +# CONFIG_MMC_CLKGATE is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=8 +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_ARMMMCI is not set +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_XILINX_PS=y +# CONFIG_MMC_SDHCI_PXAV3 is not set +# CONFIG_MMC_SDHCI_PXAV2 is not set +# CONFIG_MMC_WBSD is not set +# CONFIG_MMC_DW is not set +# CONFIG_MMC_VUB300 is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_X1205 is not set +CONFIG_RTC_DRV_PCF8563=y +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_XILINX_DMA=y +# CONFIG_AMBA_PL08X is not set +# CONFIG_DW_DMAC is not set +# CONFIG_TIMB_DMA is not set +# CONFIG_PL330_DMA is not set +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# Virtio drivers +# +# CONFIG_VIRTIO_BALLOON is not set +# CONFIG_VIRTIO_MMIO is not set + +# +# Microsoft Hyper-V guest support +# +# CONFIG_STAGING is not set +CONFIG_CLKDEV_LOOKUP=y + +# +# Hardware Spinlock drivers +# +# CONFIG_IOMMU_SUPPORT is not set +# CONFIG_VIRT_DRIVERS is not set +# CONFIG_PM_DEVFREQ is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT23=y +CONFIG_EXT4_FS_XATTR=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +# CONFIG_EXT4_FS_SECURITY is not set +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +# CONFIG_FS_POSIX_ACL is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_PSTORE is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_LOCKUP_DETECTOR is not set +# CONFIG_HARDLOCKUP_DETECTOR is not set +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=20 +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_LOCK_ALLOC=y +CONFIG_PROVE_LOCKING=y +CONFIG_PROVE_RCU=y +# CONFIG_PROVE_RCU_REPEATEDLY is not set +# CONFIG_SPARSE_RCU_POINTER is not set +CONFIG_LOCKDEP=y +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_LOCKDEP is not set +CONFIG_TRACE_IRQFLAGS=y +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_INFO_REDUCED is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +# CONFIG_RCU_CPU_STALL_VERBOSE is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_LKDTM is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_TEST_KSTRTOX is not set +# CONFIG_STRICT_DEVMEM is not set +CONFIG_ARM_UNWIND=y +# CONFIG_DEBUG_USER is not set +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_LL_UART_NONE=y +# CONFIG_DEBUG_ICEDCC is not set +CONFIG_EARLY_PRINTK=y +# CONFIG_OC_ETM is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_ALGAPI2=m +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=m +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set +# CONFIG_CRYPTO_USER is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_PCRYPT is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=m +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_PCI_IOMAP=y +# CONFIG_CRC_CCITT is not set +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +# CONFIG_CRC8 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +# CONFIG_XZ_DEC is not set +# CONFIG_XZ_DEC_BCJ is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_NLATTR=y +# CONFIG_AVERAGE is not set +# CONFIG_CORDIC is not set diff --git a/arch/arm/configs/zync_xcomm_adv7511_defconfig b/arch/arm/configs/zync_xcomm_adv7511_defconfig new file mode 100644 index 0000000000000..e7f6390810d05 --- /dev/null +++ b/arch/arm/configs/zync_xcomm_adv7511_defconfig @@ -0,0 +1,248 @@ +# CONFIG_ARM_PATCH_PHYS_VIRT is not set +CONFIG_PHYS_OFFSET=0x0 +CONFIG_EXPERIMENTAL=y +CONFIG_SYSVIPC=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_EMBEDDED=y +CONFIG_PERF_EVENTS=y +CONFIG_SLAB=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_ARCH_ZYNQ=y +CONFIG_ZYNQ_EARLY_UART1=y +# CONFIG_ZYNQ_EARLY_UART_EP107 is not set +CONFIG_XILINX_FIXED_DEVTREE_ADDR=y +CONFIG_XILINX_ZED=y +CONFIG_SMP=y +CONFIG_PREEMPT=y +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +CONFIG_HIGHMEM=y +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyPS0,115200n8 root=/dev/ram rw initrd=0x00800000,16M earlyprintk mtdparts=physmap-flash.0:512K(nor-fsbl),512K(nor-u-boot),5M(nor-linux),9M(nor-user),1M(nor-scratch),-(nor-rootfs)" +CONFIG_VFP=y +CONFIG_NEON=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_SUSPEND is not set +CONFIG_PM_RUNTIME=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_VLAN_8021Q=m +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_FW_LOADER=m +CONFIG_CMA=y +CONFIG_CMA_SIZE_MBYTES=40 +CONFIG_CONNECTOR=y +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_M25P80=y +# CONFIG_M25PXX_USE_FAST_READ is not set +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_XILINX_PS=y +CONFIG_PROC_DEVICETREE=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=35384 +CONFIG_EEPROM_AT24=y +CONFIG_EEPROM_AT25=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_SG=y +CONFIG_SCSI_MULTI_LUN=y +CONFIG_NETDEVICES=y +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CHELSIO is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +CONFIG_XILINX_PS_EMAC=y +CONFIG_XILINX_PS_EMAC_HWTSTAMP=y +CONFIG_MARVELL_PHY=y +CONFIG_MDIO_BITBANG=y +# CONFIG_WLAN is not set +CONFIG_INPUT_SPARSEKMAP=y +CONFIG_INPUT_EVDEV=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_XILINX_PS_UART=y +CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +# CONFIG_HW_RANDOM is not set +CONFIG_XILINX_DEVCFG=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_GPIO=y +CONFIG_I2C_XILINX=y +CONFIG_SPI=y +CONFIG_SPI_BITBANG=y +CONFIG_SPI_XCOMM=y +CONFIG_SPI_XILINX_PS_QSPI=y +CONFIG_SPI_XILINX_PS_SPI=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_XILINX_PS=y +# CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_DRM=y +CONFIG_DRM_ENCODER_ADV7511=y +CONFIG_DRM_ANALOG=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +CONFIG_SOUND=y +CONFIG_SND=y +# CONFIG_SND_SUPPORT_OLD_API is not set +# CONFIG_SND_VERBOSE_PROCFS is not set +# CONFIG_SND_DRIVERS is not set +# CONFIG_SND_ARM is not set +# CONFIG_SND_SPI is not set +# CONFIG_SND_USB is not set +CONFIG_SND_SOC=y +CONFIG_SND_SOC_XILINX=y +CONFIG_SND_SOC_ADV7511_HDMI=y +CONFIG_HIDRAW=y +CONFIG_HID_A4TECH=y +CONFIG_HID_ACRUX=y +CONFIG_HID_ACRUX_FF=y +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_PRODIKEYS=y +CONFIG_HID_CYPRESS=y +CONFIG_HID_DRAGONRISE=y +CONFIG_DRAGONRISE_FF=y +CONFIG_HID_EMS_FF=y +CONFIG_HID_EZKEY=y +CONFIG_HID_HOLTEK=y +CONFIG_HOLTEK_FF=y +CONFIG_HID_KEYTOUCH=y +CONFIG_HID_KYE=y +CONFIG_HID_UCLOGIC=y +CONFIG_HID_WALTOP=y +CONFIG_HID_GYRATION=y +CONFIG_HID_TWINHAN=y +CONFIG_HID_KENSINGTON=y +CONFIG_HID_LCPOWER=y +CONFIG_HID_LOGITECH=y +CONFIG_HID_LOGITECH_DJ=y +CONFIG_LOGITECH_FF=y +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGIG940_FF=y +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +CONFIG_HID_MULTITOUCH=y +CONFIG_HID_NTRIG=y +CONFIG_HID_ORTEK=y +CONFIG_HID_PANTHERLORD=y +CONFIG_PANTHERLORD_FF=y +CONFIG_HID_PETALYNX=y +CONFIG_HID_PICOLCD=y +CONFIG_HID_PICOLCD_FB=y +CONFIG_HID_PRIMAX=y +CONFIG_HID_ROCCAT=y +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_HID_SPEEDLINK=y +CONFIG_HID_SUNPLUS=y +CONFIG_HID_GREENASIA=y +CONFIG_GREENASIA_FF=y +CONFIG_HID_SMARTJOYPLUS=y +CONFIG_SMARTJOYPLUS_FF=y +CONFIG_HID_TOPSEED=y +CONFIG_HID_THRUSTMASTER=y +CONFIG_THRUSTMASTER_FF=y +CONFIG_HID_ZEROPLUS=y +CONFIG_ZEROPLUS_FF=y +CONFIG_HID_ZYDACRON=y +CONFIG_USB_HIDDEV=y +CONFIG_USB=y +CONFIG_USB_SUSPEND=y +CONFIG_USB_OTG=y +# CONFIG_USB_OTG_WHITELIST is not set +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +CONFIG_USB_EHCI_XUSBPS=y +CONFIG_USB_STORAGE=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_XUSBPS=y +CONFIG_XILINX_ZED_USB_OTG=y +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_XILINX_PS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_PCF8563=y +CONFIG_DMADEVICES=y +CONFIG_XILINX_DMA=y +CONFIG_STAGING=y +CONFIG_AD8366=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_IIO=y +CONFIG_IIO_KFIFO_BUF=y +CONFIG_CF_AXI_ADC=y +CONFIG_CF_AXI_FFT=y +CONFIG_AD9523=y +CONFIG_AD9548=y +CONFIG_CF_AXI_DDS=y +CONFIG_CF_AXI_DDS_AD9122=y +CONFIG_ADF4350=y +CONFIG_EXT4_FS=y +# CONFIG_DNOTIFY is not set +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +# CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_DEBUG_FS=y +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=20 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_PREEMPT is not set +CONFIG_PROVE_LOCKING=y +CONFIG_PROVE_RCU=y +CONFIG_DEBUG_INFO=y +# CONFIG_RCU_CPU_STALL_VERBOSE is not set +# CONFIG_FTRACE is not set +CONFIG_DEBUG_LL=y +CONFIG_EARLY_PRINTK=y diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 41dc31f834c3b..4bd48d4568220 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -40,7 +40,7 @@ */ #define VMALLOC_OFFSET (8*1024*1024) #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) -#define VMALLOC_END 0xff000000UL +#define VMALLOC_END 0xfd000000UL #define LIBRARY_TEXT_START 0x0c000000 diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig index 5c3b91a0059ca..feb835cc9fc22 100644 --- a/arch/arm/mach-zynq/Kconfig +++ b/arch/arm/mach-zynq/Kconfig @@ -42,6 +42,18 @@ config XILINX_L2_PREFETCH in many cases. This may not always be the best performance depending on the usage. +config XILINX_ZED + bool "Using USB OTG on the Digilent ZED board" + default n + depends on USB_SUPPORT + select USB_ULPI if USB_SUPPORT + select USB_ULPI_VIEWPORT if USB_SUPPORT + help + Select this option if using the USB OTG port on the Digilent ZED board + as a USB on-the-go port. This option is necessary to properly + initialize the TUSB1210 USB PHY used on the ZED board as an + on-the-go USB port that can supply power to a USB slave device. + config XILINX_TEST bool "Testing On Kernel Boot" default n diff --git a/arch/arm/mach-zynq/Makefile b/arch/arm/mach-zynq/Makefile index fc9f8965d3085..b67547adab99a 100644 --- a/arch/arm/mach-zynq/Makefile +++ b/arch/arm/mach-zynq/Makefile @@ -3,7 +3,7 @@ # # Common support -obj-y := common.o timer.o slcr.o pl330.o platform_devices.o +obj-y := common.o timer.o slcr.o pl330.o platform_devices.o board_zc702.o board_zed.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o obj-$(CONFIG_SMP) += platsmp.o diff --git a/arch/arm/mach-zynq/board_zc702.c b/arch/arm/mach-zynq/board_zc702.c new file mode 100644 index 0000000000000..ce16c36da3977 --- /dev/null +++ b/arch/arm/mach-zynq/board_zc702.c @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2011 Xilinx + * + * 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. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "common.h" + +#define SPIBUS_NUM_LPC 0 + +#if defined(CONFIG_AD9523) || defined(CONFIG_AD9523_MODULE) +#include +struct ad9523_channel_spec ad9523_channels[] = { + { /* ZD output */ + .channel_num = 0, + .extended_name = "ZD_OUTPUT", + .divider_output_invert_en = false, + .sync_ignore_en = false, + .low_power_mode_en = false, + .driver_mode = LVDS_4mA, + .divider_phase = 0, + .channel_divider = 8, + .use_alt_clock_src = false, + .output_dis = false, + }, + { /* DAC CLK */ + .channel_num = 12, + .extended_name = "DAC_CLK", + .divider_output_invert_en = false, + .sync_ignore_en = false, + .low_power_mode_en = false, + .driver_mode = LVPECL_8mA, + .divider_phase = 0, + .channel_divider = 2, + }, + { /* ADC CLK */ + .channel_num = 2, + .extended_name = "ADC_CLK", + .divider_output_invert_en = false, + .sync_ignore_en = false, + .low_power_mode_en = false, + .driver_mode = LVDS_7mA, + .divider_phase = 0, + .channel_divider = 4, + }, + { /* DAC REF CLK */ + .channel_num = 10, + .extended_name = "DAC_REF_CLK", + .divider_output_invert_en = false, + .sync_ignore_en = false, + .low_power_mode_en = false, + .driver_mode = LVDS_4mA, + .divider_phase = 0, + .channel_divider = 16, + }, + { /* TX LO REF */ + .channel_num = 5, + .extended_name = "TX_LO_REF_CLK", + .divider_output_invert_en = false, + .sync_ignore_en = false, + .low_power_mode_en = false, + .driver_mode = CMOS_CONF3, /* HiZ on - */ + .divider_phase = 0, + .channel_divider = 8, + }, + { /* DAC DCO */ + .channel_num = 6, + .extended_name = "DAC_DCO_CLK", + .divider_output_invert_en = false, + .sync_ignore_en = false, + .low_power_mode_en = false, + .driver_mode = LVDS_7mA, + .divider_phase = 0, + .channel_divider = 2, + }, + { /* ADC SYNC */ + .channel_num = 7, + .extended_name = "ADC_SYNC_CLK", + .divider_output_invert_en = false, + .sync_ignore_en = false, + .low_power_mode_en = false, + .driver_mode = CMOS_CONF3, /* HiZ on - */ + .divider_phase = 1, + .channel_divider = 32, + .output_dis = false, + }, + { /* RX LO REF */ + .channel_num = 9, + .extended_name = "RX_LO_REF_CLK", + .divider_output_invert_en = false, + .sync_ignore_en = false, + .low_power_mode_en = false, + .driver_mode = CMOS_CONF3, /* HiZ on - */ + .divider_phase = 0, + .channel_divider = 8, + }, +}; + +struct ad9523_platform_data ad9523_pdata_lpc = { + .vcxo_freq = 122880000, + + /* Single-Ended Input Configuration */ + .refa_diff_rcv_en = false, + .refb_diff_rcv_en = true, + .zd_in_diff_en = true, + .osc_in_diff_en = false, + .osc_in_cmos_neg_inp_en = true, + + .refa_r_div = 0, + .refb_r_div = 0, + .pll1_feedback_div = 4, + .pll1_charge_pump_current_nA = 2000, +#if defined(CONFIG_ADIXCOMM_SYNC) + .zero_delay_mode_internal_en = false, +#else + .zero_delay_mode_internal_en = true, +#endif + .osc_in_feedback_en = false, + .refa_cmos_neg_inp_en = true, + .pll1_loop_filter_rzero = 3, + +#if defined(CONFIG_ADIXCOMM_SYNC) + .ref_mode = 2, /* 3 ?*/ +#else + .ref_mode = 3, /* 3 ?*/ +#endif + + .pll2_charge_pump_current_nA = 420000, + .pll2_ndiv_a_cnt = 0, + .pll2_ndiv_b_cnt = 3, + .pll2_freq_doubler_en = true, + .pll2_r2_div = 1, + .pll2_vco_diff_m1 = 3, + .pll2_vco_diff_m2 = 3, + + .rpole2 = 0, + .rzero = 2, + .cpole1 = 2, + .rzero_bypass_en = false, + + /* Output Channel Configuration */ + .num_channels = ARRAY_SIZE(ad9523_channels), + .channels = ad9523_channels, + .name = "ad9523-lpc" +}; +#endif + +#if defined(CONFIG_ADF4350) || defined(CONFIG_ADF4350_MODULE) +#include +static struct adf4350_platform_data adf4350_tx_pdata_lpc = { + .name = "adf4351-tx-lpc", + .clkin = 122880000, + .channel_spacing = 10000, + .r2_user_settings = ADF4350_REG2_PD_POLARITY_POS, + ADF4350_REG2_CHARGE_PUMP_CURR_uA(2500), + .r3_user_settings = ADF4350_REG3_12BIT_CLKDIV_MODE(0), + .r4_user_settings = ADF4350_REG4_OUTPUT_PWR(3) | + ADF4350_REG4_MUTE_TILL_LOCK_EN, + .gpio_lock_detect = -1, + .power_up_frequency = 2400000000U, +}; + +static struct adf4350_platform_data adf4350_rx_pdata_lpc = { + .name = "adf4351-rx-lpc", + .clkin = 122880000, + .channel_spacing = 10000, + .r2_user_settings = ADF4350_REG2_PD_POLARITY_POS, + ADF4350_REG2_CHARGE_PUMP_CURR_uA(2500), + .r3_user_settings = ADF4350_REG3_12BIT_CLKDIV_MODE(0), + .r4_user_settings = ADF4350_REG4_OUTPUT_PWR(3) | + ADF4350_REG4_MUTE_TILL_LOCK_EN, + .gpio_lock_detect = -1, + .power_up_frequency = 2400000000U, +}; +#endif + +static struct spi_board_info __initdata xilinx_spipss_0_boardinfo[] = { +#if defined(CONFIG_AD9548) || defined(CONFIG_AD9548_MODULE) + { + .modalias = "ad9548", + .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = SPIBUS_NUM_LPC, + .chip_select = 2, /* AD9548 */ + .mode = SPI_MODE_0 | SPI_3WIRE, + }, +#endif +#if defined(CONFIG_AD9523) || defined(CONFIG_AD9523_MODULE) + { + .modalias = "ad9523-1", + .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = SPIBUS_NUM_LPC, + .chip_select = 3, /* GPIO controlled SSEL */ + .platform_data = &ad9523_pdata_lpc, /* spi_driver specific config */ + .mode = SPI_MODE_0 | SPI_3WIRE, + }, +#endif +#if defined(CONFIG_AD8366) || defined(CONFIG_AD8366_MODULE) + { + .modalias = "ad8366", + .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = SPIBUS_NUM_LPC, + .chip_select = 6, /* GPIO controlled SSEL */ + .platform_data = "ad8366-lpc", /* spi_driver specific config */ + .mode = SPI_MODE_0 | SPI_3WIRE, + }, +#endif +#if defined(CONFIG_ADF4350) || defined(CONFIG_ADF4350_MODULE) + { + .modalias = "adf4351", + .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = SPIBUS_NUM_LPC, + .chip_select = 4, /* GPIO controlled SSEL */ + .platform_data = &adf4350_rx_pdata_lpc, /* No spi_driver specific config */ + .mode = SPI_MODE_0, + }, + { + .modalias = "adf4351", + .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = SPIBUS_NUM_LPC, + .chip_select = 5, /* GPIO controlled SSEL */ + .platform_data = &adf4350_tx_pdata_lpc, /* No spi_driver specific config */ + .mode = SPI_MODE_0, + }, +#endif +}; + +extern struct sys_timer xttcpss_sys_timer; + +static void __init board_zc702_init(void) +{ + + /* initialize the xilinx common code before the board + * specific + */ + xilinx_init_machine(); + + spi_register_board_info(xilinx_spipss_0_boardinfo, + ARRAY_SIZE(xilinx_spipss_0_boardinfo)); +} + +static const char *xilinx_dt_match[] = { + "xlnx,zynq-zc702", + "xlnx,zynq-zc706", + NULL +}; + +MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform") + .map_io = xilinx_map_io, + .init_irq = xilinx_irq_init, + .handle_irq = gic_handle_irq, + .init_machine = board_zc702_init, + .timer = &xttcpss_sys_timer, + .dt_compat = xilinx_dt_match, + .reserve = xilinx_memory_init, + .restart = xilinx_system_reset, +MACHINE_END diff --git a/arch/arm/mach-zynq/board_zed.c b/arch/arm/mach-zynq/board_zed.c new file mode 100644 index 0000000000000..ab9c72650c3c6 --- /dev/null +++ b/arch/arm/mach-zynq/board_zed.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2011 Xilinx + * + * 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. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * New portions Copyright (c) 2012 Digilent Inc. + * ZED board definition file based on the board_zc702.c file. + * Additional functionality provided by the ZED board definition: + * - Recognition of ZED board in the device tree to support a single Zynq + * kernel that runs on several Zynq based boards. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include "common.h" + +//#define ZED_REV_B + +extern struct sys_timer xttcpss_sys_timer; + +static void __init board_zed_init(void) +{ + + /* initialize the xilinx common code before the board + * specific + */ + xilinx_init_machine(); + + printk("\n###############################################\n"); + printk ("# #\n"); + printk ("# Board ZED Init #\n"); + printk ("# #\n"); + printk ("###############################################\n\n"); +} + +static const char *xilinx_dt_match[] = { + "xlnx,zynq-zed", + NULL +}; + +MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform") + .map_io = xilinx_map_io, + .init_irq = xilinx_irq_init, +#ifdef GIC_CPU_CTRL + .handle_irq = gic_handle_irq, +#endif + .init_machine = board_zed_init, + .timer = &xttcpss_sys_timer, + .dt_compat = xilinx_dt_match, + .reserve = xilinx_memory_init, + .restart = xilinx_system_reset, +MACHINE_END diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c index 22a267debb33b..90315c0df53b1 100644 --- a/arch/arm/mach-zynq/common.c +++ b/arch/arm/mach-zynq/common.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -85,7 +86,7 @@ static void __init xilinx_zynq_timer_init(void) /* * Instantiate and initialize the system timer structure */ -static struct sys_timer xttcpss_sys_timer = { +struct sys_timer xttcpss_sys_timer = { .init = xilinx_zynq_timer_init, }; @@ -95,6 +96,7 @@ static struct sys_timer xttcpss_sys_timer = { void __init xilinx_map_io(void) { iotable_init(io_desc, ARRAY_SIZE(io_desc)); + init_consistent_dma_size(40 << 20); } /** @@ -202,23 +204,3 @@ void __init xilinx_init_machine(void) platform_device_init(); xilinx_opp_init(); } - -static const char *xilinx_dt_match[] = { - "xlnx,zynq-zc702", - "xlnx,zynq-zc706", - "xlnx,zynq-zc770", - NULL -}; - -extern struct sys_timer xttcpss_sys_timer; - -MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform") - .map_io = xilinx_map_io, - .init_irq = xilinx_irq_init, - .handle_irq = gic_handle_irq, - .init_machine = xilinx_init_machine, - .timer = &xttcpss_sys_timer, - .dt_compat = xilinx_dt_match, - .reserve = xilinx_memory_init, - .restart = xilinx_system_reset, -MACHINE_END diff --git a/arch/arm/mach-zynq/pl330.c b/arch/arm/mach-zynq/pl330.c index 193f0d5d150a7..2927be3c6b105 100644 --- a/arch/arm/mach-zynq/pl330.c +++ b/arch/arm/mach-zynq/pl330.c @@ -2052,7 +2052,7 @@ static void pl330_enable_dma(unsigned int channel, dma_alloc_coherent(device_data->dev, 0x1000, &channel_data->dma_prog_phy, - GFP_KERNEL); + GFP_ATOMIC); } PDEBUG("channel %d DMA program: vir %#08x, phy %#08x\n", channel, diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c index fe2d462afa313..a9c25caac3f2b 100644 --- a/arch/arm/mach-zynq/slcr.c +++ b/arch/arm/mach-zynq/slcr.c @@ -31,6 +31,7 @@ #define XSLCR_LOCK 0x4 /* SLCR lock register */ #define XSLCR_UNLOCK 0x8 /* SCLR unlock register */ +#define XSLCR_IO_PLL_CTRL_OFFSET 0x108 /* AMBA Peripheral Clk Control */ #define XSLCR_APER_CLK_CTRL_OFFSET 0x12C /* AMBA Peripheral Clk Control */ #define XSLCR_USB0_CLK_CTRL_OFFSET 0x130 /* USB 0 ULPI Clock Control */ #define XSLCR_USB1_CLK_CTRL_OFFSET 0x134 /* USB 1 ULPI Clock Control */ @@ -44,6 +45,10 @@ #define XSLCR_UART_CLK_CTRL_OFFSET 0x154 /* UART Reference Clock Control */ #define XSLCR_SPI_CLK_CTRL_OFFSET 0x158 /* SPI Reference Clock Control */ #define XSLCR_CAN_CLK_CTRL_OFFSET 0x15C /* CAN Reference Clock Control */ +#define XSLCR_FPGA0_CLK_CTRL_OFFSET 0x170 /* FPGA0 Reference Clock Control */ +#define XSLCR_FPGA1_CLK_CTRL_OFFSET 0x180 /* FPGA1 Reference Clock Control */ +#define XSLCR_FPGA2_CLK_CTRL_OFFSET 0x190 /* FPGA2 Reference Clock Control */ +#define XSLCR_FPGA3_CLK_CTRL_OFFSET 0x1a0 /* FPGA3 Reference Clock Control */ #define XSLCR_PSS_RST_CTRL_OFFSET 0x200 /* PSS Software Reset Control */ #define XSLCR_DDR_RST_CTRL_OFFSET 0x204 /* DDR Software Reset Control */ #define XSLCR_AMBA_RST_CTRL_OFFSET 0x208 /* AMBA Software Reset Control */ @@ -64,6 +69,7 @@ #define XSLCR_A9_CPU_RST_CTRL 0x244 /* CPU Software Reset Control */ #define XSLCR_REBOOT_STATUS 0x258 /* PS Reboot Status */ #define XSLCR_MIO_PIN_00_OFFSET 0x700 /* MIO PIN0 control register */ +#define XSLCR_MIO_PIN(x) (0x700 + (x) * 4) /* MIO PIN0 control register */ #define XSLCR_LVL_SHFTR_EN_OFFSET 0x900 /* Level Shifters Enable */ /* Bit masks for AMBA Peripheral Clock Control register */ @@ -2482,6 +2488,13 @@ static int __devinit xslcr_probe(struct platform_device *pdev) return ret; } +void xslcr_set_fpga3_clock(unsigned int rate) +{ + unsigned int div = DIV_ROUND_CLOSEST(1000000000, rate); + + xslcr_writereg(slcr->regs + XSLCR_FPGA2_CLK_CTRL_OFFSET, 0x100000 | (div << 8)); +} + /** * xslcr_remove - Remove call for the device. * diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 5ed654ae66e14..d1c70ae425657 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -1418,9 +1418,18 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .mode = SPI_MODE_3, }, #endif +//#if defined(CONFIG_AD525X_DPOT) || defined(CONFIG_AD525X_DPOT_MODULE) + { + .modalias = "ad5160", + .max_speed_hz = 5000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 1, //GPIO_PF10 + MAX_CTRL_CS, + .mode = SPI_MODE_0, + }, +//#endif }; -#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE) +//#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE) /* SPI controller data */ static struct bfin5xx_spi_master bfin_spi0_info = { .num_chipselect = MAX_CTRL_CS + MAX_BLACKFIN_GPIOS, @@ -1456,7 +1465,7 @@ static struct platform_device bfin_spi0_device = { .platform_data = &bfin_spi0_info, /* Passed to driver */ }, }; -#endif /* spi master and devices */ +//#endif /* spi master and devices */ #if defined(CONFIG_SPI_BFIN_SPORT) || defined(CONFIG_SPI_BFIN_SPORT_MODULE) @@ -2846,9 +2855,9 @@ static struct platform_device *stamp_devices[] __initdata = { &net2272_bfin_device, #endif -#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE) +//#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE) &bfin_spi0_device, -#endif +//#endif #if defined(CONFIG_SPI_BFIN_SPORT) || defined(CONFIG_SPI_BFIN_SPORT_MODULE) &bfin_sport_spi0_device, diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 311bfc6dedc33..025b236414833 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -24,6 +24,7 @@ config MICROBLAZE select GENERIC_CPU_DEVICES select GENERIC_ATOMIC64 select GENERIC_CLOCKEVENTS + select COMMON_CLK config SWAP def_bool n diff --git a/arch/microblaze/boot/dts/cf_ad9250_fmc_ebz_kc705.dts b/arch/microblaze/boot/dts/cf_ad9250_fmc_ebz_kc705.dts new file mode 100644 index 0000000000000..9fb65c0b0aa3a --- /dev/null +++ b/arch/microblaze/boot/dts/cf_ad9250_fmc_ebz_kc705.dts @@ -0,0 +1,439 @@ +/* + * Device Tree Generator version: 1.3 + * + * (C) Copyright 2007-2008 Xilinx, Inc. + * (C) Copyright 2007-2009 Michal Simek + * + * Michal SIMEK + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * CAUTION: This file is automatically generated by libgen. + * Version: Xilinx EDK 14.1 EDK_P.15xf + * + * XPS project directory: device-tree_bsp_0 + */ + +/dts-v1/; +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,microblaze"; + model = "testing"; + DDR3_SDRAM: memory@c0000000 { + device_type = "memory"; + reg = < 0xc0000000 0x40000000 >; + } ; + aliases { + ethernet0 = &Ethernet_Lite; + serial0 = &RS232_Uart_1; + } ; + chosen { + bootargs = "console=ttyS0 root=/dev/ram"; + } ; + + clocks { + ad9517_ref_clk: clock@0 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <30720000>; + clock-output-names = "refclk"; + }; + ad9517_clkin: clock@1 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <250000000>; + clock-output-names = "clkin"; + }; + }; + + cpus { + #address-cells = <1>; + #cpus = <0x1>; + #size-cells = <0>; + microblaze_0: cpu@0 { + clock-frequency = <100000000>; + compatible = "xlnx,microblaze-8.30.a"; + d-cache-baseaddr = <0xc0000000>; + d-cache-highaddr = <0xffffffff>; + d-cache-line-size = <0x10>; + d-cache-size = <0x4000>; + device_type = "cpu"; + i-cache-baseaddr = <0xc0000000>; + i-cache-highaddr = <0xffffffff>; + i-cache-line-size = <0x20>; + i-cache-size = <0x4000>; + model = "microblaze,8.30.a"; + reg = <0>; + timebase-frequency = <100000000>; + xlnx,addr-tag-bits = <0x10>; + xlnx,allow-dcache-wr = <0x1>; + xlnx,allow-icache-wr = <0x1>; + xlnx,area-optimized = <0x0>; + xlnx,avoid-primitives = <0x0>; + xlnx,branch-target-cache-size = <0x0>; + xlnx,cache-byte-size = <0x4000>; + xlnx,d-axi = <0x1>; + xlnx,d-lmb = <0x1>; + xlnx,d-plb = <0x0>; + xlnx,data-size = <0x20>; + xlnx,dcache-addr-tag = <0x10>; + xlnx,dcache-always-used = <0x1>; + xlnx,dcache-byte-size = <0x4000>; + xlnx,dcache-data-width = <0x0>; + xlnx,dcache-force-tag-lutram = <0x0>; + xlnx,dcache-interface = <0x0>; + xlnx,dcache-line-len = <0x4>; + xlnx,dcache-use-fsl = <0x0>; + xlnx,dcache-use-writeback = <0x0>; + xlnx,dcache-victims = <0x0>; + xlnx,debug-enabled = <0x1>; + xlnx,div-zero-exception = <0x1>; + xlnx,dynamic-bus-sizing = <0x1>; + xlnx,ecc-use-ce-exception = <0x0>; + xlnx,edge-is-positive = <0x1>; + xlnx,endianness = <0x1>; + xlnx,family = "kintex7"; + xlnx,fault-tolerant = <0x0>; + xlnx,fpu-exception = <0x0>; + xlnx,freq = <0x5f5e100>; + xlnx,fsl-data-size = <0x20>; + xlnx,fsl-exception = <0x0>; + xlnx,fsl-links = <0x0>; + xlnx,i-axi = <0x0>; + xlnx,i-lmb = <0x1>; + xlnx,i-plb = <0x0>; + xlnx,icache-always-used = <0x1>; + xlnx,icache-data-width = <0x0>; + xlnx,icache-force-tag-lutram = <0x0>; + xlnx,icache-interface = <0x0>; + xlnx,icache-line-len = <0x8>; + xlnx,icache-streams = <0x1>; + xlnx,icache-use-fsl = <0x0>; + xlnx,icache-victims = <0x8>; + xlnx,ill-opcode-exception = <0x1>; + xlnx,instance = "microblaze_0"; + xlnx,interconnect = <0x2>; + xlnx,interconnect-m-axi-dc-read-issuing = <0x2>; + xlnx,interconnect-m-axi-dc-write-issuing = <0x20>; + xlnx,interconnect-m-axi-dp-read-issuing = <0x1>; + xlnx,interconnect-m-axi-dp-write-issuing = <0x1>; + xlnx,interconnect-m-axi-ic-read-issuing = <0x8>; + xlnx,interconnect-m-axi-ip-read-issuing = <0x1>; + xlnx,interrupt-is-edge = <0x0>; + xlnx,lockstep-slave = <0x0>; + xlnx,mmu-dtlb-size = <0x4>; + xlnx,mmu-itlb-size = <0x2>; + xlnx,mmu-privileged-instr = <0x0>; + xlnx,mmu-tlb-access = <0x3>; + xlnx,mmu-zones = <0x2>; + xlnx,number-of-pc-brk = <0x1>; + xlnx,number-of-rd-addr-brk = <0x0>; + xlnx,number-of-wr-addr-brk = <0x0>; + xlnx,opcode-0x0-illegal = <0x1>; + xlnx,optimization = <0x0>; + xlnx,pc-width = <0x20>; + xlnx,pvr = <0x2>; + xlnx,pvr-user1 = <0x0>; + xlnx,pvr-user2 = <0x0>; + xlnx,reset-msr = <0x0>; + xlnx,sco = <0x0>; + xlnx,stream-interconnect = <0x0>; + xlnx,unaligned-exceptions = <0x1>; + xlnx,use-barrel = <0x1>; + xlnx,use-branch-target-cache = <0x0>; + xlnx,use-dcache = <0x1>; + xlnx,use-div = <0x1>; + xlnx,use-ext-brk = <0x1>; + xlnx,use-ext-nm-brk = <0x1>; + xlnx,use-extended-fsl-instr = <0x0>; + xlnx,use-fpu = <0x0>; + xlnx,use-hw-mul = <0x2>; + xlnx,use-icache = <0x1>; + xlnx,use-interrupt = <0x1>; + xlnx,use-mmu = <0x3>; + xlnx,use-msr-instr = <0x1>; + xlnx,use-pcmp-instr = <0x1>; + xlnx,use-reorder-instr = <0x1>; + xlnx,use-stack-protection = <0x0>; + } ; + } ; + axi4lite_0: axi@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,axi-interconnect-1.06.a", "simple-bus"; + ranges ; + Ethernet_Lite: ethernet@40e00000 { + compatible = "xlnx,axi-ethernetlite-1.01.b", "xlnx,xps-ethernetlite-1.00.a"; + device_type = "network"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 6 0 >; + local-mac-address = [ 00 0a 35 fb 52 00 ]; + phy-handle = <&phy0>; + reg = < 0x40e00000 0x10000 >; + xlnx,duplex = <0x1>; + xlnx,family = "kintex7"; + xlnx,include-global-buffers = <0x0>; + xlnx,include-internal-loopback = <0x0>; + xlnx,include-mdio = <0x1>; + xlnx,include-phy-constraints = <0x1>; + xlnx,instance = "Ethernet_Lite"; + xlnx,interconnect-s-axi-read-acceptance = <0x1>; + xlnx,interconnect-s-axi-write-acceptance = <0x1>; + xlnx,rx-ping-pong = <0x0>; + xlnx,s-axi-aclk-period-ps = <0x2710>; + xlnx,s-axi-id-width = <0x1>; + xlnx,s-axi-supports-narrow-burst = <0x0>; + xlnx,tx-ping-pong = <0x0>; + mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: phy@7 { + compatible = "marvell,88e1111"; + device_type = "ethernet-phy"; + reg = <7>; + } ; + } ; + } ; + RS232_Uart_1: serial@40600000 { + clock-frequency = <100000000>; + compatible = "xlnx,axi-uartlite-1.02.a", "xlnx,xps-uartlite-1.00.a"; + current-speed = <57600>; + device_type = "serial"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 7 0 >; + port-number = <0>; + reg = < 0x40600000 0x10000 >; + xlnx,baudrate = <0xe100>; + xlnx,data-bits = <0x8>; + xlnx,family = "kintex7"; + xlnx,instance = "RS232_Uart_1"; + xlnx,odd-parity = <0x1>; + xlnx,s-axi-aclk-freq-hz = <0x5f5e100>; + xlnx,use-parity = <0x0>; + } ; + axi_dma_0: axidma@41e20000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-dma"; + ranges = < 0x41e20000 0x41e20000 0x10000 >; + reg = < 0x41e20000 0x10000 >; +// xlnx,sg-include-stscntrl-strm = <0x0>; + dma-channel@41e20030 { + compatible = "xlnx,axi-dma-s2mm-channel"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 4 2 >; + xlnx,datawidth = <0x40>; + xlnx,include-dre = <0x0>; + } ; + } ; + axi_dma_1: axidma@41e00000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-dma"; + ranges = < 0x41e00000 0x41e00000 0x10000 >; + reg = < 0x41e00000 0x10000 >; +// xlnx,sg-include-stscntrl-strm = <0x0>; + dma-channel@41e00030 { + compatible = "xlnx,axi-dma-s2mm-channel"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 3 2 >; + xlnx,datawidth = <0x40>; + xlnx,include-dre = <0x0>; + } ; + }; + axi_spi_0: spi@40a00000 { + compatible = "xlnx,axi-spi-1.02.a", "xlnx,xps-spi-2.00.a"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 2 2 >; + reg = < 0x40a00000 0x10000 >; + xlnx,family = "kintex7"; + xlnx,fifo-exist = <0x1>; + xlnx,instance = "axi_spi_0"; + xlnx,num-ss-bits = <0x1>; + xlnx,num-transfer-bits = <0x8>; + xlnx,sck-ratio = <0x10>; + spi_fmc176: spi-fmc176@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "spi-ad9250"; + reg = <0>; + spi-max-frequency = <10000000>; + clk_ad9517: ad9517@4 { + #address-cells = <1>; + #size-cells = <0>; + #clock-cells = <0>; + compatible = "ad9517-1"; + reg = <1>; + spi-max-frequency = <10000000>; + spi-3wire; + clocks = <&ad9517_ref_clk>, <&ad9517_clkin>; + clock-names = "refclk", "clkin"; + clock-output-names = "out0", "out1", "out2", "out3", "out4", "out5", "out6", "out7"; + + }; + adc0_ad9250: ad9250@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "ad9250"; + reg = <2>; + spi-max-frequency = <10000000>; + clocks = <&clk_ad9517>; + clock-names = "out0"; + + }; + adc1_ad9250: ad9250@1 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "ad9250"; + reg = <3>; + spi-max-frequency = <10000000>; + clocks = <&clk_ad9517>; + clock-names = "out1"; + + }; + }; + }; + axi_ad9129_0: axi-ad9129@7c840000 { + compatible = "xlnx,axi-ad9129-1.00.a"; + reg = < 0x7c840000 0x10000 >; + xlnx,cf-buftype = <0x0>; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "kintex7"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; + axi_ad9250_0: cf-ad9250-1@7c820000 { + compatible = "xlnx,axi-ad9250-1.00.a"; + reg = < 0x7c820000 0x10000 >; + dma-request = <&axi_dma_0 0>; + spibus-connected = <&adc0_ad9250>; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "kintex7"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; + axi_ad9250_1: cf-ad9250-2@7c800000 { + compatible = "xlnx,axi-ad9250-1.00.a"; + reg = < 0x7c800000 0x10000 >; + dma-request = <&axi_dma_1 0>; + spibus-connected = <&adc1_ad9250>; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "kintex7"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; + + /* LCD Display */ + + axi_gpio_0: gpio@40000000 { + compatible = "xlnx,axi-xlnx-lcd-1.00.a"; + reg = < 0x40000000 0x8 >; + xlnx,all-inputs = <0x0>; + xlnx,dout-default = <0x0>; + xlnx,family = "kintex7"; + xlnx,gpio-width = <0x7>; + xlnx,instance = "axi_gpio_0"; + xlnx,interrupt-present = <0x0>; + xlnx,is-dual = <0x0>; + xlnx,tri-default = <0xffffffff>; + } ; + + axi_intc_0: interrupt-controller@41200000 { + #interrupt-cells = <0x2>; + compatible = "xlnx,axi-intc-1.01.a", "xlnx,xps-intc-1.00.a"; + interrupt-controller ; + reg = < 0x41200000 0x10000 >; + xlnx,kind-of-intr = <0xc0>; + xlnx,num-intr-inputs = <0x8>; + } ; + axi_jesd204b_rx4_0: axi-jesd204b-rx4@77a00000 { + compatible = "xlnx,axi-jesd204b-rx4-1.00.a"; + reg = < 0x77a00000 0x10000 >; + jesd,lanesync_en; + jesd,scramble_en; + jesd,frames-per-multiframe = <32>; + jesd,bytes-per-frame = <2>; + xlnx,cf-buftype = <0x1>; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "kintex7"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + clocks = <&clk_ad9517>; + clock-names = "out0"; + + } ; + axi_timer_0: timer@41c00000 { + clock-frequency = <100000000>; + compatible = "xlnx,axi-timer-1.03.a", "xlnx,xps-timer-1.00.a"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 5 2 >; + reg = < 0x41c00000 0x10000 >; + xlnx,count-width = <0x20>; + xlnx,family = "kintex7"; + xlnx,gen0-assert = <0x1>; + xlnx,gen1-assert = <0x1>; + xlnx,instance = "axi_timer_0"; + xlnx,one-timer-only = <0x0>; + xlnx,trig0-assert = <0x1>; + xlnx,trig1-assert = <0x1>; + } ; + axi_vdma_0: axivdma@7e200000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,axi-vdma"; + ranges = < 0x7e200000 0x7e200000 0x10000 >; + reg = < 0x7e200000 0x10000 >; + xlnx,include-sg = <0x0>; + xlnx,num-fstores = <0x3>; + dma-channel@7e200000 { + compatible = "xlnx,axi-vdma-mm2s-channel"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 1 2 >; + xlnx,datawidth = <0x40>; + xlnx,genlock-mode = <0x0>; + xlnx,include-dre = <0x0>; + } ; + } ; + debug_module: debug@41400000 { + compatible = "xlnx,mdm-2.00.b"; + reg = < 0x41400000 0x10000 >; + xlnx,family = "kintex7"; + xlnx,interconnect = <0x2>; + xlnx,jtag-chain = <0x2>; + xlnx,mb-dbg-ports = <0x1>; + xlnx,use-uart = <0x1>; + } ; + } ; +} ; diff --git a/arch/microblaze/boot/dts/cf_ad9250_fmc_kc705.dts b/arch/microblaze/boot/dts/cf_ad9250_fmc_kc705.dts new file mode 100644 index 0000000000000..c8eb54f1c6d8a --- /dev/null +++ b/arch/microblaze/boot/dts/cf_ad9250_fmc_kc705.dts @@ -0,0 +1,396 @@ +/* + * Device Tree Generator version: 1.3 + * + * (C) Copyright 2007-2008 Xilinx, Inc. + * (C) Copyright 2007-2009 Michal Simek + * + * Michal SIMEK + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * CAUTION: This file is automatically generated by libgen. + * Version: Xilinx EDK 14.1 EDK_P.15xf + * + * XPS project directory: device-tree_bsp_0 + */ + +/dts-v1/; +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,microblaze"; + model = "testing"; + DDR3_SDRAM: memory@c0000000 { + device_type = "memory"; + reg = < 0xc0000000 0x40000000 >; + } ; + aliases { + ethernet0 = &Ethernet_Lite; + serial0 = &RS232_Uart_1; + } ; + chosen { + bootargs = "console=ttyS0 root=/dev/ram"; + } ; + cpus { + #address-cells = <1>; + #cpus = <0x1>; + #size-cells = <0>; + microblaze_0: cpu@0 { + clock-frequency = <100000000>; + compatible = "xlnx,microblaze-8.30.a"; + d-cache-baseaddr = <0xc0000000>; + d-cache-highaddr = <0xffffffff>; + d-cache-line-size = <0x10>; + d-cache-size = <0x4000>; + device_type = "cpu"; + i-cache-baseaddr = <0xc0000000>; + i-cache-highaddr = <0xffffffff>; + i-cache-line-size = <0x20>; + i-cache-size = <0x4000>; + model = "microblaze,8.30.a"; + reg = <0>; + timebase-frequency = <100000000>; + xlnx,addr-tag-bits = <0x10>; + xlnx,allow-dcache-wr = <0x1>; + xlnx,allow-icache-wr = <0x1>; + xlnx,area-optimized = <0x0>; + xlnx,avoid-primitives = <0x0>; + xlnx,branch-target-cache-size = <0x0>; + xlnx,cache-byte-size = <0x4000>; + xlnx,d-axi = <0x1>; + xlnx,d-lmb = <0x1>; + xlnx,d-plb = <0x0>; + xlnx,data-size = <0x20>; + xlnx,dcache-addr-tag = <0x10>; + xlnx,dcache-always-used = <0x1>; + xlnx,dcache-byte-size = <0x4000>; + xlnx,dcache-data-width = <0x0>; + xlnx,dcache-force-tag-lutram = <0x0>; + xlnx,dcache-interface = <0x0>; + xlnx,dcache-line-len = <0x4>; + xlnx,dcache-use-fsl = <0x0>; + xlnx,dcache-use-writeback = <0x0>; + xlnx,dcache-victims = <0x0>; + xlnx,debug-enabled = <0x1>; + xlnx,div-zero-exception = <0x1>; + xlnx,dynamic-bus-sizing = <0x1>; + xlnx,ecc-use-ce-exception = <0x0>; + xlnx,edge-is-positive = <0x1>; + xlnx,endianness = <0x1>; + xlnx,family = "kintex7"; + xlnx,fault-tolerant = <0x0>; + xlnx,fpu-exception = <0x0>; + xlnx,freq = <0x5f5e100>; + xlnx,fsl-data-size = <0x20>; + xlnx,fsl-exception = <0x0>; + xlnx,fsl-links = <0x0>; + xlnx,i-axi = <0x0>; + xlnx,i-lmb = <0x1>; + xlnx,i-plb = <0x0>; + xlnx,icache-always-used = <0x1>; + xlnx,icache-data-width = <0x0>; + xlnx,icache-force-tag-lutram = <0x0>; + xlnx,icache-interface = <0x0>; + xlnx,icache-line-len = <0x8>; + xlnx,icache-streams = <0x1>; + xlnx,icache-use-fsl = <0x0>; + xlnx,icache-victims = <0x8>; + xlnx,ill-opcode-exception = <0x1>; + xlnx,instance = "microblaze_0"; + xlnx,interconnect = <0x2>; + xlnx,interconnect-m-axi-dc-read-issuing = <0x2>; + xlnx,interconnect-m-axi-dc-write-issuing = <0x20>; + xlnx,interconnect-m-axi-dp-read-issuing = <0x1>; + xlnx,interconnect-m-axi-dp-write-issuing = <0x1>; + xlnx,interconnect-m-axi-ic-read-issuing = <0x8>; + xlnx,interconnect-m-axi-ip-read-issuing = <0x1>; + xlnx,interrupt-is-edge = <0x0>; + xlnx,lockstep-slave = <0x0>; + xlnx,mmu-dtlb-size = <0x4>; + xlnx,mmu-itlb-size = <0x2>; + xlnx,mmu-privileged-instr = <0x0>; + xlnx,mmu-tlb-access = <0x3>; + xlnx,mmu-zones = <0x2>; + xlnx,number-of-pc-brk = <0x1>; + xlnx,number-of-rd-addr-brk = <0x0>; + xlnx,number-of-wr-addr-brk = <0x0>; + xlnx,opcode-0x0-illegal = <0x1>; + xlnx,optimization = <0x0>; + xlnx,pc-width = <0x20>; + xlnx,pvr = <0x2>; + xlnx,pvr-user1 = <0x0>; + xlnx,pvr-user2 = <0x0>; + xlnx,reset-msr = <0x0>; + xlnx,sco = <0x0>; + xlnx,stream-interconnect = <0x0>; + xlnx,unaligned-exceptions = <0x1>; + xlnx,use-barrel = <0x1>; + xlnx,use-branch-target-cache = <0x0>; + xlnx,use-dcache = <0x1>; + xlnx,use-div = <0x1>; + xlnx,use-ext-brk = <0x1>; + xlnx,use-ext-nm-brk = <0x1>; + xlnx,use-extended-fsl-instr = <0x0>; + xlnx,use-fpu = <0x0>; + xlnx,use-hw-mul = <0x2>; + xlnx,use-icache = <0x1>; + xlnx,use-interrupt = <0x1>; + xlnx,use-mmu = <0x3>; + xlnx,use-msr-instr = <0x1>; + xlnx,use-pcmp-instr = <0x1>; + xlnx,use-reorder-instr = <0x1>; + xlnx,use-stack-protection = <0x0>; + } ; + } ; + axi4lite_0: axi@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,axi-interconnect-1.06.a", "simple-bus"; + ranges ; + Ethernet_Lite: ethernet@40e00000 { + compatible = "xlnx,axi-ethernetlite-1.01.b", "xlnx,xps-ethernetlite-1.00.a"; + device_type = "network"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 4 0 >; + local-mac-address = [ 00 0a 35 b9 b5 00 ]; + phy-handle = <&phy0>; + reg = < 0x40e00000 0x10000 >; + xlnx,duplex = <0x1>; + xlnx,family = "kintex7"; + xlnx,include-global-buffers = <0x0>; + xlnx,include-internal-loopback = <0x0>; + xlnx,include-mdio = <0x1>; + xlnx,include-phy-constraints = <0x1>; + xlnx,instance = "Ethernet_Lite"; + xlnx,interconnect-s-axi-read-acceptance = <0x1>; + xlnx,interconnect-s-axi-write-acceptance = <0x1>; + xlnx,rx-ping-pong = <0x0>; + xlnx,s-axi-aclk-period-ps = <0x2710>; + xlnx,s-axi-id-width = <0x1>; + xlnx,s-axi-supports-narrow-burst = <0x0>; + xlnx,tx-ping-pong = <0x0>; + mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: phy@7 { + compatible = "marvell,88e1111"; + device_type = "ethernet-phy"; + reg = <7>; + } ; + } ; + } ; + RS232_Uart_1: serial@40600000 { + clock-frequency = <100000000>; + compatible = "xlnx,axi-uartlite-1.02.a", "xlnx,xps-uartlite-1.00.a"; + current-speed = <57600>; + device_type = "serial"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 5 0 >; + port-number = <0>; + reg = < 0x40600000 0x10000 >; + xlnx,baudrate = <0xe100>; + xlnx,data-bits = <0x8>; + xlnx,family = "kintex7"; + xlnx,instance = "RS232_Uart_1"; + xlnx,odd-parity = <0x1>; + xlnx,s-axi-aclk-freq-hz = <0x5f5e100>; + xlnx,use-parity = <0x0>; + } ; + axi_ad9250_0: cf-ad9250-1@7c820000 { + compatible = "xlnx,axi-ad9250-1.00.a"; + reg = < 0x7c820000 0x10000 >; + dma-request = <&axi_dma_0 0>; + spibus-connected = <&adc0_ad9250>; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "kintex7"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; + axi_ad9250_1: cf-ad9250-2@7c800000 { + compatible = "xlnx,axi-ad9250-1.00.a"; + reg = < 0x7c800000 0x10000 >; + dma-request = <&axi_dma_1 0>; + spibus-connected = <&adc1_ad9250>; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "kintex7"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; + axi_dma_0: axidma@41e20000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-dma"; + ranges = < 0x41e20000 0x41e20000 0x10000 >; + reg = < 0x41e20000 0x10000 >; +// xlnx,sg-include-stscntrl-strm = <0x0>; + dma-channel@41e20030 { + compatible = "xlnx,axi-dma-s2mm-channel"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 2 2 >; + xlnx,datawidth = <0x40>; + xlnx,include-dre = <0x0>; + } ; + } ; + axi_dma_1: axidma@41e00000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-dma"; + ranges = < 0x41e00000 0x41e00000 0x10000 >; + reg = < 0x41e00000 0x10000 >; +// xlnx,sg-include-stscntrl-strm = <0x0>; + dma-channel@41e00030 { + compatible = "xlnx,axi-dma-s2mm-channel"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 1 2 >; + xlnx,datawidth = <0x40>; + xlnx,include-dre = <0x0>; + } ; + } ; + + /* LCD Display */ + + axi_gpio_0: gpio@40000000 { + compatible = "xlnx,axi-xlnx-lcd-1.00.a"; + reg = < 0x40000000 0x8 >; + xlnx,all-inputs = <0x0>; + xlnx,dout-default = <0x0>; + xlnx,family = "kintex7"; + xlnx,gpio-width = <0x7>; + xlnx,instance = "axi_gpio_0"; + xlnx,interrupt-present = <0x0>; + xlnx,is-dual = <0x0>; + xlnx,tri-default = <0xffffffff>; + } ; + + /* axi_gpio_1_ad8372_ctrl */ + + axi_gpio_2: gpio@40040000 { + compatible = "xlnx,axi-gpio-1.01.b", "xlnx,xps-gpio-1.00.a"; + reg = < 0x40040000 0x8 >; + xlnx,all-inputs = <0x0>; + xlnx,dout-default = <0x0>; + xlnx,family = "kintex7"; + xlnx,gpio-width = <0x8>; + xlnx,instance = "axi_gpio_1"; + xlnx,interrupt-present = <0x0>; + xlnx,is-dual = <0x0>; + xlnx,tri-default = <0xffffffff>; + } ; + + /* axi_gpio_1_rstb_pwdn */ + + axi_gpio_3: gpio@40040008 { + compatible = "xlnx,axi-gpio-1.01.b", "xlnx,xps-gpio-1.00.a"; + reg = < 0x40040008 0x8 >; + xlnx,all-inputs = <0x0>; + xlnx,dout-default = <0x3>; + xlnx,family = "kintex7"; + xlnx,gpio-width = <0x4>; + xlnx,instance = "axi_gpio_1"; + xlnx,interrupt-present = <0x0>; + xlnx,is-dual = <0x0>; + xlnx,tri-default = <0xfffffff0>; + } ; + + axi_intc_0: interrupt-controller@41200000 { + #interrupt-cells = <0x2>; + compatible = "xlnx,axi-intc-1.01.a", "xlnx,xps-intc-1.00.a"; + interrupt-controller ; + reg = < 0x41200000 0x10000 >; + xlnx,kind-of-intr = <0x30>; + xlnx,num-intr-inputs = <0x6>; + } ; + axi_jesd204b_rx4_0: axi-jesd204b-rx4@77a20000 { + compatible = "xlnx,axi-jesd204b-rx4-1.00.a"; + reg = < 0x77a20000 0x10000 >; + jesd,lanesync_en; + jesd,scramble_en; + jesd,frames-per-multiframe = <32>; + jesd,bytes-per-frame = <2>; + xlnx,cf-buftype = <0x1>; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "kintex7"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; + + axi_spi_0: spi@40a00000 { + compatible = "xlnx,axi-spi-1.02.a", "xlnx,xps-spi-2.00.a"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 0 2 >; + reg = < 0x40a00000 0x10000 >; + xlnx,family = "kintex7"; + xlnx,fifo-exist = <0x1>; + xlnx,instance = "axi_spi_0"; + xlnx,num-ss-bits = <0x2>; + xlnx,num-transfer-bits = <0x8>; + xlnx,sck-ratio = <0x20>; + adc0_ad9250: ad9250@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "ad9250"; + reg = <0>; + spi-max-frequency = <10000000>; + }; + adc1_ad9250: ad9250@1 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "ad9250"; + reg = <1>; + spi-max-frequency = <10000000>; + }; + + } ; + axi_timer_0: timer@41c00000 { + clock-frequency = <100000000>; + compatible = "xlnx,axi-timer-1.03.a", "xlnx,xps-timer-1.00.a"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 3 2 >; + reg = < 0x41c00000 0x10000 >; + xlnx,count-width = <0x20>; + xlnx,family = "kintex7"; + xlnx,gen0-assert = <0x1>; + xlnx,gen1-assert = <0x1>; + xlnx,instance = "axi_timer_0"; + xlnx,one-timer-only = <0x0>; + xlnx,trig0-assert = <0x1>; + xlnx,trig1-assert = <0x1>; + } ; + debug_module: debug@41400000 { + compatible = "xlnx,mdm-2.00.b"; + reg = < 0x41400000 0x10000 >; + xlnx,family = "kintex7"; + xlnx,interconnect = <0x2>; + xlnx,jtag-chain = <0x2>; + xlnx,mb-dbg-ports = <0x1>; + xlnx,use-uart = <0x1>; + } ; + } ; +} ; diff --git a/arch/microblaze/boot/dts/cf_ad9265_ml605.dts b/arch/microblaze/boot/dts/cf_ad9265_ml605.dts new file mode 100644 index 0000000000000..b72c5c497dcc3 --- /dev/null +++ b/arch/microblaze/boot/dts/cf_ad9265_ml605.dts @@ -0,0 +1,328 @@ +/* + * Device Tree Generator version: 1.3 + * + * (C) Copyright 2007-2008 Xilinx, Inc. + * (C) Copyright 2007-2009 Michal Simek + * + * Michal SIMEK + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * CAUTION: This file is automatically generated by libgen. + * Version: Xilinx EDK 14.1 EDK_P.15xf + * + * XPS project directory: device-tree_bsp_0 + */ + +/dts-v1/; +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,microblaze"; + model = "testing"; + DDR3_SDRAM: memory@c0000000 { + device_type = "memory"; + reg = < 0xc0000000 0x20000000 >; + } ; + aliases { + ethernet0 = &Ethernet_Lite; + serial0 = &RS232_Uart_1; + } ; + chosen { + bootargs = "console=ttyS0 root=/dev/ram"; + } ; + cpus { + #address-cells = <1>; + #cpus = <0x1>; + #size-cells = <0>; + microblaze_0: cpu@0 { + clock-frequency = <100000000>; + compatible = "xlnx,microblaze-8.30.a"; + d-cache-baseaddr = <0xc0000000>; + d-cache-highaddr = <0xdfffffff>; + d-cache-line-size = <0x10>; + d-cache-size = <0x4000>; + device_type = "cpu"; + i-cache-baseaddr = <0xc0000000>; + i-cache-highaddr = <0xdfffffff>; + i-cache-line-size = <0x20>; + i-cache-size = <0x4000>; + model = "microblaze,8.30.a"; + reg = <0>; + timebase-frequency = <100000000>; + xlnx,addr-tag-bits = <0xf>; + xlnx,allow-dcache-wr = <0x1>; + xlnx,allow-icache-wr = <0x1>; + xlnx,area-optimized = <0x0>; + xlnx,avoid-primitives = <0x0>; + xlnx,branch-target-cache-size = <0x0>; + xlnx,cache-byte-size = <0x4000>; + xlnx,d-axi = <0x1>; + xlnx,d-lmb = <0x1>; + xlnx,d-plb = <0x0>; + xlnx,data-size = <0x20>; + xlnx,dcache-addr-tag = <0xf>; + xlnx,dcache-always-used = <0x1>; + xlnx,dcache-byte-size = <0x4000>; + xlnx,dcache-data-width = <0x0>; + xlnx,dcache-force-tag-lutram = <0x0>; + xlnx,dcache-interface = <0x0>; + xlnx,dcache-line-len = <0x4>; + xlnx,dcache-use-fsl = <0x0>; + xlnx,dcache-use-writeback = <0x0>; + xlnx,dcache-victims = <0x0>; + xlnx,debug-enabled = <0x1>; + xlnx,div-zero-exception = <0x1>; + xlnx,dynamic-bus-sizing = <0x1>; + xlnx,ecc-use-ce-exception = <0x0>; + xlnx,edge-is-positive = <0x1>; + xlnx,endianness = <0x1>; + xlnx,family = "virtex6"; + xlnx,fault-tolerant = <0x0>; + xlnx,fpu-exception = <0x0>; + xlnx,freq = <0x5f5e100>; + xlnx,fsl-data-size = <0x20>; + xlnx,fsl-exception = <0x0>; + xlnx,fsl-links = <0x0>; + xlnx,i-axi = <0x0>; + xlnx,i-lmb = <0x1>; + xlnx,i-plb = <0x0>; + xlnx,icache-always-used = <0x1>; + xlnx,icache-data-width = <0x0>; + xlnx,icache-force-tag-lutram = <0x0>; + xlnx,icache-interface = <0x0>; + xlnx,icache-line-len = <0x8>; + xlnx,icache-streams = <0x1>; + xlnx,icache-use-fsl = <0x0>; + xlnx,icache-victims = <0x8>; + xlnx,ill-opcode-exception = <0x1>; + xlnx,instance = "microblaze_0"; + xlnx,interconnect = <0x2>; + xlnx,interconnect-m-axi-dc-read-issuing = <0x2>; + xlnx,interconnect-m-axi-dc-write-issuing = <0x20>; + xlnx,interconnect-m-axi-dp-read-issuing = <0x1>; + xlnx,interconnect-m-axi-dp-write-issuing = <0x1>; + xlnx,interconnect-m-axi-ic-read-issuing = <0x8>; + xlnx,interconnect-m-axi-ip-read-issuing = <0x1>; + xlnx,interrupt-is-edge = <0x0>; + xlnx,lockstep-slave = <0x0>; + xlnx,mmu-dtlb-size = <0x4>; + xlnx,mmu-itlb-size = <0x2>; + xlnx,mmu-privileged-instr = <0x0>; + xlnx,mmu-tlb-access = <0x3>; + xlnx,mmu-zones = <0x2>; + xlnx,number-of-pc-brk = <0x1>; + xlnx,number-of-rd-addr-brk = <0x0>; + xlnx,number-of-wr-addr-brk = <0x0>; + xlnx,opcode-0x0-illegal = <0x1>; + xlnx,optimization = <0x0>; + xlnx,pc-width = <0x20>; + xlnx,pvr = <0x2>; + xlnx,pvr-user1 = <0x0>; + xlnx,pvr-user2 = <0x0>; + xlnx,reset-msr = <0x0>; + xlnx,sco = <0x0>; + xlnx,stream-interconnect = <0x0>; + xlnx,unaligned-exceptions = <0x1>; + xlnx,use-barrel = <0x1>; + xlnx,use-branch-target-cache = <0x0>; + xlnx,use-dcache = <0x1>; + xlnx,use-div = <0x1>; + xlnx,use-ext-brk = <0x1>; + xlnx,use-ext-nm-brk = <0x1>; + xlnx,use-extended-fsl-instr = <0x0>; + xlnx,use-fpu = <0x0>; + xlnx,use-hw-mul = <0x2>; + xlnx,use-icache = <0x1>; + xlnx,use-interrupt = <0x1>; + xlnx,use-mmu = <0x3>; + xlnx,use-msr-instr = <0x1>; + xlnx,use-pcmp-instr = <0x1>; + xlnx,use-reorder-instr = <0x1>; + xlnx,use-stack-protection = <0x0>; + } ; + } ; + axi4lite_0: axi@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,axi-interconnect-1.06.a", "simple-bus"; + ranges ; + Ethernet_Lite: ethernet@40e00000 { + compatible = "xlnx,axi-ethernetlite-1.01.b", "xlnx,xps-ethernetlite-1.00.a"; + device_type = "network"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 5 0 >; + local-mac-address = [ 00 0a 35 4d b4 00 ]; + phy-handle = <&phy0>; + reg = < 0x40e00000 0x10000 >; + xlnx,duplex = <0x1>; + xlnx,family = "virtex6"; + xlnx,include-global-buffers = <0x0>; + xlnx,include-internal-loopback = <0x0>; + xlnx,include-mdio = <0x1>; + xlnx,include-phy-constraints = <0x1>; + xlnx,instance = "Ethernet_Lite"; + xlnx,interconnect-s-axi-read-acceptance = <0x1>; + xlnx,interconnect-s-axi-write-acceptance = <0x1>; + xlnx,rx-ping-pong = <0x0>; + xlnx,s-axi-aclk-period-ps = <0x2710>; + xlnx,s-axi-id-width = <0x1>; + xlnx,s-axi-supports-narrow-burst = <0x0>; + xlnx,tx-ping-pong = <0x0>; + mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: phy@7 { + compatible = "marvell,88e1111"; + device_type = "ethernet-phy"; + reg = <7>; + } ; + } ; + } ; + RS232_Uart_1: serial@40600000 { + clock-frequency = <100000000>; + compatible = "xlnx,axi-uartlite-1.02.a", "xlnx,xps-uartlite-1.00.a"; + current-speed = <57600>; + device_type = "serial"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 6 0 >; + port-number = <0>; + reg = < 0x40600000 0x10000 >; + xlnx,baudrate = <0xe100>; + xlnx,data-bits = <0x8>; + xlnx,family = "virtex6"; + xlnx,instance = "RS232_Uart_1"; + xlnx,odd-parity = <0x1>; + xlnx,s-axi-aclk-freq-hz = <0x5f5e100>; + xlnx,use-parity = <0x0>; + } ; + axi_ad9265_0: cf-ad9265@73000000 { + compatible = "xlnx,axi-ad9265-1.00.a"; + reg = < 0x73000000 0x10000 >; + dma-request = <&axi_dma_0 0>; + spibus-connected = <&adc0_ad9265>; + xlnx,cf-buftype = <0x1>; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "virtex6"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; + axi_dma_0: axidma@41e00000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-dma"; + ranges = < 0x41e00000 0x41e00000 0x10000 >; + reg = < 0x41e00000 0x10000 >; +// xlnx,sg-include-stscntrl-strm = <0x0>; + dma-channel@41e00030 { + compatible = "xlnx,axi-dma-s2mm-channel"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 3 2 >; + xlnx,datawidth = <0x40>; + xlnx,include-dre = <0x0>; + } ; + } ; + axi_gpio_0: gpio@40000000 { + compatible = "xlnx,axi-xlnx-lcd-1.00.a"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 1 2 >; + reg = < 0x40000000 0x10000 >; + xlnx,all-inputs = <0x0>; + xlnx,all-inputs-2 = <0x0>; + xlnx,dout-default = <0x0>; + xlnx,dout-default-2 = <0x0>; + xlnx,family = "virtex6"; + xlnx,gpio-width = <0x7>; + xlnx,gpio2-width = <0x20>; + xlnx,instance = "axi_gpio_0"; + xlnx,interrupt-present = <0x1>; + xlnx,is-dual = <0x0>; + xlnx,tri-default = <0xffffffff>; + xlnx,tri-default-2 = <0xffffffff>; + } ; + axi_iic_0: i2c@40800000 { + compatible = "xlnx,axi-iic-1.02.a", "xlnx,xps-iic-2.00.a"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 0 2 >; + reg = < 0x40800000 0x10000 >; + xlnx,family = "virtex6"; + xlnx,gpo-width = <0x1>; + xlnx,iic-freq = <0x186a0>; + xlnx,instance = "axi_iic_0"; + xlnx,s-axi-aclk-freq-hz = <0x5f5e100>; + xlnx,scl-inertial-delay = <0x5>; + xlnx,sda-inertial-delay = <0x5>; + xlnx,sda-level = <0x1>; + xlnx,ten-bit-adr = <0x0>; + } ; + axi_intc_0: interrupt-controller@41200000 { + #interrupt-cells = <0x2>; + compatible = "xlnx,axi-intc-1.02.a", "xlnx,xps-intc-1.00.a"; + interrupt-controller ; + reg = < 0x41200000 0x10000 >; + xlnx,kind-of-intr = <0x60>; + xlnx,num-intr-inputs = <0x7>; + } ; + axi_spi_0: spi@40a00000 { + compatible = "xlnx,axi-spi-1.02.a", "xlnx,xps-spi-2.00.a"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 2 2 >; + reg = < 0x40a00000 0x10000 >; + xlnx,family = "virtex6"; + xlnx,fifo-exist = <0x1>; + xlnx,instance = "axi_spi_0"; + xlnx,num-ss-bits = <0x2>; + xlnx,num-transfer-bits = <0x8>; + xlnx,sck-ratio = <0x20>; + adc0_ad9265: ad9265@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "ad9265"; + reg = <0>; + spi-max-frequency = <10000000>; + }; + } ; + axi_timer_0: timer@41c00000 { + clock-frequency = <100000000>; + compatible = "xlnx,axi-timer-1.03.a", "xlnx,xps-timer-1.00.a"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 4 2 >; + reg = < 0x41c00000 0x10000 >; + xlnx,count-width = <0x20>; + xlnx,family = "virtex6"; + xlnx,gen0-assert = <0x1>; + xlnx,gen1-assert = <0x1>; + xlnx,instance = "axi_timer_0"; + xlnx,one-timer-only = <0x0>; + xlnx,trig0-assert = <0x1>; + xlnx,trig1-assert = <0x1>; + } ; + debug_module: debug@74800000 { + compatible = "xlnx,mdm-2.00.b"; + reg = < 0x74800000 0x10000 >; + xlnx,family = "virtex6"; + xlnx,interconnect = <0x2>; + xlnx,jtag-chain = <0x2>; + xlnx,mb-dbg-ports = <0x1>; + xlnx,use-uart = <0x1>; + } ; + } ; +} ; diff --git a/arch/microblaze/boot/dts/kc705_2xcomm_fft.dts b/arch/microblaze/boot/dts/kc705_2xcomm_fft.dts new file mode 100644 index 0000000000000..74c5fe530d59b --- /dev/null +++ b/arch/microblaze/boot/dts/kc705_2xcomm_fft.dts @@ -0,0 +1,461 @@ +/* + * Device Tree Generator version: 1.3 + * + * (C) Copyright 2007-2008 Xilinx, Inc. + * (C) Copyright 2007-2009 Michal Simek + * + * Michal SIMEK + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * CAUTION: This file is automatically generated by libgen. + * Version: Xilinx EDK 13.4 EDK_O.87xd + * + * XPS project directory: device-tree_bsp_1 + */ + +/dts-v1/; +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,microblaze"; + model = "testing"; + DDR3_SDRAM: memory@c0000000 { + device_type = "memory"; + reg = < 0xc0000000 0x20000000 >; + } ; + aliases { + ethernet0 = &Ethernet_Lite; + serial0 = &RS232_Uart_1; + } ; + chosen { + bootargs = "console=ttyS0 root=/dev/ram"; + } ; + cpus { + #address-cells = <1>; + #cpus = <0x1>; + #size-cells = <0>; + microblaze_0: cpu@0 { + clock-frequency = <100000000>; + compatible = "xlnx,microblaze-8.20.b"; + d-cache-baseaddr = <0xc0000000>; + d-cache-highaddr = <0xdfffffff>; + d-cache-line-size = <0x10>; + d-cache-size = <0x4000>; + device_type = "cpu"; + i-cache-baseaddr = <0xc0000000>; + i-cache-highaddr = <0xdfffffff>; + i-cache-line-size = <0x20>; + i-cache-size = <0x4000>; + model = "microblaze,8.20.b"; + reg = <0>; + timebase-frequency = <100000000>; + xlnx,addr-tag-bits = <0xf>; + xlnx,allow-dcache-wr = <0x1>; + xlnx,allow-icache-wr = <0x1>; + xlnx,area-optimized = <0x0>; + xlnx,avoid-primitives = <0x0>; + xlnx,branch-target-cache-size = <0x0>; + xlnx,cache-byte-size = <0x4000>; + xlnx,d-axi = <0x1>; + xlnx,d-lmb = <0x1>; + xlnx,d-plb = <0x0>; + xlnx,data-size = <0x20>; + xlnx,dcache-addr-tag = <0xf>; + xlnx,dcache-always-used = <0x1>; + xlnx,dcache-byte-size = <0x4000>; + xlnx,dcache-data-width = <0x0>; + xlnx,dcache-force-tag-lutram = <0x0>; + xlnx,dcache-interface = <0x0>; + xlnx,dcache-line-len = <0x4>; + xlnx,dcache-use-fsl = <0x0>; + xlnx,dcache-use-writeback = <0x0>; + xlnx,dcache-victims = <0x0>; + xlnx,debug-enabled = <0x1>; + xlnx,div-zero-exception = <0x1>; + xlnx,dynamic-bus-sizing = <0x1>; + xlnx,ecc-use-ce-exception = <0x0>; + xlnx,edge-is-positive = <0x1>; + xlnx,endianness = <0x1>; + xlnx,family = "kintex7"; + xlnx,fault-tolerant = <0x0>; + xlnx,fpu-exception = <0x0>; + xlnx,freq = <0x5f5e100>; + xlnx,fsl-data-size = <0x20>; + xlnx,fsl-exception = <0x0>; + xlnx,fsl-links = <0x0>; + xlnx,i-axi = <0x0>; + xlnx,i-lmb = <0x1>; + xlnx,i-plb = <0x0>; + xlnx,icache-always-used = <0x1>; + xlnx,icache-data-width = <0x0>; + xlnx,icache-force-tag-lutram = <0x0>; + xlnx,icache-interface = <0x0>; + xlnx,icache-line-len = <0x8>; + xlnx,icache-streams = <0x1>; + xlnx,icache-use-fsl = <0x0>; + xlnx,icache-victims = <0x8>; + xlnx,ill-opcode-exception = <0x1>; + xlnx,instance = "microblaze_0"; + xlnx,interconnect = <0x2>; + xlnx,interconnect-m-axi-dc-read-issuing = <0x2>; + xlnx,interconnect-m-axi-dc-write-issuing = <0x20>; + xlnx,interconnect-m-axi-dp-read-issuing = <0x1>; + xlnx,interconnect-m-axi-dp-write-issuing = <0x1>; + xlnx,interconnect-m-axi-ic-read-issuing = <0x8>; + xlnx,interconnect-m-axi-ip-read-issuing = <0x1>; + xlnx,interrupt-is-edge = <0x0>; + xlnx,lockstep-slave = <0x0>; + xlnx,mmu-dtlb-size = <0x4>; + xlnx,mmu-itlb-size = <0x2>; + xlnx,mmu-privileged-instr = <0x0>; + xlnx,mmu-tlb-access = <0x3>; + xlnx,mmu-zones = <0x2>; + xlnx,number-of-pc-brk = <0x1>; + xlnx,number-of-rd-addr-brk = <0x0>; + xlnx,number-of-wr-addr-brk = <0x0>; + xlnx,opcode-0x0-illegal = <0x1>; + xlnx,optimization = <0x0>; + xlnx,pvr = <0x2>; + xlnx,pvr-user1 = <0x0>; + xlnx,pvr-user2 = <0x0>; + xlnx,reset-msr = <0x0>; + xlnx,sco = <0x0>; + xlnx,stream-interconnect = <0x0>; + xlnx,unaligned-exceptions = <0x1>; + xlnx,use-barrel = <0x1>; + xlnx,use-branch-target-cache = <0x0>; + xlnx,use-dcache = <0x1>; + xlnx,use-div = <0x1>; + xlnx,use-ext-brk = <0x1>; + xlnx,use-ext-nm-brk = <0x1>; + xlnx,use-extended-fsl-instr = <0x0>; + xlnx,use-fpu = <0x0>; + xlnx,use-hw-mul = <0x2>; + xlnx,use-icache = <0x1>; + xlnx,use-interrupt = <0x1>; + xlnx,use-mmu = <0x3>; + xlnx,use-msr-instr = <0x1>; + xlnx,use-pcmp-instr = <0x1>; + xlnx,use-stack-protection = <0x0>; + } ; + } ; + axi4lite_0: axi@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,axi-interconnect-1.05.a", "simple-bus"; + ranges ; + Ethernet_Lite: ethernet@40e00000 { + compatible = "xlnx,axi-ethernetlite-1.01.b", "xlnx,xps-ethernetlite-1.00.a"; + device_type = "network"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 8 0 >; + local-mac-address = [ 00 0a 35 bb 67 00 ]; + phy-handle = <&phy0>; + reg = < 0x40e00000 0x10000 >; + xlnx,duplex = <0x1>; + xlnx,family = "kintex7"; + xlnx,include-global-buffers = <0x0>; + xlnx,include-internal-loopback = <0x0>; + xlnx,include-mdio = <0x1>; + xlnx,include-phy-constraints = <0x1>; + xlnx,interconnect-s-axi-read-acceptance = <0x1>; + xlnx,interconnect-s-axi-write-acceptance = <0x1>; + xlnx,rx-ping-pong = <0x0>; + xlnx,s-axi-aclk-period-ps = <0x2710>; + xlnx,s-axi-id-width = <0x1>; + xlnx,s-axi-supports-narrow-burst = <0x0>; + xlnx,tx-ping-pong = <0x0>; + mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: phy@7 { + compatible = "marvell,88e1111"; + device_type = "ethernet-phy"; + reg = <7>; + } ; + } ; + } ; + RS232_Uart_1: serial@40600000 { + clock-frequency = <100000000>; + compatible = "xlnx,axi-uartlite-1.02.a", "xlnx,xps-uartlite-1.00.a"; + current-speed = <57600>; + device_type = "serial"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 9 0 >; + port-number = <0>; + reg = < 0x40600000 0x10000 >; + xlnx,baudrate = <0xe100>; + xlnx,data-bits = <0x8>; + xlnx,family = "kintex7"; + xlnx,odd-parity = <0x1>; + xlnx,s-axi-aclk-freq-hz = <0x5f5e100>; + xlnx,use-parity = <0x0>; + } ; + axi_dma_0: axidma@41e20000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-dma"; + ranges = < 0x41e20000 0x41e20000 0x10000 >; + reg = < 0x41e20000 0x10000 >; +// xlnx,sg-include-stscntrl-strm = <0x0>; + dma-channel@41e20030 { + compatible = "xlnx,axi-dma-s2mm-channel"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 5 2 >; + xlnx,datawidth = <0x40>; + xlnx,include-dre = <0x0>; + } ; + } ; + axi_dma_1: axidma@41e00000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-dma"; + ranges = < 0x41e00000 0x41e00000 0x10000 >; + reg = < 0x41e00000 0x10000 >; +// xlnx,sg-include-stscntrl-strm = <0x0>; + dma-channel@41e00030 { + compatible = "xlnx,axi-dma-s2mm-channel"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 4 2 >; + xlnx,datawidth = <0x40>; + xlnx,include-dre = <0x0>; + } ; + } ; + axi_iic_0: i2c@40800000 { + compatible = "xlnx,axi-iic-1.01.b", "xlnx,xps-iic-2.00.a"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 6 2 >; + reg = < 0x40800000 0x10000 >; + xlnx,family = "kintex7"; + xlnx,gpo-width = <0x1>; + xlnx,iic-freq = <0x186a0>; + xlnx,s-axi-aclk-freq-hz = <0x5f5e100>; + xlnx,scl-inertial-delay = <0x5>; + xlnx,sda-inertial-delay = <0x5>; + xlnx,sda-level = <0x1>; + xlnx,ten-bit-adr = <0x0>; + mux@74 { + compatible = "pca9548"; + reg = <0x74>; + mux1: i2c@1 { /* HPC */ + #size-cells = <0>; + #address-cells = <1>; + cell-index = <1>; + spi_xcomm1: spi_xcomm1@58 { + compatible = "spi-xcomm"; + reg = <0x58>; + dac1_ad9122: ad9122@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "ad9122"; + reg = <0>; + spi-max-frequency = <10000000>; + }; + + }; + }; + + mux2: i2c@2 { /* LPC */ + #size-cells = <0>; + #address-cells = <1>; + cell-index = <2>; + spi_xcomm0: spi_xcomm0@58 { + compatible = "spi-xcomm"; + reg = <0x58>; + dac0_ad9122: ad9122@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "ad9122"; + reg = <0>; + spi-max-frequency = <10000000>; + }; + + }; + }; + }; + } ; + axi_intc_0: interrupt-controller@41200000 { + #interrupt-cells = <0x2>; + compatible = "xlnx,axi-intc-1.01.a", "xlnx,xps-intc-1.00.a"; + interrupt-controller ; + reg = < 0x41200000 0x10000 >; + xlnx,kind-of-intr = <0x300>; + xlnx,num-intr-inputs = <0xa>; + } ; +// axi_interconnect_1: axi@41e40000 { +// #address-cells = <1>; +// #size-cells = <1>; +// compatible = "xlnx,axi-interconnect-1.05.a", "simple-bus"; + axi_dma_2: axidma@41e40000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-dma"; + ranges = < 0x41e40000 0x41e40000 0x10000 >; + reg = < 0x41e40000 0x10000 >; +// xlnx,sg-include-stscntrl-strm = <0x0>; + dma-channel@41e40000 { + compatible = "xlnx,axi-dma-mm2s-channel"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 1 2 >; + xlnx,datawidth = <0x20>; + xlnx,include-dre = <0x0>; + } ; + dma-channel@41e40030 { + compatible = "xlnx,axi-dma-s2mm-channel"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 0 2 >; + xlnx,datawidth = <0x20>; + xlnx,include-dre = <0x0>; + } ; + } ; +// } ; + axi_timer_0: timer@41c00000 { + clock-frequency = <100000000>; + compatible = "xlnx,axi-timer-1.02.a", "xlnx,xps-timer-1.00.a"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 7 2 >; + reg = < 0x41c00000 0x10000 >; + xlnx,count-width = <0x20>; + xlnx,family = "kintex7"; + xlnx,gen0-assert = <0x1>; + xlnx,gen1-assert = <0x1>; + xlnx,one-timer-only = <0x0>; + xlnx,trig0-assert = <0x1>; + xlnx,trig1-assert = <0x1>; + } ; + axi_vdma_0: axivdma@7e220000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-vdma"; + ranges = < 0x7e220000 0x7e220000 0x10000 >; + reg = < 0x7e220000 0x10000 >; + xlnx,include-sg = <0x0>; + xlnx,num-fstores = <0x3>; + dma-channel@7e220000 { + compatible = "xlnx,axi-vdma-mm2s-channel"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 3 2 >; + xlnx,datawidth = <0x40>; + xlnx,genlock-mode = <0x0>; + xlnx,include-dre = <0x0>; + } ; + } ; + axi_vdma_1: axivdma@7e200000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-vdma"; + ranges = < 0x7e200000 0x7e200000 0x10000 >; + reg = < 0x7e200000 0x10000 >; + xlnx,include-sg = <0x0>; + xlnx,num-fstores = <0x3>; + dma-channel@7e200000 { + compatible = "xlnx,axi-vdma-mm2s-channel"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 2 2 >; + xlnx,datawidth = <0x40>; + xlnx,genlock-mode = <0x0>; + xlnx,include-dre = <0x0>; + } ; + } ; + cf_ad9122_core_0: cf-ad9122-core-lpc@73060000 { + compatible = "xlnx,cf-ad9122-core-2.00.a"; + reg = < 0x73060000 0x10000 >; + spibus-connected = <&dac0_ad9122>; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "kintex7"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; + cf_ad9122_core_1: cf-ad9122-core-hpc@73040000 { + compatible = "xlnx,cf-ad9122-core-2.00.a"; + reg = < 0x73040000 0x10000 >; + spibus-connected = <&dac1_ad9122>; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "kintex7"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; + cf_ad9643_core_0: cf-ad9643-core-lpc@73020000 { + compatible = "xlnx,cf-ad9643-core-1.00.a"; + reg = < 0x73020000 0x10000 >; + dma-request = <&axi_dma_0 0>; + spibus-connected = <&spi_xcomm0>; + spibus-slaveselect-connected = <0x1>; + dco-output-delay = <0x89>; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "kintex7"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; + cf_ad9643_core_1: cf-ad9643-core-hpc@73000000 { + compatible = "xlnx,cf-ad9643-core-1.00.a"; + reg = < 0x73000000 0x10000 >; + dma-request = <&axi_dma_1 0>; + spibus-connected = <&spi_xcomm1>; + spibus-slaveselect-connected = <0x1>; + dco-output-delay = <0x50>; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "kintex7"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; + cf_fft_core_0: cf-fft-core@7a200000 { + compatible = "xlnx,cf-fft-core-1.00.a"; + reg = < 0x7a200000 0x10000 >; + dma-request = <&axi_dma_2 0 + &axi_dma_2 1>; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "kintex7"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; + debug_module: debug@41400000 { + compatible = "xlnx,mdm-2.00.b"; + reg = < 0x41400000 0x10000 >; + xlnx,family = "kintex7"; + xlnx,interconnect = <0x2>; + xlnx,jtag-chain = <0x2>; + xlnx,mb-dbg-ports = <0x1>; + xlnx,use-uart = <0x1>; + } ; + } ; +} ; diff --git a/arch/microblaze/boot/dts/ml605_2xcomm_fft.dts b/arch/microblaze/boot/dts/ml605_2xcomm_fft.dts new file mode 100644 index 0000000000000..def8911556d6b --- /dev/null +++ b/arch/microblaze/boot/dts/ml605_2xcomm_fft.dts @@ -0,0 +1,458 @@ +/* + * Device Tree Generator version: 1.3 + * + * (C) Copyright 2007-2008 Xilinx, Inc. + * (C) Copyright 2007-2009 Michal Simek + * + * Michal SIMEK + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * CAUTION: This file is automatically generated by libgen. + * Version: Xilinx EDK 13.4 EDK_O.87xd + * + * XPS project directory: device-tree_bsp_1 + */ + +/dts-v1/; +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,microblaze"; + model = "testing"; + DDR3_SDRAM: memory@c0000000 { + device_type = "memory"; + reg = < 0xc0000000 0x20000000 >; + } ; + aliases { + ethernet0 = &Ethernet_Lite; + serial0 = &RS232_Uart_1; + } ; + chosen { + bootargs = "console=ttyS0 root=/dev/ram"; + } ; + cpus { + #address-cells = <1>; + #cpus = <0x1>; + #size-cells = <0>; + microblaze_0: cpu@0 { + clock-frequency = <100000000>; + compatible = "xlnx,microblaze-8.20.b"; + d-cache-baseaddr = <0xc0000000>; + d-cache-highaddr = <0xdfffffff>; + d-cache-line-size = <0x10>; + d-cache-size = <0x4000>; + device_type = "cpu"; + i-cache-baseaddr = <0xc0000000>; + i-cache-highaddr = <0xdfffffff>; + i-cache-line-size = <0x20>; + i-cache-size = <0x4000>; + model = "microblaze,8.20.b"; + reg = <0>; + timebase-frequency = <100000000>; + xlnx,addr-tag-bits = <0xf>; + xlnx,allow-dcache-wr = <0x1>; + xlnx,allow-icache-wr = <0x1>; + xlnx,area-optimized = <0x0>; + xlnx,avoid-primitives = <0x0>; + xlnx,branch-target-cache-size = <0x0>; + xlnx,cache-byte-size = <0x4000>; + xlnx,d-axi = <0x1>; + xlnx,d-lmb = <0x1>; + xlnx,d-plb = <0x0>; + xlnx,data-size = <0x20>; + xlnx,dcache-addr-tag = <0xf>; + xlnx,dcache-always-used = <0x1>; + xlnx,dcache-byte-size = <0x4000>; + xlnx,dcache-data-width = <0x0>; + xlnx,dcache-force-tag-lutram = <0x0>; + xlnx,dcache-interface = <0x0>; + xlnx,dcache-line-len = <0x4>; + xlnx,dcache-use-fsl = <0x0>; + xlnx,dcache-use-writeback = <0x0>; + xlnx,dcache-victims = <0x0>; + xlnx,debug-enabled = <0x1>; + xlnx,div-zero-exception = <0x1>; + xlnx,dynamic-bus-sizing = <0x1>; + xlnx,ecc-use-ce-exception = <0x0>; + xlnx,edge-is-positive = <0x1>; + xlnx,endianness = <0x1>; + xlnx,family = "virtex6"; + xlnx,fault-tolerant = <0x0>; + xlnx,fpu-exception = <0x0>; + xlnx,freq = <0x5f5e100>; + xlnx,fsl-data-size = <0x20>; + xlnx,fsl-exception = <0x0>; + xlnx,fsl-links = <0x0>; + xlnx,i-axi = <0x0>; + xlnx,i-lmb = <0x1>; + xlnx,i-plb = <0x0>; + xlnx,icache-always-used = <0x1>; + xlnx,icache-data-width = <0x0>; + xlnx,icache-force-tag-lutram = <0x0>; + xlnx,icache-interface = <0x0>; + xlnx,icache-line-len = <0x8>; + xlnx,icache-streams = <0x1>; + xlnx,icache-use-fsl = <0x0>; + xlnx,icache-victims = <0x8>; + xlnx,ill-opcode-exception = <0x1>; + xlnx,instance = "microblaze_0"; + xlnx,interconnect = <0x2>; + xlnx,interconnect-m-axi-dc-read-issuing = <0x2>; + xlnx,interconnect-m-axi-dc-write-issuing = <0x20>; + xlnx,interconnect-m-axi-dp-read-issuing = <0x1>; + xlnx,interconnect-m-axi-dp-write-issuing = <0x1>; + xlnx,interconnect-m-axi-ic-read-issuing = <0x8>; + xlnx,interconnect-m-axi-ip-read-issuing = <0x1>; + xlnx,interrupt-is-edge = <0x0>; + xlnx,lockstep-slave = <0x0>; + xlnx,mmu-dtlb-size = <0x4>; + xlnx,mmu-itlb-size = <0x2>; + xlnx,mmu-privileged-instr = <0x0>; + xlnx,mmu-tlb-access = <0x3>; + xlnx,mmu-zones = <0x2>; + xlnx,number-of-pc-brk = <0x1>; + xlnx,number-of-rd-addr-brk = <0x0>; + xlnx,number-of-wr-addr-brk = <0x0>; + xlnx,opcode-0x0-illegal = <0x1>; + xlnx,optimization = <0x0>; + xlnx,pvr = <0x2>; + xlnx,pvr-user1 = <0x0>; + xlnx,pvr-user2 = <0x0>; + xlnx,reset-msr = <0x0>; + xlnx,sco = <0x0>; + xlnx,stream-interconnect = <0x0>; + xlnx,unaligned-exceptions = <0x1>; + xlnx,use-barrel = <0x1>; + xlnx,use-branch-target-cache = <0x0>; + xlnx,use-dcache = <0x1>; + xlnx,use-div = <0x1>; + xlnx,use-ext-brk = <0x1>; + xlnx,use-ext-nm-brk = <0x1>; + xlnx,use-extended-fsl-instr = <0x0>; + xlnx,use-fpu = <0x0>; + xlnx,use-hw-mul = <0x2>; + xlnx,use-icache = <0x1>; + xlnx,use-interrupt = <0x1>; + xlnx,use-mmu = <0x3>; + xlnx,use-msr-instr = <0x1>; + xlnx,use-pcmp-instr = <0x1>; + xlnx,use-stack-protection = <0x0>; + } ; + } ; + axi4lite_0: axi@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,axi-interconnect-1.05.a", "simple-bus"; + ranges ; + Ethernet_Lite: ethernet@40e00000 { + compatible = "xlnx,axi-ethernetlite-1.01.b", "xlnx,xps-ethernetlite-1.00.a"; + device_type = "network"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 9 0 >; + local-mac-address = [ 00 0a 35 69 1c 00 ]; + phy-handle = <&phy0>; + reg = < 0x40e00000 0x10000 >; + xlnx,duplex = <0x1>; + xlnx,family = "virtex6"; + xlnx,include-global-buffers = <0x0>; + xlnx,include-internal-loopback = <0x0>; + xlnx,include-mdio = <0x1>; + xlnx,include-phy-constraints = <0x1>; + xlnx,interconnect-s-axi-read-acceptance = <0x1>; + xlnx,interconnect-s-axi-write-acceptance = <0x1>; + xlnx,rx-ping-pong = <0x0>; + xlnx,s-axi-aclk-period-ps = <0x2710>; + xlnx,s-axi-id-width = <0x1>; + xlnx,s-axi-supports-narrow-burst = <0x0>; + xlnx,tx-ping-pong = <0x0>; + mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: phy@7 { + compatible = "marvell,88e1111"; + device_type = "ethernet-phy"; + reg = <7>; + } ; + } ; + } ; + RS232_Uart_1: serial@40600000 { + clock-frequency = <100000000>; + compatible = "xlnx,axi-uartlite-1.02.a", "xlnx,xps-uartlite-1.00.a"; + current-speed = <57600>; + device_type = "serial"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 10 0 >; + port-number = <0>; + reg = < 0x40600000 0x10000 >; + xlnx,baudrate = <0xe100>; + xlnx,data-bits = <0x8>; + xlnx,family = "virtex6"; + xlnx,odd-parity = <0x1>; + xlnx,s-axi-aclk-freq-hz = <0x5f5e100>; + xlnx,use-parity = <0x0>; + } ; + axi_dma_0: axidma@41e00000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-dma"; + ranges = < 0x41e00000 0x41e00000 0x10000 >; + reg = < 0x41e00000 0x10000 >; +// xlnx,sg-include-stscntrl-strm = <0x0>; + dma-channel@41e00030 { + compatible = "xlnx,axi-dma-s2mm-channel"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 7 2 >; + xlnx,datawidth = <0x40>; + xlnx,include-dre = <0x0>; + } ; + } ; + axi_dma_1: axidma@41e10000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-dma"; + ranges = < 0x41e10000 0x41e10000 0x10000 >; + reg = < 0x41e10000 0x10000 >; +// xlnx,sg-include-stscntrl-strm = <0x0>; + dma-channel@41e10030 { + compatible = "xlnx,axi-dma-s2mm-channel"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 6 2 >; + xlnx,datawidth = <0x40>; + xlnx,include-dre = <0x0>; + } ; + } ; + axi_iic_0: i2c@40800000 { + compatible = "xlnx,axi-iic-1.01.b", "xlnx,xps-iic-2.00.a"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 5 2 >; + reg = < 0x40800000 0x10000 >; + xlnx,family = "virtex6"; + xlnx,gpo-width = <0x1>; + xlnx,iic-freq = <0x186a0>; + xlnx,s-axi-aclk-freq-hz = <0x5f5e100>; + xlnx,scl-inertial-delay = <0x5>; + xlnx,sda-inertial-delay = <0x5>; + xlnx,sda-level = <0x1>; + xlnx,ten-bit-adr = <0x0>; + spi_xcomm0: spi_xcomm0@59 { + compatible = "spi-xcomm"; + reg = <0x59>; + dac0_ad9122: ad9122@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "ad9122"; + reg = <0>; + spi-max-frequency = <10000000>; + }; + + }; + } ; + axi_iic_1: i2c@40810000 { + compatible = "xlnx,axi-iic-1.01.b", "xlnx,xps-iic-2.00.a"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 4 2 >; + reg = < 0x40810000 0x10000 >; + xlnx,family = "virtex6"; + xlnx,gpo-width = <0x1>; + xlnx,iic-freq = <0x186a0>; + xlnx,s-axi-aclk-freq-hz = <0x5f5e100>; + xlnx,scl-inertial-delay = <0x5>; + xlnx,sda-inertial-delay = <0x5>; + xlnx,sda-level = <0x1>; + xlnx,ten-bit-adr = <0x0>; + spi_xcomm1: spi_xcomm1@58 { + compatible = "spi-xcomm"; + reg = <0x58>; + dac1_ad9122: ad9122@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "ad9122"; + reg = <0>; + spi-max-frequency = <10000000>; + }; + + }; + } ; + axi_intc_0: interrupt-controller@41200000 { + #interrupt-cells = <0x2>; + compatible = "xlnx,axi-intc-1.01.a", "xlnx,xps-intc-1.00.a"; + interrupt-controller ; + reg = < 0x41200000 0x10000 >; + xlnx,kind-of-intr = <0x600>; + xlnx,num-intr-inputs = <0xb>; + } ; +// axi_interconnect_1: axi@41e40000 { +// #address-cells = <1>; +// #size-cells = <1>; +// compatible = "xlnx,axi-interconnect-1.05.a", "simple-bus"; + axi_dma_2: axidma@41e40000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-dma"; + ranges = < 0x41e40000 0x41e40000 0x10000 >; + reg = < 0x41e40000 0x10000 >; +// xlnx,sg-include-stscntrl-strm = <0x0>; + dma-channel@41e40000 { + compatible = "xlnx,axi-dma-mm2s-channel"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 1 2 >; + xlnx,datawidth = <0x20>; + xlnx,include-dre = <0x0>; + } ; + dma-channel@41e40030 { + compatible = "xlnx,axi-dma-s2mm-channel"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 0 2 >; + xlnx,datawidth = <0x20>; + xlnx,include-dre = <0x0>; + } ; + } ; + cf_fft_core_0: cf-fft-core@7a200000 { + compatible = "xlnx,cf-fft-core-1.00.a"; + reg = < 0x7a200000 0x10000 >; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "virtex6"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; +// } ; + axi_timer_0: timer@41c00000 { + clock-frequency = <100000000>; + compatible = "xlnx,axi-timer-1.03.a", "xlnx,xps-timer-1.00.a"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 8 2 >; + reg = < 0x41c00000 0x10000 >; + xlnx,count-width = <0x20>; + xlnx,family = "virtex6"; + xlnx,gen0-assert = <0x1>; + xlnx,gen1-assert = <0x1>; + xlnx,one-timer-only = <0x0>; + xlnx,trig0-assert = <0x1>; + xlnx,trig1-assert = <0x1>; + } ; + axi_vdma_0: axivdma@7e220000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-vdma"; + ranges = < 0x7e220000 0x7e220000 0x10000 >; + reg = < 0x7e220000 0x10000 >; + xlnx,include-sg = <0x0>; + xlnx,num-fstores = <0x3>; + dma-channel@7e220000 { + compatible = "xlnx,axi-vdma-mm2s-channel"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 3 2 >; + xlnx,datawidth = <0x40>; + xlnx,genlock-mode = <0x0>; + xlnx,include-dre = <0x0>; + } ; + } ; + axi_vdma_1: axivdma@7e200000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-vdma"; + ranges = < 0x7e200000 0x7e200000 0x10000 >; + reg = < 0x7e200000 0x10000 >; + xlnx,include-sg = <0x0>; + xlnx,num-fstores = <0x3>; + dma-channel@7e200000 { + compatible = "xlnx,axi-vdma-mm2s-channel"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 2 2 >; + xlnx,datawidth = <0x40>; + xlnx,genlock-mode = <0x0>; + xlnx,include-dre = <0x0>; + } ; + } ; + cf_ad9122_core_0: cf-ad9122-core-lpc@73020000 { + compatible = "xlnx,cf-ad9122-core-2.00.a"; + reg = < 0x73020000 0x10000 >; + spibus-connected = <&dac0_ad9122>; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "virtex6"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; + cf_ad9122_core_1: cf-ad9122-core-hpc@73030000 { + compatible = "xlnx,cf-ad9122-core-2.00.a"; + reg = < 0x73030000 0x10000 >; + spibus-connected = <&dac1_ad9122>; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "virtex6"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; + cf_ad9643_core_0: cf-ad9643-core-lpc@73000000 { + compatible = "xlnx,cf-ad9643-core-1.00.a"; + reg = < 0x73000000 0x10000 >; + dma-request = <&axi_dma_0 0>; + spibus-connected = <&spi_xcomm0>; + spibus-slaveselect-connected = <0x1>; + dco-output-delay = <0x8c>; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "virtex6"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; + cf_ad9643_core_1: cf-ad9643-core-hpc@73010000 { + compatible = "xlnx,cf-ad9643-core-1.00.a"; + reg = < 0x73010000 0x10000 >; + dma-request = <&axi_dma_1 0>; + spibus-connected = <&spi_xcomm1>; + spibus-slaveselect-connected = <0x1>; + dco-output-delay = <0x89>; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "virtex6"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; + debug_module: debug@74800000 { + compatible = "xlnx,mdm-2.00.b"; + reg = < 0x74800000 0x10000 >; + xlnx,family = "virtex6"; + xlnx,interconnect = <0x2>; + xlnx,jtag-chain = <0x2>; + xlnx,mb-dbg-ports = <0x1>; + xlnx,use-uart = <0x1>; + } ; + } ; +} ; diff --git a/arch/microblaze/boot/dts/ml605_xcomm.dts b/arch/microblaze/boot/dts/ml605_xcomm.dts new file mode 100644 index 0000000000000..34f1b9e76e3b9 --- /dev/null +++ b/arch/microblaze/boot/dts/ml605_xcomm.dts @@ -0,0 +1,346 @@ +/* + * Device Tree Generator version: 1.3 + * + * (C) Copyright 2007-2008 Xilinx, Inc. + * (C) Copyright 2007-2009 Michal Simek + * + * Michal SIMEK + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * CAUTION: This file is automatically generated by libgen. + * Version: Xilinx EDK 13.3 EDK_O.76xd + * + * XPS project directory: device-tree_bsp_0 + */ + +/dts-v1/; +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,microblaze"; + model = "testing"; + DDR3_SDRAM: memory@c0000000 { + device_type = "memory"; + reg = < 0xc0000000 0x20000000 >; + } ; + aliases { + ethernet0 = &Ethernet_Lite; + serial0 = &RS232_Uart_1; + } ; + chosen { + bootargs = "console=ttyS0 root=/dev/ram"; + } ; + cpus { + #address-cells = <1>; + #cpus = <0x1>; + #size-cells = <0>; + microblaze_0: cpu@0 { + clock-frequency = <100000000>; + compatible = "xlnx,microblaze-8.20.a"; + d-cache-baseaddr = <0xc0000000>; + d-cache-highaddr = <0xdfffffff>; + d-cache-line-size = <0x10>; + d-cache-size = <0x4000>; + device_type = "cpu"; + i-cache-baseaddr = <0xc0000000>; + i-cache-highaddr = <0xdfffffff>; + i-cache-line-size = <0x20>; + i-cache-size = <0x4000>; + model = "microblaze,8.20.a"; + reg = <0>; + timebase-frequency = <100000000>; + xlnx,addr-tag-bits = <0xf>; + xlnx,allow-dcache-wr = <0x1>; + xlnx,allow-icache-wr = <0x1>; + xlnx,area-optimized = <0x0>; + xlnx,avoid-primitives = <0x0>; + xlnx,branch-target-cache-size = <0x0>; + xlnx,cache-byte-size = <0x4000>; + xlnx,d-axi = <0x1>; + xlnx,d-lmb = <0x1>; + xlnx,d-plb = <0x0>; + xlnx,data-size = <0x20>; + xlnx,dcache-addr-tag = <0xf>; + xlnx,dcache-always-used = <0x1>; + xlnx,dcache-byte-size = <0x4000>; + xlnx,dcache-data-width = <0x0>; + xlnx,dcache-force-tag-lutram = <0x0>; + xlnx,dcache-interface = <0x0>; + xlnx,dcache-line-len = <0x4>; + xlnx,dcache-use-fsl = <0x0>; + xlnx,dcache-use-writeback = <0x0>; + xlnx,dcache-victims = <0x0>; + xlnx,debug-enabled = <0x1>; + xlnx,div-zero-exception = <0x1>; + xlnx,dynamic-bus-sizing = <0x1>; + xlnx,ecc-use-ce-exception = <0x0>; + xlnx,edge-is-positive = <0x1>; + xlnx,endianness = <0x1>; + xlnx,family = "virtex6"; + xlnx,fault-tolerant = <0x0>; + xlnx,fpu-exception = <0x0>; + xlnx,freq = <0x5f5e100>; + xlnx,fsl-data-size = <0x20>; + xlnx,fsl-exception = <0x0>; + xlnx,fsl-links = <0x0>; + xlnx,i-axi = <0x0>; + xlnx,i-lmb = <0x1>; + xlnx,i-plb = <0x0>; + xlnx,icache-always-used = <0x1>; + xlnx,icache-data-width = <0x0>; + xlnx,icache-force-tag-lutram = <0x0>; + xlnx,icache-interface = <0x0>; + xlnx,icache-line-len = <0x8>; + xlnx,icache-streams = <0x1>; + xlnx,icache-use-fsl = <0x0>; + xlnx,icache-victims = <0x8>; + xlnx,ill-opcode-exception = <0x1>; + xlnx,instance = "microblaze_0"; + xlnx,interconnect = <0x2>; + xlnx,interconnect-m-axi-dc-read-issuing = <0x2>; + xlnx,interconnect-m-axi-dc-write-issuing = <0x20>; + xlnx,interconnect-m-axi-dp-read-issuing = <0x1>; + xlnx,interconnect-m-axi-dp-write-issuing = <0x1>; + xlnx,interconnect-m-axi-ic-read-issuing = <0x8>; + xlnx,interconnect-m-axi-ip-read-issuing = <0x1>; + xlnx,interrupt-is-edge = <0x0>; + xlnx,lockstep-slave = <0x0>; + xlnx,mmu-dtlb-size = <0x4>; + xlnx,mmu-itlb-size = <0x2>; + xlnx,mmu-privileged-instr = <0x0>; + xlnx,mmu-tlb-access = <0x3>; + xlnx,mmu-zones = <0x2>; + xlnx,number-of-pc-brk = <0x1>; + xlnx,number-of-rd-addr-brk = <0x0>; + xlnx,number-of-wr-addr-brk = <0x0>; + xlnx,opcode-0x0-illegal = <0x1>; + xlnx,optimization = <0x0>; + xlnx,pvr = <0x2>; + xlnx,pvr-user1 = <0x0>; + xlnx,pvr-user2 = <0x0>; + xlnx,reset-msr = <0x0>; + xlnx,sco = <0x0>; + xlnx,stream-interconnect = <0x0>; + xlnx,unaligned-exceptions = <0x1>; + xlnx,use-barrel = <0x1>; + xlnx,use-branch-target-cache = <0x0>; + xlnx,use-dcache = <0x1>; + xlnx,use-div = <0x1>; + xlnx,use-ext-brk = <0x1>; + xlnx,use-ext-nm-brk = <0x1>; + xlnx,use-extended-fsl-instr = <0x0>; + xlnx,use-fpu = <0x0>; + xlnx,use-hw-mul = <0x2>; + xlnx,use-icache = <0x1>; + xlnx,use-interrupt = <0x1>; + xlnx,use-mmu = <0x3>; + xlnx,use-msr-instr = <0x1>; + xlnx,use-pcmp-instr = <0x1>; + xlnx,use-stack-protection = <0x0>; + } ; + } ; + axi4lite_0: axi@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,axi-interconnect-1.04.a", "simple-bus"; + ranges ; + Ethernet_Lite: ethernet@40e00000 { + compatible = "xlnx,axi-ethernetlite-1.01.a", "xlnx,xps-ethernetlite-1.00.a"; + device_type = "network"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 3 0 >; + local-mac-address = [ 00 0a 35 4f 78 00 ]; + phy-handle = <&phy0>; + reg = < 0x40e00000 0x10000 >; + xlnx,duplex = <0x1>; + xlnx,family = "virtex6"; + xlnx,include-global-buffers = <0x0>; + xlnx,include-internal-loopback = <0x0>; + xlnx,include-mdio = <0x1>; + xlnx,include-phy-constraints = <0x1>; + xlnx,interconnect-s-axi-read-acceptance = <0x1>; + xlnx,interconnect-s-axi-write-acceptance = <0x1>; + xlnx,rx-ping-pong = <0x0>; + xlnx,s-axi-aclk-period-ps = <0x2710>; + xlnx,s-axi-id-width = <0x1>; + xlnx,s-axi-supports-narrow-burst = <0x0>; + xlnx,tx-ping-pong = <0x0>; + mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: phy@7 { + compatible = "marvell,88e1111"; + device_type = "ethernet-phy"; + reg = <7>; + } ; + } ; + } ; + RS232_Uart_1: serial@40600000 { + clock-frequency = <100000000>; + compatible = "xlnx,axi-uartlite-1.02.a", "xlnx,xps-uartlite-1.00.a"; + current-speed = <57600>; + device_type = "serial"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 4 0 >; + port-number = <0>; + reg = < 0x40600000 0x10000 >; + xlnx,baudrate = <0xe100>; + xlnx,data-bits = <0x8>; + xlnx,family = "virtex6"; + xlnx,odd-parity = <0x1>; + xlnx,s-axi-aclk-freq-hz = <0x5f5e100>; + xlnx,use-parity = <0x0>; + } ; + + axi_dma_0: axidma@41e00000 { + #address-cells = <1>; + #size-cells = <1>; + #dma-cells = <1>; + compatible = "xlnx,axi-dma"; + ranges = < 0x41e00000 0x41e00000 0x10000 >; + reg = < 0x41e00000 0x10000 >; + xlnx,sg-include-stscntrl-strm = <0x0>; + dma-channel@41e00000 { + compatible = "xlnx,axi-dma-s2mm-channel"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 1 2 >; + xlnx,datawidth = <0x20>; + xlnx,include-dre = <0x0>; + } ; + } ; +/* + axi_dma_0: axi-dma@41e00000 { + compatible = "xlnx,axi-dma"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 1 2 >; + reg = < 0x41e00000 0x10000 >; + xlnx,dlytmr-resolution = <0x7d>; + xlnx,family = "virtex6"; + xlnx,include-mm2s = <0x0>; + xlnx,include-mm2s-dre = <0x0>; + xlnx,include-mm2s-sf = <0x1>; + xlnx,include-s2mm = <0x1>; + xlnx,include-s2mm-dre = <0x0>; + xlnx,include-s2mm-sf = <0x1>; + xlnx,include-sg = <0x0>; + xlnx,interconnect-m-axi-mm2s-read-fifo-depth = <0x0>; + xlnx,interconnect-m-axi-mm2s-read-issuing = <0x4>; + xlnx,interconnect-m-axi-s2mm-write-fifo-depth = <0x0>; + xlnx,interconnect-m-axi-s2mm-write-issuing = <0x4>; + xlnx,mm2s-burst-size = <0x10>; + xlnx,prmry-is-aclk-async = <0x1>; + xlnx,s-axi-lite-aclk-freq-hz = <0x5f5e100>; + xlnx,s-axi-lite-addr-width = <0x20>; + xlnx,s-axi-lite-data-width = <0x20>; + xlnx,s-axi-lite-protocol = "AXI4LITE"; + xlnx,s-axi-lite-supports-read = <0x1>; + xlnx,s-axi-lite-supports-write = <0x1>; + xlnx,s2mm-burst-size = <0x10>; + xlnx,sg-include-desc-queue = <0x0>; + xlnx,sg-include-stscntrl-strm = <0x1>; + xlnx,sg-length-width = <0xe>; + xlnx,sg-use-stsapp-length = <0x1>; + } ; +*/ + axi_iic_0: i2c@40800000 { + compatible = "xlnx,axi-iic-1.01.b", "xlnx,xps-iic-2.00.a"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 0 2 >; + reg = < 0x40800000 0x10000 >; + xlnx,family = "virtex6"; + xlnx,gpo-width = <0x1>; + xlnx,iic-freq = <0x186a0>; + xlnx,s-axi-aclk-freq-hz = <0x5f5e100>; + xlnx,scl-inertial-delay = <0x0>; + xlnx,sda-inertial-delay = <0x0>; + xlnx,sda-level = <0x1>; + xlnx,ten-bit-adr = <0x0>; + spi_xcomm: spi_xcomm@50 { + compatible = "spi-xcomm"; + reg = <0x50>; + dac_ad9122: ad9122@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "ad9122"; + reg = <0>; + spi-max-frequency = <10000000>; + }; + + }; + } ; + axi_intc_0: interrupt-controller@41200000 { + #interrupt-cells = <0x2>; + compatible = "xlnx,axi-intc-1.01.a", "xlnx,xps-intc-1.00.a"; + interrupt-controller ; + reg = < 0x41200000 0x10000 >; + xlnx,kind-of-intr = <0x18>; + xlnx,num-intr-inputs = <0x5>; + } ; + axi_timer_0: timer@41c00000 { + clock-frequency = <100000000>; + compatible = "xlnx,axi-timer-1.03.a", "xlnx,xps-timer-1.00.a"; + interrupt-parent = <&axi_intc_0>; + interrupts = < 2 2 >; + reg = < 0x41c00000 0x10000 >; + xlnx,count-width = <0x20>; + xlnx,family = "virtex6"; + xlnx,gen0-assert = <0x1>; + xlnx,gen1-assert = <0x1>; + xlnx,one-timer-only = <0x0>; + xlnx,trig0-assert = <0x1>; + xlnx,trig1-assert = <0x1>; + } ; + cf_ad9122_core_0: cf-ad9122-core@73020000 { + compatible = "xlnx,cf-ad9122-core-1.00.a"; + reg = < 0x73020000 0x10000 >; + spibus-connected = <&dac_ad9122>; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "virtex6"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + } ; + cf_ad9643_core_0: cf-ad9643-core@73000000 { + compatible = "xlnx,cf-ad9643-core-1.00.a"; + reg = < 0x73000000 0x10000 >; + axistream-connected = <&axi_dma_0>; + spibus-connected = <&spi_xcomm>; + spibus-slaveselect-connected = <0x1>; + xlnx,dphase-timeout = <0x8>; + xlnx,family = "virtex6"; + xlnx,num-mem = <0x1>; + xlnx,num-reg = <0x1>; + xlnx,s-axi-min-size = <0x1ff>; + xlnx,slv-awidth = <0x20>; + xlnx,slv-dwidth = <0x20>; + xlnx,use-wstrb = <0x0>; + dma-request = <&axi_dma_0 0>; + } ; + debug_module: debug@74800000 { + compatible = "xlnx,mdm-2.00.b"; + reg = < 0x74800000 0x10000 >; + xlnx,family = "virtex6"; + xlnx,interconnect = <0x2>; + xlnx,jtag-chain = <0x2>; + xlnx,mb-dbg-ports = <0x1>; + xlnx,use-uart = <0x1>; + } ; + } ; +} ; diff --git a/arch/microblaze/configs/kc705_ad9250_defconfig b/arch/microblaze/configs/kc705_ad9250_defconfig new file mode 100644 index 0000000000000..82ad7d6acbba5 --- /dev/null +++ b/arch/microblaze/configs/kc705_ad9250_defconfig @@ -0,0 +1,1381 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/microblaze 3.5.0-rc4 Kernel Configuration +# +CONFIG_MICROBLAZE=y +# CONFIG_SWAP is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_ZONE_DMA=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_CSUM=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_DEFAULT_HOSTNAME="(none)" +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_FHANDLE is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_IRQ_DOMAIN=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +# CONFIG_NO_HZ is not set +CONFIG_HIGH_RES_TIMERS=y + +# +# RCU Subsystem +# +CONFIG_TINY_RCU=y +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_CHECKPOINT_RESTORE is not set +# CONFIG_NAMESPACES is not set +# CONFIG_SCHED_AUTOGROUP is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="rootfs.cpio.gz" +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_ROOT_GID=0 +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +CONFIG_INITRAMFS_COMPRESSION_NONE=y +# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EXPERT=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_EMBEDDED=y + +# +# Kernel Performance Events And Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_API_DEBUG=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_BLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +# CONFIG_FREEZER is not set + +# +# Platform options +# +# CONFIG_PLATFORM_GENERIC is not set +CONFIG_PLATFORM_ML605_ADIXCOMM=y +# CONFIG_PLATFORM_KC705_ADIXCOMM is not set +# CONFIG_ADIXCOMM_SYNC is not set +CONFIG_OPT_LIB_FUNCTION=y +# CONFIG_OPT_LIB_ASM is not set + +# +# Definitions for MICROBLAZE0 +# +CONFIG_KERNEL_BASE_ADDR=0xc0000000 +CONFIG_XILINX_MICROBLAZE0_FAMILY="virtex6" +CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR=1 +CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR=1 +CONFIG_XILINX_MICROBLAZE0_USE_BARREL=1 +CONFIG_XILINX_MICROBLAZE0_USE_DIV=1 +CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL=2 +CONFIG_XILINX_MICROBLAZE0_USE_FPU=0 +CONFIG_XILINX_MICROBLAZE0_HW_VER="8.20.a" + +# +# Processor type and features +# +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SCHED_HRTICK=y +CONFIG_MMU=y + +# +# Boot options +# +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttyUL0,57600 root=/dev/ram" +CONFIG_CMDLINE_FORCE=y +# CONFIG_SECCOMP is not set + +# +# Advanced setup +# +CONFIG_ADVANCED_OPTIONS=y +# CONFIG_HIGHMEM is not set +CONFIG_LOWMEM_SIZE_BOOL=y +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_MANUAL_RESET_VECTOR=0x0 +CONFIG_KERNEL_START_BOOL=y +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE_BOOL=y +CONFIG_TASK_SIZE=0x80000000 +CONFIG_KERNEL_PAD=0x80000 +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_MEMBLOCK_NODE_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_COMPACTION is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_NEED_PER_CPU_KM=y +# CONFIG_CLEANCACHE is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Bus Options +# +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS is not set +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_INET_UDP_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set +# CONFIG_DNS_RESOLVER is not set +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +CONFIG_BQL=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_GENERIC_CPU_DEVICES=y +# CONFIG_DMA_SHARED_BUFFER is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_RAM=y +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +CONFIG_MTD_PHYSMAP_OF=y +# CONFIG_MTD_GPIO_ADDR is not set +# CONFIG_MTD_PLATRAM is not set +# CONFIG_MTD_LATCH_ADDR is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +CONFIG_MTD_M25P80=y +CONFIG_M25PXX_USE_FAST_READ=y +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOCG3 is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set +# CONFIG_MTD_UBI is not set +CONFIG_DTC=y +CONFIG_OF=y + +# +# Device Tree and Open Firmware support +# +CONFIG_PROC_DEVICETREE=y +# CONFIG_OF_SELFTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_IRQ=y +CONFIG_OF_DEVICE=y +CONFIG_OF_I2C=y +CONFIG_OF_NET=y +CONFIG_OF_MDIO=y +CONFIG_OF_MTD=y +# CONFIG_PARPORT is not set + +# +# Misc devices +# +CONFIG_AD525X_DPOT=y +CONFIG_AD525X_DPOT_I2C=y +CONFIG_AD525X_DPOT_SPI=y +# CONFIG_ICS932S401 is not set +CONFIG_XLNX_LCD=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_BMP085_I2C is not set +# CONFIG_BMP085_SPI is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=y +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_EEPROM_93XX46 is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_NETDEVICES=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +# CONFIG_DUMMY is not set +# CONFIG_EQUALIZER is not set +# CONFIG_MII is not set +# CONFIG_NET_TEAM is not set +# CONFIG_MACVLAN is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set + +# +# CAIF transport drivers +# +CONFIG_ETHERNET=y +CONFIG_NET_VENDOR_BROADCOM=y +# CONFIG_B44 is not set +# CONFIG_NET_CALXEDA_XGMAC is not set +CONFIG_NET_VENDOR_CHELSIO=y +# CONFIG_DNET is not set +CONFIG_NET_VENDOR_INTEL=y +CONFIG_NET_VENDOR_I825XX=y +CONFIG_NET_VENDOR_MARVELL=y +CONFIG_NET_VENDOR_MICREL=y +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +CONFIG_NET_VENDOR_MICROCHIP=y +# CONFIG_ENC28J60 is not set +CONFIG_NET_VENDOR_NATSEMI=y +CONFIG_NET_VENDOR_8390=y +# CONFIG_ETHOC is not set +CONFIG_NET_VENDOR_SEEQ=y +# CONFIG_SEEQ8005 is not set +CONFIG_NET_VENDOR_STMICRO=y +# CONFIG_STMMAC_ETH is not set +CONFIG_NET_VENDOR_WIZNET=y +# CONFIG_WIZNET_W5100 is not set +# CONFIG_WIZNET_W5300 is not set +CONFIG_NET_VENDOR_XILINX=y +CONFIG_XILINX_EMACLITE=y +# CONFIG_XILINX_AXI_EMAC is not set +# CONFIG_XILINX_LL_TEMAC is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_AMD_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_BUS_MUX_GPIO is not set +# CONFIG_MICREL_KS8995MA is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +CONFIG_WLAN=y +# CONFIG_HOSTAP is not set +# CONFIG_WL_TI is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +CONFIG_DEVKMEM=y + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_DW is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX3107 is not set +CONFIG_SERIAL_UARTLITE=y +CONFIG_SERIAL_UARTLITE_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_TTY_PRINTK is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_XILINX_HWICAP is not set +# CONFIG_R3964 is not set + +# +# PCMCIA character devices +# +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +# CONFIG_I2C_MUX is not set +# CONFIG_I2C_HELPER_AUTO is not set +# CONFIG_I2C_SMBUS is not set + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +# CONFIG_I2C_SIMTEC is not set +CONFIG_I2C_XILINX=y + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +CONFIG_SPI_BITBANG=y +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PXA2XX_PCI is not set +# CONFIG_SPI_XCOMM is not set +CONFIG_SPI_XILINX=y +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_HSI is not set + +# +# PPS support +# +# CONFIG_PPS is not set + +# +# PPS generators support +# + +# +# PTP clock support +# + +# +# Enable Device Drivers -> PPS to see the PTP clock options. +# +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_OF_GPIO=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO drivers: +# +# CONFIG_GPIO_GENERIC_PLATFORM is not set +CONFIG_GPIO_XILINX=y + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_SX150X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_74X164 is not set + +# +# AC97 GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_MFD_LM3533 is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_STMPE is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_S5M_CORE is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_EXYNOS_VIDEO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_SOUND is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +CONFIG_USB_ARCH_HAS_EHCI=y +# CONFIG_USB_ARCH_HAS_XHCI is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_RTC_CLASS is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_XILINX_DMA=y +# CONFIG_TIMB_DMA is not set +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# Virtio drivers +# +# CONFIG_VIRTIO_BALLOON is not set +# CONFIG_VIRTIO_MMIO is not set + +# +# Microsoft Hyper-V guest support +# +CONFIG_STAGING=y +# CONFIG_ECHO is not set +# CONFIG_RTLLIB is not set + +# +# IIO staging drivers +# +CONFIG_IIO_SW_RING=y + +# +# Accelerometers +# +# CONFIG_ADIS16201 is not set +# CONFIG_ADIS16203 is not set +# CONFIG_ADIS16204 is not set +# CONFIG_ADIS16209 is not set +# CONFIG_ADIS16220 is not set +# CONFIG_ADIS16240 is not set +# CONFIG_KXSD9 is not set +# CONFIG_LIS3L02DQ is not set +# CONFIG_SCA3000 is not set + +# +# Analog to digital converters +# +# CONFIG_AD7291 is not set +# CONFIG_AD7298 is not set +# CONFIG_AD7606 is not set +# CONFIG_AD799X is not set +# CONFIG_AD7476 is not set +# CONFIG_AD7887 is not set +# CONFIG_AD7780 is not set +# CONFIG_AD7793 is not set +# CONFIG_AD7816 is not set +# CONFIG_AD7192 is not set +# CONFIG_ADT7310 is not set +# CONFIG_ADT7410 is not set +# CONFIG_AD7280 is not set +# CONFIG_MAX1363 is not set + +# +# Analog digital bi-direction converters +# +# CONFIG_ADT7316 is not set + +# +# Capacitance to digital converters +# +# CONFIG_AD7150 is not set +# CONFIG_AD7152 is not set +# CONFIG_AD7746 is not set + +# +# Direct Digital Synthesis +# +# CONFIG_AD5930 is not set +# CONFIG_AD9832 is not set +# CONFIG_AD9834 is not set +# CONFIG_AD9850 is not set +# CONFIG_AD9852 is not set +# CONFIG_AD9910 is not set +# CONFIG_AD9951 is not set + +# +# Digital gyroscope sensors +# +# CONFIG_ADIS16060 is not set +# CONFIG_ADIS16080 is not set +# CONFIG_ADIS16130 is not set +# CONFIG_ADIS16260 is not set +# CONFIG_ADXRS450 is not set + +# +# Network Analyzer, Impedance Converters +# +# CONFIG_AD5933 is not set + +# +# Inertial measurement units +# +# CONFIG_ADIS16400 is not set + +# +# Light sensors +# +# CONFIG_SENSORS_ISL29018 is not set +# CONFIG_SENSORS_ISL29028 is not set +# CONFIG_SENSORS_TSL2563 is not set +# CONFIG_TSL2583 is not set +# CONFIG_TSL2x7x is not set + +# +# Magnetometer sensors +# +# CONFIG_SENSORS_AK8975 is not set +# CONFIG_SENSORS_HMC5843 is not set + +# +# Active energy metering IC +# +# CONFIG_ADE7753 is not set +# CONFIG_ADE7754 is not set +# CONFIG_ADE7758 is not set +# CONFIG_ADE7759 is not set +# CONFIG_ADE7854 is not set + +# +# Resolver to digital converters +# +# CONFIG_AD2S90 is not set +# CONFIG_AD2S1200 is not set +# CONFIG_AD2S1210 is not set + +# +# Triggers - standalone +# +# CONFIG_IIO_GPIO_TRIGGER is not set +# CONFIG_IIO_SYSFS_TRIGGER is not set +# CONFIG_IIO_SIMPLE_DUMMY is not set +# CONFIG_ZSMALLOC is not set +# CONFIG_FT1000 is not set + +# +# Speakup console speech +# +# CONFIG_STAGING_MEDIA is not set + +# +# Android +# +# CONFIG_ANDROID is not set +# CONFIG_PHONE is not set +# CONFIG_IPACK_BUS is not set +# CONFIG_WIMAX_GDM72XX is not set + +# +# Hardware Spinlock drivers +# +CONFIG_IOMMU_SUPPORT=y + +# +# Remoteproc drivers (EXPERIMENTAL) +# + +# +# Rpmsg drivers (EXPERIMENTAL) +# +# CONFIG_VIRT_DRIVERS is not set +# CONFIG_PM_DEVFREQ is not set +# CONFIG_EXTCON is not set +# CONFIG_MEMORY is not set +CONFIG_IIO=y +CONFIG_IIO_BUFFER=y +CONFIG_IIO_KFIFO_BUF=y +CONFIG_IIO_TRIGGER=y +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 + +# +# Analog to digital converters +# +# CONFIG_AD7266 is not set +CONFIG_CF_AXI_ADC=y +CONFIG_CF_AXI_FFT=y +CONFIG_AXI_JESD204B=y + +# +# Amplifiers +# +# CONFIG_AD8366 is not set + +# +# Light sensors +# +# CONFIG_VCNL4000 is not set + +# +# Frequency Synthesizers DDS/PLL +# + +# +# Clock Generator/Distribution +# +# CONFIG_AD9523 is not set +# CONFIG_AD9548 is not set + +# +# Direct Digital Synthesis +# +CONFIG_CF_AXI_DDS=y +CONFIG_CF_AXI_DDS_AD9122=y + +# +# Phase-Locked Loop (PLL) frequency synthesizers +# +# CONFIG_ADF4350 is not set + +# +# Digital to analog converters +# +# CONFIG_AD5064 is not set +# CONFIG_AD5360 is not set +# CONFIG_AD5380 is not set +# CONFIG_AD5421 is not set +# CONFIG_AD5624R_SPI is not set +# CONFIG_AD5446 is not set +# CONFIG_AD5504 is not set +# CONFIG_AD5764 is not set +# CONFIG_AD5791 is not set +# CONFIG_AD5686 is not set +# CONFIG_MAX517 is not set +# CONFIG_MCP4725 is not set + +# +# File systems +# +# CONFIG_FS_POSIX_ACL is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ECRYPT_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set +# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_PSTORE is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V2=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_NLS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_LOCKUP_DETECTOR is not set +# CONFIG_HARDLOCKUP_DETECTOR is not set +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +# CONFIG_DETECT_HUNG_TASK is not set +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_TEST_KSTRTOX is not set +CONFIG_EARLY_PRINTK=y +# CONFIG_HEART_BEAT is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_ENCRYPTED_KEYS is not set +CONFIG_KEYS_DEBUG_PROC_KEYS=y +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set +# CONFIG_CRYPTO_USER is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IO=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +# CONFIG_CRC8 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +# CONFIG_XZ_DEC is not set +# CONFIG_XZ_DEC_BCJ is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y +# CONFIG_AVERAGE is not set +# CONFIG_CORDIC is not set +# CONFIG_DDR is not set diff --git a/arch/microblaze/configs/kc705_ad9250_fmc_ebz_defconfig b/arch/microblaze/configs/kc705_ad9250_fmc_ebz_defconfig new file mode 100644 index 0000000000000..82ad7d6acbba5 --- /dev/null +++ b/arch/microblaze/configs/kc705_ad9250_fmc_ebz_defconfig @@ -0,0 +1,1381 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/microblaze 3.5.0-rc4 Kernel Configuration +# +CONFIG_MICROBLAZE=y +# CONFIG_SWAP is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_ZONE_DMA=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_CSUM=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_DEFAULT_HOSTNAME="(none)" +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_FHANDLE is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_IRQ_DOMAIN=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +# CONFIG_NO_HZ is not set +CONFIG_HIGH_RES_TIMERS=y + +# +# RCU Subsystem +# +CONFIG_TINY_RCU=y +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_CHECKPOINT_RESTORE is not set +# CONFIG_NAMESPACES is not set +# CONFIG_SCHED_AUTOGROUP is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="rootfs.cpio.gz" +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_ROOT_GID=0 +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +CONFIG_INITRAMFS_COMPRESSION_NONE=y +# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EXPERT=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_EMBEDDED=y + +# +# Kernel Performance Events And Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_API_DEBUG=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_BLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +# CONFIG_FREEZER is not set + +# +# Platform options +# +# CONFIG_PLATFORM_GENERIC is not set +CONFIG_PLATFORM_ML605_ADIXCOMM=y +# CONFIG_PLATFORM_KC705_ADIXCOMM is not set +# CONFIG_ADIXCOMM_SYNC is not set +CONFIG_OPT_LIB_FUNCTION=y +# CONFIG_OPT_LIB_ASM is not set + +# +# Definitions for MICROBLAZE0 +# +CONFIG_KERNEL_BASE_ADDR=0xc0000000 +CONFIG_XILINX_MICROBLAZE0_FAMILY="virtex6" +CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR=1 +CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR=1 +CONFIG_XILINX_MICROBLAZE0_USE_BARREL=1 +CONFIG_XILINX_MICROBLAZE0_USE_DIV=1 +CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL=2 +CONFIG_XILINX_MICROBLAZE0_USE_FPU=0 +CONFIG_XILINX_MICROBLAZE0_HW_VER="8.20.a" + +# +# Processor type and features +# +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SCHED_HRTICK=y +CONFIG_MMU=y + +# +# Boot options +# +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttyUL0,57600 root=/dev/ram" +CONFIG_CMDLINE_FORCE=y +# CONFIG_SECCOMP is not set + +# +# Advanced setup +# +CONFIG_ADVANCED_OPTIONS=y +# CONFIG_HIGHMEM is not set +CONFIG_LOWMEM_SIZE_BOOL=y +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_MANUAL_RESET_VECTOR=0x0 +CONFIG_KERNEL_START_BOOL=y +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE_BOOL=y +CONFIG_TASK_SIZE=0x80000000 +CONFIG_KERNEL_PAD=0x80000 +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_MEMBLOCK_NODE_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_COMPACTION is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_NEED_PER_CPU_KM=y +# CONFIG_CLEANCACHE is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Bus Options +# +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS is not set +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_INET_UDP_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set +# CONFIG_DNS_RESOLVER is not set +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +CONFIG_BQL=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_GENERIC_CPU_DEVICES=y +# CONFIG_DMA_SHARED_BUFFER is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_RAM=y +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +CONFIG_MTD_PHYSMAP_OF=y +# CONFIG_MTD_GPIO_ADDR is not set +# CONFIG_MTD_PLATRAM is not set +# CONFIG_MTD_LATCH_ADDR is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +CONFIG_MTD_M25P80=y +CONFIG_M25PXX_USE_FAST_READ=y +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOCG3 is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set +# CONFIG_MTD_UBI is not set +CONFIG_DTC=y +CONFIG_OF=y + +# +# Device Tree and Open Firmware support +# +CONFIG_PROC_DEVICETREE=y +# CONFIG_OF_SELFTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_IRQ=y +CONFIG_OF_DEVICE=y +CONFIG_OF_I2C=y +CONFIG_OF_NET=y +CONFIG_OF_MDIO=y +CONFIG_OF_MTD=y +# CONFIG_PARPORT is not set + +# +# Misc devices +# +CONFIG_AD525X_DPOT=y +CONFIG_AD525X_DPOT_I2C=y +CONFIG_AD525X_DPOT_SPI=y +# CONFIG_ICS932S401 is not set +CONFIG_XLNX_LCD=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_BMP085_I2C is not set +# CONFIG_BMP085_SPI is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=y +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_EEPROM_93XX46 is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_NETDEVICES=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +# CONFIG_DUMMY is not set +# CONFIG_EQUALIZER is not set +# CONFIG_MII is not set +# CONFIG_NET_TEAM is not set +# CONFIG_MACVLAN is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set + +# +# CAIF transport drivers +# +CONFIG_ETHERNET=y +CONFIG_NET_VENDOR_BROADCOM=y +# CONFIG_B44 is not set +# CONFIG_NET_CALXEDA_XGMAC is not set +CONFIG_NET_VENDOR_CHELSIO=y +# CONFIG_DNET is not set +CONFIG_NET_VENDOR_INTEL=y +CONFIG_NET_VENDOR_I825XX=y +CONFIG_NET_VENDOR_MARVELL=y +CONFIG_NET_VENDOR_MICREL=y +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +CONFIG_NET_VENDOR_MICROCHIP=y +# CONFIG_ENC28J60 is not set +CONFIG_NET_VENDOR_NATSEMI=y +CONFIG_NET_VENDOR_8390=y +# CONFIG_ETHOC is not set +CONFIG_NET_VENDOR_SEEQ=y +# CONFIG_SEEQ8005 is not set +CONFIG_NET_VENDOR_STMICRO=y +# CONFIG_STMMAC_ETH is not set +CONFIG_NET_VENDOR_WIZNET=y +# CONFIG_WIZNET_W5100 is not set +# CONFIG_WIZNET_W5300 is not set +CONFIG_NET_VENDOR_XILINX=y +CONFIG_XILINX_EMACLITE=y +# CONFIG_XILINX_AXI_EMAC is not set +# CONFIG_XILINX_LL_TEMAC is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_AMD_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_BUS_MUX_GPIO is not set +# CONFIG_MICREL_KS8995MA is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +CONFIG_WLAN=y +# CONFIG_HOSTAP is not set +# CONFIG_WL_TI is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +CONFIG_DEVKMEM=y + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_DW is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX3107 is not set +CONFIG_SERIAL_UARTLITE=y +CONFIG_SERIAL_UARTLITE_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_TTY_PRINTK is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_XILINX_HWICAP is not set +# CONFIG_R3964 is not set + +# +# PCMCIA character devices +# +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +# CONFIG_I2C_MUX is not set +# CONFIG_I2C_HELPER_AUTO is not set +# CONFIG_I2C_SMBUS is not set + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +# CONFIG_I2C_SIMTEC is not set +CONFIG_I2C_XILINX=y + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +CONFIG_SPI_BITBANG=y +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PXA2XX_PCI is not set +# CONFIG_SPI_XCOMM is not set +CONFIG_SPI_XILINX=y +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_HSI is not set + +# +# PPS support +# +# CONFIG_PPS is not set + +# +# PPS generators support +# + +# +# PTP clock support +# + +# +# Enable Device Drivers -> PPS to see the PTP clock options. +# +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_OF_GPIO=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO drivers: +# +# CONFIG_GPIO_GENERIC_PLATFORM is not set +CONFIG_GPIO_XILINX=y + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_SX150X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_74X164 is not set + +# +# AC97 GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_MFD_LM3533 is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_STMPE is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_S5M_CORE is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_EXYNOS_VIDEO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_SOUND is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +CONFIG_USB_ARCH_HAS_EHCI=y +# CONFIG_USB_ARCH_HAS_XHCI is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_RTC_CLASS is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_XILINX_DMA=y +# CONFIG_TIMB_DMA is not set +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# Virtio drivers +# +# CONFIG_VIRTIO_BALLOON is not set +# CONFIG_VIRTIO_MMIO is not set + +# +# Microsoft Hyper-V guest support +# +CONFIG_STAGING=y +# CONFIG_ECHO is not set +# CONFIG_RTLLIB is not set + +# +# IIO staging drivers +# +CONFIG_IIO_SW_RING=y + +# +# Accelerometers +# +# CONFIG_ADIS16201 is not set +# CONFIG_ADIS16203 is not set +# CONFIG_ADIS16204 is not set +# CONFIG_ADIS16209 is not set +# CONFIG_ADIS16220 is not set +# CONFIG_ADIS16240 is not set +# CONFIG_KXSD9 is not set +# CONFIG_LIS3L02DQ is not set +# CONFIG_SCA3000 is not set + +# +# Analog to digital converters +# +# CONFIG_AD7291 is not set +# CONFIG_AD7298 is not set +# CONFIG_AD7606 is not set +# CONFIG_AD799X is not set +# CONFIG_AD7476 is not set +# CONFIG_AD7887 is not set +# CONFIG_AD7780 is not set +# CONFIG_AD7793 is not set +# CONFIG_AD7816 is not set +# CONFIG_AD7192 is not set +# CONFIG_ADT7310 is not set +# CONFIG_ADT7410 is not set +# CONFIG_AD7280 is not set +# CONFIG_MAX1363 is not set + +# +# Analog digital bi-direction converters +# +# CONFIG_ADT7316 is not set + +# +# Capacitance to digital converters +# +# CONFIG_AD7150 is not set +# CONFIG_AD7152 is not set +# CONFIG_AD7746 is not set + +# +# Direct Digital Synthesis +# +# CONFIG_AD5930 is not set +# CONFIG_AD9832 is not set +# CONFIG_AD9834 is not set +# CONFIG_AD9850 is not set +# CONFIG_AD9852 is not set +# CONFIG_AD9910 is not set +# CONFIG_AD9951 is not set + +# +# Digital gyroscope sensors +# +# CONFIG_ADIS16060 is not set +# CONFIG_ADIS16080 is not set +# CONFIG_ADIS16130 is not set +# CONFIG_ADIS16260 is not set +# CONFIG_ADXRS450 is not set + +# +# Network Analyzer, Impedance Converters +# +# CONFIG_AD5933 is not set + +# +# Inertial measurement units +# +# CONFIG_ADIS16400 is not set + +# +# Light sensors +# +# CONFIG_SENSORS_ISL29018 is not set +# CONFIG_SENSORS_ISL29028 is not set +# CONFIG_SENSORS_TSL2563 is not set +# CONFIG_TSL2583 is not set +# CONFIG_TSL2x7x is not set + +# +# Magnetometer sensors +# +# CONFIG_SENSORS_AK8975 is not set +# CONFIG_SENSORS_HMC5843 is not set + +# +# Active energy metering IC +# +# CONFIG_ADE7753 is not set +# CONFIG_ADE7754 is not set +# CONFIG_ADE7758 is not set +# CONFIG_ADE7759 is not set +# CONFIG_ADE7854 is not set + +# +# Resolver to digital converters +# +# CONFIG_AD2S90 is not set +# CONFIG_AD2S1200 is not set +# CONFIG_AD2S1210 is not set + +# +# Triggers - standalone +# +# CONFIG_IIO_GPIO_TRIGGER is not set +# CONFIG_IIO_SYSFS_TRIGGER is not set +# CONFIG_IIO_SIMPLE_DUMMY is not set +# CONFIG_ZSMALLOC is not set +# CONFIG_FT1000 is not set + +# +# Speakup console speech +# +# CONFIG_STAGING_MEDIA is not set + +# +# Android +# +# CONFIG_ANDROID is not set +# CONFIG_PHONE is not set +# CONFIG_IPACK_BUS is not set +# CONFIG_WIMAX_GDM72XX is not set + +# +# Hardware Spinlock drivers +# +CONFIG_IOMMU_SUPPORT=y + +# +# Remoteproc drivers (EXPERIMENTAL) +# + +# +# Rpmsg drivers (EXPERIMENTAL) +# +# CONFIG_VIRT_DRIVERS is not set +# CONFIG_PM_DEVFREQ is not set +# CONFIG_EXTCON is not set +# CONFIG_MEMORY is not set +CONFIG_IIO=y +CONFIG_IIO_BUFFER=y +CONFIG_IIO_KFIFO_BUF=y +CONFIG_IIO_TRIGGER=y +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 + +# +# Analog to digital converters +# +# CONFIG_AD7266 is not set +CONFIG_CF_AXI_ADC=y +CONFIG_CF_AXI_FFT=y +CONFIG_AXI_JESD204B=y + +# +# Amplifiers +# +# CONFIG_AD8366 is not set + +# +# Light sensors +# +# CONFIG_VCNL4000 is not set + +# +# Frequency Synthesizers DDS/PLL +# + +# +# Clock Generator/Distribution +# +# CONFIG_AD9523 is not set +# CONFIG_AD9548 is not set + +# +# Direct Digital Synthesis +# +CONFIG_CF_AXI_DDS=y +CONFIG_CF_AXI_DDS_AD9122=y + +# +# Phase-Locked Loop (PLL) frequency synthesizers +# +# CONFIG_ADF4350 is not set + +# +# Digital to analog converters +# +# CONFIG_AD5064 is not set +# CONFIG_AD5360 is not set +# CONFIG_AD5380 is not set +# CONFIG_AD5421 is not set +# CONFIG_AD5624R_SPI is not set +# CONFIG_AD5446 is not set +# CONFIG_AD5504 is not set +# CONFIG_AD5764 is not set +# CONFIG_AD5791 is not set +# CONFIG_AD5686 is not set +# CONFIG_MAX517 is not set +# CONFIG_MCP4725 is not set + +# +# File systems +# +# CONFIG_FS_POSIX_ACL is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ECRYPT_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set +# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_PSTORE is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V2=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_NLS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_LOCKUP_DETECTOR is not set +# CONFIG_HARDLOCKUP_DETECTOR is not set +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +# CONFIG_DETECT_HUNG_TASK is not set +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_TEST_KSTRTOX is not set +CONFIG_EARLY_PRINTK=y +# CONFIG_HEART_BEAT is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_ENCRYPTED_KEYS is not set +CONFIG_KEYS_DEBUG_PROC_KEYS=y +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set +# CONFIG_CRYPTO_USER is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IO=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +# CONFIG_CRC8 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +# CONFIG_XZ_DEC is not set +# CONFIG_XZ_DEC_BCJ is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y +# CONFIG_AVERAGE is not set +# CONFIG_CORDIC is not set +# CONFIG_DDR is not set diff --git a/arch/microblaze/configs/kc705_xcomm_defconfig b/arch/microblaze/configs/kc705_xcomm_defconfig new file mode 100644 index 0000000000000..a4d7d99c21e96 --- /dev/null +++ b/arch/microblaze/configs/kc705_xcomm_defconfig @@ -0,0 +1,1312 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/microblaze 3.3.0-rc3 Kernel Configuration +# +CONFIG_MICROBLAZE=y +# CONFIG_SWAP is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +# CONFIG_GENERIC_TIME_VSYSCALL is not set +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_CSUM=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_DEFAULT_HOSTNAME="(none)" +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_FHANDLE is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y + +# +# RCU Subsystem +# +CONFIG_TINY_RCU=y +# CONFIG_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_CHECKPOINT_RESTORE is not set +# CONFIG_NAMESPACES is not set +# CONFIG_SCHED_AUTOGROUP is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="rootfs.cpio.gz" +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_ROOT_GID=0 +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +CONFIG_INITRAMFS_COMPRESSION_NONE=y +# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EXPERT=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_EMBEDDED=y + +# +# Kernel Performance Events And Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_API_DEBUG=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_BLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +# CONFIG_FREEZER is not set + +# +# Platform options +# +# CONFIG_PLATFORM_GENERIC is not set +# CONFIG_PLATFORM_ML605_ADIXCOMM is not set +CONFIG_PLATFORM_KC705_ADIXCOMM=y +# CONFIG_ADIXCOMM_SYNC is not set +CONFIG_OPT_LIB_FUNCTION=y +# CONFIG_OPT_LIB_ASM is not set + +# +# Definitions for MICROBLAZE0 +# +CONFIG_KERNEL_BASE_ADDR=0xc0000000 +CONFIG_XILINX_MICROBLAZE0_FAMILY="kintex7" +CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR=1 +CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR=1 +CONFIG_XILINX_MICROBLAZE0_USE_BARREL=1 +CONFIG_XILINX_MICROBLAZE0_USE_DIV=1 +CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL=2 +CONFIG_XILINX_MICROBLAZE0_USE_FPU=0 +CONFIG_XILINX_MICROBLAZE0_HW_VER="8.20.b" + +# +# Processor type and features +# +CONFIG_TICK_ONESHOT=y +# CONFIG_NO_HZ is not set +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SCHED_HRTICK=y +CONFIG_MMU=y + +# +# Boot options +# +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttyUL0,57600 root=/dev/ram" +CONFIG_CMDLINE_FORCE=y +# CONFIG_SECCOMP is not set + +# +# Advanced setup +# +CONFIG_ADVANCED_OPTIONS=y +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE_BOOL=y +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_MANUAL_RESET_VECTOR=0x0 +CONFIG_KERNEL_START_BOOL=y +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE_BOOL=y +CONFIG_TASK_SIZE=0x80000000 +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_COMPACTION is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_NEED_PER_CPU_KM=y +# CONFIG_CLEANCACHE is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Bus Options +# +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS is not set +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_INET_UDP_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set +# CONFIG_DNS_RESOLVER is not set +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +CONFIG_BQL=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_GENERIC_CPU_DEVICES=y +# CONFIG_DMA_SHARED_BUFFER is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_RAM=y +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +CONFIG_MTD_PHYSMAP_OF=y +# CONFIG_MTD_GPIO_ADDR is not set +# CONFIG_MTD_PLATRAM is not set +# CONFIG_MTD_LATCH_ADDR is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +CONFIG_MTD_M25P80=y +CONFIG_M25PXX_USE_FAST_READ=y +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOCG3 is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set +# CONFIG_MTD_UBI is not set +CONFIG_DTC=y +CONFIG_OF=y + +# +# Device Tree and Open Firmware support +# +CONFIG_PROC_DEVICETREE=y +# CONFIG_OF_SELFTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_IRQ=y +CONFIG_OF_DEVICE=y +CONFIG_OF_GPIO=y +CONFIG_OF_I2C=y +CONFIG_OF_NET=y +CONFIG_OF_SPI=y +CONFIG_OF_MDIO=y +# CONFIG_PARPORT is not set + +# +# Misc devices +# +CONFIG_AD525X_DPOT=y +CONFIG_AD525X_DPOT_I2C=y +CONFIG_AD525X_DPOT_SPI=y +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_BMP085 is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=y +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_EEPROM_93XX46 is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_NETDEVICES=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +# CONFIG_DUMMY is not set +# CONFIG_EQUALIZER is not set +# CONFIG_MII is not set +# CONFIG_NET_TEAM is not set +# CONFIG_MACVLAN is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set + +# +# CAIF transport drivers +# +CONFIG_ETHERNET=y +CONFIG_NET_VENDOR_BROADCOM=y +# CONFIG_B44 is not set +# CONFIG_NET_CALXEDA_XGMAC is not set +CONFIG_NET_VENDOR_CHELSIO=y +# CONFIG_DNET is not set +CONFIG_NET_VENDOR_INTEL=y +CONFIG_NET_VENDOR_I825XX=y +CONFIG_NET_VENDOR_MARVELL=y +CONFIG_NET_VENDOR_MICREL=y +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +CONFIG_NET_VENDOR_MICROCHIP=y +# CONFIG_ENC28J60 is not set +CONFIG_NET_VENDOR_NATSEMI=y +CONFIG_NET_VENDOR_8390=y +# CONFIG_ETHOC is not set +CONFIG_NET_VENDOR_SEEQ=y +# CONFIG_SEEQ8005 is not set +CONFIG_NET_VENDOR_STMICRO=y +# CONFIG_STMMAC_ETH is not set +CONFIG_NET_VENDOR_XILINX=y +CONFIG_XILINX_EMACLITE=y +# CONFIG_XILINX_LL_TEMAC is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MICREL_KS8995MA is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +CONFIG_WLAN=y +# CONFIG_HOSTAP is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +CONFIG_DEVKMEM=y + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_DW is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX3107 is not set +CONFIG_SERIAL_UARTLITE=y +CONFIG_SERIAL_UARTLITE_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_TTY_PRINTK is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_XILINX_HWICAP is not set +# CONFIG_R3964 is not set + +# +# PCMCIA character devices +# +# CONFIG_TCG_TPM is not set +# CONFIG_RAMOOPS is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y + +# +# Multiplexer I2C Chip support +# +# CONFIG_I2C_MUX_GPIO is not set +# CONFIG_I2C_MUX_PCA9541 is not set +CONFIG_I2C_MUX_PCA954x=y +# CONFIG_I2C_HELPER_AUTO is not set +# CONFIG_I2C_SMBUS is not set + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +# CONFIG_I2C_SIMTEC is not set +CONFIG_I2C_XILINX=y + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +CONFIG_SPI_BITBANG=y +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PXA2XX_PCI is not set +CONFIG_SPI_XCOMM=y +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set + +# +# PPS generators support +# + +# +# PTP clock support +# + +# +# Enable Device Drivers -> PPS to see the PTP clock options. +# +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO drivers: +# +# CONFIG_GPIO_GENERIC_PLATFORM is not set +CONFIG_GPIO_XILINX=y + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_SX150X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_74X164 is not set + +# +# AC97 GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_MFD_STMPE is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_S5M_CORE is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13XXX is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_SOUND is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_RTC_CLASS is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_XILINX_DMA=y +# CONFIG_TIMB_DMA is not set +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# Virtio drivers +# +# CONFIG_VIRTIO_BALLOON is not set +# CONFIG_VIRTIO_MMIO is not set + +# +# Microsoft Hyper-V guest support +# +CONFIG_STAGING=y +# CONFIG_ECHO is not set +# CONFIG_RTLLIB is not set +CONFIG_IIO=y +CONFIG_IIO_BUFFER=y +CONFIG_IIO_SW_RING=y +CONFIG_IIO_KFIFO_BUF=y +CONFIG_IIO_TRIGGER=y +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 + +# +# Accelerometers +# +# CONFIG_ADIS16201 is not set +# CONFIG_ADIS16203 is not set +# CONFIG_ADIS16204 is not set +# CONFIG_ADIS16209 is not set +# CONFIG_ADIS16220 is not set +# CONFIG_ADIS16240 is not set +# CONFIG_KXSD9 is not set +# CONFIG_LIS3L02DQ is not set +# CONFIG_SCA3000 is not set + +# +# Analog to digital converters +# +# CONFIG_AD7291 is not set +# CONFIG_AD7298 is not set +# CONFIG_AD7606 is not set +# CONFIG_AD799X is not set +# CONFIG_AD7476 is not set +# CONFIG_AD7887 is not set +# CONFIG_AD7780 is not set +# CONFIG_AD7793 is not set +# CONFIG_AD7816 is not set +# CONFIG_AD7192 is not set +# CONFIG_ADT7310 is not set +# CONFIG_ADT7410 is not set +# CONFIG_AD7280 is not set +CONFIG_CF_AD9467=y +# CONFIG_MAX1363 is not set + +# +# Analog digital bi-direction converters +# +# CONFIG_ADT7316 is not set + +# +# Amplifiers +# +CONFIG_AD8366=y + +# +# Capacitance to digital converters +# +# CONFIG_AD7150 is not set +# CONFIG_AD7152 is not set +# CONFIG_AD7746 is not set + +# +# Digital to analog converters +# +# CONFIG_AD5064 is not set +# CONFIG_AD5360 is not set +# CONFIG_AD5380 is not set +# CONFIG_AD5421 is not set +# CONFIG_AD5624R_SPI is not set +# CONFIG_AD5446 is not set +# CONFIG_AD5504 is not set +# CONFIG_AD5764 is not set +# CONFIG_AD5791 is not set +# CONFIG_AD5686 is not set +# CONFIG_MAX517 is not set + +# +# Frequency Synthesizers DDS/PLL +# + +# +# Clock Generator/Distribution +# +CONFIG_AD9523=y +CONFIG_AD9548=y + +# +# Direct Digital Synthesis +# +# CONFIG_AD5930 is not set +# CONFIG_AD9832 is not set +# CONFIG_AD9834 is not set +# CONFIG_AD9850 is not set +# CONFIG_AD9852 is not set +# CONFIG_AD9910 is not set +# CONFIG_AD9951 is not set +CONFIG_AD9122_CF=y +CONFIG_AD9122_CF_DAC=y + +# +# Phase-Locked Loop (PLL) frequency synthesizers +# +CONFIG_ADF4350=y + +# +# Digital gyroscope sensors +# +# CONFIG_ADIS16060 is not set +# CONFIG_ADIS16080 is not set +# CONFIG_ADIS16130 is not set +# CONFIG_ADIS16260 is not set +# CONFIG_ADXRS450 is not set + +# +# Network Analyzer, Impedance Converters +# +# CONFIG_AD5933 is not set + +# +# Inertial measurement units +# +# CONFIG_ADIS16400 is not set + +# +# Light sensors +# +# CONFIG_SENSORS_ISL29018 is not set +# CONFIG_SENSORS_TSL2563 is not set +# CONFIG_TSL2583 is not set + +# +# Magnetometer sensors +# +# CONFIG_SENSORS_AK8975 is not set +# CONFIG_SENSORS_HMC5843 is not set + +# +# Active energy metering IC +# +# CONFIG_ADE7753 is not set +# CONFIG_ADE7754 is not set +# CONFIG_ADE7758 is not set +# CONFIG_ADE7759 is not set +# CONFIG_ADE7854 is not set + +# +# Resolver to digital converters +# +# CONFIG_AD2S90 is not set +# CONFIG_AD2S1200 is not set +# CONFIG_AD2S1210 is not set + +# +# Triggers - standalone +# +# CONFIG_IIO_GPIO_TRIGGER is not set +# CONFIG_IIO_SYSFS_TRIGGER is not set +# CONFIG_IIO_SIMPLE_DUMMY is not set +# CONFIG_FT1000 is not set + +# +# Speakup console speech +# +# CONFIG_STAGING_MEDIA is not set + +# +# Android +# +# CONFIG_ANDROID is not set +# CONFIG_PHONE is not set + +# +# Hardware Spinlock drivers +# +CONFIG_IOMMU_SUPPORT=y +# CONFIG_VIRT_DRIVERS is not set +# CONFIG_PM_DEVFREQ is not set + +# +# File systems +# +# CONFIG_FS_POSIX_ACL is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ECRYPT_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set +# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_PSTORE is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_NLS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_LOCKUP_DETECTOR is not set +# CONFIG_HARDLOCKUP_DETECTOR is not set +# CONFIG_DETECT_HUNG_TASK is not set +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_TEST_KSTRTOX is not set +CONFIG_EARLY_PRINTK=y +# CONFIG_HEART_BEAT is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_ENCRYPTED_KEYS is not set +CONFIG_KEYS_DEBUG_PROC_KEYS=y +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set +# CONFIG_CRYPTO_USER is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_PCI_IOMAP=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +# CONFIG_CRC8 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +# CONFIG_XZ_DEC is not set +# CONFIG_XZ_DEC_BCJ is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y +# CONFIG_AVERAGE is not set +# CONFIG_CORDIC is not set diff --git a/arch/microblaze/configs/ml605_ad9265_defconfig b/arch/microblaze/configs/ml605_ad9265_defconfig new file mode 100644 index 0000000000000..d291911e060fc --- /dev/null +++ b/arch/microblaze/configs/ml605_ad9265_defconfig @@ -0,0 +1,1378 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/microblaze 3.5.0-rc4 Kernel Configuration +# +CONFIG_MICROBLAZE=y +# CONFIG_SWAP is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_ZONE_DMA=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_CSUM=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_DEFAULT_HOSTNAME="(none)" +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_FHANDLE is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_IRQ_DOMAIN=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +# CONFIG_NO_HZ is not set +CONFIG_HIGH_RES_TIMERS=y + +# +# RCU Subsystem +# +CONFIG_TINY_RCU=y +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_CHECKPOINT_RESTORE is not set +# CONFIG_NAMESPACES is not set +# CONFIG_SCHED_AUTOGROUP is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="rootfs.cpio.gz" +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_ROOT_GID=0 +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +CONFIG_INITRAMFS_COMPRESSION_NONE=y +# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EXPERT=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_EMBEDDED=y + +# +# Kernel Performance Events And Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_API_DEBUG=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_BLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +# CONFIG_FREEZER is not set + +# +# Platform options +# +# CONFIG_PLATFORM_GENERIC is not set +CONFIG_PLATFORM_ML605_ADIXCOMM=y +# CONFIG_PLATFORM_KC705_ADIXCOMM is not set +# CONFIG_ADIXCOMM_SYNC is not set +CONFIG_OPT_LIB_FUNCTION=y +# CONFIG_OPT_LIB_ASM is not set + +# +# Definitions for MICROBLAZE0 +# +CONFIG_KERNEL_BASE_ADDR=0xc0000000 +CONFIG_XILINX_MICROBLAZE0_FAMILY="virtex6" +CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR=1 +CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR=1 +CONFIG_XILINX_MICROBLAZE0_USE_BARREL=1 +CONFIG_XILINX_MICROBLAZE0_USE_DIV=1 +CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL=2 +CONFIG_XILINX_MICROBLAZE0_USE_FPU=0 +CONFIG_XILINX_MICROBLAZE0_HW_VER="8.20.a" + +# +# Processor type and features +# +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SCHED_HRTICK=y +CONFIG_MMU=y + +# +# Boot options +# +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttyUL0,57600 root=/dev/ram" +CONFIG_CMDLINE_FORCE=y +# CONFIG_SECCOMP is not set + +# +# Advanced setup +# +CONFIG_ADVANCED_OPTIONS=y +# CONFIG_HIGHMEM is not set +CONFIG_LOWMEM_SIZE_BOOL=y +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_MANUAL_RESET_VECTOR=0x0 +CONFIG_KERNEL_START_BOOL=y +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE_BOOL=y +CONFIG_TASK_SIZE=0x80000000 +CONFIG_KERNEL_PAD=0x80000 +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_MEMBLOCK_NODE_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_COMPACTION is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_NEED_PER_CPU_KM=y +# CONFIG_CLEANCACHE is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Bus Options +# +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS is not set +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_INET_UDP_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set +# CONFIG_DNS_RESOLVER is not set +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +CONFIG_BQL=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_GENERIC_CPU_DEVICES=y +# CONFIG_DMA_SHARED_BUFFER is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_RAM=y +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +CONFIG_MTD_PHYSMAP_OF=y +# CONFIG_MTD_GPIO_ADDR is not set +# CONFIG_MTD_PLATRAM is not set +# CONFIG_MTD_LATCH_ADDR is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +CONFIG_MTD_M25P80=y +CONFIG_M25PXX_USE_FAST_READ=y +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOCG3 is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set +# CONFIG_MTD_UBI is not set +CONFIG_DTC=y +CONFIG_OF=y + +# +# Device Tree and Open Firmware support +# +CONFIG_PROC_DEVICETREE=y +# CONFIG_OF_SELFTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_IRQ=y +CONFIG_OF_DEVICE=y +CONFIG_OF_I2C=y +CONFIG_OF_NET=y +CONFIG_OF_MDIO=y +CONFIG_OF_MTD=y +# CONFIG_PARPORT is not set + +# +# Misc devices +# +# CONFIG_AD525X_DPOT is not set +# CONFIG_ICS932S401 is not set +CONFIG_XLNX_LCD=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_BMP085_I2C is not set +# CONFIG_BMP085_SPI is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=y +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_EEPROM_93XX46 is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_NETDEVICES=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +# CONFIG_DUMMY is not set +# CONFIG_EQUALIZER is not set +# CONFIG_MII is not set +# CONFIG_NET_TEAM is not set +# CONFIG_MACVLAN is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set + +# +# CAIF transport drivers +# +CONFIG_ETHERNET=y +CONFIG_NET_VENDOR_BROADCOM=y +# CONFIG_B44 is not set +# CONFIG_NET_CALXEDA_XGMAC is not set +CONFIG_NET_VENDOR_CHELSIO=y +# CONFIG_DNET is not set +CONFIG_NET_VENDOR_INTEL=y +CONFIG_NET_VENDOR_I825XX=y +CONFIG_NET_VENDOR_MARVELL=y +CONFIG_NET_VENDOR_MICREL=y +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +CONFIG_NET_VENDOR_MICROCHIP=y +# CONFIG_ENC28J60 is not set +CONFIG_NET_VENDOR_NATSEMI=y +CONFIG_NET_VENDOR_8390=y +# CONFIG_ETHOC is not set +CONFIG_NET_VENDOR_SEEQ=y +# CONFIG_SEEQ8005 is not set +CONFIG_NET_VENDOR_STMICRO=y +# CONFIG_STMMAC_ETH is not set +CONFIG_NET_VENDOR_WIZNET=y +# CONFIG_WIZNET_W5100 is not set +# CONFIG_WIZNET_W5300 is not set +CONFIG_NET_VENDOR_XILINX=y +CONFIG_XILINX_EMACLITE=y +# CONFIG_XILINX_AXI_EMAC is not set +# CONFIG_XILINX_LL_TEMAC is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_AMD_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_BUS_MUX_GPIO is not set +# CONFIG_MICREL_KS8995MA is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +CONFIG_WLAN=y +# CONFIG_HOSTAP is not set +# CONFIG_WL_TI is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +CONFIG_DEVKMEM=y + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_DW is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX3107 is not set +CONFIG_SERIAL_UARTLITE=y +CONFIG_SERIAL_UARTLITE_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_TTY_PRINTK is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_XILINX_HWICAP is not set +# CONFIG_R3964 is not set + +# +# PCMCIA character devices +# +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +# CONFIG_I2C_MUX is not set +# CONFIG_I2C_HELPER_AUTO is not set +# CONFIG_I2C_SMBUS is not set + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +# CONFIG_I2C_SIMTEC is not set +CONFIG_I2C_XILINX=y + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +CONFIG_SPI_BITBANG=y +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PXA2XX_PCI is not set +# CONFIG_SPI_XCOMM is not set +CONFIG_SPI_XILINX=y +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_HSI is not set + +# +# PPS support +# +# CONFIG_PPS is not set + +# +# PPS generators support +# + +# +# PTP clock support +# + +# +# Enable Device Drivers -> PPS to see the PTP clock options. +# +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_OF_GPIO=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO drivers: +# +# CONFIG_GPIO_GENERIC_PLATFORM is not set +CONFIG_GPIO_XILINX=y + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_SX150X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_74X164 is not set + +# +# AC97 GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_MFD_LM3533 is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_STMPE is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_S5M_CORE is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_EXYNOS_VIDEO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_SOUND is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +CONFIG_USB_ARCH_HAS_EHCI=y +# CONFIG_USB_ARCH_HAS_XHCI is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_RTC_CLASS is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_XILINX_DMA=y +# CONFIG_TIMB_DMA is not set +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# Virtio drivers +# +# CONFIG_VIRTIO_BALLOON is not set +# CONFIG_VIRTIO_MMIO is not set + +# +# Microsoft Hyper-V guest support +# +CONFIG_STAGING=y +# CONFIG_ECHO is not set +# CONFIG_RTLLIB is not set + +# +# IIO staging drivers +# +CONFIG_IIO_SW_RING=y + +# +# Accelerometers +# +# CONFIG_ADIS16201 is not set +# CONFIG_ADIS16203 is not set +# CONFIG_ADIS16204 is not set +# CONFIG_ADIS16209 is not set +# CONFIG_ADIS16220 is not set +# CONFIG_ADIS16240 is not set +# CONFIG_KXSD9 is not set +# CONFIG_LIS3L02DQ is not set +# CONFIG_SCA3000 is not set + +# +# Analog to digital converters +# +# CONFIG_AD7291 is not set +# CONFIG_AD7298 is not set +# CONFIG_AD7606 is not set +# CONFIG_AD799X is not set +# CONFIG_AD7476 is not set +# CONFIG_AD7887 is not set +# CONFIG_AD7780 is not set +# CONFIG_AD7793 is not set +# CONFIG_AD7816 is not set +# CONFIG_AD7192 is not set +# CONFIG_ADT7310 is not set +# CONFIG_ADT7410 is not set +# CONFIG_AD7280 is not set +# CONFIG_MAX1363 is not set + +# +# Analog digital bi-direction converters +# +# CONFIG_ADT7316 is not set + +# +# Capacitance to digital converters +# +# CONFIG_AD7150 is not set +# CONFIG_AD7152 is not set +# CONFIG_AD7746 is not set + +# +# Direct Digital Synthesis +# +# CONFIG_AD5930 is not set +# CONFIG_AD9832 is not set +# CONFIG_AD9834 is not set +# CONFIG_AD9850 is not set +# CONFIG_AD9852 is not set +# CONFIG_AD9910 is not set +# CONFIG_AD9951 is not set + +# +# Digital gyroscope sensors +# +# CONFIG_ADIS16060 is not set +# CONFIG_ADIS16080 is not set +# CONFIG_ADIS16130 is not set +# CONFIG_ADIS16260 is not set +# CONFIG_ADXRS450 is not set + +# +# Network Analyzer, Impedance Converters +# +# CONFIG_AD5933 is not set + +# +# Inertial measurement units +# +# CONFIG_ADIS16400 is not set + +# +# Light sensors +# +# CONFIG_SENSORS_ISL29018 is not set +# CONFIG_SENSORS_ISL29028 is not set +# CONFIG_SENSORS_TSL2563 is not set +# CONFIG_TSL2583 is not set +# CONFIG_TSL2x7x is not set + +# +# Magnetometer sensors +# +# CONFIG_SENSORS_AK8975 is not set +# CONFIG_SENSORS_HMC5843 is not set + +# +# Active energy metering IC +# +# CONFIG_ADE7753 is not set +# CONFIG_ADE7754 is not set +# CONFIG_ADE7758 is not set +# CONFIG_ADE7759 is not set +# CONFIG_ADE7854 is not set + +# +# Resolver to digital converters +# +# CONFIG_AD2S90 is not set +# CONFIG_AD2S1200 is not set +# CONFIG_AD2S1210 is not set + +# +# Triggers - standalone +# +# CONFIG_IIO_GPIO_TRIGGER is not set +# CONFIG_IIO_SYSFS_TRIGGER is not set +# CONFIG_IIO_SIMPLE_DUMMY is not set +# CONFIG_ZSMALLOC is not set +# CONFIG_FT1000 is not set + +# +# Speakup console speech +# +# CONFIG_STAGING_MEDIA is not set + +# +# Android +# +# CONFIG_ANDROID is not set +# CONFIG_PHONE is not set +# CONFIG_IPACK_BUS is not set +# CONFIG_WIMAX_GDM72XX is not set + +# +# Hardware Spinlock drivers +# +CONFIG_IOMMU_SUPPORT=y + +# +# Remoteproc drivers (EXPERIMENTAL) +# + +# +# Rpmsg drivers (EXPERIMENTAL) +# +# CONFIG_VIRT_DRIVERS is not set +# CONFIG_PM_DEVFREQ is not set +# CONFIG_EXTCON is not set +# CONFIG_MEMORY is not set +CONFIG_IIO=y +CONFIG_IIO_BUFFER=y +CONFIG_IIO_KFIFO_BUF=y +CONFIG_IIO_TRIGGER=y +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 + +# +# Analog to digital converters +# +# CONFIG_AD7266 is not set +CONFIG_CF_AXI_ADC=y +# CONFIG_CF_AXI_FFT is not set +# CONFIG_AXI_JESD204B is not set + +# +# Amplifiers +# +# CONFIG_AD8366 is not set + +# +# Light sensors +# +# CONFIG_VCNL4000 is not set + +# +# Frequency Synthesizers DDS/PLL +# + +# +# Clock Generator/Distribution +# +# CONFIG_AD9523 is not set +# CONFIG_AD9548 is not set + +# +# Direct Digital Synthesis +# +# CONFIG_CF_AXI_DDS is not set + +# +# Phase-Locked Loop (PLL) frequency synthesizers +# +# CONFIG_ADF4350 is not set + +# +# Digital to analog converters +# +# CONFIG_AD5064 is not set +# CONFIG_AD5360 is not set +# CONFIG_AD5380 is not set +# CONFIG_AD5421 is not set +# CONFIG_AD5624R_SPI is not set +# CONFIG_AD5446 is not set +# CONFIG_AD5504 is not set +# CONFIG_AD5764 is not set +# CONFIG_AD5791 is not set +# CONFIG_AD5686 is not set +# CONFIG_MAX517 is not set +# CONFIG_MCP4725 is not set + +# +# File systems +# +# CONFIG_FS_POSIX_ACL is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ECRYPT_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set +# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_PSTORE is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V2=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_NLS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_LOCKUP_DETECTOR is not set +# CONFIG_HARDLOCKUP_DETECTOR is not set +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +# CONFIG_DETECT_HUNG_TASK is not set +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_TEST_KSTRTOX is not set +CONFIG_EARLY_PRINTK=y +# CONFIG_HEART_BEAT is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_ENCRYPTED_KEYS is not set +CONFIG_KEYS_DEBUG_PROC_KEYS=y +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set +# CONFIG_CRYPTO_USER is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IO=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +# CONFIG_CRC8 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +# CONFIG_XZ_DEC is not set +# CONFIG_XZ_DEC_BCJ is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y +# CONFIG_AVERAGE is not set +# CONFIG_CORDIC is not set +# CONFIG_DDR is not set diff --git a/arch/microblaze/configs/ml605_xcomm_defconfig b/arch/microblaze/configs/ml605_xcomm_defconfig new file mode 100644 index 0000000000000..828c67463d09a --- /dev/null +++ b/arch/microblaze/configs/ml605_xcomm_defconfig @@ -0,0 +1,1395 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/microblaze 3.5.0-rc4 Kernel Configuration +# +CONFIG_MICROBLAZE=y +# CONFIG_SWAP is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_ZONE_DMA=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_CSUM=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_DEFAULT_HOSTNAME="(none)" +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_FHANDLE is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_IRQ_DOMAIN=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +# CONFIG_NO_HZ is not set +CONFIG_HIGH_RES_TIMERS=y + +# +# RCU Subsystem +# +CONFIG_TINY_RCU=y +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_CHECKPOINT_RESTORE is not set +# CONFIG_NAMESPACES is not set +# CONFIG_SCHED_AUTOGROUP is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="rootfs.cpio.gz" +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_ROOT_GID=0 +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +CONFIG_INITRAMFS_COMPRESSION_NONE=y +# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EXPERT=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_EMBEDDED=y + +# +# Kernel Performance Events And Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_BLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +# CONFIG_FREEZER is not set + +# +# Platform options +# +# CONFIG_PLATFORM_GENERIC is not set +CONFIG_PLATFORM_ML605_ADIXCOMM=y +# CONFIG_PLATFORM_KC705_ADIXCOMM is not set +# CONFIG_ADIXCOMM_SYNC is not set +CONFIG_OPT_LIB_FUNCTION=y +# CONFIG_OPT_LIB_ASM is not set + +# +# Definitions for MICROBLAZE0 +# +CONFIG_KERNEL_BASE_ADDR=0xc0000000 +CONFIG_XILINX_MICROBLAZE0_FAMILY="virtex6" +CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR=1 +CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR=1 +CONFIG_XILINX_MICROBLAZE0_USE_BARREL=1 +CONFIG_XILINX_MICROBLAZE0_USE_DIV=1 +CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL=2 +CONFIG_XILINX_MICROBLAZE0_USE_FPU=0 +CONFIG_XILINX_MICROBLAZE0_HW_VER="8.20.a" + +# +# Processor type and features +# +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SCHED_HRTICK=y +CONFIG_MMU=y + +# +# Boot options +# +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttyUL0,57600 root=/dev/ram" +CONFIG_CMDLINE_FORCE=y +# CONFIG_SECCOMP is not set + +# +# Advanced setup +# +CONFIG_ADVANCED_OPTIONS=y +# CONFIG_HIGHMEM is not set +CONFIG_LOWMEM_SIZE_BOOL=y +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_MANUAL_RESET_VECTOR=0x0 +CONFIG_KERNEL_START_BOOL=y +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE_BOOL=y +CONFIG_TASK_SIZE=0x80000000 +CONFIG_KERNEL_PAD=0x80000 +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_MEMBLOCK_NODE_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_COMPACTION is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_NEED_PER_CPU_KM=y +# CONFIG_CLEANCACHE is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Bus Options +# +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS is not set +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_INET_UDP_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set +# CONFIG_DNS_RESOLVER is not set +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +CONFIG_BQL=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_GENERIC_CPU_DEVICES=y +# CONFIG_DMA_SHARED_BUFFER is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_RAM=y +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +CONFIG_MTD_PHYSMAP_OF=y +# CONFIG_MTD_GPIO_ADDR is not set +# CONFIG_MTD_PLATRAM is not set +# CONFIG_MTD_LATCH_ADDR is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +CONFIG_MTD_M25P80=y +CONFIG_M25PXX_USE_FAST_READ=y +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOCG3 is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set +# CONFIG_MTD_UBI is not set +CONFIG_DTC=y +CONFIG_OF=y + +# +# Device Tree and Open Firmware support +# +CONFIG_PROC_DEVICETREE=y +# CONFIG_OF_SELFTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_IRQ=y +CONFIG_OF_DEVICE=y +CONFIG_OF_I2C=y +CONFIG_OF_NET=y +CONFIG_OF_MDIO=y +CONFIG_OF_MTD=y +# CONFIG_PARPORT is not set + +# +# Misc devices +# +CONFIG_AD525X_DPOT=y +CONFIG_AD525X_DPOT_I2C=y +CONFIG_AD525X_DPOT_SPI=y +# CONFIG_ATMEL_PWM is not set +# CONFIG_ICS932S401 is not set +CONFIG_XLNX_LCD=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_BMP085_I2C is not set +# CONFIG_BMP085_SPI is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=y +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_EEPROM_93XX46 is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_NETDEVICES=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +# CONFIG_DUMMY is not set +# CONFIG_EQUALIZER is not set +# CONFIG_MII is not set +# CONFIG_NET_TEAM is not set +# CONFIG_MACVLAN is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set + +# +# CAIF transport drivers +# +CONFIG_ETHERNET=y +CONFIG_NET_VENDOR_BROADCOM=y +# CONFIG_B44 is not set +# CONFIG_NET_CALXEDA_XGMAC is not set +CONFIG_NET_VENDOR_CHELSIO=y +# CONFIG_DNET is not set +CONFIG_NET_VENDOR_INTEL=y +CONFIG_NET_VENDOR_I825XX=y +CONFIG_NET_VENDOR_MARVELL=y +CONFIG_NET_VENDOR_MICREL=y +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +CONFIG_NET_VENDOR_MICROCHIP=y +# CONFIG_ENC28J60 is not set +CONFIG_NET_VENDOR_NATSEMI=y +CONFIG_NET_VENDOR_8390=y +# CONFIG_ETHOC is not set +CONFIG_NET_VENDOR_SEEQ=y +# CONFIG_SEEQ8005 is not set +CONFIG_NET_VENDOR_STMICRO=y +# CONFIG_STMMAC_ETH is not set +CONFIG_NET_VENDOR_WIZNET=y +# CONFIG_WIZNET_W5100 is not set +# CONFIG_WIZNET_W5300 is not set +CONFIG_NET_VENDOR_XILINX=y +CONFIG_XILINX_EMACLITE=y +# CONFIG_XILINX_AXI_EMAC is not set +# CONFIG_XILINX_LL_TEMAC is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_AMD_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_BUS_MUX_GPIO is not set +# CONFIG_MICREL_KS8995MA is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +CONFIG_WLAN=y +# CONFIG_HOSTAP is not set +# CONFIG_WL_TI is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +CONFIG_DEVKMEM=y + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_DW is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX3107 is not set +CONFIG_SERIAL_UARTLITE=y +CONFIG_SERIAL_UARTLITE_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_TTY_PRINTK is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_XILINX_HWICAP is not set +# CONFIG_R3964 is not set + +# +# PCMCIA character devices +# +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +# CONFIG_I2C_MUX is not set +# CONFIG_I2C_HELPER_AUTO is not set +# CONFIG_I2C_SMBUS is not set + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +# CONFIG_I2C_SIMTEC is not set +CONFIG_I2C_XILINX=y + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +CONFIG_SPI_BITBANG=y +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PXA2XX_PCI is not set +CONFIG_SPI_XCOMM=y +# CONFIG_SPI_AD9250FMC is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_HSI is not set + +# +# PPS support +# +# CONFIG_PPS is not set + +# +# PPS generators support +# + +# +# PTP clock support +# + +# +# Enable Device Drivers -> PPS to see the PTP clock options. +# +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_OF_GPIO=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO drivers: +# +# CONFIG_GPIO_GENERIC_PLATFORM is not set +CONFIG_GPIO_XILINX=y + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_SX150X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_74X164 is not set + +# +# AC97 GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_MFD_LM3533 is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_STMPE is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_S5M_CORE is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_EXYNOS_VIDEO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_SOUND is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +CONFIG_USB_ARCH_HAS_EHCI=y +# CONFIG_USB_ARCH_HAS_XHCI is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_RTC_CLASS is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_XILINX_DMA=y +# CONFIG_DW_DMAC is not set +# CONFIG_TIMB_DMA is not set +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# Virtio drivers +# +# CONFIG_VIRTIO_BALLOON is not set +# CONFIG_VIRTIO_MMIO is not set + +# +# Microsoft Hyper-V guest support +# +CONFIG_STAGING=y +# CONFIG_ECHO is not set +# CONFIG_RTLLIB is not set + +# +# IIO staging drivers +# +CONFIG_IIO_SW_RING=y + +# +# Accelerometers +# +# CONFIG_ADIS16201 is not set +# CONFIG_ADIS16203 is not set +# CONFIG_ADIS16204 is not set +# CONFIG_ADIS16209 is not set +# CONFIG_ADIS16220 is not set +# CONFIG_ADIS16240 is not set +# CONFIG_KXSD9 is not set +# CONFIG_LIS3L02DQ is not set +# CONFIG_SCA3000 is not set + +# +# Analog to digital converters +# +# CONFIG_AD7291 is not set +# CONFIG_AD7298 is not set +# CONFIG_AD7606 is not set +# CONFIG_AD799X is not set +# CONFIG_AD7476 is not set +# CONFIG_AD7887 is not set +# CONFIG_AD7780 is not set +# CONFIG_AD7793 is not set +# CONFIG_AD7816 is not set +# CONFIG_AD7192 is not set +# CONFIG_ADT7310 is not set +# CONFIG_ADT7410 is not set +# CONFIG_AD7280 is not set +# CONFIG_MAX1363 is not set + +# +# Analog digital bi-direction converters +# +# CONFIG_ADT7316 is not set + +# +# Capacitance to digital converters +# +# CONFIG_AD7150 is not set +# CONFIG_AD7152 is not set +# CONFIG_AD7746 is not set + +# +# Direct Digital Synthesis +# +# CONFIG_AD5930 is not set +# CONFIG_AD9832 is not set +# CONFIG_AD9834 is not set +# CONFIG_AD9850 is not set +# CONFIG_AD9852 is not set +# CONFIG_AD9910 is not set +# CONFIG_AD9951 is not set + +# +# Digital gyroscope sensors +# +# CONFIG_ADIS16060 is not set +# CONFIG_ADIS16080 is not set +# CONFIG_ADIS16130 is not set +# CONFIG_ADIS16260 is not set +# CONFIG_ADXRS450 is not set + +# +# Network Analyzer, Impedance Converters +# +# CONFIG_AD5933 is not set + +# +# Inertial measurement units +# +# CONFIG_ADIS16400 is not set + +# +# Light sensors +# +# CONFIG_SENSORS_ISL29018 is not set +# CONFIG_SENSORS_ISL29028 is not set +# CONFIG_SENSORS_TSL2563 is not set +# CONFIG_TSL2583 is not set +# CONFIG_TSL2x7x is not set + +# +# Magnetometer sensors +# +# CONFIG_SENSORS_AK8975 is not set +# CONFIG_SENSORS_HMC5843 is not set + +# +# Active energy metering IC +# +# CONFIG_ADE7753 is not set +# CONFIG_ADE7754 is not set +# CONFIG_ADE7758 is not set +# CONFIG_ADE7759 is not set +# CONFIG_ADE7854 is not set + +# +# Resolver to digital converters +# +# CONFIG_AD2S90 is not set +# CONFIG_AD2S1200 is not set +# CONFIG_AD2S1210 is not set + +# +# Triggers - standalone +# +# CONFIG_IIO_GPIO_TRIGGER is not set +# CONFIG_IIO_SYSFS_TRIGGER is not set +# CONFIG_IIO_SIMPLE_DUMMY is not set +# CONFIG_ZSMALLOC is not set +# CONFIG_FT1000 is not set + +# +# Speakup console speech +# +# CONFIG_STAGING_MEDIA is not set + +# +# Android +# +# CONFIG_ANDROID is not set +# CONFIG_PHONE is not set +# CONFIG_IPACK_BUS is not set +# CONFIG_WIMAX_GDM72XX is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y + +# +# Common Clock Framework +# +# CONFIG_COMMON_CLK_DEBUG is not set + +# +# Hardware Spinlock drivers +# +CONFIG_IOMMU_SUPPORT=y + +# +# Remoteproc drivers (EXPERIMENTAL) +# + +# +# Rpmsg drivers (EXPERIMENTAL) +# +# CONFIG_VIRT_DRIVERS is not set +# CONFIG_PM_DEVFREQ is not set +# CONFIG_EXTCON is not set +# CONFIG_MEMORY is not set +CONFIG_IIO=y +CONFIG_IIO_BUFFER=y +CONFIG_IIO_KFIFO_BUF=y +CONFIG_IIO_TRIGGER=y +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 + +# +# Analog to digital converters +# +# CONFIG_AD7266 is not set +CONFIG_CF_AXI_ADC=y +CONFIG_CF_AXI_FFT=y +# CONFIG_AXI_JESD204B is not set + +# +# Amplifiers +# +CONFIG_AD8366=y + +# +# Light sensors +# +# CONFIG_VCNL4000 is not set + +# +# Frequency Synthesizers DDS/PLL +# + +# +# Clock Generator/Distribution +# +CONFIG_AD9523=y +CONFIG_AD9548=y +# CONFIG_AD9517 is not set + +# +# Direct Digital Synthesis +# +CONFIG_CF_AXI_DDS=y +CONFIG_CF_AXI_DDS_AD9122=y + +# +# Phase-Locked Loop (PLL) frequency synthesizers +# +CONFIG_ADF4350=y + +# +# Digital to analog converters +# +# CONFIG_AD5064 is not set +# CONFIG_AD5360 is not set +# CONFIG_AD5380 is not set +# CONFIG_AD5421 is not set +# CONFIG_AD5624R_SPI is not set +# CONFIG_AD5446 is not set +# CONFIG_AD5504 is not set +# CONFIG_AD5764 is not set +# CONFIG_AD5791 is not set +# CONFIG_AD5686 is not set +# CONFIG_MAX517 is not set +# CONFIG_MCP4725 is not set + +# +# File systems +# +# CONFIG_FS_POSIX_ACL is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ECRYPT_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set +# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_PSTORE is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V2=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_NLS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_LOCKUP_DETECTOR is not set +# CONFIG_HARDLOCKUP_DETECTOR is not set +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +# CONFIG_DETECT_HUNG_TASK is not set +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_TEST_KSTRTOX is not set +CONFIG_EARLY_PRINTK=y +# CONFIG_HEART_BEAT is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_ENCRYPTED_KEYS is not set +CONFIG_KEYS_DEBUG_PROC_KEYS=y +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set +# CONFIG_CRYPTO_USER is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IO=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +# CONFIG_CRC8 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +# CONFIG_XZ_DEC is not set +# CONFIG_XZ_DEC_BCJ is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y +# CONFIG_AVERAGE is not set +# CONFIG_CORDIC is not set +# CONFIG_DDR is not set diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c index eab6abf5652e4..11a4154bfa67e 100644 --- a/arch/microblaze/kernel/cpu/cpuinfo.c +++ b/arch/microblaze/kernel/cpu/cpuinfo.c @@ -57,6 +57,7 @@ const struct family_string_key family_string_lookup[] = { {"virtex6", 0xe}, /* FIXME There is no key code defined for spartan2 */ {"spartan2", 0xf0}, + {"kintex7", 0x10}, {NULL, 0}, }; diff --git a/arch/microblaze/platform/Kconfig.platform b/arch/microblaze/platform/Kconfig.platform index 669c7eec293eb..638e313fe7b19 100644 --- a/arch/microblaze/platform/Kconfig.platform +++ b/arch/microblaze/platform/Kconfig.platform @@ -16,8 +16,25 @@ config PLATFORM_GENERIC help Choose this option for the Generic platform. +config PLATFORM_ML605_ADIXCOMM + bool "Analog Devices XCOMM on Xilinx ML605" + help + Choose this option for the XCOMM ML605 platform. + +config PLATFORM_KC705_ADIXCOMM + bool "Analog Devices XCOMM on Xilinx KC705" + help + Choose this option for the XCOMM KC705 platform. + endchoice +config ADIXCOMM_SYNC + bool "XCOMM Sync Clocks" + depends on PLATFORM_KC705_ADIXCOMM || PLATFORM_ML605_ADIXCOMM + default n + help + Choose this option for the XCOMM platform to sync clocks. + config SELFMOD bool "Use self modified code for intc/timer" depends on EXPERIMENTAL && NO_MMU @@ -59,8 +76,7 @@ config OPT_LIB_ASM Allows turn on optimalized library function (memcpy and memmove). Function are written in asm code. -if PLATFORM_GENERIC=y - source "arch/microblaze/platform/generic/Kconfig.auto" -endif + +source "arch/microblaze/platform/generic/Kconfig.auto" endmenu diff --git a/arch/microblaze/platform/Makefile b/arch/microblaze/platform/Makefile index ea1b75cc57758..637fc54ecfc0c 100644 --- a/arch/microblaze/platform/Makefile +++ b/arch/microblaze/platform/Makefile @@ -4,3 +4,5 @@ #obj-$(CONFIG_PLATFORM_GENERIC) += generic/ obj-y += platform.o +obj-$(CONFIG_PLATFORM_ML605_ADIXCOMM) += platform_xcomm.o +obj-$(CONFIG_PLATFORM_KC705_ADIXCOMM) += platform_xcomm.o diff --git a/arch/microblaze/platform/platform.c b/arch/microblaze/platform/platform.c index b9529caa507af..01c84965ccff2 100644 --- a/arch/microblaze/platform/platform.c +++ b/arch/microblaze/platform/platform.c @@ -15,16 +15,26 @@ #include #include +#include + static struct of_device_id xilinx_of_bus_ids[] __initdata = { { .compatible = "simple-bus", }, { .compatible = "xlnx,compound", }, {} }; +static const __initconst struct of_device_id clk_match[] = { + { .compatible = "fixed-clock", .data = of_fixed_clk_setup, }, + { /* sentinel */ } +}; + + static int __init microblaze_device_probe(void) { of_platform_bus_probe(NULL, xilinx_of_bus_ids, NULL); of_platform_reset_gpio_probe(); + of_clk_init(clk_match); + return 0; } device_initcall(microblaze_device_probe); diff --git a/arch/microblaze/platform/platform_xcomm.c b/arch/microblaze/platform/platform_xcomm.c new file mode 100644 index 0000000000000..4d46067505c6e --- /dev/null +++ b/arch/microblaze/platform/platform_xcomm.c @@ -0,0 +1,354 @@ +/* + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include + +#if defined(CONFIG_PLATFORM_ML605_ADIXCOMM) +#define SPIBUS_NUM_LPC 0 +#define SPIBUS_NUM_HPC 1 +#elif defined(CONFIG_PLATFORM_KC705_ADIXCOMM) +#define SPIBUS_NUM_LPC 1 +#define SPIBUS_NUM_HPC 0 +#endif + +#if defined(CONFIG_AD9523) || defined(CONFIG_AD9523_MODULE) +#include + +struct ad9523_channel_spec ad9523_channels[] = { + { /* ZD output */ + .channel_num = 0, + .extended_name = "ZD_OUTPUT", + .divider_output_invert_en = false, + .sync_ignore_en = false, + .low_power_mode_en = false, + .driver_mode = LVDS_4mA, + .divider_phase = 0, + .channel_divider = 8, + .use_alt_clock_src = false, + .output_dis = false, + }, + { /* DAC CLK */ + .channel_num = 12, + .extended_name = "DAC_CLK", + .divider_output_invert_en = false, + .sync_ignore_en = false, + .low_power_mode_en = false, + .driver_mode = LVPECL_8mA, + .divider_phase = 0, + .channel_divider = 2, + }, + { /* ADC CLK */ + .channel_num = 2, + .extended_name = "ADC_CLK", + .divider_output_invert_en = false, + .sync_ignore_en = false, + .low_power_mode_en = false, + .driver_mode = LVDS_7mA, + .divider_phase = 0, + .channel_divider = 4, + }, + { /* DAC REF CLK */ + .channel_num = 10, + .extended_name = "DAC_REF_CLK", + .divider_output_invert_en = false, + .sync_ignore_en = false, + .low_power_mode_en = false, + .driver_mode = LVDS_4mA, + .divider_phase = 0, + .channel_divider = 16, + }, + { /* TX LO REF */ + .channel_num = 5, + .extended_name = "TX_LO_REF_CLK", + .divider_output_invert_en = false, + .sync_ignore_en = false, + .low_power_mode_en = false, + .driver_mode = CMOS_CONF3, /* HiZ on - */ + .divider_phase = 0, + .channel_divider = 8, + }, + { /* DAC DCO */ + .channel_num = 6, + .extended_name = "DAC_DCO_CLK", + .divider_output_invert_en = false, + .sync_ignore_en = false, + .low_power_mode_en = false, + .driver_mode = LVDS_7mA, + .divider_phase = 0, + .channel_divider = 2, + }, + { /* ADC SYNC */ + .channel_num = 7, + .extended_name = "ADC_SYNC_CLK", + .divider_output_invert_en = false, + .sync_ignore_en = false, + .low_power_mode_en = false, + .driver_mode = CMOS_CONF3, /* HiZ on - */ + .divider_phase = 1, + .channel_divider = 32, + .output_dis = false, + }, + { /* RX LO REF */ + .channel_num = 9, + .extended_name = "RX_LO_REF_CLK", + .divider_output_invert_en = false, + .sync_ignore_en = false, + .low_power_mode_en = false, + .driver_mode = CMOS_CONF3, /* HiZ on - */ + .divider_phase = 0, + .channel_divider = 8, + }, +}; + +struct ad9523_platform_data ad9523_pdata_lpc = { + .vcxo_freq = 122880000, + + /* Single-Ended Input Configuration */ + .refa_diff_rcv_en = false, + .refb_diff_rcv_en = true, + .zd_in_diff_en = true, + .osc_in_diff_en = false, + .osc_in_cmos_neg_inp_en = true, + + .refa_r_div = 0, + .refb_r_div = 0, + .pll1_feedback_div = 4, + .pll1_charge_pump_current_nA = 2000, + .zero_delay_mode_internal_en = false, + .osc_in_feedback_en = false, + .refa_cmos_neg_inp_en = true, + .pll1_loop_filter_rzero = 3, + + .ref_mode = SELECT_REFB, // REVERT_TO_REFA, /* 3 ?*/ + + .pll2_charge_pump_current_nA = 420000, + .pll2_ndiv_a_cnt = 0, + .pll2_ndiv_b_cnt = 3, + .pll2_freq_doubler_en = true, + .pll2_r2_div = 1, + .pll2_vco_diff_m1 = 3, + .pll2_vco_diff_m2 = 3, + + .rpole2 = 0, + .rzero = 2, + .cpole1 = 2, + .rzero_bypass_en = false, + + /* Output Channel Configuration */ + .num_channels = ARRAY_SIZE(ad9523_channels), + .channels = ad9523_channels, + .name = "ad9523-lpc" +}; + +struct ad9523_platform_data ad9523_pdata_hpc = { + .vcxo_freq = 122880000, + + /* Single-Ended Input Configuration */ + .refa_diff_rcv_en = false, + .refb_diff_rcv_en = true, + .zd_in_diff_en = true, + .osc_in_diff_en = false, + .osc_in_cmos_neg_inp_en = true, + + .refa_r_div = 0, + .refb_r_div = 0, + .pll1_feedback_div = 4, + .pll1_charge_pump_current_nA = 2000, + .zero_delay_mode_internal_en = false, + .osc_in_feedback_en = false, + .refa_cmos_neg_inp_en = true, + .pll1_loop_filter_rzero = 3, + + .ref_mode = SELECT_REFB, // REVERT_TO_REFA, /* 3 ?*/ + + .pll2_charge_pump_current_nA = 420000, + .pll2_ndiv_a_cnt = 0, + .pll2_ndiv_b_cnt = 3, + .pll2_freq_doubler_en = true, + .pll2_r2_div = 1, + .pll2_vco_diff_m1 = 3, + .pll2_vco_diff_m2 = 3, + + .rpole2 = 0, + .rzero = 2, + .cpole1 = 2, + .rzero_bypass_en = false, + + /* Output Channel Configuration */ + .num_channels = ARRAY_SIZE(ad9523_channels), + .channels = ad9523_channels, + .name = "ad9523-hpc" +}; +#endif + +#if defined(CONFIG_ADF4350) || defined(CONFIG_ADF4350_MODULE) +#include +static struct adf4350_platform_data adf4350_tx_pdata_lpc = { + .name = "adf4351-tx-lpc", + .clkin = 122880000, + .channel_spacing = 10000, + .r2_user_settings = ADF4350_REG2_PD_POLARITY_POS, + ADF4350_REG2_CHARGE_PUMP_CURR_uA(2500), + .r3_user_settings = ADF4350_REG3_12BIT_CLKDIV_MODE(0), + .r4_user_settings = ADF4350_REG4_OUTPUT_PWR(3) | + ADF4350_REG4_MUTE_TILL_LOCK_EN, + .gpio_lock_detect = -1, + .power_up_frequency = 2400000000, +}; + +static struct adf4350_platform_data adf4350_rx_pdata_lpc = { + .name = "adf4351-rx-lpc", + .clkin = 122880000, + .channel_spacing = 10000, + .r2_user_settings = ADF4350_REG2_PD_POLARITY_POS, + ADF4350_REG2_CHARGE_PUMP_CURR_uA(2500), + .r3_user_settings = ADF4350_REG3_12BIT_CLKDIV_MODE(0), + .r4_user_settings = ADF4350_REG4_OUTPUT_PWR(3) | + ADF4350_REG4_MUTE_TILL_LOCK_EN, + .gpio_lock_detect = -1, + .power_up_frequency = 2400000000, +}; +static struct adf4350_platform_data adf4350_tx_pdata_hpc = { + .name = "adf4351-tx-hpc", + .clkin = 122880000, + .channel_spacing = 10000, + .r2_user_settings = ADF4350_REG2_PD_POLARITY_POS, + ADF4350_REG2_CHARGE_PUMP_CURR_uA(2500), + .r3_user_settings = ADF4350_REG3_12BIT_CLKDIV_MODE(0), + .r4_user_settings = ADF4350_REG4_OUTPUT_PWR(3) | + ADF4350_REG4_MUTE_TILL_LOCK_EN, + .gpio_lock_detect = -1, + .power_up_frequency = 2400000000, +}; + +static struct adf4350_platform_data adf4350_rx_pdata_hpc = { + .name = "adf4351-rx-hpc", + .clkin = 122880000, + .channel_spacing = 10000, + .r2_user_settings = ADF4350_REG2_PD_POLARITY_POS, + ADF4350_REG2_CHARGE_PUMP_CURR_uA(2500), + .r3_user_settings = ADF4350_REG3_12BIT_CLKDIV_MODE(0), + .r4_user_settings = ADF4350_REG4_OUTPUT_PWR(3) | + ADF4350_REG4_MUTE_TILL_LOCK_EN, + .gpio_lock_detect = -1, + .power_up_frequency = 2400000000, +}; +#endif + +static struct spi_board_info xcomm_spi_board_info[] __initdata = { +#if defined(CONFIG_AD9548) || defined(CONFIG_AD9548_MODULE) + { + .modalias = "ad9548", + .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = SPIBUS_NUM_LPC, + .chip_select = 2, /* AD9548 */ + .mode = SPI_MODE_0 | SPI_3WIRE, + }, + { + .modalias = "ad9548", + .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = SPIBUS_NUM_HPC, + .chip_select = 2, /* AD9548 */ + .mode = SPI_MODE_0 | SPI_3WIRE, + }, +#endif +#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) + { + .modalias = "spidev", + .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = SPIBUS_NUM_LPC, + .chip_select = 2, /* AD9548 */ + }, + { + .modalias = "spidev", + .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = SPIBUS_NUM_HPC, + .chip_select = 2, /* AD9548 */ + }, +#endif +#if defined(CONFIG_AD9523) || defined(CONFIG_AD9523_MODULE) + { + .modalias = "ad9523-1", + .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = SPIBUS_NUM_LPC, + .chip_select = 3, /* GPIO controlled SSEL */ + .platform_data = &ad9523_pdata_lpc, /* spi_driver specific config */ + .mode = SPI_MODE_0 | SPI_3WIRE, + }, + { + .modalias = "ad9523-1", + .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = SPIBUS_NUM_HPC, + .chip_select = 3, /* GPIO controlled SSEL */ + .platform_data = &ad9523_pdata_hpc, /* spi_driver specific config */ + .mode = SPI_MODE_0 | SPI_3WIRE, + }, +#endif +#if defined(CONFIG_AD8366) || defined(CONFIG_AD8366_MODULE) + { + .modalias = "ad8366", + .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = SPIBUS_NUM_LPC, + .chip_select = 6, /* GPIO controlled SSEL */ + .platform_data = "ad8366-lpc", /* spi_driver specific config */ + .mode = SPI_MODE_0 | SPI_3WIRE, + }, + { + .modalias = "ad8366", + .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = SPIBUS_NUM_HPC, + .chip_select = 6, /* GPIO controlled SSEL */ + .platform_data = "ad8366-hpc", /* spi_driver specific config */ + .mode = SPI_MODE_0 | SPI_3WIRE, + }, +#endif +#if defined(CONFIG_ADF4350) || defined(CONFIG_ADF4350_MODULE) + { + .modalias = "adf4351", + .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = SPIBUS_NUM_LPC, + .chip_select = 4, /* GPIO controlled SSEL */ + .platform_data = &adf4350_rx_pdata_lpc, /* No spi_driver specific config */ + .mode = SPI_MODE_0, + }, + { + .modalias = "adf4351", + .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = SPIBUS_NUM_LPC, + .chip_select = 5, /* GPIO controlled SSEL */ + .platform_data = &adf4350_tx_pdata_lpc, /* No spi_driver specific config */ + .mode = SPI_MODE_0, + }, + { + .modalias = "adf4351", + .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = SPIBUS_NUM_HPC, + .chip_select = 4, /* GPIO controlled SSEL */ + .platform_data = &adf4350_rx_pdata_hpc, /* No spi_driver specific config */ + .mode = SPI_MODE_0, + }, + { + .modalias = "adf4351", + .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = SPIBUS_NUM_HPC, + .chip_select = 5, /* GPIO controlled SSEL */ + .platform_data = &adf4350_tx_pdata_hpc, /* No spi_driver specific config */ + .mode = SPI_MODE_0, + }, + +#endif +}; + +static int __init xcomm_device_probe(void) +{ + spi_register_board_info(xcomm_spi_board_info, ARRAY_SIZE(xcomm_spi_board_info)); + + return 0; +} +device_initcall(xcomm_device_probe); diff --git a/drivers/Makefile b/drivers/Makefile index 66d483e07d298..92fd18cbe539c 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -76,6 +76,7 @@ obj-$(CONFIG_USB_OTG_UTILS) += usb/ obj-$(CONFIG_USB) += usb/ obj-$(CONFIG_PCI) += usb/ obj-$(CONFIG_USB_GADGET) += usb/ +obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_SERIO) += input/serio/ obj-$(CONFIG_GAMEPORT) += input/gameport/ obj-$(CONFIG_INPUT) += input/ diff --git a/drivers/base/core.c b/drivers/base/core.c index 5e6e00bc1652a..c2cbb9de5bb5b 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -649,6 +649,7 @@ void device_initialize(struct device *dev) { dev->kobj.kset = devices_kset; kobject_init(&dev->kobj, &device_ktype); + INIT_LIST_HEAD(&dev->deferred_probe); INIT_LIST_HEAD(&dev->dma_pools); mutex_init(&dev->mutex); lockdep_set_novalidate_class(&dev->mutex); diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index de754c3e1b7f5..bfeceb210d5b2 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -33,15 +33,13 @@ if DMADEVICES comment "DMA Devices" -source "drivers/dma/xilinx/Kconfig" - -#config XILINX_DMA -# tristate "Xilinx DMA engines support" -# select DMA_ENGINE -# ---help--- -# Enable support for the Xilinx DMA controllers. It supports three DMA -# engines: Axi Central DMA (memory to memory transfer), Axi DMA (memory and -# device transfer), and Axi VDMA (memory and video device transfer). +config XILINX_DMA + tristate "Xilinx DMA engines support" + select DMA_ENGINE + ---help--- + Enable support for the Xilinx DMA controllers. It supports three DMA + engines: Axi Central DMA (memory to memory transfer), Axi DMA (memory and + device transfer), and Axi VDMA (memory and video device transfer). config INTEL_MID_DMAC tristate "Intel MID DMA support for Peripheral DMA controllers" @@ -260,6 +258,14 @@ config IMX_DMA Support the i.MX DMA engine. This engine is integrated into Freescale i.MX1/21/27 chips. +config XILINX_DMA + tristate "Xilinx DMA engines support" + select DMA_ENGINE + help + Enable support for the Xilinx DMA controllers. It supports three DMA + engines: Axi Central DMA (memory to memory transfer), Axi DMA (memory and + device transfer), and Axi VDMA (memory and video device transfer). + config MXS_DMA bool "MXS DMA support" depends on SOC_IMX23 || SOC_IMX28 || SOC_IMX6Q diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index a34765439879b..2be9587c38ee4 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -33,4 +33,3 @@ obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o obj-$(CONFIG_DMA_OMAP) += omap-dma.o obj-$(CONFIG_XILINX_DMA) += xilinx_dma.o -obj-$(CONFIG_XILINX_DMA_ENGINES) += xilinx/ diff --git a/drivers/dma/xilinx/Kconfig b/drivers/dma/xilinx/Kconfig deleted file mode 100644 index 704a2b8784235..0000000000000 --- a/drivers/dma/xilinx/Kconfig +++ /dev/null @@ -1,53 +0,0 @@ -# -# XILINX DMA Engines configuration -# - -menuconfig XILINX_DMA_ENGINES - bool "Xilinx DMA Engines" - help - Enable support for the Xilinx DMA controllers. It supports three DMA - engines: Axi Central DMA (memory to memory transfer), Axi DMA (memory and - device transfer), and Axi VDMA (memory and video device transfer). - -if XILINX_DMA_ENGINES - -config XILINX_AXIDMA - tristate "Xilinx AXI DMA Engine" - select DMA_ENGINE - help - Enable support for Xilinx Axi DMA (memory and device transfer). - -config XILINX_DMATEST - tristate "DMA Test client for AXI DMA" - depends on XILINX_AXIDMA - help - Simple DMA test client. Say N unless you're debugging a - DMA Device driver. - -config XILINX_AXIVDMA - tristate "Xilinx AXI VDMA Engine" - select DMA_ENGINE - help - Enable support for Xilinx Axi VDMA (memory and video device transfer). - -config XILINX_VDMATEST - tristate "DMA Test client for VDMA" - depends on XILINX_AXIVDMA - help - Simple DMA test client. Say N unless you're debugging a - DMA Device driver. - -config XILINX_AXICDMA - tristate "Xilinx AXI CDMA Engine" - select DMA_ENGINE - help - Enable support for Xilinx Axi Central DMA (memory to memory transfer). - -config XILINX_CDMATEST - tristate "DMA Test client for CDMA" - depends on XILINX_AXICDMA - help - Simple DMA test client. Say N unless you're debugging a - DMA Device driver. - -endif # XILINX_DMA_ENGINES diff --git a/drivers/dma/xilinx/Makefile b/drivers/dma/xilinx/Makefile deleted file mode 100644 index 3362ad9b62a89..0000000000000 --- a/drivers/dma/xilinx/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -obj-$(CONFIG_XILINX_AXIDMA) += xilinx_axidma.o -obj-$(CONFIG_XILINX_DMATEST) += dmatest.o -obj-$(CONFIG_XILINX_AXIVDMA) += xilinx_axivdma.o -obj-$(CONFIG_XILINX_VDMATEST) += vdmatest.o -obj-$(CONFIG_XILINX_AXICDMA) += xilinx_axicdma.o -obj-$(CONFIG_XILINX_CDMATEST) += cdmatest.o diff --git a/drivers/dma/xilinx/cdmatest.c b/drivers/dma/xilinx/cdmatest.c deleted file mode 100644 index 4f2bb0ff12f62..0000000000000 --- a/drivers/dma/xilinx/cdmatest.c +++ /dev/null @@ -1,644 +0,0 @@ -/* - * XILINX CDMA Engine test module - * - * Copyright (C) 2012 Xilinx, Inc. All rights reserved. - * - * Based on Atmel DMA Test Client - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static unsigned int test_buf_size = 64; -module_param(test_buf_size, uint, S_IRUGO); -MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer"); - -static char test_channel[20]; -module_param_string(channel, test_channel, sizeof(test_channel), S_IRUGO); -MODULE_PARM_DESC(channel, "Bus ID of the channel to test (default: any)"); - -static char test_device[20]; -module_param_string(device, test_device, sizeof(test_device), S_IRUGO); -MODULE_PARM_DESC(device, "Bus ID of the DMA Engine to test (default: any)"); - -static unsigned int threads_per_chan = 1; -module_param(threads_per_chan, uint, S_IRUGO); -MODULE_PARM_DESC(threads_per_chan, - "Number of threads to start per channel (default: 1)"); - -static unsigned int max_channels; -module_param(max_channels, uint, S_IRUGO); -MODULE_PARM_DESC(max_channels, - "Maximum number of channels to use (default: all)"); - -static unsigned int iterations; -module_param(iterations, uint, S_IRUGO); -MODULE_PARM_DESC(iterations, - "Iterations before stopping test (default: infinite)"); - -static unsigned int xor_sources = 3; -module_param(xor_sources, uint, S_IRUGO); -MODULE_PARM_DESC(xor_sources, - "Number of xor source buffers (default: 3)"); - -static unsigned int pq_sources = 3; -module_param(pq_sources, uint, S_IRUGO); -MODULE_PARM_DESC(pq_sources, - "Number of p+q source buffers (default: 3)"); - -/* - * Initialization patterns. All bytes in the source buffer has bit 7 - * set, all bytes in the destination buffer has bit 7 cleared. - * - * Bit 6 is set for all bytes which are to be copied by the DMA - * engine. Bit 5 is set for all bytes which are to be overwritten by - * the DMA engine. - * - * The remaining bits are the inverse of a counter which increments by - * one for each byte address. - */ -#define PATTERN_SRC 0x80 -#define PATTERN_DST 0x00 -#define PATTERN_COPY 0x40 -#define PATTERN_OVERWRITE 0x20 -#define PATTERN_COUNT_MASK 0x1f - -struct cdmatest_thread { - struct list_head node; - struct task_struct *task; - struct dma_chan *chan; - u8 **srcs; - u8 **dsts; - enum dma_transaction_type type; -}; - -struct cdmatest_chan { - struct list_head node; - struct dma_chan *chan; - struct list_head threads; -}; - -/* - * These are protected by dma_list_mutex since they're only used by - * the DMA filter function callback - */ -static LIST_HEAD(cdmatest_channels); -static unsigned int nr_channels; - -static bool cdmatest_match_channel(struct dma_chan *chan) -{ - if (test_channel[0] == '\0') - return true; - return strcmp(dma_chan_name(chan), test_channel) == 0; -} - -static bool cdmatest_match_device(struct dma_device *device) -{ - if (test_device[0] == '\0') - return true; - return strcmp(dev_name(device->dev), test_device) == 0; -} - -static unsigned long cdmatest_random(void) -{ - unsigned long buf; - - get_random_bytes(&buf, sizeof(buf)); - return buf; -} - -static void cdmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len) -{ - unsigned int i; - u8 *buf; - - for (; (buf = *bufs); bufs++) { - for (i = 0; i < start; i++) - buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK); - for ( ; i < start + len; i++) - buf[i] = PATTERN_SRC | PATTERN_COPY - | (~i & PATTERN_COUNT_MASK); - for ( ; i < test_buf_size; i++) - buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK); - buf++; - } -} - -static void cdmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len) -{ - unsigned int i; - u8 *buf; - - for (; (buf = *bufs); bufs++) { - for (i = 0; i < start; i++) - buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK); - for ( ; i < start + len; i++) - buf[i] = PATTERN_DST | PATTERN_OVERWRITE - | (~i & PATTERN_COUNT_MASK); - for ( ; i < test_buf_size; i++) - buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK); - } -} - -static void cdmatest_mismatch(u8 actual, u8 pattern, unsigned int index, - unsigned int counter, bool is_srcbuf) -{ - u8 diff = actual ^ pattern; - u8 expected = pattern | (~counter & PATTERN_COUNT_MASK); - const char *thread_name = current->comm; - - if (is_srcbuf) - pr_warn( - "%s: srcbuf[0x%x] overwritten! Expected %02x, got %02x\n", - thread_name, index, expected, actual); - else if ((pattern & PATTERN_COPY) - && (diff & (PATTERN_COPY | PATTERN_OVERWRITE))) - pr_warn( - "%s: dstbuf[0x%x] not copied! Expected %02x, got %02x\n", - thread_name, index, expected, actual); - else if (diff & PATTERN_SRC) - pr_warn( - "%s: dstbuf[0x%x] was copied! Expected %02x, got %02x\n", - thread_name, index, expected, actual); - else - pr_warn( - "%s: dstbuf[0x%x] mismatch! Expected %02x, got %02x\n", - thread_name, index, expected, actual); -} - -static unsigned int cdmatest_verify(u8 **bufs, unsigned int start, - unsigned int end, unsigned int counter, u8 pattern, - bool is_srcbuf) -{ - unsigned int i; - unsigned int error_count = 0; - u8 actual; - u8 expected; - u8 *buf; - unsigned int counter_orig = counter; - - for (; (buf = *bufs); bufs++) { - counter = counter_orig; - for (i = start; i < end; i++) { - actual = buf[i]; - expected = pattern | (~counter & PATTERN_COUNT_MASK); - if (actual != expected) { - if (error_count < 32) - cdmatest_mismatch(actual, pattern, i, - counter, is_srcbuf); - error_count++; - } - counter++; - } - } - - if (error_count > 32) - pr_warn("%s: %u errors suppressed\n", - current->comm, error_count - 32); - - return error_count; -} - -static void cdmatest_callback(void *completion) -{ - complete(completion); -} - -/* - * This function repeatedly tests DMA transfers of various lengths and - * offsets for a given operation type until it is told to exit by - * kthread_stop(). There may be multiple threads running this function - * in parallel for a single channel, and there may be multiple channels - * being tested in parallel. - * - * Before each test, the source and destination buffer is initialized - * with a known pattern. This pattern is different depending on - * whether it's in an area which is supposed to be copied or - * overwritten, and different in the source and destination buffers. - * So if the DMA engine doesn't copy exactly what we tell it to copy, - * we'll notice. - */ -static int cdmatest_func(void *data) -{ - struct cdmatest_thread *thread = data; - struct dma_chan *chan; - const char *thread_name; - unsigned int src_off, dst_off, len; - unsigned int error_count; - unsigned int failed_tests = 0; - unsigned int total_tests = 0; - dma_cookie_t cookie; - enum dma_status status; - enum dma_ctrl_flags flags; - u8 pq_coefs[pq_sources + 1]; - int ret; - int src_cnt; - int dst_cnt; - int i; - - thread_name = current->comm; - - ret = -ENOMEM; - - /* JZ: limit testing scope here */ - iterations = 5; - - smp_rmb(); - chan = thread->chan; - if (thread->type == DMA_MEMCPY) - src_cnt = dst_cnt = 1; - else if (thread->type == DMA_XOR) { - src_cnt = xor_sources | 1; - /* force odd to ensure dst = src */ - dst_cnt = 1; - } else if (thread->type == DMA_PQ) { - src_cnt = pq_sources | 1; - /* force odd to ensure dst = src */ - dst_cnt = 2; - for (i = 0; i < src_cnt; i++) - pq_coefs[i] = 1; - } else - goto err_srcs; - - thread->srcs = kcalloc(src_cnt+1, sizeof(u8 *), GFP_KERNEL); - if (!thread->srcs) - goto err_srcs; - for (i = 0; i < src_cnt; i++) { - thread->srcs[i] = kmalloc(test_buf_size, GFP_KERNEL); - if (!thread->srcs[i]) - goto err_srcbuf; - } - thread->srcs[i] = NULL; - - thread->dsts = kcalloc(dst_cnt+1, sizeof(u8 *), GFP_KERNEL); - if (!thread->dsts) - goto err_dsts; - for (i = 0; i < dst_cnt; i++) { - thread->dsts[i] = kmalloc(test_buf_size, GFP_KERNEL); - if (!thread->dsts[i]) - goto err_dstbuf; - } - thread->dsts[i] = NULL; - - set_user_nice(current, 10); - - flags = DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP | DMA_PREP_INTERRUPT; - - while (!kthread_should_stop() - && !(iterations && total_tests >= iterations)) { - struct dma_device *dev = chan->device; - struct dma_async_tx_descriptor *tx = NULL; - dma_addr_t dma_srcs[src_cnt]; - dma_addr_t dma_dsts[dst_cnt]; - struct completion cmp; - unsigned long tmo = msecs_to_jiffies(3000); - u8 align = 0; - - total_tests++; - - /* honor alignment restrictions */ - if (thread->type == DMA_MEMCPY) - align = dev->copy_align; - else if (thread->type == DMA_XOR) - align = dev->xor_align; - else if (thread->type == DMA_PQ) - align = dev->pq_align; - - if (1 << align > test_buf_size) { - pr_err("%u-byte buffer too small for %d-byte alignment\n", - test_buf_size, 1 << align); - break; - } - - len = cdmatest_random() % test_buf_size + 1; - len = (len >> align) << align; - if (!len) - len = 1 << align; - src_off = cdmatest_random() % (test_buf_size - len + 1); - dst_off = cdmatest_random() % (test_buf_size - len + 1); - - src_off = (src_off >> align) << align; - dst_off = (dst_off >> align) << align; - - cdmatest_init_srcs(thread->srcs, src_off, len); - cdmatest_init_dsts(thread->dsts, dst_off, len); - - for (i = 0; i < src_cnt; i++) { - u8 *buf = thread->srcs[i] + src_off; - - dma_srcs[i] = dma_map_single(dev->dev, buf, len, - DMA_MEM_TO_DEV); - } - /* map with DMA_MEM_TO_MEM to force writeback/invalidate */ - for (i = 0; i < dst_cnt; i++) { - dma_dsts[i] = dma_map_single(dev->dev, thread->dsts[i], - test_buf_size, - DMA_MEM_TO_MEM); - } - - if (thread->type == DMA_MEMCPY) { - tx = dev->device_prep_dma_memcpy(chan, - dma_dsts[0] + dst_off, - dma_srcs[0], len, - flags); - - } else if (thread->type == DMA_XOR) - tx = dev->device_prep_dma_xor(chan, - dma_dsts[0] + dst_off, - dma_srcs, src_cnt, - len, flags); - else if (thread->type == DMA_PQ) { - dma_addr_t dma_pq[dst_cnt]; - - for (i = 0; i < dst_cnt; i++) - dma_pq[i] = dma_dsts[i] + dst_off; - tx = dev->device_prep_dma_pq(chan, dma_pq, dma_srcs, - src_cnt, pq_coefs, - len, flags); - } - - if (!tx) { - for (i = 0; i < src_cnt; i++) - dma_unmap_single(dev->dev, dma_srcs[i], len, - DMA_MEM_TO_DEV); - for (i = 0; i < dst_cnt; i++) - dma_unmap_single(dev->dev, dma_dsts[i], - test_buf_size, - DMA_MEM_TO_MEM); - pr_warn( - "%s: #%u: prep error with src_off=0x%x ", - thread_name, total_tests - 1, src_off); - pr_warn("dst_off=0x%x len=0x%x\n", - dst_off, len); - msleep(100); - failed_tests++; - continue; - } - - init_completion(&cmp); - tx->callback = cdmatest_callback; - tx->callback_param = &cmp; - cookie = tx->tx_submit(tx); - - if (dma_submit_error(cookie)) { - pr_warn( - "%s: #%u: submit error %d with src_off=0x%x ", - thread_name, total_tests - 1, - cookie, src_off); - pr_warn("dst_off=0x%x len=0x%x\n", - dst_off, len); - msleep(100); - failed_tests++; - continue; - } - dma_async_issue_pending(chan); - - tmo = wait_for_completion_timeout(&cmp, tmo); - status = dma_async_is_tx_complete(chan, cookie, NULL, NULL); - - if (tmo == 0) { - pr_warn("%s: #%u: test timed out\n", - thread_name, total_tests - 1); - failed_tests++; - continue; - } else if (status != DMA_SUCCESS) { - pr_warn( - "%s: #%u: got completion callback, ", - thread_name, total_tests - 1); - pr_warn("but status is \'%s\'\n", - status == DMA_ERROR ? "error" : - "in progress"); - failed_tests++; - continue; - } - - /* Unmap by myself (see DMA_COMPL_SKIP_DEST_UNMAP above) */ - for (i = 0; i < dst_cnt; i++) - dma_unmap_single(dev->dev, dma_dsts[i], test_buf_size, - DMA_MEM_TO_MEM); - - error_count = 0; - - pr_debug("%s: verifying source buffer...\n", thread_name); - error_count += cdmatest_verify(thread->srcs, 0, src_off, - 0, PATTERN_SRC, true); - error_count += cdmatest_verify(thread->srcs, src_off, - src_off + len, src_off, - PATTERN_SRC | PATTERN_COPY, true); - error_count += cdmatest_verify(thread->srcs, src_off + len, - test_buf_size, src_off + len, - PATTERN_SRC, true); - - pr_debug("%s: verifying dest buffer...\n", - thread->task->comm); - error_count += cdmatest_verify(thread->dsts, 0, dst_off, - 0, PATTERN_DST, false); - error_count += cdmatest_verify(thread->dsts, dst_off, - dst_off + len, src_off, - PATTERN_SRC | PATTERN_COPY, false); - error_count += cdmatest_verify(thread->dsts, dst_off + len, - test_buf_size, dst_off + len, - PATTERN_DST, false); - - if (error_count) { - pr_warn("%s: #%u: %u errors with ", - thread_name, total_tests - 1, error_count); - pr_warn("src_off=0x%x dst_off=0x%x len=0x%x\n", - src_off, dst_off, len); - failed_tests++; - } else { - pr_debug("%s: #%u: No errors with ", - thread_name, total_tests - 1); - pr_debug("src_off=0x%x dst_off=0x%x len=0x%x\n", - src_off, dst_off, len); - } - } - - ret = 0; - for (i = 0; thread->dsts[i]; i++) - kfree(thread->dsts[i]); -err_dstbuf: - kfree(thread->dsts); -err_dsts: - for (i = 0; thread->srcs[i]; i++) - kfree(thread->srcs[i]); -err_srcbuf: - kfree(thread->srcs); -err_srcs: - pr_notice("%s: terminating after %u tests, %u failures (status %d)\n", - thread_name, total_tests, failed_tests, ret); - - if (iterations > 0) - while (!kthread_should_stop()) { - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait_cdmatest_exit); - interruptible_sleep_on(&wait_cdmatest_exit); - } - - return ret; -} - -static void cdmatest_cleanup_channel(struct cdmatest_chan *dtc) -{ - struct cdmatest_thread *thread; - struct cdmatest_thread *_thread; - int ret; - - list_for_each_entry_safe(thread, _thread, &dtc->threads, node) { - ret = kthread_stop(thread->task); - pr_debug("cdmatest: thread %s exited with status %d\n", - thread->task->comm, ret); - list_del(&thread->node); - kfree(thread); - } - kfree(dtc); -} - -static int cdmatest_add_threads(struct cdmatest_chan *dtc, - enum dma_transaction_type type) -{ - struct cdmatest_thread *thread; - struct dma_chan *chan = dtc->chan; - char *op; - unsigned int i; - - if (type == DMA_MEMCPY) - op = "copy"; - else if (type == DMA_XOR) - op = "xor"; - else if (type == DMA_PQ) - op = "pq"; - else - return -EINVAL; - - for (i = 0; i < threads_per_chan; i++) { - thread = kzalloc(sizeof(struct cdmatest_thread), GFP_KERNEL); - if (!thread) { - pr_warn("cdmatest: No memory for %s-%s%u\n", - dma_chan_name(chan), op, i); - - break; - } - thread->chan = dtc->chan; - thread->type = type; - smp_wmb(); - thread->task = kthread_run(cdmatest_func, thread, "%s-%s%u", - dma_chan_name(chan), op, i); - if (IS_ERR(thread->task)) { - pr_warn("cdmatest: Failed to run thread %s-%s%u\n", - dma_chan_name(chan), op, i); - kfree(thread); - break; - } - - /* srcbuf and dstbuf are allocated by the thread itself */ - - list_add_tail(&thread->node, &dtc->threads); - } - - return i; -} - -static int cdmatest_add_channel(struct dma_chan *chan) -{ - struct cdmatest_chan *dtc; - struct dma_device *dma_dev = chan->device; - unsigned int thread_count = 0; - int cnt; - - dtc = kmalloc(sizeof(struct cdmatest_chan), GFP_KERNEL); - if (!dtc) { - pr_warn("cdmatest: No memory for %s\n", dma_chan_name(chan)); - return -ENOMEM; - } - - dtc->chan = chan; - INIT_LIST_HEAD(&dtc->threads); - - if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) { - cnt = cdmatest_add_threads(dtc, DMA_MEMCPY); - thread_count += cnt > 0 ? cnt : 0; - } - if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) { - cnt = cdmatest_add_threads(dtc, DMA_XOR); - thread_count += cnt > 0 ? cnt : 0; - } - if (dma_has_cap(DMA_PQ, dma_dev->cap_mask)) { - cnt = cdmatest_add_threads(dtc, DMA_PQ); - thread_count += cnt > 0 ? cnt : 0; - } - - pr_info("cdmatest: Started %u threads using %s\n", - thread_count, dma_chan_name(chan)); - - list_add_tail(&dtc->node, &cdmatest_channels); - nr_channels++; - - return 0; -} - -static bool filter(struct dma_chan *chan, void *param) -{ - if (!cdmatest_match_channel(chan) || - !cdmatest_match_device(chan->device)) - return false; - - return true; -} - -static int __init cdmatest_init(void) -{ - dma_cap_mask_t mask; - struct dma_chan *chan; - int err = 0; - - dma_cap_zero(mask); - dma_cap_set(DMA_MEMCPY, mask); - for (;;) { - chan = dma_request_channel(mask, filter, NULL); - - if (chan) { - err = cdmatest_add_channel(chan); - if (err) { - dma_release_channel(chan); - break; /* add_channel failed, punt */ - } - } else - break; /* no more channels available */ - if (max_channels && nr_channels >= max_channels) - break; /* we have all we need */ - } - - return err; -} -/* when compiled-in wait for drivers to load first */ -late_initcall(cdmatest_init); - -static void __exit cdmatest_exit(void) -{ - struct cdmatest_chan *dtc, *_dtc; - struct dma_chan *chan; - - list_for_each_entry_safe(dtc, _dtc, &cdmatest_channels, node) { - list_del(&dtc->node); - chan = dtc->chan; - cdmatest_cleanup_channel(dtc); - pr_debug("cdmatest: dropped channel %s\n", - dma_chan_name(chan)); - dma_release_channel(chan); - } -} -module_exit(cdmatest_exit); - -MODULE_AUTHOR("Xilinx, Inc."); -MODULE_DESCRIPTION("Xilinx AXI CDMA Test Client"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/dma/xilinx/dmatest.c b/drivers/dma/xilinx/dmatest.c deleted file mode 100644 index e9104f27322ff..0000000000000 --- a/drivers/dma/xilinx/dmatest.c +++ /dev/null @@ -1,649 +0,0 @@ -/* - * XILINX AXI DMA Engine test module - * - * Copyright (C) 2010 Xilinx, Inc. All rights reserved. - * - * Based on Atmel DMA Test Client - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static unsigned int test_buf_size = 64; -module_param(test_buf_size, uint, S_IRUGO); -MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer"); - -static unsigned int iterations; -module_param(iterations, uint, S_IRUGO); -MODULE_PARM_DESC(iterations, - "Iterations before stopping test (default: infinite)"); - -/* - * Initialization patterns. All bytes in the source buffer has bit 7 - * set, all bytes in the destination buffer has bit 7 cleared. - * - * Bit 6 is set for all bytes which are to be copied by the DMA - * engine. Bit 5 is set for all bytes which are to be overwritten by - * the DMA engine. - * - * The remaining bits are the inverse of a counter which increments by - * one for each byte address. - */ -#define PATTERN_SRC 0x80 -#define PATTERN_DST 0x00 -#define PATTERN_COPY 0x40 -#define PATTERN_OVERWRITE 0x20 -#define PATTERN_COUNT_MASK 0x1f - -struct dmatest_slave_thread { - struct list_head node; - struct task_struct *task; - struct dma_chan *tx_chan; - struct dma_chan *rx_chan; - u8 **srcs; - u8 **dsts; - enum dma_transaction_type type; -}; - -struct dmatest_chan { - struct list_head node; - struct dma_chan *chan; - struct list_head threads; -}; - -/* - * These are protected by dma_list_mutex since they're only used by - * the DMA filter function callback - */ -static LIST_HEAD(dmatest_channels); -static unsigned int nr_channels; - -static unsigned long dmatest_random(void) -{ - unsigned long buf; - - get_random_bytes(&buf, sizeof(buf)); - return buf; -} - -static void dmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len) -{ - unsigned int i; - u8 *buf; - - for (; (buf = *bufs); bufs++) { - for (i = 0; i < start; i++) - buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK); - for ( ; i < start + len; i++) - buf[i] = PATTERN_SRC | PATTERN_COPY - | (~i & PATTERN_COUNT_MASK); - for ( ; i < test_buf_size; i++) - buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK); - buf++; - } -} - -static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len) -{ - unsigned int i; - u8 *buf; - - for (; (buf = *bufs); bufs++) { - for (i = 0; i < start; i++) - buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK); - for ( ; i < start + len; i++) - buf[i] = PATTERN_DST | PATTERN_OVERWRITE - | (~i & PATTERN_COUNT_MASK); - for ( ; i < test_buf_size; i++) - buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK); - } -} - -static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index, - unsigned int counter, bool is_srcbuf) -{ - u8 diff = actual ^ pattern; - u8 expected = pattern | (~counter & PATTERN_COUNT_MASK); - const char *thread_name = current->comm; - - if (is_srcbuf) - pr_warn( - "%s: srcbuf[0x%x] overwritten! Expected %02x, got %02x\n", - thread_name, index, expected, actual); - else if ((pattern & PATTERN_COPY) - && (diff & (PATTERN_COPY | PATTERN_OVERWRITE))) - pr_warn( - "%s: dstbuf[0x%x] not copied! Expected %02x, got %02x\n", - thread_name, index, expected, actual); - else if (diff & PATTERN_SRC) - pr_warn( - "%s: dstbuf[0x%x] was copied! Expected %02x, got %02x\n", - thread_name, index, expected, actual); - else - pr_warn( - "%s: dstbuf[0x%x] mismatch! Expected %02x, got %02x\n", - thread_name, index, expected, actual); -} - -static unsigned int dmatest_verify(u8 **bufs, unsigned int start, - unsigned int end, unsigned int counter, u8 pattern, - bool is_srcbuf) -{ - unsigned int i; - unsigned int error_count = 0; - u8 actual; - u8 expected; - u8 *buf; - unsigned int counter_orig = counter; - - for (; (buf = *bufs); bufs++) { - counter = counter_orig; - for (i = start; i < end; i++) { - actual = buf[i]; - expected = pattern | (~counter & PATTERN_COUNT_MASK); - if (actual != expected) { - if (error_count < 32) - dmatest_mismatch(actual, pattern, i, - counter, is_srcbuf); - error_count++; - } - counter++; - } - } - - if (error_count > 32) - pr_warn("%s: %u errors suppressed\n", - current->comm, error_count - 32); - - return error_count; -} - -static void dmatest_slave_tx_callback(void *completion) -{ - complete(completion); -} - -static void dmatest_slave_rx_callback(void *completion) -{ - complete(completion); -} - -/* Function for slave transfers - * Each thread requires 2 channels, one for transmit, and one for receive - */ -static int dmatest_slave_func(void *data) -{ - struct dmatest_slave_thread *thread = data; - struct dma_chan *tx_chan; - struct dma_chan *rx_chan; - const char *thread_name; - unsigned int src_off, dst_off, len; - unsigned int error_count; - unsigned int failed_tests = 0; - unsigned int total_tests = 0; - dma_cookie_t tx_cookie; - dma_cookie_t rx_cookie; - enum dma_status status; - enum dma_ctrl_flags flags; - int ret; - int src_cnt; - int dst_cnt; - int bd_cnt = 11; - int i; - struct xilinx_dma_config config; - thread_name = current->comm; - - ret = -ENOMEM; - - /* JZ: limit testing scope here */ - iterations = 5; - test_buf_size = 700; - - smp_rmb(); - tx_chan = thread->tx_chan; - rx_chan = thread->rx_chan; - src_cnt = dst_cnt = bd_cnt; - - thread->srcs = kcalloc(src_cnt+1, sizeof(u8 *), GFP_KERNEL); - if (!thread->srcs) - goto err_srcs; - for (i = 0; i < src_cnt; i++) { - thread->srcs[i] = kmalloc(test_buf_size, GFP_KERNEL); - if (!thread->srcs[i]) - goto err_srcbuf; - } - thread->srcs[i] = NULL; - - thread->dsts = kcalloc(dst_cnt+1, sizeof(u8 *), GFP_KERNEL); - if (!thread->dsts) - goto err_dsts; - for (i = 0; i < dst_cnt; i++) { - thread->dsts[i] = kmalloc(test_buf_size, GFP_KERNEL); - if (!thread->dsts[i]) - goto err_dstbuf; - } - thread->dsts[i] = NULL; - - set_user_nice(current, 10); - - flags = DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP | DMA_PREP_INTERRUPT; - - while (!kthread_should_stop() - && !(iterations && total_tests >= iterations)) { - struct dma_device *tx_dev = tx_chan->device; - struct dma_device *rx_dev = rx_chan->device; - struct dma_async_tx_descriptor *txd = NULL; - struct dma_async_tx_descriptor *rxd = NULL; - dma_addr_t dma_srcs[src_cnt]; - dma_addr_t dma_dsts[dst_cnt]; - struct completion rx_cmp; - struct completion tx_cmp; - unsigned long rx_tmo = - msecs_to_jiffies(300000); /* RX takes longer */ - unsigned long tx_tmo = msecs_to_jiffies(30000); - u8 align = 0; - struct scatterlist tx_sg[bd_cnt]; - struct scatterlist rx_sg[bd_cnt]; - - total_tests++; - - /* honor larger alignment restrictions */ - align = tx_dev->copy_align; - if (rx_dev->copy_align > align) - align = rx_dev->copy_align; - - if (1 << align > test_buf_size) { - pr_err("%u-byte buffer too small for %d-byte alignment\n", - test_buf_size, 1 << align); - break; - } - - len = dmatest_random() % test_buf_size + 1; - len = (len >> align) << align; - if (!len) - len = 1 << align; - src_off = dmatest_random() % (test_buf_size - len + 1); - dst_off = dmatest_random() % (test_buf_size - len + 1); - - src_off = (src_off >> align) << align; - dst_off = (dst_off >> align) << align; - - dmatest_init_srcs(thread->srcs, src_off, len); - dmatest_init_dsts(thread->dsts, dst_off, len); - - for (i = 0; i < src_cnt; i++) { - u8 *buf = thread->srcs[i] + src_off; - - dma_srcs[i] = dma_map_single(tx_dev->dev, buf, len, - DMA_MEM_TO_DEV); - } - - for (i = 0; i < dst_cnt; i++) { - dma_dsts[i] = dma_map_single(rx_dev->dev, - thread->dsts[i], - test_buf_size, - DMA_MEM_TO_DEV); - - dma_unmap_single(rx_dev->dev, dma_dsts[i], - test_buf_size, - DMA_MEM_TO_DEV); - - dma_dsts[i] = dma_map_single(rx_dev->dev, - thread->dsts[i], - test_buf_size, - DMA_DEV_TO_MEM); - } - - sg_init_table(tx_sg, bd_cnt); - sg_init_table(rx_sg, bd_cnt); - - for (i = 0; i < bd_cnt; i++) { - sg_dma_address(&tx_sg[i]) = dma_srcs[i]; - sg_dma_address(&rx_sg[i]) = dma_dsts[i] + dst_off; - - sg_dma_len(&tx_sg[i]) = len; - sg_dma_len(&rx_sg[i]) = len; - - } - - /* Only one interrupt */ - config.coalesc = 1; - config.delay = 0; - rx_dev->device_control(rx_chan, DMA_SLAVE_CONFIG, - (unsigned long)&config); - - config.coalesc = 1; - config.delay = 0; - tx_dev->device_control(tx_chan, DMA_SLAVE_CONFIG, - (unsigned long)&config); - - rxd = rx_dev->device_prep_slave_sg(rx_chan, rx_sg, bd_cnt, - DMA_DEV_TO_MEM, flags, NULL); - - txd = tx_dev->device_prep_slave_sg(tx_chan, tx_sg, bd_cnt, - DMA_MEM_TO_DEV, flags, NULL); - - if (!rxd || !txd) { - for (i = 0; i < src_cnt; i++) - dma_unmap_single(tx_dev->dev, dma_srcs[i], len, - DMA_MEM_TO_DEV); - for (i = 0; i < dst_cnt; i++) - dma_unmap_single(rx_dev->dev, dma_dsts[i], - test_buf_size, - DMA_DEV_TO_MEM); - pr_warn( - "%s: #%u: prep error with src_off=0x%x ", - thread_name, total_tests - 1, src_off); - pr_warn("dst_off=0x%x len=0x%x\n", - dst_off, len); - msleep(100); - failed_tests++; - continue; - } - - init_completion(&rx_cmp); - rxd->callback = dmatest_slave_rx_callback; - rxd->callback_param = &rx_cmp; - rx_cookie = rxd->tx_submit(rxd); - - init_completion(&tx_cmp); - txd->callback = dmatest_slave_tx_callback; - txd->callback_param = &tx_cmp; - tx_cookie = txd->tx_submit(txd); - - if (dma_submit_error(rx_cookie) || - dma_submit_error(tx_cookie)) { - pr_warn( - "%s: #%u: submit error %d/%d with src_off=0x%x ", - thread_name, total_tests - 1, - rx_cookie, tx_cookie, src_off); - pr_warn("dst_off=0x%x len=0x%x\n", - dst_off, len); - msleep(100); - failed_tests++; - continue; - } - dma_async_issue_pending(tx_chan); - dma_async_issue_pending(rx_chan); - - tx_tmo = wait_for_completion_timeout(&tx_cmp, tx_tmo); - - status = dma_async_is_tx_complete(tx_chan, tx_cookie, - NULL, NULL); - - if (tx_tmo == 0) { - pr_warn("%s: #%u: tx test timed out\n", - thread_name, total_tests - 1); - failed_tests++; - continue; - } else if (status != DMA_SUCCESS) { - pr_warn( - "%s: #%u: tx got completion callback, ", - thread_name, total_tests - 1); - pr_warn("but status is \'%s\'\n", - status == DMA_ERROR ? "error" : - "in progress"); - failed_tests++; - continue; - } - - rx_tmo = wait_for_completion_timeout(&rx_cmp, rx_tmo); - status = dma_async_is_tx_complete(rx_chan, rx_cookie, - NULL, NULL); - - if (rx_tmo == 0) { - pr_warn("%s: #%u: rx test timed out\n", - thread_name, total_tests - 1); - failed_tests++; - continue; - } else if (status != DMA_SUCCESS) { - pr_warn( - "%s: #%u: rx got completion callback, ", - thread_name, total_tests - 1); - pr_warn("but status is \'%s\'\n", - status == DMA_ERROR ? "error" : - "in progress"); - failed_tests++; - continue; - } - - /* Unmap by myself (see DMA_COMPL_SKIP_DEST_UNMAP above) */ - for (i = 0; i < dst_cnt; i++) - dma_unmap_single(rx_dev->dev, dma_dsts[i], - test_buf_size, DMA_DEV_TO_MEM); - - error_count = 0; - - pr_debug("%s: verifying source buffer...\n", thread_name); - error_count += dmatest_verify(thread->srcs, 0, src_off, - 0, PATTERN_SRC, true); - error_count += dmatest_verify(thread->srcs, src_off, - src_off + len, src_off, - PATTERN_SRC | PATTERN_COPY, true); - error_count += dmatest_verify(thread->srcs, src_off + len, - test_buf_size, src_off + len, - PATTERN_SRC, true); - - pr_debug("%s: verifying dest buffer...\n", - thread->task->comm); - error_count += dmatest_verify(thread->dsts, 0, dst_off, - 0, PATTERN_DST, false); - error_count += dmatest_verify(thread->dsts, dst_off, - dst_off + len, src_off, - PATTERN_SRC | PATTERN_COPY, false); - error_count += dmatest_verify(thread->dsts, dst_off + len, - test_buf_size, dst_off + len, - PATTERN_DST, false); - - if (error_count) { - pr_warn("%s: #%u: %u errors with ", - thread_name, total_tests - 1, error_count); - pr_warn("src_off=0x%x dst_off=0x%x len=0x%x\n", - src_off, dst_off, len); - failed_tests++; - } else { - pr_debug("%s: #%u: No errors with ", - thread_name, total_tests - 1); - pr_debug("src_off=0x%x dst_off=0x%x len=0x%x\n", - src_off, dst_off, len); - } - } - - ret = 0; - for (i = 0; thread->dsts[i]; i++) - kfree(thread->dsts[i]); -err_dstbuf: - kfree(thread->dsts); -err_dsts: - for (i = 0; thread->srcs[i]; i++) - kfree(thread->srcs[i]); -err_srcbuf: - kfree(thread->srcs); -err_srcs: - pr_notice("%s: terminating after %u tests, %u failures (status %d)\n", - thread_name, total_tests, failed_tests, ret); - - if (iterations > 0) - while (!kthread_should_stop()) { - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait_dmatest_exit); - interruptible_sleep_on(&wait_dmatest_exit); - } - - return ret; -} - -static void dmatest_cleanup_channel(struct dmatest_chan *dtc) -{ - struct dmatest_slave_thread *thread; - struct dmatest_slave_thread *_thread; - int ret; - - list_for_each_entry_safe(thread, _thread, &dtc->threads, node) { - ret = kthread_stop(thread->task); - pr_debug("dmatest: thread %s exited with status %d\n", - thread->task->comm, ret); - list_del(&thread->node); - kfree(thread); - } - kfree(dtc); -} - -static int dmatest_add_slave_threads(struct dmatest_chan *tx_dtc, - struct dmatest_chan *rx_dtc) -{ - struct dmatest_slave_thread *thread; - struct dma_chan *tx_chan = tx_dtc->chan; - struct dma_chan *rx_chan = rx_dtc->chan; - - thread = kzalloc(sizeof(struct dmatest_slave_thread), GFP_KERNEL); - if (!thread) { - pr_warn("dmatest: No memory for slave thread %s-%s\n", - dma_chan_name(tx_chan), dma_chan_name(rx_chan)); - - } - - thread->tx_chan = tx_chan; - thread->rx_chan = rx_chan; - thread->type = (enum dma_transaction_type)DMA_SLAVE; - smp_wmb(); - thread->task = kthread_run(dmatest_slave_func, thread, "%s-%s", - dma_chan_name(tx_chan), dma_chan_name(rx_chan)); - if (IS_ERR(thread->task)) { - pr_warn("dmatest: Failed to run thread %s-%s\n", - dma_chan_name(tx_chan), dma_chan_name(rx_chan)); - kfree(thread); - } - - /* srcbuf and dstbuf are allocated by the thread itself */ - - list_add_tail(&thread->node, &tx_dtc->threads); - - /* Added one thread with 2 channels */ - return 1; -} - -static int dmatest_add_slave_channels(struct dma_chan *tx_chan, - struct dma_chan *rx_chan) -{ - struct dmatest_chan *tx_dtc; - struct dmatest_chan *rx_dtc; - unsigned int thread_count = 0; - - tx_dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL); - if (!tx_dtc) { - pr_warn("dmatest: No memory for tx %s\n", - dma_chan_name(tx_chan)); - return -ENOMEM; - } - - rx_dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL); - if (!rx_dtc) { - pr_warn("dmatest: No memory for rx %s\n", - dma_chan_name(rx_chan)); - return -ENOMEM; - } - - tx_dtc->chan = tx_chan; - rx_dtc->chan = rx_chan; - INIT_LIST_HEAD(&tx_dtc->threads); - INIT_LIST_HEAD(&rx_dtc->threads); - - dmatest_add_slave_threads(tx_dtc, rx_dtc); - thread_count += 1; - - pr_info("dmatest: Started %u threads using %s %s\n", - thread_count, dma_chan_name(tx_chan), dma_chan_name(rx_chan)); - - list_add_tail(&tx_dtc->node, &dmatest_channels); - list_add_tail(&rx_dtc->node, &dmatest_channels); - nr_channels += 2; - - return 0; -} - -static bool xdma_filter(struct dma_chan *chan, void *param) -{ - pr_debug("dmatest: Private is %x\n", *((int *)chan->private)); - - if (*((int *)chan->private) == *(int *)param) - return true; - - return false; -} - -static int __init dmatest_init(void) -{ - dma_cap_mask_t mask; - struct dma_chan *chan; - int err = 0; - - /* JZ for slave transfer channels */ - enum dma_data_direction direction; - struct dma_chan *rx_chan; - u32 match; - - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE | DMA_PRIVATE, mask); - - direction = DMA_MEM_TO_DEV; - match = (direction & 0xFF) | XILINX_DMA_IP_DMA; - pr_debug("dmatest: match is %x\n", match); - - chan = dma_request_channel(mask, xdma_filter, (void *)&match); - - if (chan) - pr_debug("dmatest: Found tx device\n"); - else - pr_info("dmatest: Did not find tx device\n"); - - direction = DMA_DEV_TO_MEM; - match = (direction & 0xFF) | XILINX_DMA_IP_DMA; - rx_chan = dma_request_channel(mask, xdma_filter, &match); - - if (rx_chan) - pr_debug("dmatest: Found rx device\n"); - else - pr_info("dmatest: Did not find rx device\n"); - - if (chan && rx_chan) { - err = dmatest_add_slave_channels(chan, rx_chan); - if (err) { - dma_release_channel(chan); - dma_release_channel(rx_chan); - } - } - - return err; -} -/* when compiled-in wait for drivers to load first */ -late_initcall(dmatest_init); - -static void __exit dmatest_exit(void) -{ - struct dmatest_chan *dtc, *_dtc; - struct dma_chan *chan; - - list_for_each_entry_safe(dtc, _dtc, &dmatest_channels, node) { - list_del(&dtc->node); - chan = dtc->chan; - dmatest_cleanup_channel(dtc); - pr_debug("dmatest: dropped channel %s\n", - dma_chan_name(chan)); - dma_release_channel(chan); - } -} -module_exit(dmatest_exit); - -MODULE_AUTHOR("Xilinx, Inc."); -MODULE_DESCRIPTION("Xilinx AXI DMA Test Client"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/dma/xilinx/vdmatest.c b/drivers/dma/xilinx/vdmatest.c deleted file mode 100644 index 6c7ada89c6233..0000000000000 --- a/drivers/dma/xilinx/vdmatest.c +++ /dev/null @@ -1,620 +0,0 @@ -/* - * XILIN VDMA Engine test module - * - * Copyright (C) 2012 Xilinx, Inc. All rights reserved. - * - * Based on Atmel DMA Test Client - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static unsigned int test_buf_size = 64; -module_param(test_buf_size, uint, S_IRUGO); -MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer"); - -static unsigned int iterations; -module_param(iterations, uint, S_IRUGO); -MODULE_PARM_DESC(iterations, - "Iterations before stopping test (default: infinite)"); - -/* - * Initialization patterns. All bytes in the source buffer has bit 7 - * set, all bytes in the destination buffer has bit 7 cleared. - * - * Bit 6 is set for all bytes which are to be copied by the DMA - * engine. Bit 5 is set for all bytes which are to be overwritten by - * the DMA engine. - * - * The remaining bits are the inverse of a counter which increments by - * one for each byte address. - */ -#define PATTERN_SRC 0x80 -#define PATTERN_DST 0x00 -#define PATTERN_COPY 0x40 -#define PATTERN_OVERWRITE 0x20 -#define PATTERN_COUNT_MASK 0x1f - -struct vdmatest_slave_thread { - struct list_head node; - struct task_struct *task; - struct dma_chan *tx_chan; - struct dma_chan *rx_chan; - u8 **srcs; - u8 **dsts; - enum dma_transaction_type type; -}; - -struct vdmatest_chan { - struct list_head node; - struct dma_chan *chan; - struct list_head threads; -}; - -/* - * These are protected by dma_list_mutex since they're only used by - * the DMA filter function callback - */ -static LIST_HEAD(vdmatest_channels); -static unsigned int nr_channels; - -static void vdmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len) -{ - unsigned int i; - u8 *buf; - - for (; (buf = *bufs); bufs++) { - for (i = 0; i < start; i++) - buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK); - for ( ; i < start + len; i++) - buf[i] = PATTERN_SRC | PATTERN_COPY - | (~i & PATTERN_COUNT_MASK); - for ( ; i < test_buf_size; i++) - buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK); - buf++; - } -} - -static void vdmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len) -{ - unsigned int i; - u8 *buf; - - for (; (buf = *bufs); bufs++) { - for (i = 0; i < start; i++) - buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK); - for ( ; i < start + len; i++) - buf[i] = PATTERN_DST | PATTERN_OVERWRITE - | (~i & PATTERN_COUNT_MASK); - for ( ; i < test_buf_size; i++) - buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK); - } -} - -static void vdmatest_mismatch(u8 actual, u8 pattern, unsigned int index, - unsigned int counter, bool is_srcbuf) -{ - u8 diff = actual ^ pattern; - u8 expected = pattern | (~counter & PATTERN_COUNT_MASK); - const char *thread_name = current->comm; - - if (is_srcbuf) - pr_warn( - "%s: srcbuf[0x%x] overwritten! Expected %02x, got %02x\n", - thread_name, index, expected, actual); - else if ((pattern & PATTERN_COPY) - && (diff & (PATTERN_COPY | PATTERN_OVERWRITE))) - pr_warn( - "%s: dstbuf[0x%x] not copied! Expected %02x, got %02x\n", - thread_name, index, expected, actual); - else if (diff & PATTERN_SRC) - pr_warn( - "%s: dstbuf[0x%x] was copied! Expected %02x, got %02x\n", - thread_name, index, expected, actual); - else - pr_warn( - "%s: dstbuf[0x%x] mismatch! Expected %02x, got %02x\n", - thread_name, index, expected, actual); -} - -static unsigned int vdmatest_verify(u8 **bufs, unsigned int start, - unsigned int end, unsigned int counter, u8 pattern, - bool is_srcbuf) -{ - unsigned int i; - unsigned int error_count = 0; - u8 actual; - u8 expected; - u8 *buf; - unsigned int counter_orig = counter; - - for (; (buf = *bufs); bufs++) { - counter = counter_orig; - for (i = start; i < end; i++) { - actual = buf[i]; - expected = pattern | (~counter & PATTERN_COUNT_MASK); - if (actual != expected) { - if (error_count < 32) - vdmatest_mismatch(actual, pattern, i, - counter, is_srcbuf); - error_count++; - } - counter++; - } - } - - if (error_count > 32) - pr_warn("%s: %u errors suppressed\n", - current->comm, error_count - 32); - - return error_count; -} - -static void vdmatest_slave_tx_callback(void *completion) -{ - pr_debug("Got tx callback\n"); - complete(completion); -} - -static void vdmatest_slave_rx_callback(void *completion) -{ - pr_debug("Got rx callback\n"); - complete(completion); -} - -/* - * Function for slave transfers - * Each thread requires 2 channels, one for transmit, and one for receive - */ -static int vdmatest_slave_func(void *data) -{ - struct vdmatest_slave_thread *thread = data; - struct dma_chan *tx_chan; - struct dma_chan *rx_chan; - const char *thread_name; - unsigned int len; - unsigned int error_count; - unsigned int failed_tests = 0; - unsigned int total_tests = 0; - dma_cookie_t tx_cookie; - dma_cookie_t rx_cookie; - enum dma_status status; - enum dma_ctrl_flags flags; - int ret; - int frm_cnt = 8; - int i; - int hsize = 64; - int vsize = 32; - struct xilinx_vdma_config config; - thread_name = current->comm; - - ret = -ENOMEM; - - /* JZ: limit testing scope here */ - iterations = 1; - test_buf_size = hsize * vsize; - - smp_rmb(); - tx_chan = thread->tx_chan; - rx_chan = thread->rx_chan; - - thread->srcs = kcalloc(frm_cnt+1, sizeof(u8 *), GFP_KERNEL); - if (!thread->srcs) - goto err_srcs; - for (i = 0; i < frm_cnt; i++) { - thread->srcs[i] = kmalloc(test_buf_size, GFP_KERNEL); - if (!thread->srcs[i]) - goto err_srcbuf; - } - thread->srcs[i] = NULL; - - thread->dsts = kcalloc(frm_cnt+1, sizeof(u8 *), GFP_KERNEL); - if (!thread->dsts) - goto err_dsts; - for (i = 0; i < frm_cnt; i++) { - thread->dsts[i] = kmalloc(test_buf_size, GFP_KERNEL); - if (!thread->dsts[i]) - goto err_dstbuf; - } - thread->dsts[i] = NULL; - - set_user_nice(current, 10); - - flags = DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP | DMA_PREP_INTERRUPT; - - while (!kthread_should_stop() - && !(iterations && total_tests >= iterations)) { - struct dma_device *tx_dev = tx_chan->device; - struct dma_device *rx_dev = rx_chan->device; - struct dma_async_tx_descriptor *txd = NULL; - struct dma_async_tx_descriptor *rxd = NULL; - dma_addr_t dma_srcs[frm_cnt]; - dma_addr_t dma_dsts[frm_cnt]; - struct completion rx_cmp; - struct completion tx_cmp; - unsigned long rx_tmo = - msecs_to_jiffies(30000); /* RX takes longer */ - unsigned long tx_tmo = msecs_to_jiffies(30000); - u8 align = 0; - struct scatterlist tx_sg[frm_cnt]; - struct scatterlist rx_sg[frm_cnt]; - - total_tests++; - - /* honor larger alignment restrictions */ - align = tx_dev->copy_align; - if (rx_dev->copy_align > align) - align = rx_dev->copy_align; - - if (1 << align > test_buf_size) { - pr_err("%u-byte buffer too small for %d-byte alignment\n", - test_buf_size, 1 << align); - break; - } - - len = test_buf_size; - vdmatest_init_srcs(thread->srcs, 0, len); - vdmatest_init_dsts(thread->dsts, 0, len); - - sg_init_table(tx_sg, frm_cnt); - sg_init_table(rx_sg, frm_cnt); - - for (i = 0; i < frm_cnt; i++) { - u8 *buf = thread->srcs[i]; - - dma_srcs[i] = dma_map_single(tx_dev->dev, buf, len, - DMA_MEM_TO_DEV); - pr_debug("src buf %x dma %x\n", (unsigned int)buf, - dma_srcs[i]); - sg_dma_address(&tx_sg[i]) = dma_srcs[i]; - sg_dma_len(&tx_sg[i]) = len; - } - - for (i = 0; i < frm_cnt; i++) { - dma_dsts[i] = dma_map_single(rx_dev->dev, - thread->dsts[i], - test_buf_size, - DMA_DEV_TO_MEM); - pr_debug("dst %x dma %x\n", - (unsigned int)thread->dsts[i], - dma_dsts[i]); - sg_dma_address(&rx_sg[i]) = dma_dsts[i]; - sg_dma_len(&rx_sg[i]) = len; - } - - /* Set up hardware configuration information */ - config.direction = DMA_MEM_TO_DEV; - config.vsize = vsize; - config.hsize = hsize; - config.stride = hsize; - config.frm_cnt_en = 1; - config.coalesc = frm_cnt * 10; - config.delay = 0; - /* The following is do-not-care, need to set to 0 */ - config.frm_dly = 0; - config.park = 1; - config.gen_lock = 0; - config.master = 0; - config.park_frm = 0; - config.disable_intr = 0; - tx_dev->device_control(tx_chan, DMA_SLAVE_CONFIG, - (unsigned long)&config); - - config.direction = DMA_DEV_TO_MEM; - config.park = 0; - rx_dev->device_control(rx_chan, DMA_SLAVE_CONFIG, - (unsigned long)&config); - - rxd = rx_dev->device_prep_slave_sg(rx_chan, rx_sg, frm_cnt, - DMA_DEV_TO_MEM, flags, NULL); - - txd = tx_dev->device_prep_slave_sg(tx_chan, tx_sg, frm_cnt, - DMA_MEM_TO_DEV, flags, NULL); - - if (!rxd || !txd) { - for (i = 0; i < frm_cnt; i++) - dma_unmap_single(tx_dev->dev, dma_srcs[i], len, - DMA_MEM_TO_DEV); - for (i = 0; i < frm_cnt; i++) - dma_unmap_single(rx_dev->dev, dma_dsts[i], - test_buf_size, - DMA_DEV_TO_MEM); - pr_warn("%s: #%u: prep error with len=0x%x ", - thread_name, total_tests - 1, len); - msleep(100); - failed_tests++; - continue; - } - - init_completion(&rx_cmp); - rxd->callback = vdmatest_slave_rx_callback; - rxd->callback_param = &rx_cmp; - rx_cookie = rxd->tx_submit(rxd); - - init_completion(&tx_cmp); - txd->callback = vdmatest_slave_tx_callback; - txd->callback_param = &tx_cmp; - tx_cookie = txd->tx_submit(txd); - - if (dma_submit_error(rx_cookie) || - dma_submit_error(tx_cookie)) { - pr_warn("%s: #%u: submit error %d/%d with len=0x%x ", - thread_name, total_tests - 1, - rx_cookie, tx_cookie, len); - msleep(100); - failed_tests++; - continue; - } - dma_async_issue_pending(tx_chan); - dma_async_issue_pending(rx_chan); - - tx_tmo = wait_for_completion_timeout(&tx_cmp, tx_tmo); - - status = dma_async_is_tx_complete(tx_chan, tx_cookie, - NULL, NULL); - - if (tx_tmo == 0) { - pr_warn("%s: #%u: tx test timed out\n", - thread_name, total_tests - 1); - failed_tests++; - continue; - } else if (status != DMA_SUCCESS) { - pr_warn( - "%s: #%u: tx got completion callback, ", - thread_name, total_tests - 1); - pr_warn("but status is \'%s\'\n", - status == DMA_ERROR ? "error" : - "in progress"); - failed_tests++; - continue; - } - - rx_tmo = wait_for_completion_timeout(&rx_cmp, rx_tmo); - status = dma_async_is_tx_complete(rx_chan, rx_cookie, - NULL, NULL); - - if (rx_tmo == 0) { - pr_warn("%s: #%u: rx test timed out\n", - thread_name, total_tests - 1); - failed_tests++; - continue; - } else if (status != DMA_SUCCESS) { - pr_warn( - "%s: #%u: rx got completion callback, ", - thread_name, total_tests - 1); - pr_warn("but status is \'%s\'\n", - status == DMA_ERROR ? "error" : - "in progress"); - failed_tests++; - continue; - } - - /* Unmap by myself (see DMA_COMPL_SKIP_DEST_UNMAP above) */ - for (i = 0; i < frm_cnt; i++) - dma_unmap_single(rx_dev->dev, dma_dsts[i], - test_buf_size, DMA_DEV_TO_MEM); - - error_count = 0; - - pr_debug("%s: verifying source buffer...\n", thread_name); - error_count += vdmatest_verify(thread->srcs, 0, 0, - 0, PATTERN_SRC, true); - error_count += vdmatest_verify(thread->srcs, 0, - len, 0, PATTERN_SRC | PATTERN_COPY, true); - error_count += vdmatest_verify(thread->srcs, len, - test_buf_size, len, PATTERN_SRC, true); - - pr_debug("%s: verifying dest buffer...\n", - thread->task->comm); - error_count += vdmatest_verify(thread->dsts, 0, 0, - 0, PATTERN_DST, false); - error_count += vdmatest_verify(thread->dsts, 0, - len, 0, PATTERN_SRC | PATTERN_COPY, false); - error_count += vdmatest_verify(thread->dsts, len, - test_buf_size, len, PATTERN_DST, false); - - if (error_count) { - pr_warn("%s: #%u: %u errors with len=0x%x\n", - thread_name, total_tests - 1, error_count, len); - failed_tests++; - } else { - pr_debug("%s: #%u: No errors with len=0x%x\n", - thread_name, total_tests - 1, len); - } - } - - ret = 0; - for (i = 0; thread->dsts[i]; i++) - kfree(thread->dsts[i]); -err_dstbuf: - kfree(thread->dsts); -err_dsts: - for (i = 0; thread->srcs[i]; i++) - kfree(thread->srcs[i]); -err_srcbuf: - kfree(thread->srcs); -err_srcs: - pr_notice("%s: terminating after %u tests, %u failures (status %d)\n", - thread_name, total_tests, failed_tests, ret); - - if (iterations > 0) - while (!kthread_should_stop()) { - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait_vdmatest_exit); - interruptible_sleep_on(&wait_vdmatest_exit); - } - - return ret; -} - -static void vdmatest_cleanup_channel(struct vdmatest_chan *dtc) -{ - struct vdmatest_slave_thread *thread; - struct vdmatest_slave_thread *_thread; - int ret; - - list_for_each_entry_safe(thread, _thread, - &dtc->threads, node) { - ret = kthread_stop(thread->task); - pr_info("vdmatest: thread %s exited with status %d\n", - thread->task->comm, ret); - list_del(&thread->node); - kfree(thread); - } - kfree(dtc); -} - -static int vdmatest_add_slave_threads(struct vdmatest_chan *tx_dtc, - struct vdmatest_chan *rx_dtc) -{ - struct vdmatest_slave_thread *thread; - struct dma_chan *tx_chan = tx_dtc->chan; - struct dma_chan *rx_chan = rx_dtc->chan; - - thread = kzalloc(sizeof(struct vdmatest_slave_thread), GFP_KERNEL); - if (!thread) { - pr_warn("vdmatest: No memory for slave thread %s-%s\n", - dma_chan_name(tx_chan), dma_chan_name(rx_chan)); - - } - - thread->tx_chan = tx_chan; - thread->rx_chan = rx_chan; - thread->type = (enum dma_transaction_type)DMA_SLAVE; - smp_wmb(); - thread->task = kthread_run(vdmatest_slave_func, thread, "%s-%s", - dma_chan_name(tx_chan), dma_chan_name(rx_chan)); - if (IS_ERR(thread->task)) { - pr_warn("vdmatest: Failed to run thread %s-%s\n", - dma_chan_name(tx_chan), dma_chan_name(rx_chan)); - kfree(thread); - } - - /* srcbuf and dstbuf are allocated by the thread itself */ - - list_add_tail(&thread->node, &tx_dtc->threads); - - /* Added one thread with 2 channels */ - return 1; -} - -static int vdmatest_add_slave_channels(struct dma_chan *tx_chan, - struct dma_chan *rx_chan) -{ - struct vdmatest_chan *tx_dtc; - struct vdmatest_chan *rx_dtc; - unsigned int thread_count = 0; - - tx_dtc = kmalloc(sizeof(struct vdmatest_chan), GFP_KERNEL); - if (!tx_dtc) { - pr_warn("vdmatest: No memory for tx %s\n", - dma_chan_name(tx_chan)); - return -ENOMEM; - } - - rx_dtc = kmalloc(sizeof(struct vdmatest_chan), GFP_KERNEL); - if (!rx_dtc) { - pr_warn("vdmatest: No memory for rx %s\n", - dma_chan_name(rx_chan)); - return -ENOMEM; - } - - tx_dtc->chan = tx_chan; - rx_dtc->chan = rx_chan; - INIT_LIST_HEAD(&tx_dtc->threads); - INIT_LIST_HEAD(&rx_dtc->threads); - - vdmatest_add_slave_threads(tx_dtc, rx_dtc); - thread_count += 1; - - pr_info("vdmatest: Started %u threads using %s %s\n", - thread_count, dma_chan_name(tx_chan), dma_chan_name(rx_chan)); - - list_add_tail(&tx_dtc->node, &vdmatest_channels); - list_add_tail(&rx_dtc->node, &vdmatest_channels); - nr_channels += 2; - - return 0; -} - -static bool xdma_filter(struct dma_chan *chan, void *param) -{ - if (*((int *)chan->private) == *(int *)param) - return true; - - return false; -} - -static int __init vdmatest_init(void) -{ - dma_cap_mask_t mask; - struct dma_chan *chan; - int err = 0; - - enum dma_data_direction direction; - u32 match; - struct dma_chan *rx_chan; - - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE | DMA_PRIVATE, mask); - - direction = DMA_MEM_TO_DEV; - match = (direction & 0xFF) | XILINX_DMA_IP_VDMA; - pr_debug("vdmatest: match is %x\n", match); - - chan = dma_request_channel(mask, xdma_filter, (void *)&match); - - if (chan) - pr_debug("vdmatest: Found tx device\n"); - else - pr_info("vdmatest: Did not find tx device\n"); - - direction = DMA_DEV_TO_MEM; - match = (direction & 0xFF) | XILINX_DMA_IP_VDMA; - rx_chan = dma_request_channel(mask, xdma_filter, &match); - - if (rx_chan) - pr_debug("vdmatest: Found rx device\n"); - else - pr_info("vdmatest: Did not find rx device\n"); - - if (chan && rx_chan) { - err = vdmatest_add_slave_channels(chan, rx_chan); - if (err) { - dma_release_channel(chan); - dma_release_channel(rx_chan); - } - } - return err; -} -/* when compiled-in wait for drivers to load first */ -late_initcall(vdmatest_init); - -static void __exit vdmatest_exit(void) -{ - struct vdmatest_chan *dtc, *_dtc; - struct dma_chan *chan; - - list_for_each_entry_safe(dtc, _dtc, &vdmatest_channels, node) { - list_del(&dtc->node); - chan = dtc->chan; - vdmatest_cleanup_channel(dtc); - pr_info("vdmatest: dropped channel %s\n", - dma_chan_name(chan)); - dma_release_channel(chan); - } -} -module_exit(vdmatest_exit); - -MODULE_AUTHOR("Xilinx, Inc."); -MODULE_DESCRIPTION("Xilinx AXI VDMA Test Client"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/dma/xilinx/xilinx_axicdma.c b/drivers/dma/xilinx/xilinx_axicdma.c deleted file mode 100644 index 170c67a50b9ec..0000000000000 --- a/drivers/dma/xilinx/xilinx_axicdma.c +++ /dev/null @@ -1,1095 +0,0 @@ -/* - * Xilinx Central DMA Engine support - * - * Copyright (C) 2010 Xilinx, Inc. All rights reserved. - * - * Based on the Freescale DMA driver. - * - * Description: - * . Axi CDMA engine, it does transfers between memory and memory - * - * This 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Hw specific definitions */ -#define XILINX_CDMA_MAX_CHANS_PER_DEVICE 0x1 -#define XILINX_CDMA_MAX_TRANS_LEN 0x7FFFFF - -/* General register bits definitions */ -#define XILINX_CDMA_CR_RESET_MASK 0x00000004 - /* Reset DMA engine */ - -#define XILINX_CDMA_SR_IDLE_MASK 0x00000002 - /* DMA channel idle */ - -#define XILINX_CDMA_SR_ERR_INTERNAL_MASK 0x00000010 - /* Datamover internal err */ -#define XILINX_CDMA_SR_ERR_SLAVE_MASK 0x00000020 - /* Datamover slave err */ -#define XILINX_CDMA_SR_ERR_DECODE_MASK 0x00000040 - /* Datamover decode err */ -#define XILINX_CDMA_SR_ERR_SG_INT_MASK 0x00000100 - /* SG internal err */ -#define XILINX_CDMA_SR_ERR_SG_SLV_MASK 0x00000200 - /* SG slave err */ -#define XILINX_CDMA_SR_ERR_SG_DEC_MASK 0x00000400 - /* SG decode err */ -#define XILINX_CDMA_SR_ERR_ALL_MASK 0x00000770 - /* All errors */ - -#define XILINX_CDMA_XR_IRQ_IOC_MASK 0x00001000 - /* Completion interrupt */ -#define XILINX_CDMA_XR_IRQ_DELAY_MASK 0x00002000 - /* Delay interrupt */ -#define XILINX_CDMA_XR_IRQ_ERROR_MASK 0x00004000 - /* Error interrupt */ -#define XILINX_CDMA_XR_IRQ_ALL_MASK 0x00007000 - /* All interrupts */ - -#define XILINX_CDMA_XR_DELAY_MASK 0xFF000000 - /* Delay timeout counter */ -#define XILINX_CDMA_XR_COALESCE_MASK 0x00FF0000 - /* Coalesce counter */ - -#define XILINX_CDMA_IRQ_SHIFT 12 -#define XILINX_CDMA_DELAY_SHIFT 24 -#define XILINX_CDMA_COALESCE_SHIFT 16 - -#define XILINX_CDMA_DELAY_MAX 0xFF - /* Maximum delay counter value */ -#define XILINX_CDMA_COALESCE_MAX 0xFF - /* Maximum coalescing counter value */ - -#define XILINX_CDMA_CR_SGMODE_MASK 0x00000008 - /* Scatter gather mode */ - -#define XILINX_CDMA_SR_SGINCLD_MASK 0x00000008 - /* Hybrid build */ -#define XILINX_CDMA_XR_IRQ_SIMPLE_ALL_MASK 0x00005000 - /* All interrupts for simple mode */ - -/* BD definitions for Axi Cdma */ -#define XILINX_CDMA_BD_STS_COMPL_MASK 0x80000000 -#define XILINX_CDMA_BD_STS_ERR_MASK 0x70000000 -#define XILINX_CDMA_BD_STS_ALL_MASK 0xF0000000 - -/* Feature encodings */ -#define XILINX_CDMA_FTR_DATA_WIDTH_MASK 0x000000FF - /* Data width mask, 1024 */ -#define XILINX_CDMA_FTR_HAS_SG 0x00000100 - /* Has SG */ -#define XILINX_CDMA_FTR_HAS_SG_SHIFT 8 - /* Has SG shift */ - -/* Delay loop counter to prevent hardware failure */ -#define XILINX_CDMA_RESET_LOOP 1000000 -#define XILINX_CDMA_HALT_LOOP 1000000 - -/* Device Id in the private structure */ -#define XILINX_CDMA_DEVICE_ID_SHIFT 28 - -/* IO accessors */ -#define CDMA_OUT(addr, val) (iowrite32(val, addr)) -#define CDMA_IN(addr) (ioread32(addr)) - -/* Hardware descriptor */ -struct xilinx_cdma_desc_hw { - u32 next_desc; /* 0x00 */ - u32 pad1; /* 0x04 */ - u32 src_addr; /* 0x08 */ - u32 pad2; /* 0x0C */ - u32 dest_addr; /* 0x10 */ - u32 pad3; /* 0x14 */ - u32 control; /* 0x18 */ - u32 status; /* 0x1C */ -} __aligned(64); - -/* Software descriptor */ -struct xilinx_cdma_desc_sw { - struct xilinx_cdma_desc_hw hw; - struct list_head node; - struct list_head tx_list; - struct dma_async_tx_descriptor async_tx; -} __aligned(64); - -/* AXI CDMA Registers Structure */ -struct xcdma_regs { - u32 cr; /* 0x00 Control Register */ - u32 sr; /* 0x04 Status Register */ - u32 cdr; /* 0x08 Current Descriptor Register */ - u32 pad1; - u32 tdr; /* 0x10 Tail Descriptor Register */ - u32 pad2; - u32 src; /* 0x18 Source Address Register */ - u32 pad3; - u32 dst; /* 0x20 Destination Address Register */ - u32 pad4; - u32 btt_ref; /* 0x28 Bytes To Transfer */ -}; - -/* Per DMA specific operations should be embedded in the channel structure */ -struct xilinx_cdma_chan { - struct xcdma_regs __iomem *regs; /* Control status registers */ - dma_cookie_t completed_cookie; /* Maximum cookie completed */ - dma_cookie_t cookie; /* The current cookie */ - spinlock_t lock; /* Descriptor operation lock */ - bool sg_waiting; /* SG transfer waiting */ - struct list_head active_list; /* Active descriptors */ - struct list_head pending_list; /* Descriptors waiting */ - struct dma_chan common; /* DMA common channel */ - struct dma_pool *desc_pool; /* Descriptors pool */ - struct device *dev; /* The dma device */ - int irq; /* Channel IRQ */ - int id; /* Channel ID */ - enum dma_transfer_direction direction; /* Transfer direction */ - int max_len; /* Max data len per transfer */ - int is_lite; /* Whether is light build */ - int has_SG; /* Support scatter transfers */ - int has_DRE; /* For unaligned transfers */ - int err; /* Channel has errors */ - struct tasklet_struct tasklet; /* Cleanup work after irq */ - u32 feature; /* IP feature */ - u32 private; /* Match info for - channel request */ - void (*start_transfer)(struct xilinx_cdma_chan *chan); - struct xilinx_cdma_config config; /* Device configuration info */ -}; - -struct xilinx_cdma_device { - void __iomem *regs; - struct device *dev; - struct dma_device common; - struct xilinx_cdma_chan *chan[XILINX_CDMA_MAX_CHANS_PER_DEVICE]; - u32 feature; - int irq; -}; - -#define to_xilinx_chan(chan) \ - container_of(chan, struct xilinx_cdma_chan, common) - -/* Required functions */ - -static int xilinx_cdma_alloc_chan_resources(struct dma_chan *dchan) -{ - struct xilinx_cdma_chan *chan = to_xilinx_chan(dchan); - - /* Has this channel already been allocated? */ - if (chan->desc_pool) - return 1; - - /* - * We need the descriptor to be aligned to 64bytes - * for meeting Xilinx DMA specification requirement. - */ - chan->desc_pool = dma_pool_create("xilinx_cdma_desc_pool", - chan->dev, - sizeof(struct xilinx_cdma_desc_sw), - __alignof__(struct xilinx_cdma_desc_sw), 0); - if (!chan->desc_pool) { - dev_err(chan->dev, - "unable to allocate channel %d descriptor pool\n", - chan->id); - return -ENOMEM; - } - - chan->completed_cookie = 1; - chan->cookie = 1; - - /* there is at least one descriptor free to be allocated */ - return 1; -} - -static void xilinx_cdma_free_desc_list(struct xilinx_cdma_chan *chan, - struct list_head *list) -{ - struct xilinx_cdma_desc_sw *desc, *_desc; - - list_for_each_entry_safe(desc, _desc, list, node) { - list_del(&desc->node); - dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys); - } -} - -static void xilinx_cdma_free_desc_list_reverse(struct xilinx_cdma_chan *chan, - struct list_head *list) -{ - struct xilinx_cdma_desc_sw *desc, *_desc; - - list_for_each_entry_safe_reverse(desc, _desc, list, node) { - list_del(&desc->node); - dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys); - } -} - -static void xilinx_cdma_free_chan_resources(struct dma_chan *dchan) -{ - struct xilinx_cdma_chan *chan = to_xilinx_chan(dchan); - unsigned long flags; - - dev_dbg(chan->dev, "Free all channel resources.\n"); - spin_lock_irqsave(&chan->lock, flags); - xilinx_cdma_free_desc_list(chan, &chan->active_list); - xilinx_cdma_free_desc_list(chan, &chan->pending_list); - spin_unlock_irqrestore(&chan->lock, flags); - - dma_pool_destroy(chan->desc_pool); - chan->desc_pool = NULL; -} - -static enum dma_status xilinx_cdma_desc_status(struct xilinx_cdma_chan *chan, - struct xilinx_cdma_desc_sw *desc) -{ - return dma_async_is_complete(desc->async_tx.cookie, - chan->completed_cookie, - chan->cookie); -} - -static void xilinx_cdma_chan_desc_cleanup(struct xilinx_cdma_chan *chan) -{ - struct xilinx_cdma_desc_sw *desc, *_desc; - unsigned long flags; - - spin_lock_irqsave(&chan->lock, flags); - - list_for_each_entry_safe(desc, _desc, &chan->active_list, node) { - dma_async_tx_callback callback; - void *callback_param; - - if (xilinx_cdma_desc_status(chan, desc) == DMA_IN_PROGRESS) - break; - - /* Remove from the list of running transactions */ - list_del(&desc->node); - - /* Run the link descriptor callback function */ - callback = desc->async_tx.callback; - callback_param = desc->async_tx.callback_param; - if (callback) { - spin_unlock_irqrestore(&chan->lock, flags); - callback(callback_param); - spin_lock_irqsave(&chan->lock, flags); - } - - /* Run any dependencies, then free the descriptor */ - dma_run_dependencies(&desc->async_tx); - dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys); - } - - spin_unlock_irqrestore(&chan->lock, flags); -} - -static enum dma_status xilinx_tx_status(struct dma_chan *dchan, - dma_cookie_t cookie, - struct dma_tx_state *txstate) -{ - struct xilinx_cdma_chan *chan = to_xilinx_chan(dchan); - dma_cookie_t last_used; - dma_cookie_t last_complete; - - xilinx_cdma_chan_desc_cleanup(chan); - - last_used = dchan->cookie; - last_complete = chan->completed_cookie; - - dma_set_tx_state(txstate, last_complete, last_used, 0); - - return dma_async_is_complete(cookie, last_complete, last_used); -} - -static int cdma_is_idle(struct xilinx_cdma_chan *chan) -{ - return CDMA_IN(&chan->regs->sr) & XILINX_CDMA_SR_IDLE_MASK; -} - -/* Only needed for Axi CDMA v2_00_a or earlier core */ -static void cdma_sg_toggle(struct xilinx_cdma_chan *chan) -{ - CDMA_OUT(&chan->regs->cr, - CDMA_IN(&chan->regs->cr) & ~XILINX_CDMA_CR_SGMODE_MASK); - - CDMA_OUT(&chan->regs->cr, - CDMA_IN(&chan->regs->cr) | XILINX_CDMA_CR_SGMODE_MASK); -} - -#define XILINX_CDMA_DRIVER_DEBUG 0 - -#if (XILINX_CDMA_DRIVER_DEBUG == 1) -static void desc_dump(struct xilinx_cdma_desc_hw *hw) -{ - pr_info("hw desc %x:\n", (unsigned int)hw); - pr_info("\tnext_desc %x\n", hw->next_desc); - pr_info("\tsrc_addr %x\n", hw->src_addr); - pr_info("\tdest_addr %x\n", hw->dest_addr); - pr_info("\thsize %x\n", hw->hsize); - pr_info("\tcontrol %x\n", hw->control); - pr_info("\tstatus %x\n", hw->status); -} -#endif - -static void xilinx_cdma_start_transfer(struct xilinx_cdma_chan *chan) -{ - unsigned long flags; - struct xilinx_cdma_desc_sw *desch, *desct; - struct xilinx_cdma_desc_hw *hw; - - if (chan->err) - return; - - spin_lock_irqsave(&chan->lock, flags); - - if (list_empty(&chan->pending_list)) - goto out_unlock; - - /* If hardware is busy, cannot submit */ - if (!cdma_is_idle(chan)) { - dev_dbg(chan->dev, "DMA controller still busy %x\n", - CDMA_IN(&chan->regs->sr)); - goto out_unlock; - } - - /* Enable interrupts */ - CDMA_OUT(&chan->regs->cr, - CDMA_IN(&chan->regs->cr) | XILINX_CDMA_XR_IRQ_ALL_MASK); - - desch = list_first_entry(&chan->pending_list, - struct xilinx_cdma_desc_sw, node); - - if (chan->has_SG) { - - /* If hybrid mode, append pending list to active list */ - desct = container_of(chan->pending_list.prev, - struct xilinx_cdma_desc_sw, node); - - list_splice_tail_init(&chan->pending_list, &chan->active_list); - - /* - * If hardware is idle, then all descriptors on the active list - * are done, start new transfers - */ - cdma_sg_toggle(chan); - - CDMA_OUT(&chan->regs->cdr, desch->async_tx.phys); - - /* Update tail ptr register and start the transfer */ - CDMA_OUT(&chan->regs->tdr, desct->async_tx.phys); - goto out_unlock; - } - - /* In simple mode */ - list_del(&desch->node); - list_add_tail(&desch->node, &chan->active_list); - - hw = &desch->hw; - - CDMA_OUT(&chan->regs->src, hw->src_addr); - CDMA_OUT(&chan->regs->dst, hw->dest_addr); - - /* Start the transfer */ - CDMA_OUT(&chan->regs->btt_ref, - hw->control & XILINX_CDMA_MAX_TRANS_LEN); - -out_unlock: - spin_unlock_irqrestore(&chan->lock, flags); -} - -/* - * If sg mode, link the pending list to running list; if simple mode, get the - * head of the pending list and submit it to hw - */ -static void xilinx_cdma_issue_pending(struct dma_chan *dchan) -{ - struct xilinx_cdma_chan *chan = to_xilinx_chan(dchan); - - xilinx_cdma_start_transfer(chan); -} - -/** - * xilinx_cdma_update_completed_cookie - Update the completed cookie. - * @chan : xilinx DMA channel - * - * CONTEXT: hardirq - */ -static void xilinx_cdma_update_completed_cookie(struct xilinx_cdma_chan *chan) -{ - struct xilinx_cdma_desc_sw *desc = NULL; - struct xilinx_cdma_desc_hw *hw = NULL; - unsigned long flags; - dma_cookie_t cookie = -EBUSY; - int done = 0; - - spin_lock_irqsave(&chan->lock, flags); - - if (list_empty(&chan->active_list)) { - dev_dbg(chan->dev, "no running descriptors\n"); - goto out_unlock; - } - - /* Get the last completed descriptor, update the cookie to that */ - list_for_each_entry(desc, &chan->active_list, node) { - if (chan->has_SG) { - hw = &desc->hw; - - /* If a BD has no status bits set, hw has it */ - if (!(hw->status & XILINX_CDMA_BD_STS_ALL_MASK)) { - break; - } else { - done = 1; - cookie = desc->async_tx.cookie; - } - } else { - /* In non-SG mode, all active entries are done */ - done = 1; - cookie = desc->async_tx.cookie; - } - } - - if (done) - chan->completed_cookie = cookie; - -out_unlock: - spin_unlock_irqrestore(&chan->lock, flags); -} - -/* Reset hardware */ -static int cdma_init(struct xilinx_cdma_chan *chan) -{ - int loop = XILINX_CDMA_RESET_LOOP; - u32 tmp; - - CDMA_OUT(&chan->regs->cr, - CDMA_IN(&chan->regs->cr) | XILINX_CDMA_CR_RESET_MASK); - - tmp = CDMA_IN(&chan->regs->cr) & XILINX_CDMA_CR_RESET_MASK; - - /* Wait for the hardware to finish reset */ - while (loop && tmp) { - tmp = CDMA_IN(&chan->regs->cr) & XILINX_CDMA_CR_RESET_MASK; - loop -= 1; - } - - if (!loop) { - dev_err(chan->dev, "reset timeout, cr %x, sr %x\n", - CDMA_IN(&chan->regs->cr), CDMA_IN(&chan->regs->sr)); - return 1; - } - - /* For Axi CDMA, always do sg transfers if sg mode is built in */ - if ((chan->feature & XILINX_DMA_IP_CDMA) && chan->has_SG) - CDMA_OUT(&chan->regs->cr, tmp | XILINX_CDMA_CR_SGMODE_MASK); - - return 0; -} - - -static irqreturn_t cdma_intr_handler(int irq, void *data) -{ - struct xilinx_cdma_chan *chan = data; - int update_cookie = 0; - int to_transfer = 0; - u32 stat, reg; - - reg = CDMA_IN(&chan->regs->cr); - - /* Disable intr */ - CDMA_OUT(&chan->regs->cr, - reg & ~XILINX_CDMA_XR_IRQ_ALL_MASK); - - stat = CDMA_IN(&chan->regs->sr); - if (!(stat & XILINX_CDMA_XR_IRQ_ALL_MASK)) - return IRQ_NONE; - - /* Ack the interrupts */ - CDMA_OUT(&chan->regs->sr, XILINX_CDMA_XR_IRQ_ALL_MASK); - - /* Check for only the interrupts which are enabled */ - stat &= (reg & XILINX_CDMA_XR_IRQ_ALL_MASK); - - if (stat & XILINX_CDMA_XR_IRQ_ERROR_MASK) { - dev_err(chan->dev, - "Channel %x has errors %x, cdr %x tdr %x\n", - (unsigned int)chan, - (unsigned int)CDMA_IN(&chan->regs->sr), - (unsigned int)CDMA_IN(&chan->regs->cdr), - (unsigned int)CDMA_IN(&chan->regs->tdr)); - chan->err = 1; - } - - /* - * Device takes too long to do the transfer when user requires - * responsiveness - */ - if (stat & XILINX_CDMA_XR_IRQ_DELAY_MASK) - dev_dbg(chan->dev, "Inter-packet latency too long\n"); - - if (stat & XILINX_CDMA_XR_IRQ_IOC_MASK) { - update_cookie = 1; - to_transfer = 1; - } - - if (update_cookie) - xilinx_cdma_update_completed_cookie(chan); - - if (to_transfer) - chan->start_transfer(chan); - - tasklet_schedule(&chan->tasklet); - return IRQ_HANDLED; -} - -static void cdma_do_tasklet(unsigned long data) -{ - struct xilinx_cdma_chan *chan = (struct xilinx_cdma_chan *)data; - - xilinx_cdma_chan_desc_cleanup(chan); -} - -/* Append the descriptor list to the pending list */ -static void append_desc_queue(struct xilinx_cdma_chan *chan, - struct xilinx_cdma_desc_sw *desc) -{ - struct xilinx_cdma_desc_sw *tail = container_of(chan->pending_list.prev, - struct xilinx_cdma_desc_sw, node); - struct xilinx_cdma_desc_hw *hw; - - if (list_empty(&chan->pending_list)) - goto out_splice; - - /* - * Add the hardware descriptor to the chain of hardware descriptors - * that already exists in memory. - */ - hw = &(tail->hw); - hw->next_desc = (u32)desc->async_tx.phys; - - /* - * Add the software descriptor and all children to the list - * of pending transactions - */ -out_splice: - list_splice_tail_init(&desc->tx_list, &chan->pending_list); -} - -/* - * Assign cookie to each descriptor, and append the descriptors to the pending - * list - */ -static dma_cookie_t xilinx_cdma_tx_submit(struct dma_async_tx_descriptor *tx) -{ - struct xilinx_cdma_chan *chan = to_xilinx_chan(tx->chan); - struct xilinx_cdma_desc_sw *desc = container_of(tx, - struct xilinx_cdma_desc_sw, async_tx); - struct xilinx_cdma_desc_sw *child; - unsigned long flags; - dma_cookie_t cookie = -EBUSY; - - if (chan->err) { - /* - * If reset fails, need to hard reset the system. - * Channel is no longer functional - */ - if (!cdma_init(chan)) - chan->err = 0; - else - return cookie; - } - - spin_lock_irqsave(&chan->lock, flags); - - /* - * assign cookies to all of the software descriptors - * that make up this transaction - */ - cookie = chan->cookie; - list_for_each_entry(child, &desc->tx_list, node) { - cookie++; - if (cookie < 0) - cookie = DMA_MIN_COOKIE; - - child->async_tx.cookie = cookie; - } - - chan->cookie = cookie; - - /* put this transaction onto the tail of the pending queue */ - append_desc_queue(chan, desc); - - spin_unlock_irqrestore(&chan->lock, flags); - - return cookie; -} - -static struct xilinx_cdma_desc_sw *xilinx_cdma_alloc_descriptor( - struct xilinx_cdma_chan *chan) -{ - struct xilinx_cdma_desc_sw *desc; - dma_addr_t pdesc; - - desc = dma_pool_alloc(chan->desc_pool, GFP_ATOMIC, &pdesc); - if (!desc) { - dev_dbg(chan->dev, "out of memory for desc\n"); - return NULL; - } - - memset(desc, 0, sizeof(*desc)); - INIT_LIST_HEAD(&desc->tx_list); - dma_async_tx_descriptor_init(&desc->async_tx, &chan->common); - desc->async_tx.tx_submit = xilinx_cdma_tx_submit; - desc->async_tx.phys = pdesc; - - return desc; -} - -/** - * xilinx_cdma_prep_memcpy - prepare descriptors for a memcpy transaction - * @dchan: DMA channel - * @dma_dst: destination address - * @dma_src: source address - * @len: transfer length - * @flags: transfer ack flags - */ -static struct dma_async_tx_descriptor *xilinx_cdma_prep_memcpy( - struct dma_chan *dchan, dma_addr_t dma_dst, dma_addr_t dma_src, - size_t len, unsigned long flags) -{ - struct xilinx_cdma_chan *chan; - struct xilinx_cdma_desc_sw *first = NULL, *prev = NULL, *new; - struct xilinx_cdma_desc_hw *hw, *prev_hw; - size_t copy; - dma_addr_t src = dma_src; - dma_addr_t dst = dma_dst; - - if (!dchan) - return NULL; - - if (!len) - return NULL; - - chan = to_xilinx_chan(dchan); - - if (chan->err) { - - /* - * If reset fails, need to hard reset the system. - * Channel is no longer functional - */ - if (!cdma_init(chan)) - chan->err = 0; - else - return NULL; - } - - /* - * If build does not have Data Realignment Engine (DRE), - * src has to be aligned - */ - if (!chan->has_DRE) { - if ((dma_src & - (chan->feature & XILINX_CDMA_FTR_DATA_WIDTH_MASK)) || - (dma_dst & - (chan->feature & XILINX_CDMA_FTR_DATA_WIDTH_MASK))) { - - dev_err(chan->dev, - "Src/Dest address not aligned when no DRE\n"); - - return NULL; - } - } - - do { - /* Allocate descriptor from DMA pool */ - new = xilinx_cdma_alloc_descriptor(chan); - if (!new) { - dev_err(chan->dev, - "No free memory for link descriptor\n"); - goto fail; - } - - copy = min_t(size_t, len, chan->max_len); - - /* if lite build, transfer cannot cross page boundary */ - if (chan->is_lite) - copy = min(copy, (size_t)(PAGE_MASK - - (src & PAGE_MASK))); - - if (!copy) { - dev_err(chan->dev, - "Got zero transfer length for %x\n", - (unsigned int)src); - goto fail; - } - - hw = &(new->hw); - hw->control = - (hw->control & ~XILINX_CDMA_MAX_TRANS_LEN) | copy; - hw->src_addr = src; - hw->dest_addr = dst; - - if (!first) - first = new; - else { - prev_hw = &(prev->hw); - prev_hw->next_desc = new->async_tx.phys; - } - - new->async_tx.cookie = 0; - async_tx_ack(&new->async_tx); - - prev = new; - len -= copy; - src += copy; - dst += copy; - - /* Insert the descriptor to the list */ - list_add_tail(&new->node, &first->tx_list); - } while (len); - - /* Link the last BD with the first BD */ - hw->next_desc = first->async_tx.phys; - - new->async_tx.flags = flags; /* client is in control of this ack */ - new->async_tx.cookie = -EBUSY; - - return &first->async_tx; - -fail: - if (!first) - return NULL; - - xilinx_cdma_free_desc_list_reverse(chan, &first->tx_list); - return NULL; -} - -/* Run-time device configuration for Axi CDMA */ -static int xilinx_cdma_device_control(struct dma_chan *dchan, - enum dma_ctrl_cmd cmd, unsigned long arg) -{ - struct xilinx_cdma_chan *chan; - unsigned long flags; - - if (!dchan) - return -EINVAL; - - chan = to_xilinx_chan(dchan); - - if (cmd == DMA_TERMINATE_ALL) { - spin_lock_irqsave(&chan->lock, flags); - - /* Remove and free all of the descriptors in the lists */ - xilinx_cdma_free_desc_list(chan, &chan->pending_list); - xilinx_cdma_free_desc_list(chan, &chan->active_list); - - spin_unlock_irqrestore(&chan->lock, flags); - return 0; - } else if (cmd == DMA_SLAVE_CONFIG) { - /* - * Configure interrupt coalescing and delay counter - * Use value XILINX_CDMA_NO_CHANGE to signal no change - */ - struct xilinx_cdma_config *cfg = - (struct xilinx_cdma_config *)arg; - u32 reg = CDMA_IN(&chan->regs->cr); - - if (cfg->coalesc <= XILINX_CDMA_COALESCE_MAX) { - reg &= ~XILINX_CDMA_XR_COALESCE_MASK; - reg |= cfg->coalesc << XILINX_CDMA_COALESCE_SHIFT; - - chan->config.coalesc = cfg->coalesc; - } - - if (cfg->delay <= XILINX_CDMA_DELAY_MAX) { - reg &= ~XILINX_CDMA_XR_DELAY_MASK; - reg |= cfg->delay << XILINX_CDMA_DELAY_SHIFT; - chan->config.delay = cfg->delay; - } - - CDMA_OUT(&chan->regs->cr, reg); - - return 0; - } - - return -ENXIO; -} - -/* - * Logarithm function to compute alignment shift - * - * Only deals with value less than 4096. - */ -static int my_log(int value) -{ - int i = 0; - while ((1 << i) < value) { - i++; - - if (i >= 12) - return 0; - } - - return i; -} - -static void xilinx_cdma_chan_remove(struct xilinx_cdma_chan *chan) -{ - irq_dispose_mapping(chan->irq); - list_del(&chan->common.device_node); - kfree(chan); -} - -/* - * Probing channels - * - * . Get channel features from the device tree entry - * . Initialize special channel handling routines - */ -static int __devinit xilinx_cdma_chan_probe(struct xilinx_cdma_device *xdev, - struct device_node *node, u32 feature) -{ - struct xilinx_cdma_chan *chan; - int err; - int *value; - u32 width = 0, device_id = 0; - - /* alloc channel */ - chan = kzalloc(sizeof(*chan), GFP_KERNEL); - if (!chan) { - dev_err(xdev->dev, "no free memory for DMA channels!\n"); - err = -ENOMEM; - goto out_return; - } - - chan->feature = feature; - chan->is_lite = 0; - chan->has_DRE = 0; - chan->has_SG = 0; - chan->max_len = XILINX_CDMA_MAX_TRANS_LEN; - - value = (int *)of_get_property(node, "xlnx,include-dre", - NULL); - if (value) - chan->has_DRE = be32_to_cpup(value); - - value = (int *)of_get_property(node, - "xlnx,datawidth", - NULL); - if (value) { - width = be32_to_cpup(value) >> 3; /* convert bits to bytes */ - - /* If data width is greater than 8 bytes, DRE is not in hw */ - if (width > 8) - chan->has_DRE = 0; - - chan->feature |= width - 1; - } - - value = (int *)of_get_property(node, "xlnx,device-id", NULL); - if (value) - device_id = be32_to_cpup(value); - - chan->direction = DMA_MEM_TO_MEM; - chan->start_transfer = xilinx_cdma_start_transfer; - - chan->has_SG = (xdev->feature & XILINX_CDMA_FTR_HAS_SG) >> - XILINX_CDMA_FTR_HAS_SG_SHIFT; - - value = (int *)of_get_property(node, - "xlnx,lite-mode", NULL); - if (value) { - if (be32_to_cpup(value) == 1) { - chan->is_lite = 1; - value = (int *)of_get_property(node, - "xlnx,max-burst-len", NULL); - if (value) { - if (!width) { - dev_err(xdev->dev, - "Lite mode w/o data width property\n"); - goto out_free_chan; - } - chan->max_len = width * - be32_to_cpup(value); - } - } - } - - chan->regs = (struct xcdma_regs *)xdev->regs; - chan->id = 0; - - /* - * Used by dmatest channel matching in slave transfers - * Can change it to be a structure to have more matching information - */ - chan->private = (chan->direction & 0xFF) | - (chan->feature & XILINX_DMA_IP_MASK) | - (device_id << XILINX_CDMA_DEVICE_ID_SHIFT); - chan->common.private = (void *)&(chan->private); - - if (!chan->has_DRE) - xdev->common.copy_align = my_log(width); - - chan->dev = xdev->dev; - xdev->chan[chan->id] = chan; - - tasklet_init(&chan->tasklet, cdma_do_tasklet, (unsigned long)chan); - - /* Initialize the channel */ - if (cdma_init(chan)) { - dev_err(xdev->dev, "Reset channel failed\n"); - goto out_free_chan; - } - - spin_lock_init(&chan->lock); - INIT_LIST_HEAD(&chan->pending_list); - INIT_LIST_HEAD(&chan->active_list); - - chan->common.device = &xdev->common; - - /* Find the IRQ line, if it exists in the device tree */ - chan->irq = irq_of_parse_and_map(node, 0); - err = request_irq(chan->irq, cdma_intr_handler, IRQF_SHARED, - "xilinx-cdma-controller", chan); - if (err) { - dev_err(xdev->dev, "unable to request IRQ\n"); - goto out_free_irq; - } - - /* Add the channel to DMA device channel list */ - list_add_tail(&chan->common.device_node, &xdev->common.channels); - xdev->common.chancnt++; - - return 0; - -out_free_irq: - irq_dispose_mapping(chan->irq); -out_free_chan: - kfree(chan); -out_return: - return err; -} - -static int __devinit xilinx_cdma_of_probe(struct platform_device *op) -{ - struct xilinx_cdma_device *xdev; - struct device_node *child, *node; - int err; - int *value; - - dev_info(&op->dev, "Probing xilinx axi cdma engine\n"); - - xdev = kzalloc(sizeof(struct xilinx_cdma_device), GFP_KERNEL); - if (!xdev) { - dev_err(&op->dev, "Not enough memory for device\n"); - err = -ENOMEM; - goto out_return; - } - - xdev->dev = &(op->dev); - INIT_LIST_HEAD(&xdev->common.channels); - - node = op->dev.of_node; - xdev->feature = 0; - - /* iomap registers */ - xdev->regs = of_iomap(node, 0); - if (!xdev->regs) { - dev_err(&op->dev, "unable to iomap registers\n"); - err = -ENOMEM; - goto out_free_xdev; - } - - /* Axi CDMA only does memcpy */ - if (of_device_is_compatible(node, "xlnx,axi-cdma")) { - xdev->feature |= XILINX_DMA_IP_CDMA; - - value = (int *)of_get_property(node, "xlnx,include-sg", - NULL); - if (value) { - if (be32_to_cpup(value) == 1) - xdev->feature |= XILINX_CDMA_FTR_HAS_SG; - } - - dma_cap_set(DMA_MEMCPY, xdev->common.cap_mask); - xdev->common.device_prep_dma_memcpy = xilinx_cdma_prep_memcpy; - xdev->common.device_control = xilinx_cdma_device_control; - xdev->common.device_issue_pending = xilinx_cdma_issue_pending; - } - - xdev->common.device_alloc_chan_resources = - xilinx_cdma_alloc_chan_resources; - xdev->common.device_free_chan_resources = - xilinx_cdma_free_chan_resources; - xdev->common.device_tx_status = xilinx_tx_status; - xdev->common.dev = &op->dev; - - dev_set_drvdata(&op->dev, xdev); - - for_each_child_of_node(node, child) { - xilinx_cdma_chan_probe(xdev, child, xdev->feature); - } - - dma_async_device_register(&xdev->common); - - return 0; - -out_free_xdev: - kfree(xdev); - -out_return: - return err; -} - -static int __devexit xilinx_cdma_of_remove(struct platform_device *op) -{ - struct xilinx_cdma_device *xdev; - int i; - - xdev = dev_get_drvdata(&op->dev); - dma_async_device_unregister(&xdev->common); - - for (i = 0; i < XILINX_CDMA_MAX_CHANS_PER_DEVICE; i++) { - if (xdev->chan[i]) - xilinx_cdma_chan_remove(xdev->chan[i]); - } - - iounmap(xdev->regs); - dev_set_drvdata(&op->dev, NULL); - kfree(xdev); - - return 0; -} - -static const struct of_device_id xilinx_cdma_of_ids[] = { - { .compatible = "xlnx,axi-cdma",}, - {} -}; - -static struct platform_driver xilinx_cdma_of_driver = { - .driver = { - .name = "xilinx-cdma", - .owner = THIS_MODULE, - .of_match_table = xilinx_cdma_of_ids, - }, - .probe = xilinx_cdma_of_probe, - .remove = __devexit_p(xilinx_cdma_of_remove), -}; - -module_platform_driver(xilinx_cdma_of_driver); - -MODULE_AUTHOR("Xilinx, Inc."); -MODULE_DESCRIPTION("Xilinx CDMA driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/dma/xilinx/xilinx_axidma.c b/drivers/dma/xilinx/xilinx_axidma.c deleted file mode 100644 index 65a16edf94426..0000000000000 --- a/drivers/dma/xilinx/xilinx_axidma.c +++ /dev/null @@ -1,1201 +0,0 @@ -/* - * Xilinx AXI DMA Engine support - * - * Copyright (C) 2012 Xilinx, Inc. All rights reserved. - * - * Based on the Freescale DMA driver. - * - * Description: - * . Axi DMA engine, it does transfers between memory and device. It can be - * configured to have one channel or two channels. If configured as two - * channels, one is to transmit to a device and another is to receive from - * a device. - * - * This 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Hw specific definitions */ -#define XILINX_DMA_MAX_CHANS_PER_DEVICE 0x2 -#define XILINX_DMA_MAX_TRANS_LEN 0x7FFFFF - -/* General register bits definitions */ -#define XILINX_DMA_CR_RESET_MASK 0x00000004 - /* Reset DMA engine */ -#define XILINX_DMA_CR_RUNSTOP_MASK 0x00000001 - /* Start/stop DMA engine */ - -#define XILINX_DMA_SR_HALTED_MASK 0x00000001 - /* DMA channel halted */ -#define XILINX_DMA_SR_IDLE_MASK 0x00000002 - /* DMA channel idle */ - -#define XILINX_DMA_SR_ERR_INTERNAL_MASK 0x00000010 - /* Datamover internal err */ -#define XILINX_DMA_SR_ERR_SLAVE_MASK 0x00000020 - /* Datamover slave err */ -#define XILINX_DMA_SR_ERR_DECODE_MASK 0x00000040 - /* Datamover decode err */ -#define XILINX_DMA_SR_ERR_SG_INT_MASK 0x00000100 - /* SG internal err */ -#define XILINX_DMA_SR_ERR_SG_SLV_MASK 0x00000200 - /* SG slave err */ -#define XILINX_DMA_SR_ERR_SG_DEC_MASK 0x00000400 - /* SG decode err */ -#define XILINX_DMA_SR_ERR_ALL_MASK 0x00000770 - /* All errors */ - -#define XILINX_DMA_XR_IRQ_IOC_MASK 0x00001000 - /* Completion interrupt */ -#define XILINX_DMA_XR_IRQ_DELAY_MASK 0x00002000 - /* Delay interrupt */ -#define XILINX_DMA_XR_IRQ_ERROR_MASK 0x00004000 - /* Error interrupt */ -#define XILINX_DMA_XR_IRQ_ALL_MASK 0x00007000 - /* All interrupts */ - -#define XILINX_DMA_XR_DELAY_MASK 0xFF000000 - /* Delay timeout counter */ -#define XILINX_DMA_XR_COALESCE_MASK 0x00FF0000 - /* Coalesce counter */ - -#define XILINX_DMA_IRQ_SHIFT 12 -#define XILINX_DMA_DELAY_SHIFT 24 -#define XILINX_DMA_COALESCE_SHIFT 16 - -#define XILINX_DMA_DELAY_MAX 0xFF - /* Maximum delay counter value */ -#define XILINX_DMA_COALESCE_MAX 0xFF - /* Maximum coalescing counter value */ - -#define XILINX_DMA_RX_CHANNEL_OFFSET 0x30 - -/* BD definitions for AXI Dma */ -#define XILINX_DMA_BD_STS_COMPL_MASK 0x80000000 -#define XILINX_DMA_BD_STS_ERR_MASK 0x70000000 -#define XILINX_DMA_BD_STS_ALL_MASK 0xF0000000 - -/* Axi DMA BD special bits definitions */ -#define XILINX_DMA_BD_SOP 0x08000000 /* Start of packet bit */ -#define XILINX_DMA_BD_EOP 0x04000000 /* End of packet bit */ - -/* Feature encodings */ -#define XILINX_DMA_FTR_DATA_WIDTH_MASK 0x000000FF - /* Data width mask, 1024 */ -#define XILINX_DMA_FTR_HAS_SG 0x00000100 - /* Has SG */ -#define XILINX_DMA_FTR_HAS_SG_SHIFT 8 - /* Has SG shift */ -#define XILINX_DMA_FTR_STSCNTRL_STRM 0x00010000 - /* Optional feature for dma */ - -/* Delay loop counter to prevent hardware failure */ -#define XILINX_DMA_RESET_LOOP 1000000 -#define XILINX_DMA_HALT_LOOP 1000000 - -/* Device Id in the private structure */ -#define XILINX_DMA_DEVICE_ID_SHIFT 28 - -/* IO accessors */ -#define DMA_OUT(addr, val) (iowrite32(val, addr)) -#define DMA_IN(addr) (ioread32(addr)) - -#ifdef CONFIG_XILINX_DMATEST -#define TEST_DMA_WITH_LOOPBACK -#endif - -/* Hardware descriptor */ -struct xilinx_dma_desc_hw { - u32 next_desc; /* 0x00 */ - u32 pad1; /* 0x04 */ - u32 buf_addr; /* 0x08 */ - u32 pad2; /* 0x0C */ - u32 pad3; /* 0x10 */ - u32 pad4; /* 0x14 */ - u32 control; /* 0x18 */ - u32 status; /* 0x1C */ - u32 app_0; /* 0x20 */ - u32 app_1; /* 0x24 */ - u32 app_2; /* 0x28 */ - u32 app_3; /* 0x2C */ - u32 app_4; /* 0x30 */ -} __aligned(64); - -/* Software descriptor */ -struct xilinx_dma_desc_sw { - struct xilinx_dma_desc_hw hw; - struct list_head node; - struct list_head tx_list; - struct dma_async_tx_descriptor async_tx; -} __aligned(64); - -/* AXI DMA Registers Structure */ -struct xdma_regs { - u32 cr; /* 0x00 Control Register */ - u32 sr; /* 0x04 Status Register */ - u32 cdr; /* 0x08 Current Descriptor Register */ - u32 pad1; - u32 tdr; /* 0x10 Tail Descriptor Register */ - u32 pad2; - u32 src; /* 0x18 Source Address Register (sg = 0) */ - u32 pad3; - u32 dst; /* 0x20 Destination Address Register (sg = 0) */ - u32 pad4; - u32 btt_ref; /* 0x28 Bytes To Transfer (sg = 0) */ -}; - -/* Per DMA specific operations should be embedded in the channel structure */ -struct xilinx_dma_chan { - struct xdma_regs __iomem *regs; /* Control status registers */ - dma_cookie_t completed_cookie; /* The maximum cookie completed */ - dma_cookie_t cookie; /* The current cookie */ - spinlock_t lock; /* Descriptor operation lock */ - bool sg_waiting; /* Scatter gather transfer waiting */ - struct list_head active_list; /* Active descriptors */ - struct list_head pending_list; /* Descriptors waiting */ - struct dma_chan common; /* DMA common channel */ - struct dma_pool *desc_pool; /* Descriptors pool */ - struct device *dev; /* The dma device */ - int irq; /* Channel IRQ */ - int id; /* Channel ID */ - enum dma_transfer_direction direction; - /* Transfer direction */ - int max_len; /* Maximum data len per transfer */ - int is_lite; /* Whether is light build */ - int has_SG; /* Support scatter transfers */ - int has_DRE; /* Support unaligned transfers */ - int err; /* Channel has errors */ - struct tasklet_struct tasklet; /* Cleanup work after irq */ - u32 feature; /* IP feature */ - u32 private; /* Match info for channel request */ - void (*start_transfer)(struct xilinx_dma_chan *chan); - struct xilinx_dma_config config; - /* Device configuration info */ -}; - -/* DMA Device Structure */ -struct xilinx_dma_device { - void __iomem *regs; - struct device *dev; - struct dma_device common; - struct xilinx_dma_chan *chan[XILINX_DMA_MAX_CHANS_PER_DEVICE]; - u32 feature; - int irq; -}; - -#define to_xilinx_chan(chan) \ - container_of(chan, struct xilinx_dma_chan, common) - -/* Required functions */ - -static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan) -{ - struct xilinx_dma_chan *chan = to_xilinx_chan(dchan); - - /* Has this channel already been allocated? */ - if (chan->desc_pool) - return 1; - - /* - * We need the descriptor to be aligned to 64bytes - * for meeting Xilinx DMA specification requirement. - */ - chan->desc_pool = dma_pool_create("xilinx_dma_desc_pool", - chan->dev, - sizeof(struct xilinx_dma_desc_sw), - __alignof__(struct xilinx_dma_desc_sw), 0); - if (!chan->desc_pool) { - dev_err(chan->dev, - "unable to allocate channel %d descriptor pool\n", - chan->id); - return -ENOMEM; - } - - chan->completed_cookie = 1; - chan->cookie = 1; - - /* There is at least one descriptor free to be allocated */ - return 1; -} - -static void xilinx_dma_free_desc_list(struct xilinx_dma_chan *chan, - struct list_head *list) -{ - struct xilinx_dma_desc_sw *desc, *_desc; - - list_for_each_entry_safe(desc, _desc, list, node) { - list_del(&desc->node); - dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys); - } -} - -static void xilinx_dma_free_desc_list_reverse(struct xilinx_dma_chan *chan, - struct list_head *list) -{ - struct xilinx_dma_desc_sw *desc, *_desc; - - list_for_each_entry_safe_reverse(desc, _desc, list, node) { - list_del(&desc->node); - dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys); - } -} - -static void xilinx_dma_free_chan_resources(struct dma_chan *dchan) -{ - struct xilinx_dma_chan *chan = to_xilinx_chan(dchan); - unsigned long flags; - - dev_dbg(chan->dev, "Free all channel resources.\n"); - spin_lock_irqsave(&chan->lock, flags); - xilinx_dma_free_desc_list(chan, &chan->active_list); - xilinx_dma_free_desc_list(chan, &chan->pending_list); - spin_unlock_irqrestore(&chan->lock, flags); - - dma_pool_destroy(chan->desc_pool); - chan->desc_pool = NULL; -} - -static enum dma_status xilinx_dma_desc_status(struct xilinx_dma_chan *chan, - struct xilinx_dma_desc_sw *desc) -{ - return dma_async_is_complete(desc->async_tx.cookie, - chan->completed_cookie, - chan->cookie); -} - -static void xilinx_chan_desc_cleanup(struct xilinx_dma_chan *chan) -{ - struct xilinx_dma_desc_sw *desc, *_desc; - unsigned long flags; - - spin_lock_irqsave(&chan->lock, flags); - - list_for_each_entry_safe(desc, _desc, &chan->active_list, node) { - dma_async_tx_callback callback; - void *callback_param; - - if (xilinx_dma_desc_status(chan, desc) == DMA_IN_PROGRESS) - break; - - /* Remove from the list of running transactions */ - list_del(&desc->node); - - /* Run the link descriptor callback function */ - callback = desc->async_tx.callback; - callback_param = desc->async_tx.callback_param; - if (callback) { - spin_unlock_irqrestore(&chan->lock, flags); - callback(callback_param); - spin_lock_irqsave(&chan->lock, flags); - } - - /* Run any dependencies, then free the descriptor */ - dma_run_dependencies(&desc->async_tx); - dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys); - } - - spin_unlock_irqrestore(&chan->lock, flags); -} - -static enum dma_status xilinx_tx_status(struct dma_chan *dchan, - dma_cookie_t cookie, - struct dma_tx_state *txstate) -{ - struct xilinx_dma_chan *chan = to_xilinx_chan(dchan); - dma_cookie_t last_used; - dma_cookie_t last_complete; - - xilinx_chan_desc_cleanup(chan); - - last_used = dchan->cookie; - last_complete = chan->completed_cookie; - - dma_set_tx_state(txstate, last_complete, last_used, 0); - - return dma_async_is_complete(cookie, last_complete, last_used); -} - -static int dma_is_running(struct xilinx_dma_chan *chan) -{ - return !(DMA_IN(&chan->regs->sr) & XILINX_DMA_SR_HALTED_MASK) && - (DMA_IN(&chan->regs->cr) & XILINX_DMA_CR_RUNSTOP_MASK); -} - -static int dma_is_idle(struct xilinx_dma_chan *chan) -{ - return DMA_IN(&chan->regs->sr) & XILINX_DMA_SR_IDLE_MASK; -} - -#define XILINX_DMA_DRIVER_DEBUG 0 - -#if (XILINX_DMA_DRIVER_DEBUG == 1) -static void desc_dump(struct xilinx_dma_desc_hw *hw) -{ - pr_info("hw desc %x:\n", (unsigned int)hw); - pr_info("\tnext_desc %x\n", hw->next_desc); - pr_info("\tbuf_addr %x\n", hw->buf_addr); - pr_info("\taddr_vsize %x\n", hw->addr_vsize); - pr_info("\thsize %x\n", hw->hsize); - pr_info("\tcontrol %x\n", hw->control); - pr_info("\tstatus %x\n", hw->status); -} -#endif - -/* Stop the hardware, the ongoing transfer will be finished */ -static void dma_halt(struct xilinx_dma_chan *chan) -{ - int loop = XILINX_DMA_HALT_LOOP; - - DMA_OUT(&chan->regs->cr, - DMA_IN(&chan->regs->cr) & ~XILINX_DMA_CR_RUNSTOP_MASK); - - /* Wait for the hardware to halt */ - while (loop) { - if (!(DMA_IN(&chan->regs->cr) & XILINX_DMA_CR_RUNSTOP_MASK)) - break; - - loop -= 1; - } - - if (!loop) { - pr_debug("Cannot stop channel %x: %x\n", - (unsigned int)chan, - (unsigned int)DMA_IN(&chan->regs->cr)); - chan->err = 1; - } - - return; -} - -/* Start the hardware. Transfers are not started yet */ -static void dma_start(struct xilinx_dma_chan *chan) -{ - int loop = XILINX_DMA_HALT_LOOP; - - DMA_OUT(&chan->regs->cr, - DMA_IN(&chan->regs->cr) | XILINX_DMA_CR_RUNSTOP_MASK); - - /* Wait for the hardware to start */ - while (loop) { - if (DMA_IN(&chan->regs->cr) & XILINX_DMA_CR_RUNSTOP_MASK) - break; - - loop -= 1; - } - - if (!loop) { - pr_debug("Cannot start channel %x: %x\n", - (unsigned int)chan, - (unsigned int)DMA_IN(&chan->regs->cr)); - - chan->err = 1; - } - - return; -} - - -static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) -{ - unsigned long flags; - struct xilinx_dma_desc_sw *desch, *desct; - struct xilinx_dma_desc_hw *hw; - - if (chan->err) - return; - - spin_lock_irqsave(&chan->lock, flags); - - if (list_empty(&chan->pending_list)) - goto out_unlock; - - /* If hardware is busy, cannot submit */ - if (dma_is_running(chan) && !dma_is_idle(chan)) { - dev_dbg(chan->dev, "DMA controller still busy\n"); - goto out_unlock; - } - - /* - * If hardware is idle, then all descriptors on active list are - * done, start new transfers - */ - dma_halt(chan); - - if (chan->err) - goto out_unlock; - - if (chan->has_SG) { - desch = list_first_entry(&chan->pending_list, - struct xilinx_dma_desc_sw, node); - - desct = container_of(chan->pending_list.prev, - struct xilinx_dma_desc_sw, node); - - DMA_OUT(&chan->regs->cdr, desch->async_tx.phys); - - dma_start(chan); - - if (chan->err) - goto out_unlock; - list_splice_tail_init(&chan->pending_list, &chan->active_list); - - /* Enable interrupts */ - DMA_OUT(&chan->regs->cr, - DMA_IN(&chan->regs->cr) | XILINX_DMA_XR_IRQ_ALL_MASK); - - /* Update tail ptr register and start the transfer */ - DMA_OUT(&chan->regs->tdr, desct->async_tx.phys); - goto out_unlock; - } - - /* In simple mode */ - dma_halt(chan); - - if (chan->err) - goto out_unlock; - - pr_info("xilinx_dma_start_transfer::simple DMA mode\n"); - - desch = list_first_entry(&chan->pending_list, - struct xilinx_dma_desc_sw, node); - - list_del(&desch->node); - list_add_tail(&desch->node, &chan->active_list); - - dma_start(chan); - - if (chan->err) - goto out_unlock; - - hw = &desch->hw; - - /* Enable interrupts */ - DMA_OUT(&chan->regs->cr, - DMA_IN(&chan->regs->cr) | XILINX_DMA_XR_IRQ_ALL_MASK); - - DMA_OUT(&chan->regs->src, hw->buf_addr); - - /* Start the transfer */ - DMA_OUT(&chan->regs->btt_ref, - hw->control & XILINX_DMA_MAX_TRANS_LEN); - -out_unlock: - spin_unlock_irqrestore(&chan->lock, flags); -} - -static void xilinx_dma_issue_pending(struct dma_chan *dchan) -{ - struct xilinx_dma_chan *chan = to_xilinx_chan(dchan); - - xilinx_dma_start_transfer(chan); -} - -/** - * xilinx_dma_update_completed_cookie - Update the completed cookie. - * @chan : xilinx DMA channel - * - * CONTEXT: hardirq - */ -static void xilinx_dma_update_completed_cookie(struct xilinx_dma_chan *chan) -{ - struct xilinx_dma_desc_sw *desc = NULL; - struct xilinx_dma_desc_hw *hw = NULL; - unsigned long flags; - dma_cookie_t cookie = -EBUSY; - int done = 0; - - spin_lock_irqsave(&chan->lock, flags); - - if (list_empty(&chan->active_list)) { - dev_dbg(chan->dev, "no running descriptors\n"); - goto out_unlock; - } - - /* Get the last completed descriptor, update the cookie to that */ - list_for_each_entry(desc, &chan->active_list, node) { - if (chan->has_SG) { - hw = &desc->hw; - - /* If a BD has no status bits set, hw has it */ - if (!(hw->status & XILINX_DMA_BD_STS_ALL_MASK)) { - break; - } else { - done = 1; - cookie = desc->async_tx.cookie; - } - } else { - /* In non-SG mode, all active entries are done */ - done = 1; - cookie = desc->async_tx.cookie; - } - } - - if (done) - chan->completed_cookie = cookie; - -out_unlock: - spin_unlock_irqrestore(&chan->lock, flags); -} - -/* Reset hardware */ -static int dma_init(struct xilinx_dma_chan *chan) -{ - int loop = XILINX_DMA_RESET_LOOP; - u32 tmp; - - DMA_OUT(&chan->regs->cr, - DMA_IN(&chan->regs->cr) | XILINX_DMA_CR_RESET_MASK); - - tmp = DMA_IN(&chan->regs->cr) & XILINX_DMA_CR_RESET_MASK; - - /* Wait for the hardware to finish reset */ - while (loop && tmp) { - tmp = DMA_IN(&chan->regs->cr) & XILINX_DMA_CR_RESET_MASK; - loop -= 1; - } - - if (!loop) { - dev_err(chan->dev, "reset timeout, cr %x, sr %x\n", - DMA_IN(&chan->regs->cr), DMA_IN(&chan->regs->sr)); - return 1; - } - - return 0; -} - - -static irqreturn_t dma_intr_handler(int irq, void *data) -{ - struct xilinx_dma_chan *chan = data; - int update_cookie = 0; - int to_transfer = 0; - u32 stat, reg; - - reg = DMA_IN(&chan->regs->cr); - - /* Disable intr */ - DMA_OUT(&chan->regs->cr, - reg & ~XILINX_DMA_XR_IRQ_ALL_MASK); - - stat = DMA_IN(&chan->regs->sr); - if (!(stat & XILINX_DMA_XR_IRQ_ALL_MASK)) - return IRQ_NONE; - - /* Ack the interrupts */ - DMA_OUT(&chan->regs->sr, XILINX_DMA_XR_IRQ_ALL_MASK); - - /* Check for only the interrupts which are enabled */ - stat &= (reg & XILINX_DMA_XR_IRQ_ALL_MASK); - - if (stat & XILINX_DMA_XR_IRQ_ERROR_MASK) { - dev_err(chan->dev, - "Channel %x has errors %x, cdr %x tdr %x\n", - (unsigned int)chan, - (unsigned int)DMA_IN(&chan->regs->sr), - (unsigned int)DMA_IN(&chan->regs->cdr), - (unsigned int)DMA_IN(&chan->regs->tdr)); - chan->err = 1; - } - - /* - * Device takes too long to do the transfer when user requires - * responsiveness - */ - if (stat & XILINX_DMA_XR_IRQ_DELAY_MASK) - dev_dbg(chan->dev, "Inter-packet latency too long\n"); - - if (stat & XILINX_DMA_XR_IRQ_IOC_MASK) { - update_cookie = 1; - to_transfer = 1; - } - - if (update_cookie) - xilinx_dma_update_completed_cookie(chan); - - if (to_transfer) - chan->start_transfer(chan); - - tasklet_schedule(&chan->tasklet); - return IRQ_HANDLED; -} - -static void dma_do_tasklet(unsigned long data) -{ - struct xilinx_dma_chan *chan = (struct xilinx_dma_chan *)data; - - xilinx_chan_desc_cleanup(chan); -} - -/* Append the descriptor list to the pending list */ -static void append_desc_queue(struct xilinx_dma_chan *chan, - struct xilinx_dma_desc_sw *desc) -{ - struct xilinx_dma_desc_sw *tail = - container_of(chan->pending_list.prev, - struct xilinx_dma_desc_sw, node); - struct xilinx_dma_desc_hw *hw; - - if (list_empty(&chan->pending_list)) - goto out_splice; - - /* - * Add the hardware descriptor to the chain of hardware descriptors - * that already exists in memory. - */ - hw = &(tail->hw); - hw->next_desc = (u32)desc->async_tx.phys; - - /* - * Add the software descriptor and all children to the list - * of pending transactions - */ -out_splice: - list_splice_tail_init(&desc->tx_list, &chan->pending_list); -} - -/* - * Assign cookie to each descriptor, and append the descriptors to the pending - * list - */ -static dma_cookie_t xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx) -{ - struct xilinx_dma_chan *chan = to_xilinx_chan(tx->chan); - struct xilinx_dma_desc_sw *desc = container_of(tx, - struct xilinx_dma_desc_sw, async_tx); - struct xilinx_dma_desc_sw *child; - unsigned long flags; - dma_cookie_t cookie = -EBUSY; - - if (chan->err) { - /* - * If reset fails, need to hard reset the system. - * Channel is no longer functional - */ - if (!dma_init(chan)) - chan->err = 0; - else - return cookie; - } - - spin_lock_irqsave(&chan->lock, flags); - - /* - * Assign cookies to all of the software descriptors - * that make up this transaction - */ - cookie = chan->cookie; - list_for_each_entry(child, &desc->tx_list, node) { - cookie++; - if (cookie < 0) - cookie = DMA_MIN_COOKIE; - - child->async_tx.cookie = cookie; - } - - chan->cookie = cookie; - - /* Put this transaction onto the tail of the pending queue */ - append_desc_queue(chan, desc); - - spin_unlock_irqrestore(&chan->lock, flags); - - return cookie; -} - -static struct xilinx_dma_desc_sw *xilinx_dma_alloc_descriptor( - struct xilinx_dma_chan *chan) -{ - struct xilinx_dma_desc_sw *desc; - dma_addr_t pdesc; - - desc = dma_pool_alloc(chan->desc_pool, GFP_ATOMIC, &pdesc); - if (!desc) { - dev_dbg(chan->dev, "out of memory for desc\n"); - return NULL; - } - - memset(desc, 0, sizeof(*desc)); - INIT_LIST_HEAD(&desc->tx_list); - dma_async_tx_descriptor_init(&desc->async_tx, &chan->common); - desc->async_tx.tx_submit = xilinx_dma_tx_submit; - desc->async_tx.phys = pdesc; - - return desc; -} - -/** - * xilinx_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE transaction - * @chan: DMA channel - * @sgl: scatterlist to transfer to/from - * @sg_len: number of entries in @scatterlist - * @direction: DMA direction - * @flags: transfer ack flags - */ -static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg( - struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len, - enum dma_transfer_direction direction, unsigned long flags, - void *context) -{ - struct xilinx_dma_chan *chan; - struct xilinx_dma_desc_sw *first = NULL, *prev = NULL, *new = NULL; - struct xilinx_dma_desc_hw *hw = NULL, *prev_hw = NULL; - - size_t copy; - - int i; - struct scatterlist *sg; - size_t sg_used; - dma_addr_t dma_src; - -#ifdef TEST_DMA_WITH_LOOPBACK - int total_len; -#endif - if (!dchan) - return NULL; - - chan = to_xilinx_chan(dchan); - - if (chan->direction != direction) - return NULL; - -#ifdef TEST_DMA_WITH_LOOPBACK - total_len = 0; - - for_each_sg(sgl, sg, sg_len, i) { - total_len += sg_dma_len(sg); - } -#endif - /* Build transactions using information in the scatter gather list */ - for_each_sg(sgl, sg, sg_len, i) { - sg_used = 0; - - /* Loop until the entire scatterlist entry is used */ - while (sg_used < sg_dma_len(sg)) { - - /* Allocate the link descriptor from DMA pool */ - new = xilinx_dma_alloc_descriptor(chan); - if (!new) { - dev_err(chan->dev, - "No free memory for link descriptor\n"); - goto fail; - } - - /* - * Calculate the maximum number of bytes to transfer, - * making sure it is less than the hw limit - */ - copy = min((size_t)(sg_dma_len(sg) - sg_used), - (size_t)chan->max_len); - hw = &(new->hw); - - dma_src = sg_dma_address(sg) + sg_used; - - hw->buf_addr = dma_src; - - /* Fill in the descriptor */ - hw->control = copy; - - /* - * If this is not the first descriptor, chain the - * current descriptor after the previous descriptor - * - * For the first DMA_MEM_TO_DEV transfer, set SOP - */ - if (!first) { - first = new; - if (direction == DMA_MEM_TO_DEV) { - hw->control |= XILINX_DMA_BD_SOP; -#ifdef TEST_DMA_WITH_LOOPBACK - hw->app_4 = total_len; -#endif - } - } else { - prev_hw = &(prev->hw); - prev_hw->next_desc = new->async_tx.phys; - } - - new->async_tx.cookie = 0; - async_tx_ack(&new->async_tx); - - prev = new; - sg_used += copy; - - /* Insert the link descriptor into the LD ring */ - list_add_tail(&new->node, &first->tx_list); - } - } - - /* Link the last BD with the first BD */ - hw->next_desc = first->async_tx.phys; - - if (direction == DMA_MEM_TO_DEV) - hw->control |= XILINX_DMA_BD_EOP; - - /* All scatter gather list entries has length == 0 */ - if (!first || !new) - return NULL; - - new->async_tx.flags = flags; - new->async_tx.cookie = -EBUSY; - - /* Set EOP to the last link descriptor of new list */ - hw->control |= XILINX_DMA_BD_EOP; - - return &first->async_tx; - -fail: - /* - * If first was not set, then we failed to allocate the very first - * descriptor, and we're done - */ - if (!first) - return NULL; - - /* - * First is set, so all of the descriptors we allocated have been added - * to first->tx_list, INCLUDING "first" itself. Therefore we - * must traverse the list backwards freeing each descriptor in turn - */ - xilinx_dma_free_desc_list_reverse(chan, &first->tx_list); - - return NULL; -} - -/* Run-time device configuration for Axi DMA */ -static int xilinx_dma_device_control(struct dma_chan *dchan, - enum dma_ctrl_cmd cmd, unsigned long arg) -{ - struct xilinx_dma_chan *chan; - unsigned long flags; - - if (!dchan) - return -EINVAL; - - chan = to_xilinx_chan(dchan); - - if (cmd == DMA_TERMINATE_ALL) { - /* Halt the DMA engine */ - dma_halt(chan); - - spin_lock_irqsave(&chan->lock, flags); - - /* Remove and free all of the descriptors in the lists */ - xilinx_dma_free_desc_list(chan, &chan->pending_list); - xilinx_dma_free_desc_list(chan, &chan->active_list); - - spin_unlock_irqrestore(&chan->lock, flags); - return 0; - } else if (cmd == DMA_SLAVE_CONFIG) { - /* - * Configure interrupt coalescing and delay counter - * Use value XILINX_DMA_NO_CHANGE to signal no change - */ - struct xilinx_dma_config *cfg = (struct xilinx_dma_config *)arg; - u32 reg = DMA_IN(&chan->regs->cr); - - if (cfg->coalesc <= XILINX_DMA_COALESCE_MAX) { - reg &= ~XILINX_DMA_XR_COALESCE_MASK; - reg |= cfg->coalesc << XILINX_DMA_COALESCE_SHIFT; - - chan->config.coalesc = cfg->coalesc; - } - - if (cfg->delay <= XILINX_DMA_DELAY_MAX) { - reg &= ~XILINX_DMA_XR_DELAY_MASK; - reg |= cfg->delay << XILINX_DMA_DELAY_SHIFT; - chan->config.delay = cfg->delay; - } - - DMA_OUT(&chan->regs->cr, reg); - - return 0; - } else - return -ENXIO; -} - -/* - * Logarithm function to compute alignment shift - * - * Only deals with value less than 4096. - */ -static int my_log(int value) -{ - int i = 0; - while ((1 << i) < value) { - i++; - - if (i >= 12) - return 0; - } - - return i; -} - -static void xilinx_dma_chan_remove(struct xilinx_dma_chan *chan) -{ - irq_dispose_mapping(chan->irq); - list_del(&chan->common.device_node); - kfree(chan); -} - -/* - * Probing channels - * - * . Get channel features from the device tree entry - * . Initialize special channel handling routines - */ -static int __devinit xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, - struct device_node *node, u32 feature) -{ - struct xilinx_dma_chan *chan; - int err; - int *value; - u32 width = 0, device_id = 0; - - /* alloc channel */ - chan = kzalloc(sizeof(*chan), GFP_KERNEL); - if (!chan) { - dev_err(xdev->dev, "no free memory for DMA channels!\n"); - err = -ENOMEM; - goto out_return; - } - - chan->feature = feature; - chan->is_lite = 0; - chan->has_DRE = 0; - chan->has_SG = 0; - chan->max_len = XILINX_DMA_MAX_TRANS_LEN; - - value = (int *)of_get_property(node, "xlnx,include-dre", - NULL); - if (value) - chan->has_DRE = be32_to_cpup(value); - - value = (int *)of_get_property(node, - "xlnx,datawidth", - NULL); - if (value) { - width = be32_to_cpup(value) >> 3; /* convert bits to bytes */ - - /* If data width is greater than 8 bytes, DRE is not in hw */ - if (width > 8) - chan->has_DRE = 0; - - chan->feature |= width - 1; - } - - value = (int *)of_get_property(node, "xlnx,device-id", NULL); - if (value) - device_id = be32_to_cpup(value); - - if (feature & XILINX_DMA_IP_DMA) { - chan->has_SG = (xdev->feature & XILINX_DMA_FTR_HAS_SG) >> - XILINX_DMA_FTR_HAS_SG_SHIFT; - - chan->start_transfer = xilinx_dma_start_transfer; - - if (of_device_is_compatible(node, - "xlnx,axi-dma-mm2s-channel")) - chan->direction = DMA_MEM_TO_DEV; - - if (of_device_is_compatible(node, - "xlnx,axi-dma-s2mm-channel")) - chan->direction = DMA_DEV_TO_MEM; - - } - - chan->regs = (struct xdma_regs *)xdev->regs; - chan->id = 0; - - if (chan->direction == DMA_DEV_TO_MEM) { - chan->regs = (struct xdma_regs *)((u32)xdev->regs + - XILINX_DMA_RX_CHANNEL_OFFSET); - chan->id = 1; - } - - /* - * Used by dmatest channel matching in slave transfers - * Can change it to be a structure to have more matching information - */ - chan->private = (chan->direction & 0xFF) | - (chan->feature & XILINX_DMA_IP_MASK) | - (device_id << XILINX_DMA_DEVICE_ID_SHIFT); - chan->common.private = (void *)&(chan->private); - - if (!chan->has_DRE) - xdev->common.copy_align = my_log(width); - - chan->dev = xdev->dev; - xdev->chan[chan->id] = chan; - - tasklet_init(&chan->tasklet, dma_do_tasklet, (unsigned long)chan); - - /* Initialize the channel */ - if (dma_init(chan)) { - dev_err(xdev->dev, "Reset channel failed\n"); - goto out_free_chan; - } - - - spin_lock_init(&chan->lock); - INIT_LIST_HEAD(&chan->pending_list); - INIT_LIST_HEAD(&chan->active_list); - - chan->common.device = &xdev->common; - - /* find the IRQ line, if it exists in the device tree */ - chan->irq = irq_of_parse_and_map(node, 0); - err = request_irq(chan->irq, dma_intr_handler, IRQF_SHARED, - "xilinx-dma-controller", chan); - if (err) { - dev_err(xdev->dev, "unable to request IRQ\n"); - goto out_free_irq; - } - - /* Add the channel to DMA device channel list */ - list_add_tail(&chan->common.device_node, &xdev->common.channels); - xdev->common.chancnt++; - - return 0; - -out_free_irq: - irq_dispose_mapping(chan->irq); -out_free_chan: - kfree(chan); -out_return: - return err; -} - -static int __devinit xilinx_dma_of_probe(struct platform_device *op) -{ - struct xilinx_dma_device *xdev; - struct device_node *child, *node; - int err; - int *value; - - dev_info(&op->dev, "Probing xilinx axi dma engine\n"); - - xdev = kzalloc(sizeof(struct xilinx_dma_device), GFP_KERNEL); - if (!xdev) { - dev_err(&op->dev, "Not enough memory for device\n"); - err = -ENOMEM; - goto out_return; - } - - xdev->dev = &(op->dev); - INIT_LIST_HEAD(&xdev->common.channels); - - node = op->dev.of_node; - xdev->feature = 0; - - /* iomap registers */ - xdev->regs = of_iomap(node, 0); - if (!xdev->regs) { - dev_err(&op->dev, "unable to iomap registers\n"); - err = -ENOMEM; - goto out_free_xdev; - } - - /* - * Axi DMA only do slave transfers - */ - if (of_device_is_compatible(node, "xlnx,axi-dma")) { - - xdev->feature |= XILINX_DMA_IP_DMA; - value = (int *)of_get_property(node, - "xlnx,sg-include-stscntrl-strm", - NULL); - if (value) { - if (be32_to_cpup(value) == 1) { - xdev->feature |= (XILINX_DMA_FTR_STSCNTRL_STRM | - XILINX_DMA_FTR_HAS_SG); - } - } - - dma_cap_set(DMA_SLAVE, xdev->common.cap_mask); - dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask); - xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg; - xdev->common.device_control = xilinx_dma_device_control; - xdev->common.device_issue_pending = xilinx_dma_issue_pending; - } - - xdev->common.device_alloc_chan_resources = - xilinx_dma_alloc_chan_resources; - xdev->common.device_free_chan_resources = - xilinx_dma_free_chan_resources; - xdev->common.device_tx_status = xilinx_tx_status; - xdev->common.dev = &op->dev; - - dev_set_drvdata(&op->dev, xdev); - - for_each_child_of_node(node, child) { - xilinx_dma_chan_probe(xdev, child, xdev->feature); - } - - dma_async_device_register(&xdev->common); - - return 0; - -out_free_xdev: - kfree(xdev); - -out_return: - return err; -} - -static int __devexit xilinx_dma_of_remove(struct platform_device *op) -{ - struct xilinx_dma_device *xdev; - int i; - - xdev = dev_get_drvdata(&op->dev); - dma_async_device_unregister(&xdev->common); - - for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++) { - if (xdev->chan[i]) - xilinx_dma_chan_remove(xdev->chan[i]); - } - - iounmap(xdev->regs); - dev_set_drvdata(&op->dev, NULL); - kfree(xdev); - - return 0; -} - -static const struct of_device_id xilinx_dma_of_ids[] = { - { .compatible = "xlnx,axi-dma",}, - {} -}; - -static struct platform_driver xilinx_dma_of_driver = { - .driver = { - .name = "xilinx-dma", - .owner = THIS_MODULE, - .of_match_table = xilinx_dma_of_ids, - }, - .probe = xilinx_dma_of_probe, - .remove = __devexit_p(xilinx_dma_of_remove), -}; - -module_platform_driver(xilinx_dma_of_driver); - -MODULE_AUTHOR("Xilinx, Inc."); -MODULE_DESCRIPTION("Xilinx DMA driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/dma/xilinx/xilinx_axivdma.c b/drivers/dma/xilinx/xilinx_axivdma.c deleted file mode 100644 index e39676c13f7af..0000000000000 --- a/drivers/dma/xilinx/xilinx_axivdma.c +++ /dev/null @@ -1,1321 +0,0 @@ -/* - * Xilinx Video DMA Engine support - * - * Copyright (C) 2010 Xilinx, Inc. All rights reserved. - * - * Based on the Freescale DMA driver. - * - * Description: - * . Axi VDMA engine, it does transfers between memory and video devices. - * It can be configured to have one channel or two channels. If configured - * as two channels, one is to transmit to the video device and another is - * to receive from the video device. - * - * This 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* Hw specific definitions */ -#define XILINX_VDMA_MAX_CHANS_PER_DEVICE 0x2 -#define XILINX_VDMA_MAX_TRANS_LEN 0x7FFFFF - -/* General register bits definitions */ -#define XILINX_VDMA_CR_RESET_MASK 0x00000004 - /* Reset DMA engine */ -#define XILINX_VDMA_CR_RUNSTOP_MASK 0x00000001 - /* Start/stop DMA engine */ - -#define XILINX_VDMA_SR_HALTED_MASK 0x00000001 - /* DMA channel halted */ -#define XILINX_VDMA_SR_IDLE_MASK 0x00000002 - /* DMA channel idle */ - -#define XILINX_VDMA_SR_ERR_INTERNAL_MASK 0x00000010 - /* Datamover internal err */ -#define XILINX_VDMA_SR_ERR_SLAVE_MASK 0x00000020 - /* Datamover slave err */ -#define XILINX_VDMA_SR_ERR_DECODE_MASK 0x00000040 - /* Datamover decode err */ -#define XILINX_VDMA_SR_ERR_SG_INT_MASK 0x00000100 - /* SG internal err */ -#define XILINX_VDMA_SR_ERR_SG_SLV_MASK 0x00000200 - /* SG slave err */ -#define XILINX_VDMA_SR_ERR_SG_DEC_MASK 0x00000400 - /* SG decode err */ -#define XILINX_VDMA_SR_ERR_ALL_MASK 0x00000770 - /* All errors */ - -#define XILINX_VDMA_XR_IRQ_IOC_MASK 0x00001000 - /* Completion interrupt */ -#define XILINX_VDMA_XR_IRQ_DELAY_MASK 0x00002000 - /* Delay interrupt */ -#define XILINX_VDMA_XR_IRQ_ERROR_MASK 0x00004000 - /* Error interrupt */ -#define XILINX_VDMA_XR_IRQ_ALL_MASK 0x00007000 - /* All interrupts */ - -#define XILINX_VDMA_XR_DELAY_MASK 0xFF000000 - /* Delay timeout counter */ -#define XILINX_VDMA_XR_COALESCE_MASK 0x00FF0000 - /* Coalesce counter */ - -#define XILINX_VDMA_IRQ_SHIFT 12 -#define XILINX_VDMA_DELAY_SHIFT 24 -#define XILINX_VDMA_COALESCE_SHIFT 16 - -#define XILINX_VDMA_DELAY_MAX 0xFF - /* Maximum delay counter value */ -#define XILINX_VDMA_COALESCE_MAX 0xFF - /* Maximum coalescing counter value */ - -#define XILINX_VDMA_RX_CHANNEL_OFFSET 0x30 - -#define XILINX_VDMA_CIRC_EN 0x00000002 /* Circular mode */ -#define XILINX_VDMA_SYNC_EN 0x00000008 /* Sync enable mode */ -#define XILINX_VDMA_FRMCNT_EN 0x00000010 /* Frm Cnt enable mode */ -#define XILINX_VDMA_MSTR_MASK 0x00000F00 /* Master in control */ - -#define XILINX_VDMA_EXTFSYNC_SHIFT 6 -#define XILINX_VDMA_MSTR_SHIFT 8 -#define XILINX_VDMA_WR_REF_SHIFT 8 - -#define XILINX_VDMA_FRMDLY_SHIFT 24 - -#define XILINX_VDMA_DIRECT_REG_OFFSET 0x50 -#define XILINX_VDMA_CHAN_DIRECT_REG_SIZE 0x50 - -#define XILINX_VDMA_PARK_REG_OFFSET 0x28 - -#define XILINX_VDMA_SR_ERR_FSIZE_LESS_MASK 0x00000080 - /* FSize Less Mismatch err */ -#define XILINX_VDMA_SR_ERR_LSIZE_LESS_MASK 0x00000100 - /* LSize Less Mismatch err */ -#define XILINX_VDMA_SR_ERR_FSIZE_MORE_MASK 0x00000800 - /* FSize more err */ - -/* - * Recoverable errors are DMA Internal error, FSize Less, LSize Less - * and FSize More mismatch errors. These are only recoverable only - * when C_FLUSH_ON_FSYNC is enabled in the hardware system. - */ -#define XILINX_VDMA_SR_ERR_RECOVER_MASK 0x00000990 - /* Recoverable errs */ - -/* Axi VDMA Flush on Fsync bits */ -#define XILINX_VDMA_FLUSH_S2MM 3 -#define XILINX_VDMA_FLUSH_MM2S 2 -#define XILINX_VDMA_FLUSH_BOTH 1 - -/* Feature encodings */ -#define XILINX_VDMA_FTR_HAS_SG 0x00000100 - /* Has SG */ -#define XILINX_VDMA_FTR_HAS_SG_SHIFT 8 - /* Has SG shift */ -#define XILINX_VDMA_FTR_FLUSH_MASK 0x00000600 - /* Flush-on-FSync Mask */ -#define XILINX_VDMA_FTR_FLUSH_SHIFT 9 - /* Flush-on-FSync shift */ - -/* Delay loop counter to prevent hardware failure */ -#define XILINX_VDMA_RESET_LOOP 1000000 -#define XILINX_VDMA_HALT_LOOP 1000000 - -/* Device Id in the private structure */ -#define XILINX_VDMA_DEVICE_ID_SHIFT 28 - -/* IO accessors */ -#define VDMA_OUT(addr, val) (iowrite32(val, addr)) -#define VDMA_IN(addr) (ioread32(addr)) - -/* Hardware descriptor */ -struct xilinx_vdma_desc_hw { - u32 next_desc; /* 0x00 */ - u32 pad1; /* 0x04 */ - u32 buf_addr; /* 0x08 */ - u32 pad2; /* 0x0C */ - u32 vsize; /* 0x10 */ - u32 hsize; /* 0x14 */ - u32 stride; /* 0x18 */ -} __aligned(64); - -struct xilinx_vdma_desc_sw { - struct xilinx_vdma_desc_hw hw; - struct list_head node; - struct list_head tx_list; - struct dma_async_tx_descriptor async_tx; -} __aligned(64); - -struct xvdma_regs { - u32 cr; /* 0x00 Control Register */ - u32 sr; /* 0x04 Status Register */ - u32 cdr; /* 0x08 Current Descriptor Register */ - u32 pad1; - u32 tdr; /* 0x10 Tail Descriptor Register */ - u32 pad2; -}; - -struct vdma_addr_regs { - u32 vsize; /* 0x0 Vertical size */ - u32 hsize; /* 0x4 Horizontal size */ - u32 frmdly_stride; /* 0x8 Frame delay and stride */ - u32 buf_addr[16]; /* 0xC - 0x48 Src addresses */ -}; - -/* Per DMA specific operations should be embedded in the channel structure */ -struct xilinx_vdma_chan { - struct xvdma_regs __iomem *regs; /* Control status registers */ - struct vdma_addr_regs *addr_regs; /* Direct address registers */ - dma_cookie_t completed_cookie; /* Maximum cookie completed */ - dma_cookie_t cookie; /* The current cookie */ - spinlock_t lock; /* Descriptor operation lock */ - bool sg_waiting; /* SG transfer waiting */ - struct list_head active_list; /* Active descriptors */ - struct list_head pending_list; /* Descriptors waiting */ - struct dma_chan common; /* DMA common channel */ - struct dma_pool *desc_pool; /* Descriptors pool */ - struct device *dev; /* The dma device */ - int irq; /* Channel IRQ */ - int id; /* Channel ID */ - enum dma_transfer_direction direction; /* Transfer direction */ - int max_len; /* Max data len per transfer */ - int is_lite; /* Whether is light build */ - int num_frms; /* Number of frames */ - int has_SG; /* Support scatter transfers */ - int has_DRE; /* For unaligned transfers */ - int genlock; /* Support genlock mode */ - int err; /* Channel has errors */ - struct tasklet_struct tasklet; /* Cleanup work after irq */ - u32 feature; /* IP feature */ - u32 private; /* Match info for - channel request */ - void (*start_transfer)(struct xilinx_vdma_chan *chan); - struct xilinx_vdma_config config; /* Device configuration info */ - u32 flush_fsync; /* Flush on Fsync */ -}; - -struct xilinx_vdma_device { - void __iomem *regs; - struct device *dev; - struct dma_device common; - struct xilinx_vdma_chan *chan[XILINX_VDMA_MAX_CHANS_PER_DEVICE]; - u32 feature; - int irq; -}; - -#define to_xilinx_chan(chan) \ - container_of(chan, struct xilinx_vdma_chan, common) - -/* Required functions */ - -static int xilinx_vdma_alloc_chan_resources(struct dma_chan *dchan) -{ - struct xilinx_vdma_chan *chan = to_xilinx_chan(dchan); - - /* Has this channel already been allocated? */ - if (chan->desc_pool) - return 1; - - /* - * We need the descriptor to be aligned to 64bytes - * for meeting Xilinx VDMA specification requirement. - */ - chan->desc_pool = dma_pool_create("xilinx_vdma_desc_pool", - chan->dev, - sizeof(struct xilinx_vdma_desc_sw), - __alignof__(struct xilinx_vdma_desc_sw), 0); - if (!chan->desc_pool) { - dev_err(chan->dev, - "unable to allocate channel %d descriptor pool\n", - chan->id); - return -ENOMEM; - } - - chan->completed_cookie = 1; - chan->cookie = 1; - - /* there is at least one descriptor free to be allocated */ - return 1; -} - -static void xilinx_vdma_free_desc_list(struct xilinx_vdma_chan *chan, - struct list_head *list) -{ - struct xilinx_vdma_desc_sw *desc, *_desc; - - list_for_each_entry_safe(desc, _desc, list, node) { - list_del(&desc->node); - dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys); - } -} - -static void xilinx_vdma_free_desc_list_reverse(struct xilinx_vdma_chan *chan, - struct list_head *list) -{ - struct xilinx_vdma_desc_sw *desc, *_desc; - - list_for_each_entry_safe_reverse(desc, _desc, list, node) { - list_del(&desc->node); - dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys); - } -} - -static void xilinx_vdma_free_chan_resources(struct dma_chan *dchan) -{ - struct xilinx_vdma_chan *chan = to_xilinx_chan(dchan); - unsigned long flags; - - dev_dbg(chan->dev, "Free all channel resources.\n"); - spin_lock_irqsave(&chan->lock, flags); - xilinx_vdma_free_desc_list(chan, &chan->active_list); - xilinx_vdma_free_desc_list(chan, &chan->pending_list); - spin_unlock_irqrestore(&chan->lock, flags); - - dma_pool_destroy(chan->desc_pool); - chan->desc_pool = NULL; -} - -static enum dma_status xilinx_vdma_desc_status(struct xilinx_vdma_chan *chan, - struct xilinx_vdma_desc_sw *desc) -{ - return dma_async_is_complete(desc->async_tx.cookie, - chan->completed_cookie, - chan->cookie); -} - -static void xilinx_chan_desc_cleanup(struct xilinx_vdma_chan *chan) -{ - struct xilinx_vdma_desc_sw *desc, *_desc; - unsigned long flags; - - spin_lock_irqsave(&chan->lock, flags); - - list_for_each_entry_safe(desc, _desc, &chan->active_list, node) { - dma_async_tx_callback callback; - void *callback_param; - - if (xilinx_vdma_desc_status(chan, desc) == DMA_IN_PROGRESS) - break; - - /* Remove from the list of running transactions */ - list_del(&desc->node); - - /* Run the link descriptor callback function */ - callback = desc->async_tx.callback; - callback_param = desc->async_tx.callback_param; - if (callback) { - spin_unlock_irqrestore(&chan->lock, flags); - callback(callback_param); - spin_lock_irqsave(&chan->lock, flags); - } - - /* Run any dependencies, then free the descriptor */ - dma_run_dependencies(&desc->async_tx); - dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys); - } - - spin_unlock_irqrestore(&chan->lock, flags); -} - -static enum dma_status xilinx_tx_status(struct dma_chan *dchan, - dma_cookie_t cookie, - struct dma_tx_state *txstate) -{ - struct xilinx_vdma_chan *chan = to_xilinx_chan(dchan); - dma_cookie_t last_used; - dma_cookie_t last_complete; - - xilinx_chan_desc_cleanup(chan); - - last_used = dchan->cookie; - last_complete = chan->completed_cookie; - - dma_set_tx_state(txstate, last_complete, last_used, 0); - - return dma_async_is_complete(cookie, last_complete, last_used); -} - -static int dma_is_running(struct xilinx_vdma_chan *chan) -{ - return !(VDMA_IN(&chan->regs->sr) & XILINX_VDMA_SR_HALTED_MASK) && - (VDMA_IN(&chan->regs->cr) & XILINX_VDMA_CR_RUNSTOP_MASK); -} - -static int dma_is_idle(struct xilinx_vdma_chan *chan) -{ - return VDMA_IN(&chan->regs->sr) & XILINX_VDMA_SR_IDLE_MASK; -} - -#define XILINX_VDMA_DRIVER_DEBUG 0 - -#if (XILINX_VDMA_DRIVER_DEBUG == 1) -static void desc_dump(struct xilinx_vdma_desc_hw *hw) -{ - pr_info("hw desc %x:\n", (unsigned int)hw); - pr_info("\tnext_desc %x\n", hw->next_desc); - pr_info("\tbuf_addr %x\n", hw->buf_addr); - pr_info("\tvsize %x\n", hw->vsize); - pr_info("\thsize %x\n", hw->hsize); - pr_info("\tstride %x\n", hw->stride); - pr_info("\tstatus %x\n", hw->status); - -} -#endif - -/* Stop the hardware, the ongoing transfer will be finished */ -static void vdma_halt(struct xilinx_vdma_chan *chan) -{ - int loop = XILINX_VDMA_HALT_LOOP; - - VDMA_OUT(&chan->regs->cr, - VDMA_IN(&chan->regs->cr) & ~XILINX_VDMA_CR_RUNSTOP_MASK); - - /* Wait for the hardware to halt */ - while (loop) { - if (!(VDMA_IN(&chan->regs->cr) & XILINX_VDMA_CR_RUNSTOP_MASK)) - break; - - loop -= 1; - } - - if (!loop) { - pr_debug("Cannot stop channel %x: %x\n", - (unsigned int)chan, - (unsigned int)VDMA_IN(&chan->regs->cr)); - chan->err = 1; - } - - return; -} - -/* Start the hardware. Transfers are not started yet */ -static void vdma_start(struct xilinx_vdma_chan *chan) -{ - int loop = XILINX_VDMA_HALT_LOOP; - - VDMA_OUT(&chan->regs->cr, - VDMA_IN(&chan->regs->cr) | XILINX_VDMA_CR_RUNSTOP_MASK); - - /* Wait for the hardware to start */ - while (loop) { - if (VDMA_IN(&chan->regs->cr) & XILINX_VDMA_CR_RUNSTOP_MASK) - break; - - loop -= 1; - } - - if (!loop) { - pr_debug("Cannot start channel %x: %x\n", - (unsigned int)chan, - (unsigned int)VDMA_IN(&chan->regs->cr)); - - chan->err = 1; - } - - return; -} - -static void xilinx_vdma_start_transfer(struct xilinx_vdma_chan *chan) -{ - unsigned long flags; - struct xilinx_vdma_desc_sw *desch, *desct = NULL; - struct xilinx_vdma_config *config; - u32 reg; - u8 *chan_base; - - if (chan->err) - return; - - spin_lock_irqsave(&chan->lock, flags); - - if (list_empty(&chan->pending_list)) - goto out_unlock; - - /* If it is SG mode and hardware is busy, cannot submit */ - if (chan->has_SG && dma_is_running(chan) && !dma_is_idle(chan)) { - dev_dbg(chan->dev, "DMA controller still busy\n"); - goto out_unlock; - } - - /* - * If hardware is idle, then all descriptors on the running lists are - * done, start new transfers - */ - if (chan->err) - goto out_unlock; - - if (chan->has_SG) { - desch = list_first_entry(&chan->pending_list, - struct xilinx_vdma_desc_sw, node); - - desct = container_of(chan->pending_list.prev, - struct xilinx_vdma_desc_sw, node); - - VDMA_OUT(&chan->regs->cdr, desch->async_tx.phys); - } - - /* Configure the hardware using info in the config structure */ - config = &(chan->config); - reg = VDMA_IN(&chan->regs->cr); - - if (config->frm_cnt_en) - reg |= XILINX_VDMA_FRMCNT_EN; - else - reg &= ~XILINX_VDMA_FRMCNT_EN; - - /* - * With SG, start with circular mode, so that BDs can be fetched. - * In direct register mode, if not parking, enable circular mode - */ - if ((chan->has_SG) || (!config->park)) - reg |= XILINX_VDMA_CIRC_EN; - - if (config->park) - reg &= ~XILINX_VDMA_CIRC_EN; - - VDMA_OUT(&chan->regs->cr, reg); - - if (config->park && (config->park_frm >= 0) - && (config->park_frm < chan->num_frms)) { - if (config->direction == DMA_MEM_TO_DEV) { - chan_base = (char *)chan->regs; - VDMA_OUT((chan_base + XILINX_VDMA_PARK_REG_OFFSET), - config->park_frm); - } else { - chan_base = ((char *)chan->regs - - XILINX_VDMA_RX_CHANNEL_OFFSET); - VDMA_OUT((chan_base + XILINX_VDMA_PARK_REG_OFFSET), - config->park_frm << XILINX_VDMA_WR_REF_SHIFT); - } - } - - /* Start the hardware */ - vdma_start(chan); - - if (chan->err) - goto out_unlock; - list_splice_tail_init(&chan->pending_list, &chan->active_list); - - /* - * Enable interrupts - * park/genlock testing does not use interrupts - */ - if (!chan->config.disable_intr) { - VDMA_OUT(&chan->regs->cr, - VDMA_IN(&chan->regs->cr) | - XILINX_VDMA_XR_IRQ_ALL_MASK); - } else { - VDMA_OUT(&chan->regs->cr, - (VDMA_IN(&chan->regs->cr) | - XILINX_VDMA_XR_IRQ_ALL_MASK) & - ~((chan->config.disable_intr << - XILINX_VDMA_IRQ_SHIFT))); - } - - /* Start the transfer */ - if (chan->has_SG) - VDMA_OUT(&chan->regs->tdr, desct->async_tx.phys); - else - VDMA_OUT(&chan->addr_regs->vsize, config->vsize); - -out_unlock: - spin_unlock_irqrestore(&chan->lock, flags); -} - -static void xilinx_vdma_issue_pending(struct dma_chan *dchan) -{ - struct xilinx_vdma_chan *chan = to_xilinx_chan(dchan); - - xilinx_vdma_start_transfer(chan); -} - -/** - * xilinx_vdma_update_completed_cookie - Update the completed cookie. - * @chan : xilinx DMA channel - * - * CONTEXT: hardirq - */ -static void xilinx_vdma_update_completed_cookie(struct xilinx_vdma_chan *chan) -{ - struct xilinx_vdma_desc_sw *desc = NULL; - unsigned long flags; - dma_cookie_t cookie = -EBUSY; - int done = 0; - - spin_lock_irqsave(&chan->lock, flags); - - if (list_empty(&chan->active_list)) { - dev_dbg(chan->dev, "no running descriptors\n"); - goto out_unlock; - } - - /* Get the last completed descriptor, update the cookie to that */ - list_for_each_entry(desc, &chan->active_list, node) { - /* In non-SG mode, all active entries are done */ - done = 1; - cookie = desc->async_tx.cookie; - } - - if (done) - chan->completed_cookie = cookie; - -out_unlock: - spin_unlock_irqrestore(&chan->lock, flags); -} - -/* Reset hardware */ -static int vdma_init(struct xilinx_vdma_chan *chan) -{ - int loop = XILINX_VDMA_RESET_LOOP; - u32 tmp; - - VDMA_OUT(&chan->regs->cr, - VDMA_IN(&chan->regs->cr) | XILINX_VDMA_CR_RESET_MASK); - - tmp = VDMA_IN(&chan->regs->cr) & XILINX_VDMA_CR_RESET_MASK; - - /* Wait for the hardware to finish reset */ - while (loop && tmp) { - tmp = VDMA_IN(&chan->regs->cr) & XILINX_VDMA_CR_RESET_MASK; - loop -= 1; - } - - if (!loop) { - dev_err(chan->dev, "reset timeout, cr %x, sr %x\n", - VDMA_IN(&chan->regs->cr), VDMA_IN(&chan->regs->sr)); - return 1; - } - - return 0; -} - - -static irqreturn_t vdma_intr_handler(int irq, void *data) -{ - struct xilinx_vdma_chan *chan = data; - int update_cookie = 0; - int to_transfer = 0; - u32 stat, reg; - - reg = VDMA_IN(&chan->regs->cr); - - /* Disable intr */ - VDMA_OUT(&chan->regs->cr, - reg & ~XILINX_VDMA_XR_IRQ_ALL_MASK); - - stat = VDMA_IN(&chan->regs->sr); - if (!(stat & XILINX_VDMA_XR_IRQ_ALL_MASK)) - return IRQ_NONE; - - /* Ack the interrupts */ - VDMA_OUT(&chan->regs->sr, XILINX_VDMA_XR_IRQ_ALL_MASK); - - /* Check for only the interrupts which are enabled */ - stat &= (reg & XILINX_VDMA_XR_IRQ_ALL_MASK); - - if (stat & XILINX_VDMA_XR_IRQ_ERROR_MASK) { - if (chan->flush_fsync) { - /* - * VDMA Recoverable Errors, only when - * C_FLUSH_ON_FSYNC is enabled - */ - u32 error = VDMA_IN(&chan->regs->sr) & - XILINX_VDMA_SR_ERR_RECOVER_MASK; - if (error) - VDMA_OUT(&chan->regs->sr, error); - else - chan->err = 1; - } else { - dev_err(chan->dev, - "Channel %x has errors %x, cdr %x tdr %x\n", - (unsigned int)chan, - (unsigned int)VDMA_IN(&chan->regs->sr), - (unsigned int)VDMA_IN(&chan->regs->cdr), - (unsigned int)VDMA_IN(&chan->regs->tdr)); - chan->err = 1; - } - } - - /* - * Device takes too long to do the transfer when user requires - * responsiveness - */ - if (stat & XILINX_VDMA_XR_IRQ_DELAY_MASK) - dev_dbg(chan->dev, "Inter-packet latency too long\n"); - - if (stat & XILINX_VDMA_XR_IRQ_IOC_MASK) { - update_cookie = 1; - to_transfer = 1; - } - - if (update_cookie) - xilinx_vdma_update_completed_cookie(chan); - - if (to_transfer) - chan->start_transfer(chan); - - tasklet_schedule(&chan->tasklet); - return IRQ_HANDLED; -} - -static void dma_do_tasklet(unsigned long data) -{ - struct xilinx_vdma_chan *chan = (struct xilinx_vdma_chan *)data; - - xilinx_chan_desc_cleanup(chan); -} - -/* Append the descriptor list to the pending list */ -static void append_desc_queue(struct xilinx_vdma_chan *chan, - struct xilinx_vdma_desc_sw *desc) -{ - struct xilinx_vdma_desc_sw *tail = container_of(chan->pending_list.prev, - struct xilinx_vdma_desc_sw, node); - struct xilinx_vdma_desc_hw *hw; - - if (list_empty(&chan->pending_list)) - goto out_splice; - - /* - * Add the hardware descriptor to the chain of hardware descriptors - * that already exists in memory. - */ - hw = &(tail->hw); - hw->next_desc = (u32)desc->async_tx.phys; - - /* - * Add the software descriptor and all children to the list - * of pending transactions - */ -out_splice: - list_splice_tail_init(&desc->tx_list, &chan->pending_list); -} - -/* - * Assign cookie to each descriptor, and append the descriptors to the pending - * list - */ -static dma_cookie_t xilinx_vdma_tx_submit(struct dma_async_tx_descriptor *tx) -{ - struct xilinx_vdma_chan *chan = to_xilinx_chan(tx->chan); - struct xilinx_vdma_desc_sw *desc = container_of(tx, - struct xilinx_vdma_desc_sw, async_tx); - struct xilinx_vdma_desc_sw *child; - unsigned long flags; - dma_cookie_t cookie = -EBUSY; - - if (chan->err) { - /* - * If reset fails, need to hard reset the system. - * Channel is no longer functional - */ - if (!vdma_init(chan)) - chan->err = 0; - else - return cookie; - } - - spin_lock_irqsave(&chan->lock, flags); - - /* - * assign cookies to all of the software descriptors - * that make up this transaction - */ - cookie = chan->cookie; - list_for_each_entry(child, &desc->tx_list, node) { - cookie++; - if (cookie < 0) - cookie = DMA_MIN_COOKIE; - - child->async_tx.cookie = cookie; - } - - chan->cookie = cookie; - - /* Put this transaction onto the tail of the pending queue */ - append_desc_queue(chan, desc); - - spin_unlock_irqrestore(&chan->lock, flags); - - return cookie; -} - -static struct xilinx_vdma_desc_sw *xilinx_vdma_alloc_descriptor( - struct xilinx_vdma_chan *chan) -{ - struct xilinx_vdma_desc_sw *desc; - dma_addr_t pdesc; - - desc = dma_pool_alloc(chan->desc_pool, GFP_ATOMIC, &pdesc); - if (!desc) { - dev_dbg(chan->dev, "out of memory for desc\n"); - return NULL; - } - - memset(desc, 0, sizeof(*desc)); - INIT_LIST_HEAD(&desc->tx_list); - dma_async_tx_descriptor_init(&desc->async_tx, &chan->common); - desc->async_tx.tx_submit = xilinx_vdma_tx_submit; - desc->async_tx.phys = pdesc; - - return desc; -} - -/** - * xilinx_vdma_prep_slave_sg - prepare descriptors for a DMA_SLAVE transaction - * @chan: VDMA channel - * @sgl: scatterlist to transfer to/from - * @sg_len: number of entries in @scatterlist - * @direction: DMA direction - * @flags: transfer ack flags - */ -static struct dma_async_tx_descriptor *xilinx_vdma_prep_slave_sg( - struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len, - enum dma_transfer_direction direction, unsigned long flags, - void *context) -{ - struct xilinx_vdma_chan *chan; - struct xilinx_vdma_desc_sw *first = NULL, *prev = NULL, *new = NULL; - struct xilinx_vdma_desc_hw *hw = NULL, *prev_hw = NULL; - int i; - struct scatterlist *sg; - dma_addr_t dma_src; - - if (!dchan) - return NULL; - - chan = to_xilinx_chan(dchan); - - if (chan->direction != direction) - return NULL; - - /* Enforce one sg entry for one frame */ - if (sg_len != chan->num_frms) { - dev_err(chan->dev, - "number of entries %d not the same as num stores %d\n", - sg_len, chan->num_frms); - - return NULL; - } - - if (!chan->has_SG) { - VDMA_OUT(&chan->addr_regs->hsize, chan->config.hsize); - VDMA_OUT(&chan->addr_regs->frmdly_stride, - chan->config.frm_dly << XILINX_VDMA_FRMDLY_SHIFT | - chan->config.stride); - } - - /* Build transactions using information in the scatter gather list */ - for_each_sg(sgl, sg, sg_len, i) { - /* Allocate the link descriptor from DMA pool */ - new = xilinx_vdma_alloc_descriptor(chan); - if (!new) { - dev_err(chan->dev, - "No free memory for link descriptor\n"); - goto fail; - } - - /* - * Calculate the maximum number of bytes to transfer, - * making sure it is less than the hw limit - */ - hw = &(new->hw); - - dma_src = sg_dma_address(sg); - if (chan->has_SG) { - hw->buf_addr = dma_src; - - /* Fill in the descriptor */ - hw->vsize = chan->config.vsize; - hw->hsize = chan->config.hsize; - hw->stride = (chan->config.frm_dly << - XILINX_VDMA_FRMDLY_SHIFT) | - chan->config.stride; - } else { - /* Update the registers */ - VDMA_OUT(&(chan->addr_regs->buf_addr[i]), dma_src); - } - - /* - * If this is not the first descriptor, chain the - * current descriptor after the previous descriptor - */ - if (!first) { - first = new; - } else { - prev_hw = &(prev->hw); - prev_hw->next_desc = new->async_tx.phys; - } - - new->async_tx.cookie = 0; - async_tx_ack(&new->async_tx); - - prev = new; - - /* Insert the link descriptor into the list */ - list_add_tail(&new->node, &first->tx_list); - } - - /* Link the last BD with the first BD */ - hw->next_desc = first->async_tx.phys; - - if (!first || !new) - return NULL; - - new->async_tx.flags = flags; - new->async_tx.cookie = -EBUSY; - - return &first->async_tx; - -fail: - /* - * If first was not set, then we failed to allocate the very first - * descriptor, and we're done */ - if (!first) - return NULL; - - /* - * First is set, so all of the descriptors we allocated have been added - * to first->tx_list, INCLUDING "first" itself. Therefore we - * must traverse the list backwards freeing each descriptor in turn - */ - xilinx_vdma_free_desc_list_reverse(chan, &first->tx_list); - return NULL; -} - -/* - * Run-time configuration for Axi VDMA, supports: - * . halt the channel - * . configure interrupt coalescing and inter-packet delay threshold - * . start/stop parking - * . enable genlock - * . set transfer information using config struct - */ -static int xilinx_vdma_device_control(struct dma_chan *dchan, - enum dma_ctrl_cmd cmd, unsigned long arg) -{ - struct xilinx_vdma_chan *chan; - unsigned long flags; - - if (!dchan) - return -EINVAL; - - chan = to_xilinx_chan(dchan); - - if (cmd == DMA_TERMINATE_ALL) { - /* Halt the DMA engine */ - vdma_halt(chan); - - spin_lock_irqsave(&chan->lock, flags); - - /* Remove and free all of the descriptors in the lists */ - xilinx_vdma_free_desc_list(chan, &chan->pending_list); - xilinx_vdma_free_desc_list(chan, &chan->active_list); - - spin_unlock_irqrestore(&chan->lock, flags); - return 0; - } else if (cmd == DMA_SLAVE_CONFIG) { - struct xilinx_vdma_config *cfg = - (struct xilinx_vdma_config *)arg; - u32 reg; - - if (cfg->reset) - vdma_init(chan); - - reg = VDMA_IN(&chan->regs->cr); - - /* If vsize is -1, it is park-related operations */ - if (cfg->vsize == -1) { - if (cfg->park) - reg &= ~XILINX_VDMA_CIRC_EN; - else - reg |= XILINX_VDMA_CIRC_EN; - - VDMA_OUT(&chan->regs->cr, reg); - return 0; - } - - /* If hsize is -1, it is interrupt threshold settings */ - if (cfg->hsize == -1) { - if (cfg->coalesc <= XILINX_VDMA_COALESCE_MAX) { - reg &= ~XILINX_VDMA_XR_COALESCE_MASK; - reg |= cfg->coalesc << - XILINX_VDMA_COALESCE_SHIFT; - chan->config.coalesc = cfg->coalesc; - } - - if (cfg->delay <= XILINX_VDMA_DELAY_MAX) { - reg &= ~XILINX_VDMA_XR_DELAY_MASK; - reg |= cfg->delay << XILINX_VDMA_DELAY_SHIFT; - chan->config.delay = cfg->delay; - } - - VDMA_OUT(&chan->regs->cr, reg); - return 0; - } - - /* Transfer information */ - chan->config.vsize = cfg->vsize; - chan->config.hsize = cfg->hsize; - chan->config.stride = cfg->stride; - chan->config.frm_dly = cfg->frm_dly; - chan->config.park = cfg->park; - chan->config.direction = cfg->direction; - - /* genlock settings */ - chan->config.gen_lock = cfg->gen_lock; - chan->config.master = cfg->master; - - if (cfg->gen_lock) { - if (chan->genlock) { - reg |= XILINX_VDMA_SYNC_EN; - reg |= cfg->master << XILINX_VDMA_MSTR_SHIFT; - } - } - - chan->config.frm_cnt_en = cfg->frm_cnt_en; - if (cfg->park) - chan->config.park_frm = cfg->park_frm; - else - chan->config.park_frm = -1; - - chan->config.coalesc = cfg->coalesc; - chan->config.delay = cfg->delay; - if (cfg->coalesc <= XILINX_VDMA_COALESCE_MAX) { - reg |= cfg->coalesc << XILINX_VDMA_COALESCE_SHIFT; - chan->config.coalesc = cfg->coalesc; - } - - if (cfg->delay <= XILINX_VDMA_DELAY_MAX) { - reg |= cfg->delay << XILINX_VDMA_DELAY_SHIFT; - chan->config.delay = cfg->delay; - } - - chan->config.disable_intr = cfg->disable_intr; - - if (cfg->ext_fsync) - reg |= cfg->ext_fsync << XILINX_VDMA_EXTFSYNC_SHIFT; - - VDMA_OUT(&chan->regs->cr, reg); - return 0; - } else - return -ENXIO; -} - - -/* - * Logarithm function to compute alignment shift - * Only deals with value less than 4096. - */ -static int my_log(int value) -{ - int i = 0; - while ((1 << i) < value) { - i++; - - if (i >= 12) - return 0; - } - - return i; -} - -static void xilinx_vdma_chan_remove(struct xilinx_vdma_chan *chan) -{ - irq_dispose_mapping(chan->irq); - list_del(&chan->common.device_node); - kfree(chan); -} - -/* - * Probing channels - * - * . Get channel features from the device tree entry - * . Initialize special channel handling routines - */ -static int __devinit xilinx_vdma_chan_probe(struct xilinx_vdma_device *xdev, - struct device_node *node, u32 feature) -{ - struct xilinx_vdma_chan *chan; - int err; - const __be32 *value; - u32 width = 0, device_id = 0, flush_fsync = 0; - - /* Alloc channel */ - chan = kzalloc(sizeof(*chan), GFP_KERNEL); - if (!chan) { - dev_err(xdev->dev, "no free memory for DMA channels!\n"); - err = -ENOMEM; - goto out_return; - } - - chan->feature = feature; - chan->is_lite = 0; - chan->has_DRE = 0; - chan->has_SG = 0; - chan->max_len = XILINX_VDMA_MAX_TRANS_LEN; - - value = of_get_property(node, "xlnx,include-dre", NULL); - if (value) - chan->has_DRE = be32_to_cpup(value); - - value = (int *)of_get_property(node, "xlnx,genlock-mode", NULL); - if (value) - chan->genlock = be32_to_cpup(value); - - value = (int *)of_get_property(node, "xlnx,datawidth", NULL); - if (value) { - width = be32_to_cpup(value) >> 3; /* Convert bits to bytes */ - - /* If data width is greater than 8 bytes, DRE is not in hw */ - if (width > 8) - chan->has_DRE = 0; - - chan->feature |= width - 1; - } - - value = (int *)of_get_property(node, "xlnx,device-id", NULL); - if (value) - device_id = be32_to_cpup(value); - - flush_fsync = (xdev->feature & XILINX_VDMA_FTR_FLUSH_MASK) >> - XILINX_VDMA_FTR_FLUSH_SHIFT; - - chan->start_transfer = xilinx_vdma_start_transfer; - - chan->has_SG = (xdev->feature & XILINX_VDMA_FTR_HAS_SG) >> - XILINX_VDMA_FTR_HAS_SG_SHIFT; - - if (of_device_is_compatible(node, - "xlnx,axi-vdma-mm2s-channel")) { - chan->direction = DMA_MEM_TO_DEV; - if (!chan->has_SG) { - chan->addr_regs = (struct vdma_addr_regs *) - ((u32)xdev->regs + - XILINX_VDMA_DIRECT_REG_OFFSET); - } - - if (flush_fsync == XILINX_VDMA_FLUSH_BOTH || - flush_fsync == XILINX_VDMA_FLUSH_MM2S) - chan->flush_fsync = 1; - } - - if (of_device_is_compatible(node, "xlnx,axi-vdma-s2mm-channel")) { - chan->direction = DMA_DEV_TO_MEM; - if (!chan->has_SG) { - chan->addr_regs = (struct vdma_addr_regs *) - ((u32)xdev->regs + - XILINX_VDMA_DIRECT_REG_OFFSET + - XILINX_VDMA_CHAN_DIRECT_REG_SIZE); - } - - if (flush_fsync == XILINX_VDMA_FLUSH_BOTH || - flush_fsync == XILINX_VDMA_FLUSH_S2MM) - chan->flush_fsync = 1; - } - - chan->regs = (struct xvdma_regs *)xdev->regs; - chan->id = 0; - - if (chan->direction == DMA_DEV_TO_MEM) { - chan->regs = (struct xvdma_regs *)((u32)xdev->regs + - XILINX_VDMA_RX_CHANNEL_OFFSET); - chan->id = 1; - } - - /* - * Used by dmatest channel matching in slave transfers - * Can change it to be a structure to have more matching information - */ - chan->private = (chan->direction & 0xFF) | - (chan->feature & XILINX_DMA_IP_MASK) | - (device_id << XILINX_VDMA_DEVICE_ID_SHIFT); - chan->common.private = (void *)&(chan->private); - - if (!chan->has_DRE) - xdev->common.copy_align = my_log(width); - - chan->dev = xdev->dev; - xdev->chan[chan->id] = chan; - - tasklet_init(&chan->tasklet, dma_do_tasklet, (unsigned long)chan); - - /* Initialize the channel */ - if (vdma_init(chan)) { - dev_err(xdev->dev, "Reset channel failed\n"); - goto out_free_chan; - } - - spin_lock_init(&chan->lock); - INIT_LIST_HEAD(&chan->pending_list); - INIT_LIST_HEAD(&chan->active_list); - - chan->common.device = &xdev->common; - - /* Find the IRQ line, if it exists in the device tree */ - chan->irq = irq_of_parse_and_map(node, 0); - err = request_irq(chan->irq, vdma_intr_handler, IRQF_SHARED, - "xilinx-vdma-controller", chan); - if (err) { - dev_err(xdev->dev, "unable to request IRQ\n"); - goto out_free_irq; - } - - /* Add the channel to DMA device channel list */ - list_add_tail(&chan->common.device_node, &xdev->common.channels); - xdev->common.chancnt++; - - return 0; - -out_free_irq: - irq_dispose_mapping(chan->irq); -out_free_chan: - kfree(chan); -out_return: - return err; -} - -static int __devinit xilinx_vdma_of_probe(struct platform_device *op) -{ - struct xilinx_vdma_device *xdev; - struct device_node *child, *node; - int err, i; - int *value; - int num_frames = 0; - - dev_info(&op->dev, "Probing xilinx axi vdma engine\n"); - - xdev = kzalloc(sizeof(struct xilinx_vdma_device), GFP_KERNEL); - if (!xdev) { - dev_err(&op->dev, "Not enough memory for device\n"); - err = -ENOMEM; - goto out_return; - } - - xdev->dev = &(op->dev); - INIT_LIST_HEAD(&xdev->common.channels); - - node = op->dev.of_node; - xdev->feature = 0; - - /* iomap registers */ - xdev->regs = of_iomap(node, 0); - if (!xdev->regs) { - dev_err(&op->dev, "unable to iomap registers\n"); - err = -ENOMEM; - goto out_free_xdev; - } - - /* Axi VDMA only do slave transfers */ - if (of_device_is_compatible(node, "xlnx,axi-vdma")) { - xdev->feature |= XILINX_DMA_IP_VDMA; - - value = (int *)of_get_property(node, "xlnx,include-sg", - NULL); - if (value) { - if (be32_to_cpup(value) == 1) - xdev->feature |= XILINX_VDMA_FTR_HAS_SG; - } - - value = (int *)of_get_property(node, "xlnx,num-fstores", - NULL); - if (value) - num_frames = be32_to_cpup(value); - - value = (int *)of_get_property(node, "xlnx,flush-fsync", NULL); - if (value) - xdev->feature |= be32_to_cpup(value) << - XILINX_VDMA_FTR_FLUSH_SHIFT; - - dma_cap_set(DMA_SLAVE, xdev->common.cap_mask); - dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask); - xdev->common.device_prep_slave_sg = xilinx_vdma_prep_slave_sg; - xdev->common.device_control = xilinx_vdma_device_control; - xdev->common.device_issue_pending = xilinx_vdma_issue_pending; - } - - xdev->common.device_alloc_chan_resources = - xilinx_vdma_alloc_chan_resources; - xdev->common.device_free_chan_resources = - xilinx_vdma_free_chan_resources; - xdev->common.device_tx_status = xilinx_tx_status; - xdev->common.dev = &op->dev; - - dev_set_drvdata(&op->dev, xdev); - - for_each_child_of_node(node, child) { - xilinx_vdma_chan_probe(xdev, child, xdev->feature); - } - - for (i = 0; i < XILINX_VDMA_MAX_CHANS_PER_DEVICE; i++) { - if (xdev->chan[i]) - xdev->chan[i]->num_frms = num_frames; - } - - dma_async_device_register(&xdev->common); - - return 0; - -out_free_xdev: - kfree(xdev); - -out_return: - return err; -} - -static int __devexit xilinx_vdma_of_remove(struct platform_device *op) -{ - struct xilinx_vdma_device *xdev; - int i; - - xdev = dev_get_drvdata(&op->dev); - dma_async_device_unregister(&xdev->common); - - for (i = 0; i < XILINX_VDMA_MAX_CHANS_PER_DEVICE; i++) { - if (xdev->chan[i]) - xilinx_vdma_chan_remove(xdev->chan[i]); - } - - iounmap(xdev->regs); - dev_set_drvdata(&op->dev, NULL); - kfree(xdev); - - return 0; -} - -static const struct of_device_id xilinx_vdma_of_ids[] = { - { .compatible = "xlnx,axi-vdma",}, - {} -}; - -static struct platform_driver xilinx_vdma_of_driver = { - .driver = { - .name = "xilinx-vdma", - .owner = THIS_MODULE, - .of_match_table = xilinx_vdma_of_ids, - }, - .probe = xilinx_vdma_of_probe, - .remove = __devexit_p(xilinx_vdma_of_remove), -}; - -module_platform_driver(xilinx_vdma_of_driver); - -MODULE_AUTHOR("Xilinx, Inc."); -MODULE_DESCRIPTION("Xilinx VDMA driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/dma/xilinx_dma.c b/drivers/dma/xilinx_dma.c index 055fe9d44ccb9..8888c00e6f837 100644 --- a/drivers/dma/xilinx_dma.c +++ b/drivers/dma/xilinx_dma.c @@ -2,13 +2,13 @@ * Xilinx DMA Engine support * * Copyright (C) 2010 Xilinx, Inc. All rights reserved. + * Copyright (C) 2012 Analog Device Inc. + * Author: Lars-Peter Clausen * * Based on the Freescale DMA driver. * * Description: * This driver supports three Xilinx DMA engines: - * . Axi CDMA engine, it does transfers between memory and memory, it - * only has one channel. * . Axi DMA engine, it does transfers between memory and device. It can be * configured to have one channel or two channels. If configured as two * channels, one is to transmit to a device and another is to receive from @@ -25,6 +25,7 @@ * */ + #include #include #include @@ -32,11 +33,15 @@ #include #include #include +#include #include #include #include #include -#include +#include +#include + +#include "dmaengine.h" /* Hw specific definitions */ @@ -67,7 +72,6 @@ #define XILINX_DMA_XR_DELAY_MASK 0xFF000000 /* Delay timeout counter */ #define XILINX_DMA_XR_COALESCE_MASK 0x00FF0000 /* Coalesce counter */ -#define XILINX_DMA_IRQ_SHIFT 12 #define XILINX_DMA_DELAY_SHIFT 24 #define XILINX_DMA_COALESCE_SHIFT 16 @@ -76,13 +80,6 @@ #define XILINX_DMA_RX_CHANNEL_OFFSET 0x30 -/* Axi CDMA special register bits - */ -#define XILINX_CDMA_CR_SGMODE_MASK 0x00000008 /**< Scatter gather mode */ - -#define XILINX_CDMA_SR_SGINCLD_MASK 0x00000008 /**< Hybrid build */ -#define XILINX_CDMA_XR_IRQ_SIMPLE_ALL_MASK 0x00005000 /**< All interrupts for - simple only mode */ /* Axi VDMA special register bits */ #define XILINX_VDMA_CIRC_EN 0x00000002 /* Circular mode */ @@ -90,7 +87,6 @@ #define XILINX_VDMA_FRMCNT_EN 0x00000010 /* Frm Cnt enable mode */ #define XILINX_VDMA_MSTR_MASK 0x00000F00 /* Master in control */ -#define XILINX_VDMA_EXTFSYNC_SHIFT 6 #define XILINX_VDMA_MSTR_SHIFT 8 #define XILINX_VDMA_WR_REF_SHIFT 8 @@ -99,30 +95,7 @@ #define XILINX_VDMA_DIRECT_REG_OFFSET 0x50 #define XILINX_VDMA_CHAN_DIRECT_REG_SIZE 0x50 -#define XILINX_VDMA_PARK_REG_OFFSET 0x28 - -/* Axi VDMA Specific Error bits - */ -#define XILINX_VDMA_SR_ERR_FSIZE_LESS_MASK 0x00000080 /* FSize Less - Mismatch err */ -#define XILINX_VDMA_SR_ERR_LSIZE_LESS_MASK 0x00000100 /* LSize Less - Mismatch err */ -#define XILINX_VDMA_SR_ERR_FSIZE_MORE_MASK 0x00000800 /* FSize - more err */ -/* Recoverable errors are DMA Internal error, FSize Less, LSize Less - * and FSize More mismatch errors. These are only recoverable only - * when C_FLUSH_ON_FSYNC is enabled in the hardware system. - */ -#define XILINX_VDMA_SR_ERR_RECOVER_MASK 0x00000990 /* Recoverable - errs */ - -/* Axi VDMA Flush on Fsync bits - */ -#define XILINX_VDMA_FLUSH_S2MM 3 -#define XILINX_VDMA_FLUSH_MM2S 2 -#define XILINX_VDMA_FLUSH_BOTH 1 - -/* BD definitions for Axi Dma and Axi Cdma +/* BD definitions for Axi DMA */ #define XILINX_DMA_BD_STS_COMPL_MASK 0x80000000 #define XILINX_DMA_BD_STS_ERR_MASK 0x70000000 @@ -150,10 +123,6 @@ #define XILINX_DMA_RESET_LOOP 1000000 #define XILINX_DMA_HALT_LOOP 1000000 -/* Device Id in the private structure - */ -#define XILINX_DMA_DEVICE_ID_SHIFT 28 - /* IO accessors */ #define DMA_OUT(addr, val) (iowrite32(val, addr)) @@ -177,14 +146,24 @@ struct xilinx_dma_desc_hw { u32 app_2; /* 0x28 */ u32 app_3; /* 0x2C */ u32 app_4; /* 0x30 */ -} __attribute__((aligned(64))); +} __aligned(64); struct xilinx_dma_desc_sw { - struct xilinx_dma_desc_hw hw; - struct list_head node; - struct list_head tx_list; + struct xilinx_dma_desc_hw *hw; + dma_addr_t phys; +}; + +struct xilinx_dma_transfer { struct dma_async_tx_descriptor async_tx; -} __attribute__((aligned(64))); + struct list_head head; + + bool cyclic; + unsigned int completed_descs; + + unsigned int current_desc; + unsigned int num_descs; + struct xilinx_dma_desc_sw descs[]; +}; struct xdma_regs { u32 cr; /* 0x00 Control Register */ @@ -201,6 +180,20 @@ struct xdma_regs { u32 version; /* 0x2c version (vdma) */ }; +static struct debugfs_reg32 xilinx_dma_debugfs_regs[] = { + { "Control", 0x00 }, + { "Status", 0x04 }, + { "Current descriptor", 0x08 }, + { "Tail descriptor", 0x10 }, + { "Vertical size", 0x50 }, + { "Horizontal size", 0x54 }, + { "Frame delay/stride", 0x58 }, + { "Frame address 0", 0x5c }, + { "Frame address 1", 0x60 }, + { "Frame address 2", 0x64 }, + { "Frame address 3", 0x68 }, +}; + struct vdma_addr_regs { u32 vsize; /* 0x0 Vertical size */ u32 hsize; /* 0x4 Horizontal size */ @@ -213,12 +206,10 @@ struct vdma_addr_regs { struct xilinx_dma_chan { struct xdma_regs __iomem *regs; /* Control status registers */ struct vdma_addr_regs *addr_regs; /* Direct address registers */ - dma_cookie_t completed_cookie; /* The maximum cookie completed */ - dma_cookie_t cookie; /* The current cookie */ spinlock_t lock; /* Descriptor operation lock */ - bool sg_waiting; /* Scatter gather transfer waiting */ struct list_head active_list; /* Active descriptors */ struct list_head pending_list; /* Descriptors waiting */ + struct list_head removed_list; /* Descriptors queued for removal */ struct dma_chan common; /* DMA common channel */ struct dma_pool *desc_pool; /* Descriptors pool */ struct device *dev; /* The dma device */ @@ -226,7 +217,6 @@ struct xilinx_dma_chan { int id; /* Channel ID */ enum dma_transfer_direction direction;/* Transfer direction */ int max_len; /* Maximum data len per transfer */ - int is_lite; /* Whether is light build */ int num_frms; /* Number of frames */ int has_SG; /* Support scatter transfers */ int has_DRE; /* Support unaligned transfers */ @@ -234,10 +224,11 @@ struct xilinx_dma_chan { int err; /* Channel has errors */ struct tasklet_struct tasklet; /* Cleanup work after irq */ u32 feature; /* IP feature */ - u32 private; /* Match info for channel request */ void (*start_transfer)(struct xilinx_dma_chan *chan); struct xilinx_dma_config config; /* Device configuration info */ - u32 flush_fsync; /* Flush on Fsync */ + + bool cyclic; + struct debugfs_regset32 debugfs_regset; }; struct xilinx_dma_device { @@ -249,8 +240,84 @@ struct xilinx_dma_device { int irq; }; +static dma_cookie_t xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx); + #define to_xilinx_chan(chan) container_of(chan, struct xilinx_dma_chan, common) +static void xilinx_dma_free_transfer(struct xilinx_dma_chan *chan, + struct xilinx_dma_transfer *t) +{ + unsigned int i; + for (i = 0; i < t->num_descs; ++i) + dma_pool_free(chan->desc_pool, t->descs[i].hw, t->descs[i].phys); + kfree(t); +} + +static struct xilinx_dma_transfer *xilinx_dma_alloc_transfer( + struct xilinx_dma_chan *chan, unsigned int num_descs) +{ + struct xilinx_dma_desc_hw *new, *prev; + struct xilinx_dma_transfer *t; + dma_addr_t phys; + + if (num_descs == 0) + return NULL; + + t = kzalloc(sizeof(*t) + num_descs * sizeof(*t->descs), GFP_ATOMIC); + if (!t) + return NULL; + + dma_async_tx_descriptor_init(&t->async_tx, &chan->common); + t->async_tx.tx_submit = xilinx_dma_tx_submit; + t->async_tx.cookie = -EBUSY; + + prev = NULL; + new = NULL; + for (; t->num_descs < num_descs; t->num_descs++) { + new = dma_pool_alloc(chan->desc_pool, GFP_ATOMIC, &phys); + if (!new) { + dev_err(chan->dev, "No free memory for link descriptor\n"); + goto err_free; + } + memset(new, 0, sizeof(*new)); + + if (prev) + prev->next_desc = phys; + + t->descs[t->num_descs].hw = new; + t->descs[t->num_descs].phys = phys; + prev = new; + } + + /* Link the last BD with the first BD */ + new->next_desc = t->descs[0].phys; + + return t; +err_free: + xilinx_dma_free_transfer(chan, t); + return NULL; +} + +static void xilinx_dma_free_transfer_list(struct xilinx_dma_chan *chan, + struct list_head *list) +{ + struct xilinx_dma_transfer *t, *_t; + list_for_each_entry_safe(t, _t, list, head) + xilinx_dma_free_transfer(chan, t); + INIT_LIST_HEAD(list); +} + +static void xilinx_dma_free_transfers(struct xilinx_dma_chan *chan) +{ + unsigned long flags; + + spin_lock_irqsave(&chan->lock, flags); + xilinx_dma_free_transfer_list(chan, &chan->active_list); + xilinx_dma_free_transfer_list(chan, &chan->pending_list); + xilinx_dma_free_transfer_list(chan, &chan->removed_list); + spin_unlock_irqrestore(&chan->lock, flags); +} + /* Required functions */ static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan) @@ -267,141 +334,162 @@ static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan) */ chan->desc_pool = dma_pool_create("xilinx_dma_desc_pool", chan->dev, - sizeof(struct xilinx_dma_desc_sw), - __alignof__(struct xilinx_dma_desc_sw), 0); + sizeof(struct xilinx_dma_desc_hw), + __alignof__(struct xilinx_dma_desc_hw), 0); if (!chan->desc_pool) { dev_err(chan->dev, "unable to allocate channel %d " "descriptor pool\n", chan->id); return -ENOMEM; } - chan->completed_cookie = 1; - chan->cookie = 1; + dma_cookie_init(dchan); /* there is at least one descriptor free to be allocated */ return 1; } -static void xilinx_dma_free_desc_list(struct xilinx_dma_chan *chan, - struct list_head *list) -{ - struct xilinx_dma_desc_sw *desc, *_desc; - - list_for_each_entry_safe(desc, _desc, list, node) { - list_del(&desc->node); - dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys); - } -} - -static void xilinx_dma_free_desc_list_reverse(struct xilinx_dma_chan *chan, - struct list_head *list) -{ - struct xilinx_dma_desc_sw *desc, *_desc; - - list_for_each_entry_safe_reverse(desc, _desc, list, node) { - list_del(&desc->node); - dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys); - } -} - static void xilinx_dma_free_chan_resources(struct dma_chan *dchan) { struct xilinx_dma_chan *chan = to_xilinx_chan(dchan); - unsigned long flags; dev_dbg(chan->dev, "Free all channel resources.\n"); - spin_lock_irqsave(&chan->lock, flags); - xilinx_dma_free_desc_list(chan, &chan->active_list); - xilinx_dma_free_desc_list(chan, &chan->pending_list); - spin_unlock_irqrestore(&chan->lock, flags); - + xilinx_dma_free_transfers(chan); dma_pool_destroy(chan->desc_pool); chan->desc_pool = NULL; } static enum dma_status xilinx_dma_desc_status(struct xilinx_dma_chan *chan, - struct xilinx_dma_desc_sw *desc) + struct xilinx_dma_transfer *t) +{ + return dma_async_is_complete(t->async_tx.cookie, + chan->common.completed_cookie, + chan->common.cookie); +} + +static void xilinx_dma_chan_handle_cyclic(struct xilinx_dma_chan *chan, + struct xilinx_dma_transfer *t, unsigned long *flags) { - return dma_async_is_complete(desc->async_tx.cookie, - chan->completed_cookie, - chan->cookie); + unsigned int completed_descs; + dma_async_tx_callback callback; + void *callback_param; + unsigned int i; + + /* We have to be carefull not to dereference 't' anymore after a call to + * the callback function, since it might call terminate_all and as a + * result 't' might be already freed. */ + callback = t->async_tx.callback; + callback_param = t->async_tx.callback_param; + completed_descs = t->completed_descs; + t->completed_descs = 0; + + spin_unlock_irqrestore(&chan->lock, *flags); + for (i = 0; i < completed_descs; i++) + callback(callback_param); + spin_lock_irqsave(&chan->lock, *flags); } static void xilinx_chan_desc_cleanup(struct xilinx_dma_chan *chan) { - struct xilinx_dma_desc_sw *desc, *_desc; + struct xilinx_dma_transfer *t; + dma_async_tx_callback callback; + void *callback_param; unsigned long flags; spin_lock_irqsave(&chan->lock, flags); - list_for_each_entry_safe(desc, _desc, &chan->active_list, node) { - dma_async_tx_callback callback; - void *callback_param; + /* terminate_all might be called from the callback, so we can't iterate over + * the list using list_for_each_entry_safe */ + while (!list_empty(&chan->active_list)) { + t = list_first_entry(&chan->active_list, struct xilinx_dma_transfer, head); + + if (t->cyclic) { + xilinx_dma_chan_handle_cyclic(chan, t, &flags); + break; + } - if (xilinx_dma_desc_status(chan, desc) == DMA_IN_PROGRESS) + if (xilinx_dma_desc_status(chan, t) == DMA_IN_PROGRESS) break; - /* Remove from the list of running transactions */ - list_del(&desc->node); + list_del(&t->head); - /* Run the link descriptor callback function */ - callback = desc->async_tx.callback; - callback_param = desc->async_tx.callback_param; + callback = t->async_tx.callback; + callback_param = t->async_tx.callback_param; if (callback) { spin_unlock_irqrestore(&chan->lock, flags); callback(callback_param); spin_lock_irqsave(&chan->lock, flags); } - /* Run any dependencies, then free the descriptor */ - dma_run_dependencies(&desc->async_tx); - dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys); + dma_run_dependencies(&t->async_tx); + xilinx_dma_free_transfer(chan, t); } spin_unlock_irqrestore(&chan->lock, flags); } +static struct xilinx_dma_transfer *xilinx_lookup_transfer( + struct xilinx_dma_chan *chan, dma_cookie_t cookie) +{ + struct xilinx_dma_transfer *t; + + list_for_each_entry(t, &chan->active_list, head) { + if (t->async_tx.cookie == cookie) + return t; + } + + list_for_each_entry(t, &chan->pending_list, head) { + if (t->async_tx.cookie == cookie) + return t; + } + + return NULL; +} + +static unsigned int xilinx_tx_get_residue(struct xilinx_dma_transfer *t) +{ + unsigned int residue = 0; + unsigned int i; + + /* We can't get the residue with a sub-desciptor granularity, + so all we can do is to sum up the length of all non yet completed + descritors */ + for (i = t->current_desc; i < t->num_descs; i++) + residue += t->descs[i].hw->control & XILINX_DMA_MAX_TRANS_LEN; + + return residue; +} + static enum dma_status xilinx_tx_status(struct dma_chan *dchan, dma_cookie_t cookie, struct dma_tx_state *txstate) { struct xilinx_dma_chan *chan = to_xilinx_chan(dchan); - dma_cookie_t last_used; - dma_cookie_t last_complete; - - xilinx_chan_desc_cleanup(chan); + unsigned int residue = 0; + enum dma_status status; + status = dma_cookie_status(dchan, cookie, txstate); - last_used = dchan->cookie; - last_complete = chan->completed_cookie; + if (status == DMA_IN_PROGRESS) { + struct xilinx_dma_transfer *t = xilinx_lookup_transfer(chan, cookie); + if (t) + residue = xilinx_tx_get_residue(t); + } - dma_set_tx_state(txstate, last_complete, last_used, 0); + dma_set_residue(txstate, residue); - return dma_async_is_complete(cookie, last_complete, last_used); + return status; } -static int dma_is_running(struct xilinx_dma_chan *chan) +static int xilinx_dma_is_running(struct xilinx_dma_chan *chan) { - return !(DMA_IN(&chan->regs->sr) & XILINX_DMA_SR_HALTED_MASK) && + return !(DMA_IN(&chan->regs->sr) & XILINX_DMA_SR_HALTED_MASK) || (DMA_IN(&chan->regs->cr) & XILINX_DMA_CR_RUNSTOP_MASK); } -static int dma_is_idle(struct xilinx_dma_chan *chan) +static int xilinx_dma_is_idle(struct xilinx_dma_chan *chan) { return DMA_IN(&chan->regs->sr) & XILINX_DMA_SR_IDLE_MASK; } -/* Only needed for Axi CDMA v2_00_a or earlier core - */ -static void dma_sg_toggle(struct xilinx_dma_chan *chan) -{ - - DMA_OUT(&chan->regs->cr, - DMA_IN(&chan->regs->cr) & ~XILINX_CDMA_CR_SGMODE_MASK); - - DMA_OUT(&chan->regs->cr, - DMA_IN(&chan->regs->cr) | XILINX_CDMA_CR_SGMODE_MASK); -} - #define XILINX_DMA_DRIVER_DEBUG 0 #if (XILINX_DMA_DRIVER_DEBUG == 1) @@ -414,167 +502,123 @@ static void desc_dump(struct xilinx_dma_desc_hw *hw) printk(KERN_INFO "\thsize %x\n", hw->hsize); printk(KERN_INFO "\tcontrol %x\n", hw->control); printk(KERN_INFO "\tstatus %x\n", hw->status); - } #endif -static void xilinx_cdma_start_transfer(struct xilinx_dma_chan *chan) +static int xilinx_dma_wait_status(struct xilinx_dma_chan *chan, uint32_t mask, + uint32_t value) { - unsigned long flags; - struct xilinx_dma_desc_sw *desch, *desct; - struct xilinx_dma_desc_hw *hw; + unsigned long timeout = 10000; + uint32_t status; - if (chan->err) - return; + do { + status = DMA_IN(&chan->regs->cr); + if ((status & mask) == value) + break; + } while (--timeout); - spin_lock_irqsave(&chan->lock, flags); + if ((status & mask) != value) + return -ETIMEDOUT; - if (list_empty(&chan->pending_list)) - goto out_unlock; + return 0; +} - /* If hardware is busy, cannot submit - */ - if (!dma_is_idle(chan)) { - dev_dbg(chan->dev, "DMA controller still busy %x\n", - DMA_IN(&chan->regs->sr)); - goto out_unlock; - } +static int xilinx_dma_reset(struct xilinx_dma_chan *chan) +{ + int ret; - /* Enable interrupts - */ DMA_OUT(&chan->regs->cr, - DMA_IN(&chan->regs->cr) | XILINX_DMA_XR_IRQ_ALL_MASK); - - desch = list_first_entry(&chan->pending_list, struct xilinx_dma_desc_sw, - node); - - if (chan->has_SG) { - - /* If hybrid mode, append pending list to active list - */ - desct = container_of(chan->pending_list.prev, - struct xilinx_dma_desc_sw, node); - - list_splice_tail_init(&chan->pending_list, &chan->active_list); - - /* If hardware is idle, then all descriptors on the active list - * are done, start new transfers - */ - dma_sg_toggle(chan); + DMA_IN(&chan->regs->cr) | XILINX_DMA_CR_RESET_MASK); - DMA_OUT(&chan->regs->cdr, desch->async_tx.phys); + ret = xilinx_dma_wait_status(chan, XILINX_DMA_CR_RESET_MASK, 0); - /* Update tail ptr register and start the transfer - */ - DMA_OUT(&chan->regs->tdr, desct->async_tx.phys); - goto out_unlock; + if (ret) { + dev_err(chan->dev, "reset timeout, cr %x, sr %x\n", + DMA_IN(&chan->regs->cr), DMA_IN(&chan->regs->sr)); + return 1; } - /* In simple mode - */ - list_del(&desch->node); - list_add_tail(&desch->node, &chan->active_list); - - hw = &desch->hw; - - DMA_OUT(&chan->regs->src, hw->buf_addr); - DMA_OUT(&chan->regs->dst, hw->addr_vsize); - - /* Start the transfer - */ - DMA_OUT(&chan->regs->btt_ref, - hw->control & XILINX_DMA_MAX_TRANS_LEN); + /* re-apply config */ + dmaengine_device_control(&chan->common, DMA_SLAVE_CONFIG, + (unsigned long)&chan->config); -out_unlock: - spin_unlock_irqrestore(&chan->lock, flags); + return 0; } -/* If sg mode, link the pending list to running list; if simple mode, get the - * head of the pending list and submit it to hw - */ -static void xilinx_cdma_issue_pending(struct dma_chan *dchan) +static void xilinx_dma_start_stop(struct xilinx_dma_chan *chan, bool start) { - struct xilinx_dma_chan *chan = to_xilinx_chan(dchan); - xilinx_cdma_start_transfer(chan); + uint32_t status; + uint32_t value; + int ret; + + if (start) + value = XILINX_DMA_CR_RUNSTOP_MASK; + else + value = 0; + + status = DMA_IN(&chan->regs->cr); + status &= ~XILINX_DMA_CR_RUNSTOP_MASK; + status |= value; + DMA_OUT(&chan->regs->cr, status); + + ret = xilinx_dma_wait_status(chan, XILINX_DMA_CR_RUNSTOP_MASK, value); + if (ret) { + dev_dbg(chan->dev, "Cannot %s channel %x: %x\n", + start ? "start" : "stop", chan->id, + DMA_IN(&chan->regs->cr)); + chan->err = 1; + } } /* Stop the hardware, the ongoing transfer will be finished */ static void dma_halt(struct xilinx_dma_chan *chan) { - int loop = XILINX_DMA_HALT_LOOP; - - DMA_OUT(&chan->regs->cr, - DMA_IN(&chan->regs->cr) & ~XILINX_DMA_CR_RUNSTOP_MASK); - - /* Wait for the hardware to halt - */ - while (loop) { - if (!(DMA_IN(&chan->regs->cr) & XILINX_DMA_CR_RUNSTOP_MASK)) - break; - - loop -= 1; - } - - if (!loop) { - pr_debug("Cannot stop channel %x: %x\n", - (unsigned int)chan, - (unsigned int)DMA_IN(&chan->regs->cr)); - chan->err = 1; - } - - return; + xilinx_dma_start_stop(chan, false); } /* Start the hardware. Transfers are not started yet */ static void dma_start(struct xilinx_dma_chan *chan) { - int loop = XILINX_DMA_HALT_LOOP; - - DMA_OUT(&chan->regs->cr, - DMA_IN(&chan->regs->cr) | XILINX_DMA_CR_RUNSTOP_MASK); - - /* Wait for the hardware to start - */ - while (loop) { - if (DMA_IN(&chan->regs->cr) & XILINX_DMA_CR_RUNSTOP_MASK) - break; - - loop -= 1; - } + xilinx_dma_start_stop(chan, true); +} - if (!loop) { - pr_debug("Cannot start channel %x: %x\n", - (unsigned int)chan, - (unsigned int)DMA_IN(&chan->regs->cr)); +static bool xilinx_dma_has_errors(struct xilinx_dma_chan *chan) +{ + unsigned int stat; - chan->err = 1; - } + stat = DMA_IN(&chan->regs->sr); - return; + return (stat & XILINX_DMA_XR_IRQ_ERROR_MASK) != 0; } - static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) { - unsigned long flags; - struct xilinx_dma_desc_sw *desch, *desct; + struct xilinx_dma_transfer *last_transfer, *first_transfer; + dma_addr_t first_addr, last_addr; struct xilinx_dma_desc_hw *hw; - - if (chan->err) - return; + unsigned long flags; spin_lock_irqsave(&chan->lock, flags); if (list_empty(&chan->pending_list)) goto out_unlock; + if (chan->err) { + dev_err(chan->dev, "Failed to start transfer\n"); + goto out_unlock; + } + /* If hardware is busy, cannot submit */ - if (dma_is_running(chan) && !dma_is_idle(chan)) { - dev_dbg(chan->dev, "DMA controller still busy\n"); + if (xilinx_dma_is_running(chan) && !xilinx_dma_is_idle(chan)) { + DMA_OUT(&chan->regs->cr, + DMA_IN(&chan->regs->cr) | XILINX_DMA_XR_IRQ_ALL_MASK); goto out_unlock; } + if (xilinx_dma_has_errors(chan)) + xilinx_dma_reset(chan); + /* If hardware is idle, then all descriptors on active list are * done, start new transfers */ @@ -583,14 +627,18 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) if (chan->err) goto out_unlock; + first_transfer = list_first_entry(&chan->pending_list, + struct xilinx_dma_transfer, head); + if (chan->has_SG) { - desch = list_first_entry(&chan->pending_list, - struct xilinx_dma_desc_sw, node); + uint32_t status; + last_transfer = list_entry(chan->pending_list.prev, + struct xilinx_dma_transfer, head); - desct = container_of(chan->pending_list.prev, - struct xilinx_dma_desc_sw, node); + first_addr = first_transfer->descs[0].phys; + last_addr = last_transfer->descs[last_transfer->num_descs-1].phys; - DMA_OUT(&chan->regs->cdr, desch->async_tx.phys); + DMA_OUT(&chan->regs->cdr, first_addr); dma_start(chan); @@ -598,51 +646,38 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) goto out_unlock; list_splice_tail_init(&chan->pending_list, &chan->active_list); - /* Enable interrupts - */ + /* Clear pending interrupts and enable interrupts */ + DMA_OUT(&chan->regs->sr, XILINX_DMA_XR_IRQ_ALL_MASK); DMA_OUT(&chan->regs->cr, DMA_IN(&chan->regs->cr) | XILINX_DMA_XR_IRQ_ALL_MASK); - + status = DMA_IN(&chan->regs->sr); /* Update tail ptr register and start the transfer */ - DMA_OUT(&chan->regs->tdr, desct->async_tx.phys); - goto out_unlock; - } - - /* In simple mode - */ - - dma_halt(chan); - - if (chan->err) - goto out_unlock; - - printk(KERN_INFO "xilinx_dma_start_transfer::simple DMA mode\n"); - - desch = list_first_entry(&chan->pending_list, - struct xilinx_dma_desc_sw, node); + DMA_OUT(&chan->regs->tdr, last_addr); + } else { + /* In simple mode */ - list_del(&desch->node); - list_add_tail(&desch->node, &chan->active_list); + list_move_tail(&first_transfer->head, &chan->active_list); - dma_start(chan); + dma_start(chan); - if (chan->err) - goto out_unlock; + if (chan->err) + goto out_unlock; - hw = &desch->hw; + hw = first_transfer->descs[0].hw; - /* Enable interrupts - */ - DMA_OUT(&chan->regs->cr, - DMA_IN(&chan->regs->cr) | XILINX_DMA_XR_IRQ_ALL_MASK); + /* Enable interrupts + */ + DMA_OUT(&chan->regs->cr, + DMA_IN(&chan->regs->cr) | XILINX_DMA_XR_IRQ_ALL_MASK); - DMA_OUT(&chan->regs->src, hw->buf_addr); + DMA_OUT(&chan->regs->src, hw->buf_addr); - /* Start the transfer - */ - DMA_OUT(&chan->regs->btt_ref, - hw->control & XILINX_DMA_MAX_TRANS_LEN); + /* Start the transfer + */ + DMA_OUT(&chan->regs->btt_ref, + hw->control & XILINX_DMA_MAX_TRANS_LEN); + } out_unlock: spin_unlock_irqrestore(&chan->lock, flags); @@ -651,211 +686,81 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) static void xilinx_dma_issue_pending(struct dma_chan *dchan) { struct xilinx_dma_chan *chan = to_xilinx_chan(dchan); - xilinx_dma_start_transfer(chan); + chan->start_transfer(chan); } -static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan) +/** + * xilinx_dma_update_completed_cookie - Update the completed cookie. + * @chan : xilinx DMA channel + * + * CONTEXT: hardirq + */ +static void xilinx_dma_update_completed_cookie(struct xilinx_dma_chan *chan) { + struct xilinx_dma_transfer *t; + struct xilinx_dma_desc_hw *hw = NULL; unsigned long flags; - struct xilinx_dma_desc_sw *desch, *desct = NULL; - struct xilinx_dma_config *config; - u32 reg; - u8 *chan_base; - - if (chan->err) - return; spin_lock_irqsave(&chan->lock, flags); - if (list_empty(&chan->pending_list)) - goto out_unlock; - - /* If it is SG mode and hardware is busy, cannot submit - */ - if (chan->has_SG && dma_is_running(chan) && !dma_is_idle(chan)) { - dev_dbg(chan->dev, "DMA controller still busy\n"); + if (list_empty(&chan->active_list)) { + dev_dbg(chan->dev, "no running descriptors\n"); goto out_unlock; } - /* If hardware is idle, then all descriptors on the running lists are - * done, start new transfers - */ - if (chan->err) - goto out_unlock; - - if (chan->has_SG) { - desch = list_first_entry(&chan->pending_list, - struct xilinx_dma_desc_sw, node); - - desct = container_of(chan->pending_list.prev, - struct xilinx_dma_desc_sw, node); - - DMA_OUT(&chan->regs->cdr, desch->async_tx.phys); - } + if ((!(chan->feature & XILINX_DMA_IP_VDMA)) && chan->has_SG) { + /* Get the last completed descriptor, update the cookie to that */ + list_for_each_entry(t, &chan->active_list, head) { + if (t->cyclic) { + while (true) { + hw = t->descs[t->current_desc].hw; + if (!(hw->status & XILINX_DMA_BD_STS_ALL_MASK)) + break; + t->completed_descs++; + hw->status = 0; + DMA_OUT(&chan->regs->tdr, t->descs[t->current_desc].phys); + + t->current_desc++; + if (t->current_desc == t->num_descs) + t->current_desc = 0; + } + } else { + for (; t->current_desc < t->num_descs; t->current_desc++) { + hw = t->descs[t->current_desc].hw; + if (!(hw->status & XILINX_DMA_BD_STS_ALL_MASK)) + break; + } + if (t->current_desc != t->num_descs) + break; - /* Configure the hardware using info in the config structure */ - config = &(chan->config); - reg = DMA_IN(&chan->regs->cr); - - if (config->frm_cnt_en) - reg |= XILINX_VDMA_FRMCNT_EN; - else - reg &= ~XILINX_VDMA_FRMCNT_EN; - - /* With SG, start with circular mode, so that BDs can be fetched. - * In direct register mode, if not parking, enable circular mode */ - if ((chan->has_SG) || (!config->park)) - reg |= XILINX_VDMA_CIRC_EN; - - if (config->park) - reg &= ~XILINX_VDMA_CIRC_EN; - - DMA_OUT(&chan->regs->cr, reg); - - if ((config->park_frm >= 0) && (config->park_frm < chan->num_frms)) { - if (config->direction == DMA_MEM_TO_DEV) { - chan_base = (char *)chan->regs; - DMA_OUT((chan_base + XILINX_VDMA_PARK_REG_OFFSET), - config->park_frm); - } else { - chan_base = ((char *)chan->regs - - XILINX_DMA_RX_CHANNEL_OFFSET); - DMA_OUT((chan_base + XILINX_VDMA_PARK_REG_OFFSET), - config->park_frm << XILINX_VDMA_WR_REF_SHIFT); + dma_cookie_complete(&t->async_tx); + } } - } - - /* Start the hardware - */ - dma_start(chan); - - if (chan->err) - goto out_unlock; - list_splice_tail_init(&chan->pending_list, &chan->active_list); - - /* Enable interrupts - * - * park/genlock testing does not use interrupts */ - if (!chan->config.disable_intr) { - DMA_OUT(&chan->regs->cr, - DMA_IN(&chan->regs->cr) | XILINX_DMA_XR_IRQ_ALL_MASK); } else { - DMA_OUT(&chan->regs->cr, - (DMA_IN(&chan->regs->cr) | XILINX_DMA_XR_IRQ_ALL_MASK) & - ~((chan->config.disable_intr << XILINX_DMA_IRQ_SHIFT))); - } - - /* Start the transfer - */ - if (chan->has_SG) - DMA_OUT(&chan->regs->tdr, desct->async_tx.phys); - else - DMA_OUT(&chan->addr_regs->vsize, config->vsize); - -out_unlock: - spin_unlock_irqrestore(&chan->lock, flags); -} - -static void xilinx_vdma_issue_pending(struct dma_chan *dchan) -{ - struct xilinx_dma_chan *chan = to_xilinx_chan(dchan); - xilinx_vdma_start_transfer(chan); -} - -/** - * xilinx_dma_update_completed_cookie - Update the completed cookie. - * @chan : xilinx DMA channel - * - * CONTEXT: hardirq - */ -static void xilinx_dma_update_completed_cookie(struct xilinx_dma_chan *chan) -{ - struct xilinx_dma_desc_sw *desc = NULL; - struct xilinx_dma_desc_hw *hw = NULL; - unsigned long flags; - dma_cookie_t cookie = -EBUSY; - int done = 0; - - spin_lock_irqsave(&chan->lock, flags); - - if (list_empty(&chan->active_list)) { - dev_dbg(chan->dev, "no running descriptors\n"); - goto out_unlock; - } - - /* Get the last completed descriptor, update the cookie to that */ - list_for_each_entry(desc, &chan->active_list, node) { - if ((!(chan->feature & XILINX_DMA_IP_VDMA)) && chan->has_SG) { - hw = &desc->hw; - - /* If a BD has no status bits set, hw has it */ - if (!(hw->status & XILINX_DMA_BD_STS_ALL_MASK)) { - break; + /* In non-SG mode, there is only one transfer active at a time */ + t = list_first_entry(&chan->active_list, + struct xilinx_dma_transfer, head); + t->current_desc++; + t->completed_descs++; + if (t->current_desc == t->num_descs) { + if (t->cyclic) { + t->current_desc = 0; } else { - done = 1; - cookie = desc->async_tx.cookie; + dma_cookie_complete(&t->async_tx); } - } else { - /* In non-SG mode, all active entries are done */ - done = 1; - cookie = desc->async_tx.cookie; } } - if (done) - chan->completed_cookie = cookie; - out_unlock: spin_unlock_irqrestore(&chan->lock, flags); } -/* Reset hardware - */ -static int dma_init(struct xilinx_dma_chan *chan) -{ - int loop = XILINX_DMA_RESET_LOOP; - u32 tmp; - - DMA_OUT(&chan->regs->cr, - DMA_IN(&chan->regs->cr) | XILINX_DMA_CR_RESET_MASK); - - tmp = DMA_IN(&chan->regs->cr) & XILINX_DMA_CR_RESET_MASK; - - /* Wait for the hardware to finish reset - */ - while (loop && tmp) { - tmp = DMA_IN(&chan->regs->cr) & XILINX_DMA_CR_RESET_MASK; - loop -= 1; - } - - if (!loop) { - dev_err(chan->dev, "reset timeout, cr %x, sr %x\n", - DMA_IN(&chan->regs->cr), DMA_IN(&chan->regs->sr)); - return 1; - } - - /* For Axi CDMA, always do sg transfers if sg mode is built in - */ - if ((chan->feature & XILINX_DMA_IP_CDMA) && chan->has_SG) - DMA_OUT(&chan->regs->cr, tmp | XILINX_CDMA_CR_SGMODE_MASK); - - return 0; -} - - static irqreturn_t dma_intr_handler(int irq, void *data) { struct xilinx_dma_chan *chan = data; - int update_cookie = 0; - int to_transfer = 0; - u32 stat, reg; - - reg = DMA_IN(&chan->regs->cr); + u32 stat; - /* Disable intr - */ - DMA_OUT(&chan->regs->cr, - reg & ~XILINX_DMA_XR_IRQ_ALL_MASK); + xilinx_dma_free_transfer_list(chan, &chan->removed_list); stat = DMA_IN(&chan->regs->sr); if (!(stat & XILINX_DMA_XR_IRQ_ALL_MASK)) @@ -865,30 +770,14 @@ static irqreturn_t dma_intr_handler(int irq, void *data) */ DMA_OUT(&chan->regs->sr, XILINX_DMA_XR_IRQ_ALL_MASK); - /* Check for only the interrupts which are enabled - */ - stat &= (reg & XILINX_DMA_XR_IRQ_ALL_MASK); - if (stat & XILINX_DMA_XR_IRQ_ERROR_MASK) { - if ((chan->feature & XILINX_DMA_IP_VDMA) - && chan->flush_fsync) { - /* VDMA Recoverable Errors, only when - C_FLUSH_ON_FSYNC is enabled */ - u32 error = DMA_IN(&chan->regs->sr) & - XILINX_VDMA_SR_ERR_RECOVER_MASK; - if (error) - DMA_OUT(&chan->regs->sr, error); - else - chan->err = 1; - } else { - dev_err(chan->dev, - "Channel %x has errors %x, cdr %x tdr %x\n", - (unsigned int)chan, - (unsigned int)DMA_IN(&chan->regs->sr), - (unsigned int)DMA_IN(&chan->regs->cdr), - (unsigned int)DMA_IN(&chan->regs->tdr)); - chan->err = 1; - } + dev_err(chan->dev, "Channel %x has errors %x, cr %x, cdr %x tdr %x\n", + (unsigned int)chan, (unsigned int)stat, + (unsigned int)DMA_IN(&chan->regs->cr), + (unsigned int)DMA_IN(&chan->regs->cdr), + (unsigned int)DMA_IN(&chan->regs->tdr)); + chan->err = 1; + dma_halt(chan); } /* Device takes too long to do the transfer when user requires @@ -898,15 +787,9 @@ static irqreturn_t dma_intr_handler(int irq, void *data) dev_dbg(chan->dev, "Inter-packet latency too long\n"); if (stat & XILINX_DMA_XR_IRQ_IOC_MASK) { - update_cookie = 1; - to_transfer = 1; - } - - if (update_cookie) xilinx_dma_update_completed_cookie(chan); - - if (to_transfer) chan->start_transfer(chan); + } tasklet_schedule(&chan->tasklet); return IRQ_HANDLED; @@ -915,32 +798,29 @@ static irqreturn_t dma_intr_handler(int irq, void *data) static void dma_do_tasklet(unsigned long data) { struct xilinx_dma_chan *chan = (struct xilinx_dma_chan *)data; - xilinx_chan_desc_cleanup(chan); } /* Append the descriptor list to the pending list */ static void append_desc_queue(struct xilinx_dma_chan *chan, - struct xilinx_dma_desc_sw *desc) + struct xilinx_dma_transfer *t) { - struct xilinx_dma_desc_sw *tail = container_of(chan->pending_list.prev, - struct xilinx_dma_desc_sw, node); + struct xilinx_dma_transfer *tail = container_of(chan->pending_list.prev, + struct xilinx_dma_transfer, head); struct xilinx_dma_desc_hw *hw; - if (list_empty(&chan->pending_list)) - goto out_splice; - - /* Add the hardware descriptor to the chain of hardware descriptors - * that already exists in memory. - */ - hw = &(tail->hw); - hw->next_desc = (u32)desc->async_tx.phys; + if (!list_empty(&chan->pending_list)) { + /* Add the hardware descriptor to the chain of hardware descriptors + * that already exists in memory. + */ + hw = tail->descs[tail->num_descs-1].hw; + hw->next_desc = t->descs[0].phys; + } /* Add the software descriptor and all children to the list * of pending transactions */ -out_splice: - list_splice_tail_init(&desc->tx_list, &chan->pending_list); + list_add_tail(&t->head, &chan->pending_list); } /* Assign cookie to each descriptor, and append the descriptors to the pending @@ -949,189 +829,89 @@ static void append_desc_queue(struct xilinx_dma_chan *chan, static dma_cookie_t xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx) { struct xilinx_dma_chan *chan = to_xilinx_chan(tx->chan); - struct xilinx_dma_desc_sw *desc = container_of(tx, - struct xilinx_dma_desc_sw, async_tx); - struct xilinx_dma_desc_sw *child; + struct xilinx_dma_transfer *t = container_of(tx, + struct xilinx_dma_transfer, async_tx); unsigned long flags; - dma_cookie_t cookie = -EBUSY; + dma_cookie_t cookie; + + spin_lock_irqsave(&chan->lock, flags); + + if (chan->cyclic) + goto err; if (chan->err) { /* If reset fails, need to hard reset the system. * Channel is no longer functional */ - if (!dma_init(chan)) + if (!xilinx_dma_reset(chan)) chan->err = 0; else - return cookie; + goto err; } - spin_lock_irqsave(&chan->lock, flags); - - /* - * assign cookies to all of the software descriptors - * that make up this transaction - */ - cookie = chan->cookie; - list_for_each_entry(child, &desc->tx_list, node) { - cookie++; - if (cookie < 0) - cookie = DMA_MIN_COOKIE; - - child->async_tx.cookie = cookie; - } - - chan->cookie = cookie; - + cookie = dma_cookie_assign(tx); /* put this transaction onto the tail of the pending queue */ - append_desc_queue(chan, desc); + append_desc_queue(chan, t); + + if (t->cyclic) + chan->cyclic = true; spin_unlock_irqrestore(&chan->lock, flags); return cookie; -} - -static struct xilinx_dma_desc_sw *xilinx_dma_alloc_descriptor( - struct xilinx_dma_chan *chan) -{ - struct xilinx_dma_desc_sw *desc; - dma_addr_t pdesc; - - desc = dma_pool_alloc(chan->desc_pool, GFP_ATOMIC, &pdesc); - if (!desc) { - dev_dbg(chan->dev, "out of memory for desc\n"); - return NULL; - } - - memset(desc, 0, sizeof(*desc)); - INIT_LIST_HEAD(&desc->tx_list); - dma_async_tx_descriptor_init(&desc->async_tx, &chan->common); - desc->async_tx.tx_submit = xilinx_dma_tx_submit; - desc->async_tx.phys = pdesc; - - return desc; +err: + spin_unlock_irqrestore(&chan->lock, flags); + xilinx_dma_free_transfer(chan, t); + return -EBUSY; } /** - * xilinx_dma_prep_memcpy - prepare descriptors for a memcpy transaction - * @dchan: DMA channel - * @dma_dst: destination address - * @dma_src: source address - * @len: transfer length + * xilinx_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE transaction + * @chan: DMA channel + * @sgl: scatterlist to transfer to/from + * @sg_len: number of entries in @scatterlist + * @direction: DMA direction * @flags: transfer ack flags */ -static struct dma_async_tx_descriptor *xilinx_dma_prep_memcpy( - struct dma_chan *dchan, dma_addr_t dma_dst, dma_addr_t dma_src, - size_t len, unsigned long flags) +static struct dma_async_tx_descriptor *xilinx_dma_prep_dma_cyclic( + struct dma_chan *dchan, dma_addr_t buf_addr, size_t buf_len, + size_t period_len, enum dma_transfer_direction direction, void *context) { + struct xilinx_dma_desc_hw *hw; + struct xilinx_dma_transfer *t; struct xilinx_dma_chan *chan; - struct xilinx_dma_desc_sw *first = NULL, *prev = NULL, *new; - struct xilinx_dma_desc_hw *hw, *prev_hw; - size_t copy; - dma_addr_t src = dma_src; - dma_addr_t dst = dma_dst; + unsigned int num_periods; + unsigned int i; if (!dchan) return NULL; - if (!len) - return NULL; - chan = to_xilinx_chan(dchan); - if (chan->err) { - - /* If reset fails, need to hard reset the system. - * Channel is no longer functional - */ - if (!dma_init(chan)) - chan->err = 0; - else - return NULL; - } + if (chan->direction != direction) + return NULL; - /* If build does not have Data Realignment Engine (DRE), - * src has to be aligned - */ - if (!chan->has_DRE) { - if ((dma_src & - (chan->feature & XILINX_DMA_FTR_DATA_WIDTH_MASK)) || - (dma_dst & - (chan->feature & XILINX_DMA_FTR_DATA_WIDTH_MASK))) { + num_periods = buf_len / period_len; - dev_err(chan->dev, - "Source or destination address not aligned when no DRE\n"); + t = xilinx_dma_alloc_transfer(chan, num_periods); + if (!t) + return NULL; - return NULL; - } + for (i = 0; i < num_periods; ++i) { + hw = t->descs[i].hw; + hw->buf_addr = buf_addr; + hw->control = period_len; + hw->control |= XILINX_DMA_BD_SOP | XILINX_DMA_BD_EOP; + buf_addr += period_len; } - do { - - /* Allocate descriptor from DMA pool */ - new = xilinx_dma_alloc_descriptor(chan); - if (!new) { - dev_err(chan->dev, - "No free memory for link descriptor\n"); - goto fail; - } - - copy = min(len, (size_t)chan->max_len); - - /* if lite build, transfer cannot cross page boundary - */ - if (chan->is_lite) - copy = min(copy, (size_t)(PAGE_MASK - - (src & PAGE_MASK))); - - if (!copy) { - dev_err(chan->dev, - "Got zero transfer length for %x\n", - (unsigned int)src); - goto fail; - } - - hw = &(new->hw); - hw->control = - (hw->control & ~XILINX_DMA_MAX_TRANS_LEN) | copy; - hw->buf_addr = src; - hw->addr_vsize = dst; - - if (!first) - first = new; - else { - prev_hw = &(prev->hw); - prev_hw->next_desc = new->async_tx.phys; - } - - new->async_tx.cookie = 0; - async_tx_ack(&new->async_tx); - - prev = new; - len -= copy; - src += copy; - dst += copy; - - /* Insert the descriptor to the list */ - list_add_tail(&new->node, &first->tx_list); - } while (len); - - /* Link the last BD with the first BD */ - hw->next_desc = first->async_tx.phys; - - new->async_tx.flags = flags; /* client is in control of this ack */ - new->async_tx.cookie = -EBUSY; + t->cyclic = true; - return &first->async_tx; - -fail: - if (!first) - return NULL; - - xilinx_dma_free_desc_list_reverse(chan, &first->tx_list); - return NULL; + return &t->async_tx; } + /** * xilinx_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE transaction * @chan: DMA channel @@ -1142,23 +922,19 @@ static struct dma_async_tx_descriptor *xilinx_dma_prep_memcpy( */ static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg( struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len, - enum dma_transfer_direction direction, unsigned long flags, - void *context) + enum dma_transfer_direction direction, unsigned long flags, void *context) { + struct xilinx_dma_desc_hw *hw; + struct xilinx_dma_transfer *t; struct xilinx_dma_chan *chan; - struct xilinx_dma_desc_sw *first = NULL, *prev = NULL, *new = NULL; - struct xilinx_dma_desc_hw *hw = NULL, *prev_hw = NULL; - - size_t copy; - - int i; + unsigned int total_len = 0; + unsigned int num_descs = 0; struct scatterlist *sg; - size_t sg_used; dma_addr_t dma_src; + size_t num_bytes; + size_t sg_used; + unsigned int i, j; -#ifdef TEST_DMA_WITH_LOOPBACK - int total_len; -#endif if (!dchan) return NULL; @@ -1167,107 +943,49 @@ static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg( if (chan->direction != direction) return NULL; -#ifdef TEST_DMA_WITH_LOOPBACK - total_len = 0; - for_each_sg(sgl, sg, sg_len, i) { total_len += sg_dma_len(sg); + num_descs += DIV_ROUND_UP(sg_dma_len(sg), chan->max_len); } -#endif + + t = xilinx_dma_alloc_transfer(chan, num_descs); + if (!t) + return NULL; + /* * Build transactions using information in the scatter gather list */ + j = 0; for_each_sg(sgl, sg, sg_len, i) { sg_used = 0; /* Loop until the entire scatterlist entry is used */ while (sg_used < sg_dma_len(sg)) { - - /* Allocate the link descriptor from DMA pool */ - new = xilinx_dma_alloc_descriptor(chan); - if (!new) { - dev_err(chan->dev, "No free memory for " - "link descriptor\n"); - goto fail; - } - /* * Calculate the maximum number of bytes to transfer, * making sure it is less than the hw limit */ - copy = min((size_t)(sg_dma_len(sg) - sg_used), - (size_t)chan->max_len); - hw = &(new->hw); + num_bytes = min_t(size_t, sg_dma_len(sg) - sg_used, + chan->max_len); dma_src = sg_dma_address(sg) + sg_used; + hw = t->descs[j].hw; hw->buf_addr = dma_src; - - /* Fill in the descriptor */ - hw->control = copy; - - /* - * If this is not the first descriptor, chain the - * current descriptor after the previous descriptor - * - * For the first DMA_MEM_TO_DEV transfer, set SOP - */ - if (!first) { - first = new; - if (direction == DMA_MEM_TO_DEV) { - hw->control |= XILINX_DMA_BD_SOP; -#ifdef TEST_DMA_WITH_LOOPBACK - hw->app_4 = total_len; -#endif - } - } else { - prev_hw = &(prev->hw); - prev_hw->next_desc = new->async_tx.phys; - } - - new->async_tx.cookie = 0; - async_tx_ack(&new->async_tx); - - prev = new; - sg_used += copy; - - /* Insert the link descriptor into the LD ring */ - list_add_tail(&new->node, &first->tx_list); + hw->control = num_bytes; + sg_used += num_bytes; + j++; } } - /* Link the last BD with the first BD */ - hw->next_desc = first->async_tx.phys; - - if (direction == DMA_MEM_TO_DEV) - hw->control |= XILINX_DMA_BD_EOP; - - /* All scatter gather list entries has length == 0 */ - if (!first || !new) - return NULL; - - new->async_tx.flags = flags; - new->async_tx.cookie = -EBUSY; - - /* Set EOP to the last link descriptor of new list */ - hw->control |= XILINX_DMA_BD_EOP; - - return &first->async_tx; - -fail: - /* If first was not set, then we failed to allocate the very first - * descriptor, and we're done */ - if (!first) - return NULL; + /* Set EOP to the last link descriptor of new list and + SOP to the first link descriptor. */ + t->descs[0].hw->control |= XILINX_DMA_BD_SOP; + t->descs[t->num_descs-1].hw->control |= XILINX_DMA_BD_EOP; - /* - * First is set, so all of the descriptors we allocated have been added - * to first->tx_list, INCLUDING "first" itself. Therefore we - * must traverse the list backwards freeing each descriptor in turn - */ - xilinx_dma_free_desc_list_reverse(chan, &first->tx_list); + t->async_tx.flags = flags; - return NULL; + return &t->async_tx; } /** @@ -1280,14 +998,13 @@ static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg( */ static struct dma_async_tx_descriptor *xilinx_vdma_prep_slave_sg( struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len, - enum dma_transfer_direction direction, unsigned long flags, - void *context) + enum dma_transfer_direction direction, unsigned long flags, void *context) { + struct xilinx_dma_desc_hw *hw; + struct xilinx_dma_transfer *t; struct xilinx_dma_chan *chan; - struct xilinx_dma_desc_sw *first = NULL, *prev = NULL, *new = NULL; - struct xilinx_dma_desc_hw *hw = NULL, *prev_hw = NULL; - int i; struct scatterlist *sg; + unsigned int i, j; dma_addr_t dma_src; if (!dchan) @@ -1299,13 +1016,17 @@ static struct dma_async_tx_descriptor *xilinx_vdma_prep_slave_sg( return NULL; /* Enforce one sg entry for one frame */ - if (sg_len != chan->num_frms) { + if (chan->num_frms % sg_len != 0) { dev_err(chan->dev, "number of entries %d not the " "same as num stores %d\n", sg_len, chan->num_frms); return NULL; } + t = xilinx_dma_alloc_transfer(chan, sg_len); + if (!t) + return NULL; + if (!chan->has_SG) { DMA_OUT(&chan->addr_regs->hsize, chan->config.hsize); DMA_OUT(&chan->addr_regs->frmdly_stride, @@ -1313,132 +1034,142 @@ static struct dma_async_tx_descriptor *xilinx_vdma_prep_slave_sg( chan->config.stride); } - /* Build transactions using information in the scatter gather list - */ - for_each_sg(sgl, sg, sg_len, i) { - - /* Allocate the link descriptor from DMA pool */ - new = xilinx_dma_alloc_descriptor(chan); - if (!new) { - dev_err(chan->dev, "No free memory for " - "link descriptor\n"); - goto fail; + for (j = 0; j < chan->num_frms / sg_len; ++j) { + /* Build transactions using information in the scatter gather list + */ + for_each_sg(sgl, sg, sg_len, i) { + dma_src = sg_dma_address(sg); + if (chan->has_SG) { + hw = t->descs[j * sg_len + i].hw; + hw->buf_addr = dma_src; + + /* Fill in the descriptor */ + hw->addr_vsize = chan->config.vsize; + hw->hsize = chan->config.hsize; + hw->control = (chan->config.frm_dly << + XILINX_VDMA_FRMDLY_SHIFT) | + chan->config.stride; + } else { + /* Update the registers */ + DMA_OUT(&(chan->addr_regs->buf_addr[j * sg_len + i]), dma_src); + } } + } - /* - * Calculate the maximum number of bytes to transfer, - * making sure it is less than the hw limit - */ - hw = &(new->hw); + t->async_tx.flags = flags; - dma_src = sg_dma_address(sg); - if (chan->has_SG) { - hw->buf_addr = dma_src; + return &t->async_tx; +} - /* Fill in the descriptor */ - hw->addr_vsize = chan->config.vsize; - hw->hsize = chan->config.hsize; - hw->control = (chan->config.frm_dly << - XILINX_VDMA_FRMDLY_SHIFT) | - chan->config.stride; - } else { - /* Update the registers */ - DMA_OUT(&(chan->addr_regs->buf_addr[i]), dma_src); - } +static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan) +{ + unsigned long flags; + struct xilinx_dma_transfer *t; + struct xilinx_dma_config *config; + u32 reg; - /* If this is not the first descriptor, chain the - * current descriptor after the previous descriptor - */ - if (!first) { - first = new; - } else { - prev_hw = &(prev->hw); - prev_hw->next_desc = new->async_tx.phys; - } + if (chan->err) + return; - new->async_tx.cookie = 0; - async_tx_ack(&new->async_tx); + spin_lock_irqsave(&chan->lock, flags); - prev = new; + if (list_empty(&chan->pending_list)) + goto out_unlock; - /* Insert the link descriptor into the list */ - list_add_tail(&new->node, &first->tx_list); + /* If it is SG mode and hardware is busy, cannot submit + */ + if (chan->has_SG && xilinx_dma_is_running(chan) && !xilinx_dma_is_idle(chan)) { + dev_dbg(chan->dev, "DMA controller still busy\n"); + goto out_unlock; } - /* Link the last BD with the first BD */ - hw->next_desc = first->async_tx.phys; - - if (!first || !new) - return NULL; - - new->async_tx.flags = flags; - new->async_tx.cookie = -EBUSY; + /* If hardware is idle, then all descriptors on the running lists are + * done, start new transfers + */ + dma_halt(chan); - return &first->async_tx; + if (chan->err) + goto out_unlock; -fail: - /* If first was not set, then we failed to allocate the very first - * descriptor, and we're done */ - if (!first) - return NULL; + t = list_first_entry(&chan->pending_list, struct xilinx_dma_transfer, head); - /* First is set, so all of the descriptors we allocated have been added - * to first->tx_list, INCLUDING "first" itself. Therefore we - * must traverse the list backwards freeing each descriptor in turn - */ - xilinx_dma_free_desc_list_reverse(chan, &first->tx_list); - return NULL; -} + if (chan->has_SG) + DMA_OUT(&chan->regs->cdr, t->descs[0].phys); -/* Run-time device configuration for Axi DMA and Axi CDMA */ -static int xilinx_dma_device_control(struct dma_chan *dchan, - enum dma_ctrl_cmd cmd, unsigned long arg) -{ - struct xilinx_dma_chan *chan; - unsigned long flags; + /* Configure the hardware using info in the config structure */ + config = &chan->config; + reg = DMA_IN(&chan->regs->cr); - if (!dchan) - return -EINVAL; + if (config->frm_cnt_en) + reg |= XILINX_VDMA_FRMCNT_EN; + else + reg &= ~XILINX_VDMA_FRMCNT_EN; - chan = to_xilinx_chan(dchan); + /* With SG, start with circular mode, so that BDs can be fetched. + * In direct register mode, if not parking, enable circular mode */ + if ((chan->has_SG) || (!config->park)) + reg |= XILINX_VDMA_CIRC_EN; - if (cmd == DMA_TERMINATE_ALL) { - /* Halt the DMA engine */ - dma_halt(chan); + DMA_OUT(&chan->regs->cr, reg); - spin_lock_irqsave(&chan->lock, flags); + if ((config->park_frm >= 0) && (config->park_frm < chan->num_frms)) { + if (config->direction == DMA_MEM_TO_DEV) { + DMA_OUT(&chan->regs->btt_ref, + config->park_frm << XILINX_VDMA_WR_REF_SHIFT); + } else { + DMA_OUT(&chan->regs->btt_ref, config->park_frm); + } + } - /* Remove and free all of the descriptors in the lists */ - xilinx_dma_free_desc_list(chan, &chan->pending_list); - xilinx_dma_free_desc_list(chan, &chan->active_list); + /* Start the hardware + */ + dma_start(chan); - spin_unlock_irqrestore(&chan->lock, flags); - return 0; - } else if (cmd == DMA_SLAVE_CONFIG) { - /* Configure interrupt coalescing and delay counter - * Use value XILINX_DMA_NO_CHANGE to signal no change - */ - struct xilinx_dma_config *cfg = (struct xilinx_dma_config *)arg; - u32 reg = DMA_IN(&chan->regs->cr); + if (chan->err) + goto out_unlock; + list_splice_tail_init(&chan->pending_list, &chan->active_list); - if (cfg->coalesc <= XILINX_DMA_COALESCE_MAX) { - reg &= ~XILINX_DMA_XR_COALESCE_MASK; - reg |= cfg->coalesc << XILINX_DMA_COALESCE_SHIFT; + /* Enable interrupts + * + * park/genlock testing does not use interrupts */ + /* + if (!chan->config.disable_intr) { + DMA_OUT(&chan->regs->cr, + DMA_IN(&chan->regs->cr) | XILINX_DMA_XR_IRQ_ALL_MASK); + }*/ - chan->config.coalesc = cfg->coalesc; - } + /* Start the transfer + */ + if (chan->has_SG) + DMA_OUT(&chan->regs->tdr, t->descs[t->num_descs-1].phys); + else + DMA_OUT(&chan->addr_regs->vsize, config->vsize); - if (cfg->delay <= XILINX_DMA_DELAY_MAX) { - reg &= ~XILINX_DMA_XR_DELAY_MASK; - reg |= cfg->delay << XILINX_DMA_DELAY_SHIFT; - chan->config.delay = cfg->delay; - } +out_unlock: + spin_unlock_irqrestore(&chan->lock, flags); +} - DMA_OUT(&chan->regs->cr, reg); +static int xilinx_dma_terminate_all(struct xilinx_dma_chan *chan) +{ + unsigned long flags; + /* Disable intr + */ +/* + DMA_OUT(&chan->regs->cr, + DMA_IN(&chan->regs->cr) & ~XILINX_DMA_XR_IRQ_ALL_MASK); +*/ + /* Halt the DMA engine */ + if (1) + dma_halt(chan); + else + xilinx_dma_reset(chan); + spin_lock_irqsave(&chan->lock, flags); + xilinx_dma_free_transfer_list(chan, &chan->pending_list); + list_splice_tail_init(&chan->active_list, &chan->removed_list); + spin_unlock_irqrestore(&chan->lock, flags); + chan->cyclic = false; - return 0; - } else - return -ENXIO; + return 0; } /* Run-time configuration for Axi VDMA, supports: @@ -1452,32 +1183,18 @@ static int xilinx_vdma_device_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd, unsigned long arg) { struct xilinx_dma_chan *chan; - unsigned long flags; + struct xilinx_dma_config *cfg = (struct xilinx_dma_config *)arg; + u32 reg; if (!dchan) return -EINVAL; chan = to_xilinx_chan(dchan); - if (cmd == DMA_TERMINATE_ALL) { - /* Halt the DMA engine */ - dma_halt(chan); - - spin_lock_irqsave(&chan->lock, flags); - - /* Remove and free all of the descriptors in the lists */ - xilinx_dma_free_desc_list(chan, &chan->pending_list); - xilinx_dma_free_desc_list(chan, &chan->active_list); - - spin_unlock_irqrestore(&chan->lock, flags); - return 0; - } else if (cmd == DMA_SLAVE_CONFIG) { - struct xilinx_dma_config *cfg = (struct xilinx_dma_config *)arg; - u32 reg; - - if (cfg->reset) - dma_init(chan); - + switch (cmd) { + case DMA_TERMINATE_ALL: + return xilinx_dma_terminate_all(chan); + case DMA_SLAVE_CONFIG: reg = DMA_IN(&chan->regs->cr); /* If vsize is -1, it is park-related operations */ @@ -1497,13 +1214,11 @@ static int xilinx_vdma_device_control(struct dma_chan *dchan, reg &= ~XILINX_DMA_XR_COALESCE_MASK; reg |= cfg->coalesc << XILINX_DMA_COALESCE_SHIFT; - chan->config.coalesc = cfg->coalesc; } if (cfg->delay <= XILINX_DMA_DELAY_MAX) { reg &= ~XILINX_DMA_XR_DELAY_MASK; reg |= cfg->delay << XILINX_DMA_DELAY_SHIFT; - chan->config.delay = cfg->delay; } DMA_OUT(&chan->regs->cr, reg); @@ -1511,16 +1226,7 @@ static int xilinx_vdma_device_control(struct dma_chan *dchan, } /* Transfer information */ - chan->config.vsize = cfg->vsize; - chan->config.hsize = cfg->hsize; - chan->config.stride = cfg->stride; - chan->config.frm_dly = cfg->frm_dly; - chan->config.park = cfg->park; - chan->config.direction = cfg->direction; - - /* genlock settings */ - chan->config.gen_lock = cfg->gen_lock; - chan->config.master = cfg->master; + chan->config = *cfg; if (cfg->gen_lock) { if (chan->genlock) { @@ -1529,55 +1235,66 @@ static int xilinx_vdma_device_control(struct dma_chan *dchan, } } - chan->config.frm_cnt_en = cfg->frm_cnt_en; - if (cfg->park) - chan->config.park_frm = cfg->park_frm; - else - chan->config.park_frm = -1; - - chan->config.coalesc = cfg->coalesc; - chan->config.delay = cfg->delay; - if (cfg->coalesc <= XILINX_DMA_COALESCE_MAX) { + if (cfg->coalesc <= XILINX_DMA_COALESCE_MAX) reg |= cfg->coalesc << XILINX_DMA_COALESCE_SHIFT; - chan->config.coalesc = cfg->coalesc; - } - if (cfg->delay <= XILINX_DMA_DELAY_MAX) { + if (cfg->delay <= XILINX_DMA_DELAY_MAX) reg |= cfg->delay << XILINX_DMA_DELAY_SHIFT; - chan->config.delay = cfg->delay; - } - - chan->config.disable_intr = cfg->disable_intr; - - if (cfg->ext_fsync) - reg |= cfg->ext_fsync << XILINX_VDMA_EXTFSYNC_SHIFT; DMA_OUT(&chan->regs->cr, reg); - return 0; - } else + break; + default: return -ENXIO; + } + + return 0; } -/* Logarithm function to compute alignment shift - * - * Only deals with value less than 4096. - */ -static int my_log(int value) +/* Run-time device configuration for Axi DMA and Axi CDMA */ +static int xilinx_dma_device_control(struct dma_chan *dchan, + enum dma_ctrl_cmd cmd, unsigned long arg) { - int i = 0; - while ((1 << i) < value) { - i++; + struct xilinx_dma_chan *chan; + struct xilinx_dma_config *cfg = (struct xilinx_dma_config *)arg; + u32 reg; - if (i >= 12) - return 0; + if (!dchan) + return -EINVAL; + + chan = to_xilinx_chan(dchan); + + switch (cmd) { + case DMA_TERMINATE_ALL: + return xilinx_dma_terminate_all(chan); + case DMA_SLAVE_CONFIG: + /* Configure interrupt coalescing and delay counter + * Use value XILINX_DMA_NO_CHANGE to signal no change + */ + reg = DMA_IN(&chan->regs->cr); + + chan->config = *cfg; + + if (cfg->coalesc <= XILINX_DMA_COALESCE_MAX) { + reg &= ~XILINX_DMA_XR_COALESCE_MASK; + reg |= cfg->coalesc << XILINX_DMA_COALESCE_SHIFT; + } + + if (cfg->delay <= XILINX_DMA_DELAY_MAX) { + reg &= ~XILINX_DMA_XR_DELAY_MASK; + reg |= cfg->delay << XILINX_DMA_DELAY_SHIFT; + } + + DMA_OUT(&chan->regs->cr, reg); + + break; + default: + return -ENXIO; } - return i; + return 0; } -#ifdef CONFIG_OF - static void xilinx_dma_chan_remove(struct xilinx_dma_chan *chan) { irq_dispose_mapping(chan->irq); @@ -1595,43 +1312,33 @@ static int __devinit xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, struct device_node *node, u32 feature) { struct xilinx_dma_chan *chan; - int err; - int *value; - u32 width = 0, device_id = 0, flush_fsync = 0; + u32 width = 0; + int ret; /* alloc channel */ chan = kzalloc(sizeof(*chan), GFP_KERNEL); if (!chan) { dev_err(xdev->dev, "no free memory for DMA channels!\n"); - err = -ENOMEM; + ret = -ENOMEM; goto out_return; } + spin_lock_init(&chan->lock); + INIT_LIST_HEAD(&chan->pending_list); + INIT_LIST_HEAD(&chan->active_list); + INIT_LIST_HEAD(&chan->removed_list); + chan->feature = feature; - chan->is_lite = 0; chan->has_DRE = 0; chan->has_SG = 0; chan->max_len = XILINX_DMA_MAX_TRANS_LEN; - value = (int *)of_get_property(node, "xlnx,include-dre", - NULL); - if (value) { - if (be32_to_cpup(value) == 1) - chan->has_DRE = 1; - } - - value = (int *)of_get_property(node, "xlnx,genlock-mode", - NULL); - if (value) { - if (be32_to_cpup(value) == 1) - chan->genlock = 1; - } + of_property_read_u32(node, "xlnx,include-dre", &chan->has_DRE); + of_property_read_u32(node, "xlnx,genlock-mode", &chan->genlock); + of_property_read_u32(node, "xlnx,datawidth", &width); - value = (int *)of_get_property(node, - "xlnx,datawidth", - NULL); - if (value) { - width = be32_to_cpup(value) >> 3; /* convert bits to bytes */ + if (width > 0) { + width >>= 3; /* convert bits to bytes */ /* If data width is greater than 8 bytes, DRE is not in hw */ if (width > 8) @@ -1640,62 +1347,19 @@ static int __devinit xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, chan->feature |= width - 1; } - value = (int *)of_get_property(node, "xlnx,device-id", NULL); - if (value) - device_id = be32_to_cpup(value); - - flush_fsync = (xdev->feature & XILINX_VDMA_FTR_FLUSH_MASK) >> - XILINX_VDMA_FTR_FLUSH_SHIFT; - - if (feature & XILINX_DMA_IP_CDMA) { - chan->direction = DMA_MEM_TO_MEM; - chan->start_transfer = xilinx_cdma_start_transfer; - - chan->has_SG = (xdev->feature & XILINX_DMA_FTR_HAS_SG) >> + chan->has_SG = (xdev->feature & XILINX_DMA_FTR_HAS_SG) >> XILINX_DMA_FTR_HAS_SG_SHIFT; - value = (int *)of_get_property(node, - "xlnx,lite-mode", NULL); - if (value) { - if (be32_to_cpup(value) == 1) { - chan->is_lite = 1; - value = (int *)of_get_property(node, - "xlnx,max-burst-len", NULL); - if (value) { - if (!width) { - dev_err(xdev->dev, - "Lite mode without data width property\n"); - goto out_free_chan; - } - chan->max_len = width * - be32_to_cpup(value); - } - } - } - } - if (feature & XILINX_DMA_IP_DMA) { - chan->has_SG = (xdev->feature & XILINX_DMA_FTR_HAS_SG) >> - XILINX_DMA_FTR_HAS_SG_SHIFT; - chan->start_transfer = xilinx_dma_start_transfer; - if (of_device_is_compatible(node, - "xlnx,axi-dma-mm2s-channel")) + if (of_device_is_compatible(node, "xlnx,axi-dma-mm2s-channel")) chan->direction = DMA_MEM_TO_DEV; - - if (of_device_is_compatible(node, - "xlnx,axi-dma-s2mm-channel")) + else if (of_device_is_compatible(node, "xlnx,axi-dma-s2mm-channel")) chan->direction = DMA_DEV_TO_MEM; - - } - - if (feature & XILINX_DMA_IP_VDMA) { + } else if (feature & XILINX_DMA_IP_VDMA) { chan->start_transfer = xilinx_vdma_start_transfer; - chan->has_SG = (xdev->feature & XILINX_DMA_FTR_HAS_SG) >> - XILINX_DMA_FTR_HAS_SG_SHIFT; - if (of_device_is_compatible(node, "xlnx,axi-vdma-mm2s-channel")) { chan->direction = DMA_MEM_TO_DEV; @@ -1704,9 +1368,6 @@ static int __devinit xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, ((u32)xdev->regs + XILINX_VDMA_DIRECT_REG_OFFSET); } - if (flush_fsync == XILINX_VDMA_FLUSH_BOTH || - flush_fsync == XILINX_VDMA_FLUSH_MM2S) - chan->flush_fsync = 1; } if (of_device_is_compatible(node, @@ -1718,140 +1379,113 @@ static int __devinit xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, XILINX_VDMA_DIRECT_REG_OFFSET + XILINX_VDMA_CHAN_DIRECT_REG_SIZE); } - if (flush_fsync == XILINX_VDMA_FLUSH_BOTH || - flush_fsync == XILINX_VDMA_FLUSH_S2MM) - chan->flush_fsync = 1; } } - chan->regs = (struct xdma_regs *)xdev->regs; - chan->id = 0; - - if (chan->direction == DMA_DEV_TO_MEM) { + if (chan->direction == DMA_MEM_TO_DEV) { + chan->regs = (struct xdma_regs *)xdev->regs; + chan->id = 0; + } else { chan->regs = (struct xdma_regs *)((u32)xdev->regs + XILINX_DMA_RX_CHANNEL_OFFSET); chan->id = 1; } + chan->debugfs_regset.regs = xilinx_dma_debugfs_regs; + chan->debugfs_regset.nregs = ARRAY_SIZE(xilinx_dma_debugfs_regs); + chan->debugfs_regset.base = (void __iomem *)chan->regs; + /* Used by dmatest channel matching in slave transfers * Can change it to be a structure to have more matching information */ - chan->private = (chan->direction & 0xFF) | - (chan->feature & XILINX_DMA_IP_MASK) | - (device_id << XILINX_DMA_DEVICE_ID_SHIFT); - chan->common.private = (void *)&(chan->private); + chan->common.private = (chan->direction & 0xFF) | + (chan->feature & XILINX_DMA_IP_MASK); if (!chan->has_DRE) - xdev->common.copy_align = my_log(width); + xdev->common.copy_align = ilog2(width); chan->dev = xdev->dev; xdev->chan[chan->id] = chan; tasklet_init(&chan->tasklet, dma_do_tasklet, (unsigned long)chan); - /* Initialize the channel */ - if (dma_init(chan)) { - dev_err(xdev->dev, "Reset channel failed\n"); - goto out_free_chan; - } - - - spin_lock_init(&chan->lock); - INIT_LIST_HEAD(&chan->pending_list); - INIT_LIST_HEAD(&chan->active_list); - chan->common.device = &xdev->common; /* find the IRQ line, if it exists in the device tree */ chan->irq = irq_of_parse_and_map(node, 0); - err = request_irq(chan->irq, dma_intr_handler, IRQF_SHARED, + ret = request_irq(chan->irq, dma_intr_handler, IRQF_SHARED, "xilinx-dma-controller", chan); - if (err) { - dev_err(xdev->dev, "unable to request IRQ\n"); + if (ret) { + dev_err(xdev->dev, "unable to request IRQ %d\n", ret); goto out_free_irq; } /* Add the channel to DMA device channel list */ list_add_tail(&chan->common.device_node, &xdev->common.channels); - xdev->common.chancnt++; - return 0; + /* Initialize the channel */ + if (xilinx_dma_reset(chan)) { + dev_err(xdev->dev, "Reset channel failed\n"); + goto out_free_chan; + } + return 0; out_free_irq: irq_dispose_mapping(chan->irq); out_free_chan: kfree(chan); out_return: - return err; + return ret; } -static int __devinit xilinx_dma_of_probe(struct platform_device *op) +static int __devinit xilinx_dma_of_probe(struct platform_device *pdev) { struct xilinx_dma_device *xdev; struct device_node *child, *node; - int err; + struct xilinx_dma_chan *chan; + u32 num_frames = 0; + u32 include_sg = 0; + unsigned int i; int *value; - int num_frames = 0; - - dev_info(&op->dev, "Probing xilinx axi dma engines\n"); + int ret; - xdev = kzalloc(sizeof(struct xilinx_dma_device), GFP_KERNEL); + xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL); if (!xdev) { - dev_err(&op->dev, "Not enough memory for device\n"); - err = -ENOMEM; - goto out_return; + dev_err(&pdev->dev, "Not enough memory for device\n"); + return -ENOMEM; } - xdev->dev = &(op->dev); + xdev->dev = &pdev->dev; INIT_LIST_HEAD(&xdev->common.channels); - node = op->dev.of_node; + node = pdev->dev.of_node; xdev->feature = 0; /* iomap registers */ xdev->regs = of_iomap(node, 0); if (!xdev->regs) { - dev_err(&op->dev, "unable to iomap registers\n"); - err = -ENOMEM; - goto out_free_xdev; - } - - /* Axi CDMA only does memcpy - */ - if (of_device_is_compatible(node, "xlnx,axi-cdma")) { - xdev->feature |= XILINX_DMA_IP_CDMA; - - value = (int *)of_get_property(node, "xlnx,include-sg", - NULL); - if (value) { - if (be32_to_cpup(value) == 1) - xdev->feature |= XILINX_DMA_FTR_HAS_SG; - } - - dma_cap_set(DMA_MEMCPY, xdev->common.cap_mask); - xdev->common.device_prep_dma_memcpy = xilinx_dma_prep_memcpy; - xdev->common.device_control = xilinx_dma_device_control; - xdev->common.device_issue_pending = xilinx_cdma_issue_pending; + dev_err(&pdev->dev, "unable to iomap registers\n"); + return -ENXIO; } /* Axi DMA and VDMA only do slave transfers */ if (of_device_is_compatible(node, "xlnx,axi-dma")) { - xdev->feature |= XILINX_DMA_IP_DMA; value = (int *)of_get_property(node, "xlnx,sg-include-stscntrl-strm", NULL); if (value) { - if (be32_to_cpup(value) == 1) { - xdev->feature |= (XILINX_DMA_FTR_STSCNTRL_STRM | - XILINX_DMA_FTR_HAS_SG); - } + xdev->feature |= XILINX_DMA_FTR_HAS_SG; + if (be32_to_cpup(value) == 1) + xdev->feature = XILINX_DMA_FTR_STSCNTRL_STRM; } dma_cap_set(DMA_SLAVE, xdev->common.cap_mask); dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask); + dma_cap_set(DMA_CYCLIC, xdev->common.cap_mask); xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg; + xdev->common.device_prep_dma_cyclic = xilinx_dma_prep_dma_cyclic; xdev->common.device_control = xilinx_dma_device_control; xdev->common.device_issue_pending = xilinx_dma_issue_pending; } @@ -1859,17 +1493,11 @@ static int __devinit xilinx_dma_of_probe(struct platform_device *op) if (of_device_is_compatible(node, "xlnx,axi-vdma")) { xdev->feature |= XILINX_DMA_IP_VDMA; - value = (int *)of_get_property(node, "xlnx,include-sg", - NULL); - if (value) { - if (be32_to_cpup(value) == 1) - xdev->feature |= XILINX_DMA_FTR_HAS_SG; - } + of_property_read_u32(node, "xlnx,include-sg", &include_sg); + if (include_sg) + xdev->feature |= XILINX_DMA_FTR_HAS_SG; - value = (int *)of_get_property(node, "xlnx,num-fstores", - NULL); - if (value) - num_frames = be32_to_cpup(value); + of_property_read_u32(node, "xlnx,num-fstores", &num_frames); value = (int *)of_get_property(node, "xlnx,flush-fsync", NULL); if (value) @@ -1880,7 +1508,7 @@ static int __devinit xilinx_dma_of_probe(struct platform_device *op) dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask); xdev->common.device_prep_slave_sg = xilinx_vdma_prep_slave_sg; xdev->common.device_control = xilinx_vdma_device_control; - xdev->common.device_issue_pending = xilinx_vdma_issue_pending; + xdev->common.device_issue_pending = xilinx_dma_issue_pending; } xdev->common.device_alloc_chan_resources = @@ -1888,40 +1516,50 @@ static int __devinit xilinx_dma_of_probe(struct platform_device *op) xdev->common.device_free_chan_resources = xilinx_dma_free_chan_resources; xdev->common.device_tx_status = xilinx_tx_status; - xdev->common.dev = &op->dev; - - dev_set_drvdata(&op->dev, xdev); + xdev->common.dev = &pdev->dev; for_each_child_of_node(node, child) { - xilinx_dma_chan_probe(xdev, child, xdev->feature); + ret = xilinx_dma_chan_probe(xdev, child, xdev->feature); + if (ret) + goto err_free_chan; } if (xdev->feature & XILINX_DMA_IP_VDMA) { - int i; - for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++) { if (xdev->chan[i]) xdev->chan[i]->num_frms = num_frames; } } - dma_async_device_register(&xdev->common); + ret = dma_async_device_register(&xdev->common); + if (ret) + goto err_free_chan; + + for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++) { + if (xdev->chan[i]) { + chan = xdev->chan[i]; + debugfs_create_regset32(dev_name(&chan->common.dev->device), S_IRUGO, NULL, &chan->debugfs_regset); + } + } + + platform_set_drvdata(pdev, xdev); return 0; -out_free_xdev: - kfree(xdev); +err_free_chan: + for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++) { + if (xdev->chan[i]) + xilinx_dma_chan_remove(xdev->chan[i]); + } -out_return: - return err; + return ret; } -static int __devexit xilinx_dma_of_remove(struct platform_device *op) +static int __devexit xilinx_dma_of_remove(struct platform_device *pdev) { - struct xilinx_dma_device *xdev; + struct xilinx_dma_device *xdev = platform_get_drvdata(pdev); int i; - xdev = dev_get_drvdata(&op->dev); dma_async_device_unregister(&xdev->common); for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++) { @@ -1930,16 +1568,13 @@ static int __devexit xilinx_dma_of_remove(struct platform_device *op) } iounmap(xdev->regs); - dev_set_drvdata(&op->dev, NULL); - kfree(xdev); return 0; } static const struct of_device_id xilinx_dma_of_ids[] = { - { .compatible = "xlnx,axi-cdma",}, - { .compatible = "xlnx,axi-dma",}, - { .compatible = "xlnx,axi-vdma",}, + { .compatible = "xlnx,axi-dma" }, + { .compatible = "xlnx,axi-vdma" }, {} }; @@ -1953,407 +1588,17 @@ static struct platform_driver xilinx_dma_of_driver = { .remove = __devexit_p(xilinx_dma_of_remove), }; -/*----------------------------------------------------------------------------*/ -/* Module Init / Exit */ -/*----------------------------------------------------------------------------*/ - -static __init int xilinx_dma_init(void) -{ - int ret; - - pr_info("Xilinx DMA driver\n"); - - ret = platform_driver_register(&xilinx_dma_of_driver); - if (ret) - pr_err("xilinx_dma: failed to register platform driver\n"); - - return ret; -} - -static void __exit xilinx_dma_exit(void) +static int __init xilinx_dma_init(void) { - platform_driver_unregister(&xilinx_dma_of_driver); + return platform_driver_register(&xilinx_dma_of_driver); } - subsys_initcall(xilinx_dma_init); -module_exit(xilinx_dma_exit); - -#else - -/**************************************************/ -/* Platform bus to support ARM before device tree */ -/**************************************************/ - -/* The following probe and chan_probe functions were - copied from the OF section above, then modified - to use platform data. -*/ - -static void xilinx_dma_chan_remove(struct xilinx_dma_chan *chan) -{ - free_irq(chan->irq, chan); - list_del(&chan->common.device_node); - kfree(chan); -} - -/* - * Probing channels - * - * . Get channel features from the device tree entry - * . Initialize special channel handling routines - */ -static int __devinit xilinx_dma_chan_probe(struct platform_device *pdev, - struct xilinx_dma_device *xdev, - struct dma_channel_config *channel_config, - int channel_num, u32 feature) -{ - struct xilinx_dma_chan *chan; - int err; - u32 width = 0; - struct resource *res; - - /* alloc channel */ - - - chan = kzalloc(sizeof(*chan), GFP_KERNEL); - if (!chan) { - dev_err(xdev->dev, "no free memory for DMA channels!\n"); - err = -ENOMEM; - goto out_return; - } - - chan->feature = feature; - chan->is_lite = 0; - chan->has_DRE = 0; - chan->has_SG = 0; - chan->max_len = XILINX_DMA_MAX_TRANS_LEN; - - if (channel_config->include_dre) - chan->has_DRE = 1; - - if (channel_config->genlock_mode) - chan->genlock = 1; - - width = channel_config->datawidth >> 3; - chan->feature |= width - 1; - - if (feature & XILINX_DMA_IP_CDMA) { - - chan->direction = DMA_MEM_TO_MEM; - chan->start_transfer = xilinx_cdma_start_transfer; - - chan->has_SG = (xdev->feature & XILINX_DMA_FTR_HAS_SG) >> - XILINX_DMA_FTR_HAS_SG_SHIFT; - - if (channel_config->lite_mode) { - chan->is_lite = 1; - chan->max_len = width * channel_config->max_burst_len; - } - } - - if (feature & XILINX_DMA_IP_DMA) { - chan->has_SG = 1; - chan->start_transfer = xilinx_dma_start_transfer; - - if (!strcmp(channel_config->type, "axi-dma-mm2s-channel")) - chan->direction = DMA_MEM_TO_DEV; - - if (!strcmp(channel_config->type, "axi-dma-s2mm-channel")) - chan->direction = DMA_DEV_TO_MEM; - } - - if (feature & XILINX_DMA_IP_VDMA) { - - chan->start_transfer = xilinx_vdma_start_transfer; - - chan->has_SG = (xdev->feature & XILINX_DMA_FTR_HAS_SG) >> - XILINX_DMA_FTR_HAS_SG_SHIFT; - - if (!strcmp(channel_config->type, "axi-vdma-mm2s-channel")) { - - printk(KERN_INFO, "axi-vdma-mm2s-channel found\n"); - - chan->direction = DMA_MEM_TO_DEV; - if (!chan->has_SG) { - chan->addr_regs = (struct vdma_addr_regs *) - ((u32)xdev->regs + - XILINX_VDMA_DIRECT_REG_OFFSET); - } - } - - if (!strcmp(channel_config->type, "axi-vdma-s2mm-channel")) { - - printk(KERN_INFO, "axi-vdma-s2mm-channel found\n"); - - chan->direction = DMA_DEV_TO_MEM; - if (!chan->has_SG) { - chan->addr_regs = (struct vdma_addr_regs *) - ((u32)xdev->regs + - XILINX_VDMA_DIRECT_REG_OFFSET + - XILINX_VDMA_CHAN_DIRECT_REG_SIZE); - } - } - } - - chan->regs = (struct xdma_regs *)xdev->regs; - chan->id = 0; - - if (chan->direction == DMA_DEV_TO_MEM) { - chan->regs = (struct xdma_regs *)((u32)xdev->regs + - XILINX_DMA_RX_CHANNEL_OFFSET); - chan->id = 1; - } - - /* Used by dmatest channel matching in slave transfers - * Can change it to be a structure to have more matching information - */ - chan->private = (chan->direction & 0xFF) | - (chan->feature & XILINX_DMA_IP_MASK); - chan->common.private = (void *)&(chan->private); - - if (!chan->has_DRE) - xdev->common.copy_align = my_log(width); - - chan->dev = xdev->dev; - xdev->chan[chan->id] = chan; - - tasklet_init(&chan->tasklet, dma_do_tasklet, (unsigned long)chan); - - /* Initialize the channel */ - if (dma_init(chan)) { - dev_err(xdev->dev, "Reset channel failed\n"); - goto out_free_chan; - } - - - spin_lock_init(&chan->lock); - INIT_LIST_HEAD(&chan->pending_list); - INIT_LIST_HEAD(&chan->active_list); - - chan->common.device = &xdev->common; - - /* setup the interrupt for the channel */ - - res = platform_get_resource(pdev, IORESOURCE_IRQ, channel_num); - chan->irq = res->start; - - err = request_irq(chan->irq, dma_intr_handler, IRQF_SHARED, - "xilinx-dma-controller", chan); - if (err) { - dev_err(xdev->dev, "unable to request IRQ\n"); - goto out_free_irq; - } else - dev_info(&pdev->dev, "using irq %d\n", chan->irq); - - /* Add the channel to DMA device channel list */ - list_add_tail(&chan->common.device_node, &xdev->common.channels); - xdev->common.chancnt++; - - return 0; - -out_free_irq: - free_irq(chan->irq, chan); -out_free_chan: - kfree(chan); -out_return: - return err; -} - -static int __devinit xilinx_dma_probe(struct platform_device *pdev) -{ - struct xilinx_dma_device *xdev; - int err; - int num_frames = 0; - struct resource *res; - struct device *dev = &pdev->dev; - struct dma_device_config *dma_config; - int channel; - - dev_info(&pdev->dev, "Probing xilinx axi dma engines\n"); - - xdev = kzalloc(sizeof(struct xilinx_dma_device), GFP_KERNEL); - if (!xdev) { - dev_err(&pdev->dev, "Not enough memory for device\n"); - err = -ENOMEM; - goto out_return; - } - - xdev->dev = &(pdev->dev); - INIT_LIST_HEAD(&xdev->common.channels); - - xdev->feature = 0; - - /* iomap registers */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - printk(KERN_ERR "get_resource for MEM resource for dev %d " - "failed\n", pdev->id); - err = -ENOMEM; - goto out_return; - } else { - dev_info(&pdev->dev, "device %d actual base is %x\n", - pdev->id, (unsigned int)res->start); - } - if (!request_mem_region(res->start, 0x1000, "xilinx_axidma")) { - printk(KERN_ERR "memory request failue for base %x\n", - (unsigned int)res->start); - err = -ENOMEM; - goto out_return; - } - - xdev->regs = ioremap(res->start, 0x1000); - pr_info("dma base remapped: %lx\n", (unsigned long)xdev->regs); - if (!xdev->regs) { - dev_err(&pdev->dev, "unable to iomap registers\n"); - err = -ENOMEM; - goto out_free_xdev; - } - - dma_config = (struct dma_device_config *)dev->platform_data; - - /* Axi CDMA only does memcpy - */ - if (!strcmp(dma_config->type, "axi-cdma")) { - - pr_info("found an axi-cdma configuration\n"); - xdev->feature |= XILINX_DMA_IP_CDMA; - - if (dma_config->include_sg) - xdev->feature |= XILINX_DMA_FTR_HAS_SG; - - dma_cap_set(DMA_MEMCPY, xdev->common.cap_mask); - xdev->common.device_prep_dma_memcpy = xilinx_dma_prep_memcpy; - xdev->common.device_control = xilinx_dma_device_control; - xdev->common.device_issue_pending = xilinx_cdma_issue_pending; - } - - /* Axi DMA and VDMA only do slave transfers - */ - if (!strcmp(dma_config->type, "axi-dma")) { - - pr_info("found an axi-dma configuration\n"); - - xdev->feature |= XILINX_DMA_IP_DMA; - if (dma_config->sg_include_stscntrl_strm) - xdev->feature |= XILINX_DMA_FTR_STSCNTRL_STRM; - - dma_cap_set(DMA_SLAVE, xdev->common.cap_mask); - dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask); - xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg; - xdev->common.device_control = xilinx_dma_device_control; - xdev->common.device_issue_pending = xilinx_dma_issue_pending; - } - - if (!strcmp(dma_config->type, "axi-vdma")) { - - pr_info("found an axi-vdma configuration\n"); - - xdev->feature |= XILINX_DMA_IP_VDMA; - - if (dma_config->include_sg) - xdev->feature |= XILINX_DMA_FTR_HAS_SG; - - num_frames = dma_config->num_fstores; - - dma_cap_set(DMA_SLAVE, xdev->common.cap_mask); - dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask); - xdev->common.device_prep_slave_sg = xilinx_vdma_prep_slave_sg; - xdev->common.device_control = xilinx_vdma_device_control; - xdev->common.device_issue_pending = xilinx_vdma_issue_pending; - } - - xdev->common.device_alloc_chan_resources = - xilinx_dma_alloc_chan_resources; - xdev->common.device_free_chan_resources = - xilinx_dma_free_chan_resources; - xdev->common.device_tx_status = xilinx_tx_status; - xdev->common.dev = &pdev->dev; - - dev_set_drvdata(&pdev->dev, xdev); - - for (channel = 0; channel < dma_config->channel_count; channel++) - xilinx_dma_chan_probe(pdev, xdev, - &dma_config->channel_config[channel], - channel, xdev->feature); - - if (xdev->feature & XILINX_DMA_IP_VDMA) { - int i; - - for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++) { - if (xdev->chan[i]) - xdev->chan[i]->num_frms = num_frames; - } - } - - dma_async_device_register(&xdev->common); - - return 0; - -out_free_xdev: - kfree(xdev); - -out_return: - return err; -} - - -static int __exit xilinx_dma_remove(struct platform_device *pdev) -{ - struct xilinx_dma_device *xdev = platform_get_drvdata(pdev); - int i; -#if 1 - dma_async_device_unregister(&xdev->common); -#endif - for (i = 0; i < 2; i++) { - if (xdev->chan[i]) - xilinx_dma_chan_remove(xdev->chan[i]); - } - - iounmap(xdev->regs); - dev_set_drvdata(&pdev->dev, NULL); - kfree(xdev); - - return 0; -} - -static void xilinx_dma_shutdown(struct platform_device *pdev) -{ - struct xilinx_dma_device *xdev = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < 2; i++) - dma_halt(xdev->chan[i]); -} - -static struct platform_driver xilinx_dma_driver = { - .probe = xilinx_dma_probe, - .remove = __exit_p(xilinx_dma_remove), - .shutdown = xilinx_dma_shutdown, - .driver = { - .owner = THIS_MODULE, - .name = "xilinx-axidma", - }, -}; - -/*----------------------------------------------------------------------------*/ -/* Module Init / Exit */ -/*----------------------------------------------------------------------------*/ - -static __init int xilinx_dma_init(void) -{ - int status; - status = platform_driver_register(&xilinx_dma_driver); - return status; -} -module_init(xilinx_dma_init); static void __exit xilinx_dma_exit(void) { - platform_driver_unregister(&xilinx_dma_driver); + platform_driver_unregister(&xilinx_dma_of_driver); } - module_exit(xilinx_dma_exit); -#endif -MODULE_DESCRIPTION("Xilinx DMA/CDMA/VDMA driver"); +MODULE_DESCRIPTION("Xilinx DMA/VDMA driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 90e28081712db..453a226062843 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -54,6 +54,22 @@ config DRM_TTM GPU memory types. Will be enabled automatically if a device driver uses it. +config DRM_GEM_CMA_HELPER + bool + depends on DRM + help + Choose this if you need the GEM CMA helper functions + +config DRM_KMS_CMA_HELPER + tristate + select DRM_GEM_CMA_HELPER + select DRM_KMS_HELPER + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + help + Choose this if you need the KMS cma helper functions + config DRM_TDFX tristate "3dfx Banshee/Voodoo3+" depends on DRM && PCI @@ -180,6 +196,14 @@ config DRM_SAVAGE Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister chipset. If M is selected the module will be called savage. +config DRM_ENCODER_ADV7511 + tristate "AV7511 encoder" + depends on DRM + select REGMAP_I2C + select DRM_ANALOG + +source "drivers/gpu/drm/analog/Kconfig" + source "drivers/gpu/drm/exynos/Kconfig" source "drivers/gpu/drm/vmwgfx/Kconfig" diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index f65f65ed0ddfc..0839856deac87 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -15,13 +15,17 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ drm_trace_points.o drm_global.o drm_prime.o drm-$(CONFIG_COMPAT) += drm_ioc32.o +drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o drm-usb-y := drm_usb.o drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o drm_dp_i2c_helper.o drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o +drm_kms_cma_helper-y += drm_fb_cma_helper.o + obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o +obj-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_kms_cma_helper.o CFLAGS_drm_trace_points.o := -I$(src) @@ -43,6 +47,7 @@ obj-$(CONFIG_DRM_VIA) +=via/ obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/ obj-$(CONFIG_DRM_EXYNOS) +=exynos/ obj-$(CONFIG_DRM_GMA500) += gma500/ +obj-$(CONFIG_DRM_ANALOG) += analog/ obj-$(CONFIG_DRM_UDL) += udl/ obj-$(CONFIG_DRM_AST) += ast/ obj-y += i2c/ diff --git a/drivers/gpu/drm/analog/Kconfig b/drivers/gpu/drm/analog/Kconfig new file mode 100644 index 0000000000000..6f2f8c9eb3873 --- /dev/null +++ b/drivers/gpu/drm/analog/Kconfig @@ -0,0 +1,6 @@ +config DRM_ANALOG + tristate "DRM Support for Analog FPGA platforms" + depends on DRM + default n + select DRM_KMS_CMA_HELPER + select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE diff --git a/drivers/gpu/drm/analog/Makefile b/drivers/gpu/drm/analog/Makefile new file mode 100644 index 0000000000000..01c8376cf9771 --- /dev/null +++ b/drivers/gpu/drm/analog/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the drm device driver. This driver provides support for the +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. + +analogdrm-y := analog_drm_encoder.o analog_drm_crtc.o analog_drm_drv.o + +obj-$(CONFIG_DRM_ANALOG) += analogdrm.o diff --git a/drivers/gpu/drm/analog/analog_drm_crtc.c b/drivers/gpu/drm/analog/analog_drm_crtc.c new file mode 100644 index 0000000000000..4b8459dbe4bf5 --- /dev/null +++ b/drivers/gpu/drm/analog/analog_drm_crtc.c @@ -0,0 +1,177 @@ +#include +#include +#include +#include +#include + +#include "analog_drm_crtc.h" +#include "analog_drm_drv.h" +#include "analog_drm_encoder.h" + +struct analog_drm_crtc { + struct drm_crtc drm_crtc; + struct dma_chan *dma; + struct xilinx_dma_config dma_config; + int mode; +}; + +static inline struct analog_drm_crtc *to_analog_crtc(struct drm_crtc *crtc) +{ + return container_of(crtc, struct analog_drm_crtc, drm_crtc); +} + +static int analog_drm_crtc_update(struct drm_crtc *crtc) +{ + struct analog_drm_crtc *analog_crtc = to_analog_crtc(crtc); + struct drm_display_mode *mode = &crtc->mode; + struct drm_framebuffer *fb = crtc->fb; + struct dma_async_tx_descriptor *desc; + struct drm_gem_cma_object *obj; + size_t offset; + + if (!mode || !fb) + return -EINVAL; + + if (analog_crtc->mode == DRM_MODE_DPMS_ON) { + obj = drm_fb_cma_get_gem_obj(fb, 0); + if (!obj) + return -EINVAL; + + analog_crtc->dma_config.hsize = mode->hdisplay * fb->bits_per_pixel / 8; + analog_crtc->dma_config.vsize = mode->vdisplay; + analog_crtc->dma_config.stride = fb->pitches[0]; + + dmaengine_device_control(analog_crtc->dma, DMA_SLAVE_CONFIG, + (unsigned long)&analog_crtc->dma_config); + + offset = crtc->x * fb->bits_per_pixel / 8 + crtc->y * fb->pitches[0]; + + desc = dmaengine_prep_slave_single(analog_crtc->dma, + obj->paddr + offset, + mode->vdisplay * fb->pitches[0], + DMA_MEM_TO_DEV, 0); + if (!desc) { + pr_err("Failed to prepare DMA descriptor\n"); + return -ENOMEM; + } else { + dmaengine_submit(desc); + dma_async_issue_pending(analog_crtc->dma); + } + } else { + dmaengine_terminate_all(analog_crtc->dma); + } + + return 0; +} + +static void analog_drm_crtc_dpms(struct drm_crtc *crtc, int mode) +{ + struct analog_drm_crtc *analog_crtc = to_analog_crtc(crtc); + + if (analog_crtc->mode != mode) { + analog_crtc->mode = mode; + analog_drm_crtc_update(crtc); + } +} + +static void analog_drm_crtc_prepare(struct drm_crtc *crtc) +{ + struct analog_drm_crtc *analog_crtc = to_analog_crtc(crtc); + + dmaengine_terminate_all(analog_crtc->dma); +} + +static void analog_drm_crtc_commit(struct drm_crtc *crtc) +{ + struct analog_drm_crtc *analog_crtc = to_analog_crtc(crtc); + + analog_crtc->mode = DRM_MODE_DPMS_ON; + analog_drm_crtc_update(crtc); +} + +static bool +analog_drm_crtc_mode_fixup(struct drm_crtc *crtc, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + return true; +} + +static int +analog_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, int x, int y, + struct drm_framebuffer *old_fb) +{ + /* We do everything in commit() */ + return 0; +} + +static int analog_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, + struct drm_framebuffer *old_fb) +{ + return analog_drm_crtc_update(crtc); +} + +static void analog_drm_crtc_load_lut(struct drm_crtc *crtc) +{ +} + +static struct drm_crtc_helper_funcs analog_crtc_helper_funcs = { + .dpms = analog_drm_crtc_dpms, + .prepare = analog_drm_crtc_prepare, + .commit = analog_drm_crtc_commit, + .mode_fixup = analog_drm_crtc_mode_fixup, + .mode_set = analog_drm_crtc_mode_set, + .mode_set_base = analog_drm_crtc_mode_set_base, + .load_lut = analog_drm_crtc_load_lut, +}; + +static void analog_drm_crtc_destroy(struct drm_crtc *crtc) +{ + struct analog_drm_crtc *analog_crtc = to_analog_crtc(crtc); + + drm_crtc_cleanup(crtc); + dma_release_channel(analog_crtc->dma); + kfree(analog_crtc); +} + +static struct drm_crtc_funcs analog_crtc_funcs = { + .set_config = drm_crtc_helper_set_config, + .destroy = analog_drm_crtc_destroy, +}; + +static bool xlnx_pcm_filter(struct dma_chan *chan, void *param) +{ + struct xlnx_pcm_dma_params *p = param; + + return chan->device->dev->of_node == p->of_node && + chan->chan_id == p->chan_id; +} + +struct drm_crtc *analog_drm_crtc_create(struct drm_device *dev) +{ + struct analog_drm_private *p = dev->dev_private; + struct analog_drm_crtc *analog_crtc; + struct drm_crtc *crtc; + dma_cap_mask_t mask; + + analog_crtc = kzalloc(sizeof(*analog_crtc), GFP_KERNEL); + if (!analog_crtc) { + DRM_ERROR("failed to allocate analog crtc\n"); + return ERR_PTR(-ENOMEM); + } + + crtc = &analog_crtc->drm_crtc; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + dma_cap_set(DMA_PRIVATE, mask); + + analog_crtc->dma = dma_request_channel(mask, xlnx_pcm_filter, + &p->dma_params); + + drm_crtc_init(dev, crtc, &analog_crtc_funcs); + drm_crtc_helper_add(crtc, &analog_crtc_helper_funcs); + + return crtc; +} diff --git a/drivers/gpu/drm/analog/analog_drm_crtc.h b/drivers/gpu/drm/analog/analog_drm_crtc.h new file mode 100644 index 0000000000000..6585042d154b6 --- /dev/null +++ b/drivers/gpu/drm/analog/analog_drm_crtc.h @@ -0,0 +1,9 @@ +#ifndef _ANALOG_DRM_CRTC_H_ +#define _ANALOG_DRM_CRTC_H_ + +struct drm_device; +struct drm_crtc; + +struct drm_crtc* analog_drm_crtc_create(struct drm_device *dev); + +#endif diff --git a/drivers/gpu/drm/analog/analog_drm_drv.c b/drivers/gpu/drm/analog/analog_drm_drv.c new file mode 100644 index 0000000000000..27eae0196c7ea --- /dev/null +++ b/drivers/gpu/drm/analog/analog_drm_drv.c @@ -0,0 +1,245 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "analog_drm_drv.h" +#include "analog_drm_crtc.h" +#include "analog_drm_encoder.h" + +#define DRIVER_NAME "analog_drm" +#define DRIVER_DESC "ANALOG DRM" +#define DRIVER_DATE "20110530" +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 0 + +static struct platform_device *analog_drm_pdev; +static struct i2c_adapter *slave_adapter; +static struct i2c_adapter *ddc_adapter; + +static void analog_drm_output_poll_changed(struct drm_device *dev) +{ + struct analog_drm_private *private = dev->dev_private; + drm_fbdev_cma_hotplug_event(private->fbdev); +} + +static struct drm_mode_config_funcs analog_drm_mode_config_funcs = { + .fb_create = drm_fb_cma_create, + .output_poll_changed = analog_drm_output_poll_changed, +}; + +static void analog_drm_mode_config_init(struct drm_device *dev) +{ + dev->mode_config.min_width = 0; + dev->mode_config.min_height = 0; + + dev->mode_config.max_width = 4096; + dev->mode_config.max_height = 4096; + + dev->mode_config.funcs = &analog_drm_mode_config_funcs; +} + +static int analog_drm_load(struct drm_device *dev, unsigned long flags) +{ + struct analog_drm_private *private; + struct of_phandle_args dma_spec; + struct device_node *of_node; + int ret; + + ret = of_parse_phandle_with_args(analog_drm_pdev->dev.of_node, "dma-request", + "#dma-cells", 0, &dma_spec); + if (ret) + return ret; + + private = kzalloc(sizeof(struct analog_drm_private), GFP_KERNEL); + if (!private) + return -ENOMEM; + + dev->dev_private = (void *)private; + + private->dma_params.of_node = dma_spec.np; + private->dma_params.chan_id = dma_spec.args[0]; + + drm_mode_config_init(dev); + + /* init kms poll for handling hpd */ + drm_kms_helper_poll_init(dev); + + analog_drm_mode_config_init(dev); + + private->crtc = analog_drm_crtc_create(dev); + if (IS_ERR(private->crtc)) { + ret = PTR_ERR(private->crtc); + goto err_crtc; + } + + of_node = dev->platformdev->dev.of_node; + private->base = of_iomap(of_node, 0); + private->base_clock = of_iomap(of_node, 1); + + private->ddc_adapter = ddc_adapter; + private->slave_adapter = slave_adapter; + + analog_drm_encoder_create(dev); + private->fbdev = drm_fbdev_cma_init(dev, 32, 1, 1); + if (IS_ERR(private->fbdev)) { + DRM_ERROR("failed to initialize drm fbdev\n"); + ret = PTR_ERR(private->fbdev); + goto err_drm_device; + } + + return 0; + +err_drm_device: +/* analog_drm_device_unregister(dev);*/ +err_crtc: + drm_mode_config_cleanup(dev); + kfree(private); + + return ret; +} + +static int analog_drm_unload(struct drm_device *dev) +{ + struct analog_drm_private *private = dev->dev_private; + + drm_fbdev_cma_fini(private->fbdev); + /*analog_drm_device_unregister(dev);*/ + drm_kms_helper_poll_fini(dev); + drm_mode_config_cleanup(dev); + + iounmap(private->base); + iounmap(private->base_clock); + + kfree(dev->dev_private); + + return 0; +} + +static void analog_drm_lastclose(struct drm_device *dev) +{ + struct analog_drm_private *private = dev->dev_private; + drm_fbdev_cma_restore_mode(private->fbdev); +} + +static const struct file_operations analog_drm_driver_fops = { + .owner = THIS_MODULE, + .open = drm_open, + .mmap = drm_gem_cma_mmap, + .poll = drm_poll, + .read = drm_read, + .unlocked_ioctl = drm_ioctl, + .release = drm_release, +}; + +static struct drm_driver analog_drm_driver = { + .driver_features = DRIVER_BUS_PLATFORM | + DRIVER_MODESET | DRIVER_GEM, + .load = analog_drm_load, + .unload = analog_drm_unload, + .lastclose = analog_drm_lastclose, + .gem_free_object = drm_gem_cma_free_object, + .gem_vm_ops = &drm_gem_cma_vm_ops, + .dumb_create = drm_gem_cma_dumb_create, + .dumb_map_offset = drm_gem_cma_dumb_map_offset, + .dumb_destroy = drm_gem_cma_dumb_destroy, + .fops = &analog_drm_driver_fops, + .name = DRIVER_NAME, + .desc = DRIVER_DESC, + .date = DRIVER_DATE, + .major = DRIVER_MAJOR, + .minor = DRIVER_MINOR, +}; + +static void drm_register_work(struct work_struct *work) +{ + drm_platform_init(&analog_drm_driver, analog_drm_pdev); +} + +static DECLARE_WORK(register_work, drm_register_work); + +static int analog_drm_attach_i2c_adapter(struct device *dev, void *data) +{ + struct device_node *of_node; + + if (dev->type != &i2c_adapter_type) + return 0; + + if (analog_drm_pdev == NULL || dev->of_node == NULL) + return 0; + + if (/*ddc_adapter && */slave_adapter) + return 0; + + of_node = analog_drm_pdev->dev.of_node; + + +/* if (dev->of_node == of_parse_phandle(of_node, "ddc_adapter", 0)) + ddc_adapter = to_i2c_adapter(dev); + else*/ if (dev->of_node == of_parse_phandle(of_node, "slave_adapter", 0)) + slave_adapter = to_i2c_adapter(dev); + + if (/*ddc_adapter && */slave_adapter) + schedule_work(®ister_work); + + return 0; +} + +static int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action, + void *data) +{ + struct device *dev = data; + + switch (action) { + case BUS_NOTIFY_ADD_DEVICE: + analog_drm_attach_i2c_adapter(dev, NULL); + } + + return 0; +} + +static struct notifier_block i2cdev_notifier = { + .notifier_call = i2cdev_notifier_call, +}; + +static int analog_drm_platform_probe(struct platform_device *pdev) +{ + analog_drm_pdev = pdev; + bus_register_notifier(&i2c_bus_type, &i2cdev_notifier); + i2c_for_each_dev(NULL, analog_drm_attach_i2c_adapter); + + return 0; +} + +static int analog_drm_platform_remove(struct platform_device *pdev) +{ + drm_platform_exit(&analog_drm_driver, pdev); + return 0; +} +static const struct of_device_id adv7511_encoder_of_match[] __devinitconst = { + { .compatible = "adi,cf-adv7x11-core-1.00.a", }, + {}, +}; +MODULE_DEVICE_TABLE(of, adv7511_encoder_of_match); + +static struct platform_driver adv7511_encoder_driver = { + .driver = { + .name = "cf-adv7x11-core", + .owner = THIS_MODULE, + .of_match_table = adv7511_encoder_of_match, + }, + .probe = analog_drm_platform_probe, + .remove = __devexit_p(analog_drm_platform_remove), +}; +module_platform_driver(adv7511_encoder_driver); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("DRM support for Analog Devices FPGA platforms"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/analog/analog_drm_drv.h b/drivers/gpu/drm/analog/analog_drm_drv.h new file mode 100644 index 0000000000000..c0b1fc686c21b --- /dev/null +++ b/drivers/gpu/drm/analog/analog_drm_drv.h @@ -0,0 +1,28 @@ +#ifndef _ANALOG_DRM_DRV_H_ +#define _ANALOG_DRM_DRV_H_ + +#include +#include +#include + +struct xlnx_pcm_dma_params { + struct device_node *of_node; + int chan_id; +}; + +struct analog_drm_encoder; + +struct analog_drm_private { + struct drm_fbdev_cma *fbdev; + struct drm_crtc *crtc; + struct analog_drm_encoder *encoder; + struct i2c_adapter *ddc_adapter; + struct i2c_adapter *slave_adapter; + + void __iomem *base; + void __iomem *base_clock; + + struct xlnx_pcm_dma_params dma_params; +}; + +#endif diff --git a/drivers/gpu/drm/analog/analog_drm_encoder.c b/drivers/gpu/drm/analog/analog_drm_encoder.c new file mode 100644 index 0000000000000..c36b59dac6cb8 --- /dev/null +++ b/drivers/gpu/drm/analog/analog_drm_encoder.c @@ -0,0 +1,666 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "analog_drm_drv.h" + +#include "../i2c/adv7511.h" + +#define ANALOG_REG_CTRL 0x04 +#define ANALOG_REG_HTIMING1 0x08 +#define ANALOG_REG_HTIMING2 0x0C +/* +#define ANALOG_REG_VTIMING 0x0c +*/ +#define ANALOG_REG_VTIMING1 0x10 +#define ANALOG_REG_VTIMING2 0x14 +#define ANALOG_REG_STATUS 0x10 +#define ANALOG_REG_COLOR_PATTERN 0x1c + +#define ANALOG_CTRL_ENABLE BIT(0) +#define ANALOG_CTRL_CSC_BYPASS BIT(1) +#define ANALOG_CTRL_TPG_ENABLE BIT(2) + +#define ANALOG_STATUS_VMDA_UNDERFLOW BIT(4) +#define ANALOG_STATUS_VMDA_OVERFLOW BIT(3) +#define ANALOG_STATUS_VMDA_BE_ERROR BIT(2) +#define ANALOG_STATUS_VMDA_TPM_OOS BIT(1) +#define ANALOG_STATUS_HDMI_TPM_OOS BIT(0) + +#define ANALOG_COLOR_PATTERN_ENABLE BIT(24) + +static struct debugfs_reg32 analog_drm_encoder_debugfs_regs[] = { + { "Control", ANALOG_REG_CTRL }, + { "HTiming1", ANALOG_REG_HTIMING1 }, + { "HTiming2", ANALOG_REG_HTIMING2 }, + { "VTiming1", ANALOG_REG_VTIMING1 }, + { "VTiming2", ANALOG_REG_VTIMING2 }, + { "Status", ANALOG_REG_STATUS }, +}; + +static uint16_t adv7511_csc_ycbcr_to_rgb[] = { + 0x0734, 0x04ad, 0x0000, 0x1c1b, + 0x1ddc, 0x04ad, 0x1f24, 0x0135, + 0x0000, 0x04ad, 0x087c, 0x1b77, +}; +/* +static struct adv7511_video_input_config adv7511_config_imageon = { + .id = ADV7511_INPUT_ID_16_20_24BIT_YCbCr422_EMBEDDED_SYNC, + .input_style = ADV7511_INPUT_STYLE1, + .sync_pulse = ADV7511_INPUT_SYNC_PULSE_NONE, + .clock_delay = ADV7511_INPUT_CLOCK_DELAY_NONE, + .reverse_bitorder = 0, + .bit_justification = 0, + .vsync_polartity_low = false, + .hsync_polartity_low = false, + .up_conversion_first_order_interpolation = false, + .input_color_depth = ADV7511_INPUT_COLOR_DEPTH_8BIT, + .output_format = ADV7511_OUTPUT_FORMAT_RGB_444, + .csc_enable = true, + .csc_coefficents = adv7511_csc_ycbcr_to_rgb, + .csc_scaling_factor = 3, + .bit_justification = ADV7511_INPUT_BIT_JUSTIFICATION_LEFT, +}; +*/ + +static struct adv7511_video_input_config adv7511_config_zc702 = { + .id = ADV7511_INPUT_ID_16_20_24BIT_YCbCr422_SEPARATE_SYNC, + .input_style = ADV7511_INPUT_STYLE1, + .sync_pulse = ADV7511_INPUT_SYNC_PULSE_NONE, + .clock_delay = ADV7511_INPUT_CLOCK_DELAY_NONE, + .reverse_bitorder = 0, + .vsync_polartity_low = false, + .hsync_polartity_low = false, + .up_conversion_first_order_interpolation = false, + .input_color_depth = ADV7511_INPUT_COLOR_DEPTH_8BIT, + .output_format = ADV7511_OUTPUT_FORMAT_RGB_444, + .csc_enable = true, + .csc_coefficents = adv7511_csc_ycbcr_to_rgb, + .csc_scaling_factor = ADV7511_CSC_SCALING_4, + .bit_justification = ADV7511_INPUT_BIT_JUSTIFICATION_RIGHT, + .tmds_clock_inversion = true, +}; + +struct analog_drm_encoder { + struct drm_encoder_slave encoder; + struct drm_connector connector; + + struct debugfs_regset32 regset; +}; + +static inline struct analog_drm_encoder *to_analog_encoder(struct drm_encoder *enc) +{ + return container_of(enc, struct analog_drm_encoder, encoder.base); +} + +static inline struct drm_encoder *connector_to_encoder(struct drm_connector *connector) +{ + struct analog_drm_encoder *enc = container_of(connector, struct analog_drm_encoder, connector); + return &enc->encoder.base; +} + +static int analog_drm_connector_init(struct drm_device *dev, + struct drm_connector *connector, struct drm_encoder *encoder); + +static inline struct drm_encoder_slave_funcs * +get_slave_funcs(struct drm_encoder *enc) +{ + if (!to_encoder_slave(enc)) + return NULL; + + return to_encoder_slave(enc)->slave_funcs; +} + +static int debugfs_cp_get(void *data, u64 *val) +{ + struct analog_drm_private *private = data; + *val = ioread32(private->base + ANALOG_REG_COLOR_PATTERN); + return 0; +} + +static int debugfs_cp_set(void *data, u64 val) +{ + struct analog_drm_private *private = data; + iowrite32(0x0000000, private->base + ANALOG_REG_COLOR_PATTERN); + iowrite32(0x1000000 | val, private->base + ANALOG_REG_COLOR_PATTERN); + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(fops_cp, debugfs_cp_get, debugfs_cp_set, "0x%08llx\n"); + +static void analog_drm_encoder_dpms(struct drm_encoder *encoder, int mode) +{ + struct analog_drm_encoder *analog_encoder = to_analog_encoder(encoder); + struct drm_connector *connector = &analog_encoder->connector; + struct analog_drm_private *private = encoder->dev->dev_private; + struct drm_encoder_slave_funcs *sfuncs = get_slave_funcs(encoder); + struct adv7511_video_input_config config = adv7511_config_zc702; + + switch (mode) { + case DRM_MODE_DPMS_ON: + iowrite32(ANALOG_CTRL_ENABLE, private->base + ANALOG_REG_CTRL); + if (connector->display_info.raw_edid) { + struct edid *edid = (struct edid *)connector->display_info.raw_edid; + config.hdmi_mode = drm_detect_hdmi_monitor(edid); + } else { + config.hdmi_mode = false; + } + + printk("raw_edid: %p %d\n", connector->display_info.raw_edid, + connector->display_info.color_formats); + + if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCRCB422) && + config.hdmi_mode) { + config.csc_enable = false; + config.output_format = ADV7511_OUTPUT_FORMAT_YCBCR_422; + pr_info("Using YCbCr output\n"); + } else { + config.csc_enable = true; + config.output_format = ADV7511_OUTPUT_FORMAT_RGB_444; + pr_info("Using RGB output\n"); + } + + sfuncs->set_config(encoder, &config); + break; + default: + iowrite32(0, private->base + ANALOG_REG_CTRL); + break; + } + + if (sfuncs && sfuncs->dpms) + sfuncs->dpms(encoder, mode); +} + +struct analog_drm_crtc_clock_setting { + long clock; + uint32_t settings[10]; +}; + +static const struct analog_drm_crtc_clock_setting clock_settings[] = { + { /* 162 Mhz */ + .clock = 162000, + .settings = { + 0x00c4, 0x0080, 0x2042, 0x0209, 0x0080, + 0x023f, 0x7c01, 0x7fe9, 0x0100, 0x1090, + }, + }, + { /* 154 Mhz */ + .clock = 154000, + .settings = { + 0x0082, 0x0000, 0x2187, 0x0514, 0x0000, + 0x00fa, 0x7c01, 0x7fe9, 0x0800, 0x1090, + }, + }, + { /* 148.5 Mhz */ + .clock = 148500, + .settings = { + 0x00c3, 0x0000, 0x2146, 0x0619, 0x0080, + 0x00fa, 0x7c01, 0x7fe9, 0x0800, 0x8090, + }, + }, + { /* 146.25 Mhz */ + .clock = 146250, + .settings = { + 0x00c3, 0x0000, 0x2187, 0x071d, 0x0080, + 0x00fa, 0x7c01, 0x7fe9, 0x0800, 0x8090, + }, + }, + { /* 138.5 Mhz */ + .clock = 138500, + .settings = { + 0x0083, 0x0080, 0x2187, 0x0597, 0x0080, + 0x00fa, 0x7c01, 0x7fe9, 0x0800, 0x1090, + }, + }, + { /* 135 Mhz */ + .clock = 135000, + .settings = { + 0x0104, 0x0000, 0x2083, 0x034e, 0x0080, + 0x015e, 0x7c01, 0x7fe9, 0x0100, 0x8090, + }, + }, + { /* 108 Mhz */ + .clock = 108000, + .settings = { + 0x0145, 0x0000, 0x2083, 0x034e, 0x0080, + 0x015e, 0x7c01, 0x7fe9, 0x0100, 0x8090, + }, + }, + { /* 106.5 Mhz */ + .clock = 106500, + .settings = { + 0x00c4, 0x0080, 0x2146, 0x0515, 0x0080, + 0x00fa, 0x7c01, 0x7fe9, 0x0800, 0x1090, + }, + }, + { /* 78.8 Mhz */ + .clock = 78800, + .settings = { + 0x0146, 0x0080, 0x2042, 0x0187, 0x0080, + 0x02ee, 0x7c01, 0x7fe9, 0x0800, 0x9090, + }, + }, + { /* 75 Mhz */ + .clock = 75000, + .settings = { + 0x0104, 0x0000, 0x1041, 0x0042, 0x0080, + 0x03e8, 0x2001, 0x23e9, 0x0100, 0x9890, + }, + }, + { /* 74.25 Mhz */ + .clock = 74250, + .settings = { + 0x0186, 0x0000, 0x2146, 0x0619, 0x0080, + 0x00fa, 0x7c01, 0x7fe9, 0x0800, 0x8090, + }, + }, + { /* 65 Mhz */ + .clock = 65000, + .settings = { + 0x0145, 0x0000, 0x0082, 0x0187, 0x0080, + 0x02ee, 0x7c01, 0x7fe9, 0x0800, 0x9090, + }, + }, + { /* 57.284 Mhz */ + .clock = 57284, + .settings = { + 0x0208, 0x0000, 0x0186, 0x06dc, 0x0080, + 0x00fa, 0x7c01, 0x7fe9, 0x0800, 0x8090, + }, + }, + { /* 50 Mhz */ + .clock = 50000, + .settings = { + 0x0186, 0x0000, 0x1041, 0x0042, 0x0080, + 0x03e8, 0x2001, 0x23e9, 0x0100, 0x9890, + }, + }, + { /* 49.5 Mhz */ + .clock = 49500, + .settings = { + 0x02cb, 0x0000, 0x2105, 0x0619, 0x0080, + 0x00fa, 0x7c01, 0x7fe9, 0x0800, 0x8090, + }, + }, + { /* 40 Mhz */ + .clock = 40000, + .settings = { + 0x01c8, 0x0080, 0x1041, 0x0042, 0x0080, + 0x03e8, 0x2001, 0x23e9, 0x0100, 0x9890, + }, + }, + { /* 36 Mhz */ + .clock = 36000, + .settings = { + 0x030d, 0x0080, 0x0041, 0x0105, 0x0080, + 0x03e8, 0x6401, 0x67e9, 0x0100, 0x9090, + }, + }, + { /* 31.5 Mhz */ + .clock = 31500, + .settings = { + 0x030d, 0x0080, 0x0208, 0x07e0, 0x0080, + 0x00fa, 0x7c01, 0x7fe9, 0x0800, 0x8090, + }, + }, + { /* 30.24 Mhz */ + .clock = 30240, + .settings = { + 0x038f, 0x0080, 0x2187, 0x071d, 0x0080, + 0x00fa, 0x7c01, 0x7fe9, 0x0800, 0x8090, + }, + }, + { /* 28.32 Mhz */ + .clock = 28320, + .settings = { + 0x030d, 0x0080, 0x2187, 0x05d7, 0x0000, + 0x00fa, 0x7c01, 0x7fe9, 0x0800, 0x1090, + }, + + }, + { /* 27 Mhz */ + .clock = 27000, + .settings = { + 0x0514, 0x0000, 0x2083, 0x034e, 0x0080, + 0x015e, 0x7c01, 0x7fe9, 0x0100, 0x8090, + }, + }, + { /* 25.2 MHz */ + .clock = 25200, + .settings = { + 0x030d, 0x0080, 0x028a, 0x07e0, 0x0080, + 0x00fa, 0x7c01, 0x7fe9, 0x0800, 0x8090, + }, + }, + { /* 25.175 Mhz */ + .clock = 25175, + .settings = { + 0x034d, 0x0000, 0x2146, 0x0492, 0x0000, + 0x0113, 0x7c01, 0x7fe9, 0x0100, 0x8090, + }, + }, + { /* 13.5 MHz */ + .clock = 13500, + .settings = { + 0x0a28, 0x0000, 0x2083, 0x034e, 0x0080, + 0x015e, 0x7c01, 0x7fe9, 0x0100, 0x8090, + }, + }, +}; + +static const struct analog_drm_crtc_clock_setting *analog_drm_encoder_closest_clock(long clock) +{ + const struct analog_drm_crtc_clock_setting *best_setting = NULL; + long best_diff, diff; + unsigned int i; + + best_diff = LONG_MAX; + + for (i = 0; i < ARRAY_SIZE(clock_settings); ++i) { + diff = abs(clock_settings[i].clock - clock); + if (diff < best_diff) { + best_diff = diff; + best_setting = &clock_settings[i]; + } + } + + return best_setting; +} + +static bool analog_drm_encoder_mode_fixup(struct drm_encoder *encoder, + struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) +{ + struct drm_encoder_slave_funcs *sfuncs = get_slave_funcs(encoder); + + if (sfuncs && sfuncs->mode_fixup) + return sfuncs->mode_fixup(encoder, mode, adjusted_mode); + + return true; +} + +static void analog_drm_write_clock_reg(struct analog_drm_private *private, + unsigned int reg, unsigned int val) +{ + iowrite32(val, private->base_clock + reg); +} + +#define ANALOG_CLOCK_REG_UPDATE_ENABLE 0x04 +#define ANALOG_CLOCK_REG_CONFIG(x) (0x08 + (0x04 * x)) + +static int analog_drm_encoder_set_clock(struct analog_drm_private *private, long clock) +{ + const struct analog_drm_crtc_clock_setting *best_setting; + unsigned int i; + + best_setting = analog_drm_encoder_closest_clock(clock); + + if (!best_setting) + return -EINVAL; + + printk("setting clock to: %lu\n", best_setting->clock); + + analog_drm_write_clock_reg(private, ANALOG_CLOCK_REG_UPDATE_ENABLE, 0); + + for (i = 0; i < 10; ++i) { + analog_drm_write_clock_reg(private, ANALOG_CLOCK_REG_CONFIG(i), + best_setting->settings[i]); + } + + analog_drm_write_clock_reg(private, ANALOG_CLOCK_REG_UPDATE_ENABLE, 1); + + return 0; +} + +static void analog_drm_encoder_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) +{ + struct drm_encoder_slave_funcs *sfuncs = get_slave_funcs(encoder); + struct analog_drm_private *private = encoder->dev->dev_private; + unsigned int h_de_min, h_de_max; + unsigned int v_de_min, v_de_max; + unsigned int htotal, hactive; + unsigned int vtotal, vactive; + + if (sfuncs && sfuncs->mode_set) + sfuncs->mode_set(encoder, mode, adjusted_mode); + + htotal = mode->htotal; + hactive = mode->hdisplay; + vtotal = mode->vtotal; + vactive = mode->vdisplay; + + hactive = mode->hsync_end - mode->hsync_start; + vactive = mode->vsync_end - mode->vsync_start; + + h_de_min = htotal - mode->hsync_start; + h_de_max = h_de_min + mode->hdisplay; + v_de_min = vtotal - mode->vsync_start; + v_de_max = v_de_min + mode->vdisplay; + + iowrite32((hactive << 16) | htotal, private->base + ANALOG_REG_HTIMING1); + iowrite32((h_de_min << 16) | h_de_max, private->base + ANALOG_REG_HTIMING2); + iowrite32((vactive << 16) | vtotal, private->base + ANALOG_REG_VTIMING1); + iowrite32((v_de_min << 16) | v_de_max, private->base + ANALOG_REG_VTIMING2); + + analog_drm_encoder_set_clock(private, mode->clock); +} + +static void analog_drm_encoder_commit(struct drm_encoder *encoder) +{ + analog_drm_encoder_dpms(encoder, DRM_MODE_DPMS_ON); +} + +static void analog_drm_encoder_prepare(struct drm_encoder *encoder) +{ + analog_drm_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); +} + +static struct drm_crtc *analog_drm_encoder_get_crtc(struct drm_encoder *encoder) +{ + return encoder->crtc; +} + +static struct drm_encoder_helper_funcs analog_encoder_helper_funcs = { + .dpms = analog_drm_encoder_dpms, + .mode_fixup = analog_drm_encoder_mode_fixup, + .mode_set = analog_drm_encoder_mode_set, + .prepare = analog_drm_encoder_prepare, + .commit = analog_drm_encoder_commit, + .get_crtc = analog_drm_encoder_get_crtc, +}; + +static void analog_drm_encoder_destroy(struct drm_encoder *encoder) +{ + struct drm_encoder_slave_funcs *sfuncs = get_slave_funcs(encoder); + struct analog_drm_encoder *analog_encoder = + to_analog_encoder(encoder); + + if (sfuncs && sfuncs->destroy) + sfuncs->destroy(encoder); + + drm_encoder_cleanup(encoder); + encoder->dev->mode_config.num_encoder--; + kfree(analog_encoder); +} + +static struct drm_encoder_funcs analog_encoder_funcs = { + .destroy = analog_drm_encoder_destroy, +}; + +static struct i2c_board_info fmc_adv7511_encoder_info[] = { + { + I2C_BOARD_INFO("adv7511", 0x39), + }, + { } +}; + +struct drm_encoder *analog_drm_encoder_create(struct drm_device *dev) +{ + struct drm_encoder *encoder; + struct drm_connector *connector; + struct analog_drm_encoder *analog_encoder; + struct analog_drm_private *priv = dev->dev_private; + + analog_encoder = kzalloc(sizeof(*analog_encoder), GFP_KERNEL); + if (!analog_encoder) { + DRM_ERROR("failed to allocate encoder\n"); + return NULL; + } + + encoder = &analog_encoder->encoder.base; + encoder->possible_crtcs = 1; + + drm_encoder_init(dev, encoder, &analog_encoder_funcs, + DRM_MODE_ENCODER_TMDS); + drm_encoder_helper_add(encoder, &analog_encoder_helper_funcs); + + drm_i2c_encoder_init(dev, to_encoder_slave(encoder), + priv->slave_adapter, + fmc_adv7511_encoder_info); + + connector = &analog_encoder->connector; + + analog_drm_connector_init(dev, connector, encoder); + + analog_encoder->regset.base = priv->base; + analog_encoder->regset.regs = analog_drm_encoder_debugfs_regs; + analog_encoder->regset.nregs = ARRAY_SIZE(analog_drm_encoder_debugfs_regs); + debugfs_create_regset32(dev_name(dev->dev), S_IRUGO, NULL, &analog_encoder->regset); + debugfs_create_file("color_pattern", 0666, NULL, priv, &fops_cp); + + return encoder; +} + +static struct i2c_adapter *analog_drm_get_ddc_adapter(struct drm_device *dev) +{ + struct analog_drm_private *priv = dev->dev_private; + + return priv->ddc_adapter; +} + +static int analog_drm_connector_get_modes(struct drm_connector *connector) +{ + struct drm_encoder *encoder = connector_to_encoder(connector); + struct drm_encoder_slave_funcs *sfuncs = get_slave_funcs(encoder); + struct i2c_adapter *adapter = analog_drm_get_ddc_adapter(connector->dev); + struct edid *edid; + int count = 0; + + kfree(connector->display_info.raw_edid); + connector->display_info.raw_edid = NULL; + + if (adapter) { + edid = drm_get_edid(connector, adapter); + drm_mode_connector_update_edid_property(connector, + edid); + count += drm_add_edid_modes(connector, edid); + } else { + if (sfuncs && sfuncs->get_modes) + count += sfuncs->get_modes(encoder, connector); + } + + return count; +} + +static int analog_drm_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + if (mode->clock > 165000) + return MODE_CLOCK_HIGH; + + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + return MODE_NO_INTERLACE; + + return MODE_OK; +} + +static struct drm_encoder *analog_drm_best_encoder(struct drm_connector *connector) +{ + return connector_to_encoder(connector); +} + +static struct drm_connector_helper_funcs analog_connector_helper_funcs = { + .get_modes = analog_drm_connector_get_modes, + .mode_valid = analog_drm_connector_mode_valid, + .best_encoder = analog_drm_best_encoder, +}; + +static enum drm_connector_status +analog_drm_connector_detect(struct drm_connector *connector, bool force) +{ + enum drm_connector_status status = connector_status_unknown; + struct drm_encoder *encoder = connector_to_encoder(connector); + struct drm_encoder_slave_funcs *sfuncs = get_slave_funcs(encoder); + struct i2c_adapter *adapter = analog_drm_get_ddc_adapter(connector->dev); + struct edid *edid; + + if (adapter) { + kfree(connector->display_info.raw_edid); + connector->display_info.raw_edid = NULL; + + edid = drm_get_edid(connector, adapter); + if (edid) + status = connector_status_connected; + else + status = connector_status_disconnected; + } + + if (sfuncs && sfuncs->detect) + status = sfuncs->detect(encoder, connector); + + return status; +} + +static void analog_drm_connector_destroy(struct drm_connector *connector) +{ + drm_sysfs_connector_remove(connector); + drm_connector_cleanup(connector); +} + +static struct drm_connector_funcs analog_connector_funcs = { + .dpms = drm_helper_connector_dpms, + .fill_modes = drm_helper_probe_single_connector_modes, + .detect = analog_drm_connector_detect, + .destroy = analog_drm_connector_destroy, +}; + +static int analog_drm_connector_init(struct drm_device *dev, + struct drm_connector *connector, struct drm_encoder *encoder) +{ + int type; + int err; + + type = DRM_MODE_CONNECTOR_HDMIA; + connector->polled = DRM_CONNECTOR_POLL_CONNECT | + DRM_CONNECTOR_POLL_DISCONNECT; + + drm_connector_init(dev, connector, &analog_connector_funcs, type); + drm_connector_helper_add(connector, &analog_connector_helper_funcs); + + err = drm_sysfs_connector_add(connector); + if (err) + goto err_connector; + + connector->encoder = encoder; + + err = drm_mode_connector_attach_encoder(connector, encoder); + if (err) { + DRM_ERROR("failed to attach a connector to a encoder\n"); + goto err_sysfs; + } + + return 0; + +err_sysfs: + drm_sysfs_connector_remove(connector); +err_connector: + drm_connector_cleanup(connector); + return err; +} diff --git a/drivers/gpu/drm/analog/analog_drm_encoder.h b/drivers/gpu/drm/analog/analog_drm_encoder.h new file mode 100644 index 0000000000000..575903b71789f --- /dev/null +++ b/drivers/gpu/drm/analog/analog_drm_encoder.h @@ -0,0 +1,6 @@ +#ifndef _ANALOG_DRM_ENCODER_H_ +#define _ANALOG_DRM_ENCODER_H_ + +struct drm_encoder *analog_drm_encoder_create(struct drm_device *dev); + +#endif diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 6fbfc244748fd..9eda9e5ff2757 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -434,6 +434,8 @@ EXPORT_SYMBOL(drm_crtc_cleanup); void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode) { + printk("new mode: %dx%d %dx%d %d\n", mode->hdisplay, mode->vdisplay, + mode->htotal, mode->vtotal, mode->clock); list_add(&mode->head, &connector->probed_modes); } EXPORT_SYMBOL(drm_mode_probed_add); diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 3252e7067d8b3..92c3e8ff118bf 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -378,7 +378,6 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, * a chance to reject the mode entirely. */ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc != crtc) continue; encoder_funcs = encoder->helper_private; diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index b7ee230572b7c..8e09db5c0c29f 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -66,6 +66,8 @@ #define EDID_QUIRK_FIRST_DETAILED_PREFERRED (1 << 5) /* use +hsync +vsync for detailed mode */ #define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) +/* No or broken YCrCb input support */ +#define EDID_QUIRK_NO_YCRCB (1 << 7) /* Force reduced-blanking timings for detailed modes */ #define EDID_QUIRK_FORCE_REDUCED_BLANKING (1 << 7) @@ -126,6 +128,9 @@ static struct edid_quirk { { "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 }, { "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 }, + /* Denon AVR */ + { "DON", 25, EDID_QUIRK_NO_YCRCB }, + /* ViewSonic VA2026w */ { "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING }, }; @@ -253,9 +258,10 @@ EXPORT_SYMBOL(drm_edid_is_valid); * Try to fetch EDID information by calling i2c driver function. */ static int -drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, +drm_do_probe_ddc_edid(void *data, unsigned char *buf, int block, int len) { + struct i2c_adapter *adapter = data; unsigned char start = block * EDID_LENGTH; int ret, retries = 5; @@ -301,8 +307,8 @@ static bool drm_edid_is_zero(u8 *in_edid, int length) return true; } -static u8 * -drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) +struct edid *drm_do_get_edid(struct drm_connector *connector, + int (*get_edid_block)(void *, unsigned char *buf, int, int), void *data) { int i, j = 0, valid_extensions = 0; u8 *block, *new; @@ -312,7 +318,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) /* base block fetch */ for (i = 0; i < 4; i++) { - if (drm_do_probe_ddc_edid(adapter, block, 0, EDID_LENGTH)) + if (get_edid_block(data, block, 0, EDID_LENGTH)) goto out; if (drm_edid_block_valid(block, 0)) break; @@ -326,7 +332,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) /* if there's no extensions, we're done */ if (block[0x7e] == 0) - return block; + return (struct edid *)block; new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL); if (!new) @@ -335,7 +341,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) for (j = 1; j <= block[0x7e]; j++) { for (i = 0; i < 4; i++) { - if (drm_do_probe_ddc_edid(adapter, + if (get_edid_block(data, block + (valid_extensions + 1) * EDID_LENGTH, j, EDID_LENGTH)) goto out; @@ -359,7 +365,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) block = new; } - return block; + return (struct edid *)block; carp: dev_warn(connector->dev->dev, "%s: EDID block %d invalid.\n", @@ -369,6 +375,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) kfree(block); return NULL; } +EXPORT_SYMBOL_GPL(drm_do_get_edid); /** * Probe DDC presence. @@ -400,8 +407,7 @@ struct edid *drm_get_edid(struct drm_connector *connector, struct edid *edid = NULL; if (drm_probe_ddc(adapter)) - edid = (struct edid *)drm_do_get_edid(connector, adapter); - + edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter); connector->display_info.raw_edid = (char *)edid; return edid; @@ -1932,6 +1938,11 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) drm_add_display_info(edid, &connector->display_info); + if (quirks & EDID_QUIRK_NO_YCRCB) { + connector->display_info.color_formats &= + ~(DRM_COLOR_FORMAT_YCRCB444 | DRM_COLOR_FORMAT_YCRCB422); + } + return num_modes; } EXPORT_SYMBOL(drm_add_edid_modes); diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c new file mode 100644 index 0000000000000..0f8fd3b312810 --- /dev/null +++ b/drivers/gpu/drm/drm_fb_cma_helper.c @@ -0,0 +1,398 @@ +/* + * drm kms/fb cma (contiguous memory allocator) helper functions + * + * Copyright (C) 2012 Analog Device Inc. + * Author: Lars-Peter Clausen + * + * Based on udl_fbdev.c + * Copyright (C) 2012 Red Hat + * + * 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 +#include +#include +#include +#include +#include +#include + +struct drm_fb_cma { + struct drm_framebuffer fb; + struct drm_gem_cma_object *obj[4]; +}; + +struct drm_fbdev_cma { + struct drm_fb_helper fb_helper; + struct drm_fb_cma *fb; +}; + +static inline struct drm_fbdev_cma *to_fbdev_cma(struct drm_fb_helper *helper) +{ + return container_of(helper, struct drm_fbdev_cma, fb_helper); +} + +static inline struct drm_fb_cma *to_fb_cma(struct drm_framebuffer *fb) +{ + return container_of(fb, struct drm_fb_cma, fb); +} + +static void drm_fb_cma_destroy(struct drm_framebuffer *fb) +{ + struct drm_fb_cma *fb_cma = to_fb_cma(fb); + int i; + + for (i = 0; i < 4; i++) { + if (fb_cma->obj[i]) + drm_gem_object_unreference_unlocked(&fb_cma->obj[i]->base); + } + + drm_framebuffer_cleanup(fb); + kfree(fb_cma); +} + +static int drm_fb_cma_create_handle(struct drm_framebuffer *fb, + struct drm_file *file_priv, unsigned int *handle) +{ + struct drm_fb_cma *fb_cma = to_fb_cma(fb); + + return drm_gem_handle_create(file_priv, + &fb_cma->obj[0]->base, handle); +} + +static struct drm_framebuffer_funcs drm_fb_cma_funcs = { + .destroy = drm_fb_cma_destroy, + .create_handle = drm_fb_cma_create_handle, +}; + +static struct drm_fb_cma *drm_fb_cma_alloc(struct drm_device *dev, + struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_cma_object **obj, + unsigned int num_planes) +{ + struct drm_fb_cma *fb_cma; + int ret; + int i; + + fb_cma = kzalloc(sizeof(*fb_cma), GFP_KERNEL); + if (!fb_cma) + return ERR_PTR(-ENOMEM); + + ret = drm_framebuffer_init(dev, &fb_cma->fb, &drm_fb_cma_funcs); + if (ret) { + dev_err(dev->dev, "Failed to initalize framebuffer: %d\n", ret); + kfree(fb_cma); + return ERR_PTR(ret); + } + + drm_helper_mode_fill_fb_struct(&fb_cma->fb, mode_cmd); + + for (i = 0; i < num_planes; i++) + fb_cma->obj[i] = obj[i]; + + return fb_cma; +} + +/** + * drm_fb_cma_create() - (struct drm_mode_config_funcs *)->fb_create callback function + * + * If your hardware has special alignment or pitch requirements these should be + * checked before calling this function. + */ +struct drm_framebuffer *drm_fb_cma_create(struct drm_device *dev, + struct drm_file *file_priv, struct drm_mode_fb_cmd2 *mode_cmd) +{ + struct drm_fb_cma *fb_cma; + struct drm_gem_cma_object *objs[4]; + struct drm_gem_object *obj; + unsigned int min_size; + int ret; + int i; + + for (i = 0; i < drm_format_num_planes(mode_cmd->pixel_format); i++) { + obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[i]); + if (!obj) { + dev_err(dev->dev, "Failed to lookup GEM object\n"); + ret = -ENXIO; + goto err_gem_object_unreference; + } + + min_size = mode_cmd->height * mode_cmd->pitches[i]; + + if (obj->size < min_size) { + drm_gem_object_unreference_unlocked(obj); + ret = -EINVAL; + goto err_gem_object_unreference; + } + objs[i] = to_drm_gem_cma_obj(obj); + } + + fb_cma = drm_fb_cma_alloc(dev, mode_cmd, objs, i); + if (IS_ERR(fb_cma)) { + ret = PTR_ERR(fb_cma); + goto err_gem_object_unreference; + } + + return &fb_cma->fb; + +err_gem_object_unreference: + for (i--; i >= 0; i--) + drm_gem_object_unreference_unlocked(&objs[i]->base); + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(drm_fb_cma_create); + +/** + * drm_fb_cma_get_gem_obj() - Get CMA GEM object for framebuffer + * @fb: The framebuffer + * @plane: Which plane + * + * Return the CMA GEM object for given framebuffer. + * + * This function will usually be called from the CRTC callback functions. + */ +struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb, + unsigned int plane) +{ + struct drm_fb_cma *fb_cma = to_fb_cma(fb); + + if (plane >= 4) + return NULL; + + return fb_cma->obj[plane]; +} +EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj); + +static struct fb_ops drm_fbdev_cma_ops = { + .owner = THIS_MODULE, + .fb_fillrect = sys_fillrect, + .fb_copyarea = sys_copyarea, + .fb_imageblit = sys_imageblit, + .fb_check_var = drm_fb_helper_check_var, + .fb_set_par = drm_fb_helper_set_par, + .fb_blank = drm_fb_helper_blank, + .fb_pan_display = drm_fb_helper_pan_display, + .fb_setcmap = drm_fb_helper_setcmap, +}; + +static int drm_fbdev_cma_create(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes) +{ + struct drm_fbdev_cma *fbdev_cma = to_fbdev_cma(helper); + struct drm_mode_fb_cmd2 mode_cmd = { 0 }; + struct drm_device *dev = helper->dev; + struct drm_gem_cma_object *obj; + struct drm_framebuffer *fb; + unsigned int bytes_per_pixel; + unsigned long offset; + struct fb_info *fbi; + size_t size; + int ret; + + DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d\n", + sizes->surface_width, sizes->surface_height, + sizes->surface_bpp); + + bytes_per_pixel = DIV_ROUND_UP(sizes->surface_bpp, 8); + + mode_cmd.width = sizes->surface_width; + mode_cmd.height = sizes->surface_height; + mode_cmd.pitches[0] = sizes->surface_width * bytes_per_pixel; + mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, + sizes->surface_depth); + + size = mode_cmd.pitches[0] * mode_cmd.height; + obj = drm_gem_cma_create(dev, size); + if (!obj) + return -ENOMEM; + + fbi = framebuffer_alloc(0, dev->dev); + if (!fbi) { + dev_err(dev->dev, "Failed to allocate framebuffer info.\n"); + ret = -ENOMEM; + goto err_drm_gem_cma_free_object; + } + + fbdev_cma->fb = drm_fb_cma_alloc(dev, &mode_cmd, &obj, 1); + if (IS_ERR(fbdev_cma->fb)) { + dev_err(dev->dev, "Failed to allocate DRM framebuffer.\n"); + ret = PTR_ERR(fbdev_cma->fb); + goto err_framebuffer_release; + } + + fb = &fbdev_cma->fb->fb; + helper->fb = fb; + helper->fbdev = fbi; + + fbi->par = helper; + fbi->flags = FBINFO_FLAG_DEFAULT; + fbi->fbops = &drm_fbdev_cma_ops; + + ret = fb_alloc_cmap(&fbi->cmap, 256, 0); + if (ret) { + dev_err(dev->dev, "Failed to allocate color map.\n"); + goto err_drm_fb_cma_destroy; + } + + drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); + drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height); + + offset = fbi->var.xoffset * bytes_per_pixel; + offset += fbi->var.yoffset * fb->pitches[0]; + + dev->mode_config.fb_base = (resource_size_t)obj->paddr; + fbi->screen_base = obj->vaddr + offset; + fbi->fix.smem_start = (unsigned long)(obj->paddr + offset); + fbi->screen_size = size; + fbi->fix.smem_len = size; + + return 0; + +err_drm_fb_cma_destroy: + drm_fb_cma_destroy(fb); +err_framebuffer_release: + framebuffer_release(fbi); +err_drm_gem_cma_free_object: + drm_gem_cma_free_object(&obj->base); + return ret; +} + +static int drm_fbdev_cma_probe(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes) +{ + int ret = 0; + + if (!helper->fb) { + ret = drm_fbdev_cma_create(helper, sizes); + if (ret < 0) + return ret; + ret = 1; + } + + return ret; +} + +static struct drm_fb_helper_funcs drm_fb_cma_helper_funcs = { + .fb_probe = drm_fbdev_cma_probe, +}; + +/** + * drm_fbdev_cma_init() - Allocate and initializes a drm_fbdev_cma struct + * @dev: DRM device + * @preferred_bpp: Preferred bits per pixel for the device + * @num_crtc: Number of CRTCs + * @max_conn_count: Maximum number of connectors + * + * Returns a newly allocated drm_fbdev_cma struct or a ERR_PTR. + */ +struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev, + unsigned int preferred_bpp, unsigned int num_crtc, + unsigned int max_conn_count) +{ + struct drm_fbdev_cma *fbdev_cma; + struct drm_fb_helper *helper; + int ret; + + fbdev_cma = kzalloc(sizeof(*fbdev_cma), GFP_KERNEL); + if (!fbdev_cma) { + dev_err(dev->dev, "Failed to allocate drm fbdev.\n"); + return ERR_PTR(-ENOMEM); + } + + fbdev_cma->fb_helper.funcs = &drm_fb_cma_helper_funcs; + helper = &fbdev_cma->fb_helper; + + ret = drm_fb_helper_init(dev, helper, num_crtc, max_conn_count); + if (ret < 0) { + dev_err(dev->dev, "Failed to initialize drm fb helper.\n"); + goto err_free; + } + + ret = drm_fb_helper_single_add_all_connectors(helper); + if (ret < 0) { + dev_err(dev->dev, "Failed to add connectors.\n"); + goto err_drm_fb_helper_fini; + + } + + ret = drm_fb_helper_initial_config(helper, preferred_bpp); + if (ret < 0) { + dev_err(dev->dev, "Failed to set inital hw configuration.\n"); + goto err_drm_fb_helper_fini; + } + + return fbdev_cma; + +err_drm_fb_helper_fini: + drm_fb_helper_fini(helper); +err_free: + kfree(fbdev_cma); + + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(drm_fbdev_cma_init); + +/** + * drm_fbdev_cma_fini() - Free drm_fbdev_cma struct + * @fbdev_cma: The drm_fbdev_cma struct + */ +void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma) +{ + if (fbdev_cma->fb_helper.fbdev) { + struct fb_info *info; + int ret; + + info = fbdev_cma->fb_helper.fbdev; + ret = unregister_framebuffer(info); + if (ret < 0) + DRM_DEBUG_KMS("failed unregister_framebuffer()\n"); + + if (info->cmap.len) + fb_dealloc_cmap(&info->cmap); + + framebuffer_release(info); + } + + if (fbdev_cma->fb) + drm_fb_cma_destroy(&fbdev_cma->fb->fb); + + drm_fb_helper_fini(&fbdev_cma->fb_helper); + kfree(fbdev_cma); +} +EXPORT_SYMBOL_GPL(drm_fbdev_cma_fini); + +/** + * drm_fbdev_cma_restore_mode() - Restores initial framebuffer mode + * @fbdev_cma: The drm_fbdev_cma struct, may be NULL + * + * This function is usually called from the DRM drivers lastclose callback. + */ +void drm_fbdev_cma_restore_mode(struct drm_fbdev_cma *fbdev_cma) +{ + if (fbdev_cma) + drm_fb_helper_restore_fbdev_mode(&fbdev_cma->fb_helper); +} +EXPORT_SYMBOL_GPL(drm_fbdev_cma_restore_mode); + +/** + * drm_fbdev_cma_hotplug_event() - Poll for hotpulug events + * @fbdev_cma: The drm_fbdev_cma struct, may be NULL + * + * This function is usually called from the DRM drivers output_poll_changed + * callback. + */ +void drm_fbdev_cma_hotplug_event(struct drm_fbdev_cma *fbdev_cma) +{ + if (fbdev_cma) + drm_fb_helper_hotplug_event(&fbdev_cma->fb_helper); +} +EXPORT_SYMBOL_GPL(drm_fbdev_cma_hotplug_event); + +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c new file mode 100644 index 0000000000000..1aa8fee1e8658 --- /dev/null +++ b/drivers/gpu/drm/drm_gem_cma_helper.c @@ -0,0 +1,251 @@ +/* + * drm gem CMA (contiguous memory allocator) helper functions + * + * Copyright (C) 2012 Sascha Hauer, Pengutronix + * + * Based on Samsung Exynos code + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * + * 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 +#include +#include +#include +#include + +#include +#include +#include + +static unsigned int get_gem_mmap_offset(struct drm_gem_object *obj) +{ + return (unsigned int)obj->map_list.hash.key << PAGE_SHIFT; +} + +static void drm_gem_cma_buf_destroy(struct drm_device *drm, + struct drm_gem_cma_object *cma_obj) +{ + dma_free_writecombine(drm->dev, cma_obj->base.size, cma_obj->vaddr, + cma_obj->paddr); +} + +/* + * drm_gem_cma_create - allocate an object with the given size + * + * returns a struct drm_gem_cma_object* on success or ERR_PTR values + * on failure. + */ +struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, + unsigned int size) +{ + struct drm_gem_cma_object *cma_obj; + struct drm_gem_object *gem_obj; + int ret; + + size = round_up(size, PAGE_SIZE); + + cma_obj = kzalloc(sizeof(*cma_obj), GFP_KERNEL); + if (!cma_obj) + return ERR_PTR(-ENOMEM); + + cma_obj->vaddr = dma_alloc_writecombine(drm->dev, size, + &cma_obj->paddr, GFP_KERNEL | __GFP_NOWARN); + if (!cma_obj->vaddr) { + dev_err(drm->dev, "failed to allocate buffer with size %d\n", size); + ret = -ENOMEM; + goto err_dma_alloc; + } + + gem_obj = &cma_obj->base; + + ret = drm_gem_object_init(drm, gem_obj, size); + if (ret) + goto err_obj_init; + + ret = drm_gem_create_mmap_offset(gem_obj); + if (ret) + goto err_create_mmap_offset; + + return cma_obj; + +err_create_mmap_offset: + drm_gem_object_release(gem_obj); + +err_obj_init: + drm_gem_cma_buf_destroy(drm, cma_obj); + +err_dma_alloc: + kfree(cma_obj); + + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(drm_gem_cma_create); + +/* + * drm_gem_cma_create_with_handle - allocate an object with the given + * size and create a gem handle on it + * + * returns a struct drm_gem_cma_object* on success or ERR_PTR values + * on failure. + */ +static struct drm_gem_cma_object *drm_gem_cma_create_with_handle( + struct drm_file *file_priv, + struct drm_device *drm, unsigned int size, + unsigned int *handle) +{ + struct drm_gem_cma_object *cma_obj; + struct drm_gem_object *gem_obj; + int ret; + + cma_obj = drm_gem_cma_create(drm, size); + if (IS_ERR(cma_obj)) + return cma_obj; + + gem_obj = &cma_obj->base; + + /* + * allocate a id of idr table where the obj is registered + * and handle has the id what user can see. + */ + ret = drm_gem_handle_create(file_priv, gem_obj, handle); + if (ret) + goto err_handle_create; + + /* drop reference from allocate - handle holds it now. */ + drm_gem_object_unreference_unlocked(gem_obj); + + return cma_obj; + +err_handle_create: + drm_gem_cma_free_object(gem_obj); + + return ERR_PTR(ret); +} + +/* + * drm_gem_cma_free_object - (struct drm_driver)->gem_free_object callback + * function + */ +void drm_gem_cma_free_object(struct drm_gem_object *gem_obj) +{ + struct drm_gem_cma_object *cma_obj; + + if (gem_obj->map_list.map) + drm_gem_free_mmap_offset(gem_obj); + + drm_gem_object_release(gem_obj); + + cma_obj = to_drm_gem_cma_obj(gem_obj); + + drm_gem_cma_buf_destroy(gem_obj->dev, cma_obj); + + kfree(cma_obj); +} +EXPORT_SYMBOL_GPL(drm_gem_cma_free_object); + +/* + * drm_gem_cma_dumb_create - (struct drm_driver)->dumb_create callback + * function + * + * This aligns the pitch and size arguments to the minimum required. wrap + * this into your own function if you need bigger alignment. + */ +int drm_gem_cma_dumb_create(struct drm_file *file_priv, + struct drm_device *dev, struct drm_mode_create_dumb *args) +{ + struct drm_gem_cma_object *cma_obj; + int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8); + + if (args->pitch < min_pitch) + args->pitch = min_pitch; + + if (args->size < args->pitch * args->height) + args->size = args->pitch * args->height; + + cma_obj = drm_gem_cma_create_with_handle(file_priv, dev, + args->size, &args->handle); + if (IS_ERR(cma_obj)) + return PTR_ERR(cma_obj); + + return 0; +} +EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_create); + +/* + * drm_gem_cma_dumb_map_offset - (struct drm_driver)->dumb_map_offset callback + * function + */ +int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv, + struct drm_device *drm, uint32_t handle, uint64_t *offset) +{ + struct drm_gem_object *gem_obj; + + mutex_lock(&drm->struct_mutex); + + gem_obj = drm_gem_object_lookup(drm, file_priv, handle); + if (!gem_obj) { + dev_err(drm->dev, "failed to lookup gem object\n"); + mutex_unlock(&drm->struct_mutex); + return -EINVAL; + } + + *offset = get_gem_mmap_offset(gem_obj); + + drm_gem_object_unreference(gem_obj); + + mutex_unlock(&drm->struct_mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_map_offset); + +const struct vm_operations_struct drm_gem_cma_vm_ops = { + .open = drm_gem_vm_open, + .close = drm_gem_vm_close, +}; +EXPORT_SYMBOL_GPL(drm_gem_cma_vm_ops); + +/* + * drm_gem_cma_mmap - (struct file_operation)->mmap callback function + */ +int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma) +{ + struct drm_gem_object *gem_obj; + struct drm_gem_cma_object *cma_obj; + int ret; + + ret = drm_gem_mmap(filp, vma); + if (ret) + return ret; + + gem_obj = vma->vm_private_data; + cma_obj = to_drm_gem_cma_obj(gem_obj); + + ret = remap_pfn_range(vma, vma->vm_start, cma_obj->paddr >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot); + if (ret) + drm_gem_vm_close(vma); + + return ret; +} +EXPORT_SYMBOL_GPL(drm_gem_cma_mmap); + +/* + * drm_gem_cma_dumb_destroy - (struct drm_driver)->dumb_destroy callback function + */ +int drm_gem_cma_dumb_destroy(struct drm_file *file_priv, + struct drm_device *drm, unsigned int handle) +{ + return drm_gem_handle_delete(file_priv, handle); +} +EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_destroy); diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 21bcd4a555d85..87e2a783d1285 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -37,7 +37,7 @@ #include "drmP.h" #include "drm_core.h" -unsigned int drm_debug = 0; /* 1 to enable debug output */ +unsigned int drm_debug = 0xff; /* 1 to enable debug output */ EXPORT_SYMBOL(drm_debug); unsigned int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */ diff --git a/drivers/gpu/drm/i2c/Makefile b/drivers/gpu/drm/i2c/Makefile index 92862563e7ee3..d7b40ed23c67b 100644 --- a/drivers/gpu/drm/i2c/Makefile +++ b/drivers/gpu/drm/i2c/Makefile @@ -5,3 +5,6 @@ obj-$(CONFIG_DRM_I2C_CH7006) += ch7006.o sil164-y := sil164_drv.o obj-$(CONFIG_DRM_I2C_SIL164) += sil164.o + +adv7511-y := adv7511_core.o adv7511_audio.o +obj-$(CONFIG_DRM_ENCODER_ADV7511) += adv7511.o diff --git a/drivers/gpu/drm/i2c/adv7511.h b/drivers/gpu/drm/i2c/adv7511.h new file mode 100644 index 0000000000000..40a860ea43e2c --- /dev/null +++ b/drivers/gpu/drm/i2c/adv7511.h @@ -0,0 +1,311 @@ +/** + * Analog Devices ADV7511 HDMI transmitter driver + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#ifndef __ADV7511_H__ +#define __ADV7511_H__ + +#define ADV7511_REG_CHIP_REVISION 0x00 +#define ADV7511_REG_N0 0x01 +#define ADV7511_REG_N1 0x02 +#define ADV7511_REG_N2 0x03 +#define ADV7511_REG_SPDIF_FREQ 0x04 +#define ADV7511_REG_CTS_AUTOMATIC1 0x05 +#define ADV7511_REG_CTS_AUTOMATIC2 0x06 +#define ADV7511_REG_CTS_MANUAL0 0x07 +#define ADV7511_REG_CTS_MANUAL1 0x08 +#define ADV7511_REG_CTS_MANUAL2 0x09 +#define ADV7511_REG_AUDIO_SOURCE 0x0a +#define ADV7511_REG_AUDIO_CONFIG 0x0b +#define ADV7511_REG_I2S_CONFIG 0x0c +#define ADV7511_REG_I2S_WIDTH 0x0d +#define ADV7511_REG_AUDIO_SUB_SRC0 0x0e +#define ADV7511_REG_AUDIO_SUB_SRC1 0x0f +#define ADV7511_REG_AUDIO_SUB_SRC2 0x10 +#define ADV7511_REG_AUDIO_SUB_SRC3 0x11 +#define ADV7511_REG_AUDIO_CFG1 0x12 +#define ADV7511_REG_AUDIO_CFG2 0x13 +#define ADV7511_REG_AUDIO_CFG3 0x14 +#define ADV7511_REG_I2C_FREQ_ID_CFG 0x15 +#define ADV7511_REG_VIDEO_INPUT_CFG1 0x16 +#define ADV7511_REG_CSC_UPPER(x) (0x18 + (x) * 2) +#define ADV7511_REG_CSC_LOWER(x) (0x19 + (x) * 2) +#define ADV7511_REG_SYNC_DECODER(x) (0x30 + (x)) +#define ADV7511_REG_DE_GENERATOR (0x35 + (x)) +#define ADV7511_REG_PIXEL_REPETITION 0x3b +#define ADV7511_REG_VIC_MANUAL 0x3c +#define ADV7511_REG_VIC_SEND 0x3d +#define ADV7511_REG_VIC_DETECTED 0x3e +#define ADV7511_REG_AUX_VIC_DETECTED 0x3f +#define ADV7511_REG_PACKET_ENABLE0 0x40 +#define ADV7511_REG_POWER 0x41 +#define ADV7511_REG_STATUS 0x42 +#define ADV7511_REG_EDID_I2C_ADDR 0x43 +#define ADV7511_REG_PACKET_ENABLE1 0x44 +#define ADV7511_REG_PACKET_I2C_ADDR 0x45 +#define ADV7511_REG_DSD_ENABLE 0x46 +#define ADV7511_REG_VIDEO_INPUT_CFG2 0x48 +#define ADV7511_REG_GC(x) (0x4b + (x)) /* 0x4b - 0x51 */ +#define ADV7511_REG_AVI_INFOFRAME_VERSION 0x52 +#define ADV7511_REG_AVI_INFOFRAME_LENGTH 0x53 +#define ADV7511_REG_AVI_INFOFRAME_CHECKSUM 0x54 +#define ADV7511_REG_AVI_INFOFRAME(x) (0x55 + (x)) /* 0x55 - 0x6f */ +#define ADV7511_REG_AUDIO_INFOFRAME_VERSION 0x70 +#define ADV7511_REG_AUDIO_INFOFRAME_LENGTH 0x71 +#define ADV7511_REG_AUDIO_INFOFRAME_CHECKSUM 0x72 +#define ADV7511_REG_AUDIO_INFOFRAME(x) (0x73 + (x)) /* 0x73 - 0x7c */ +#define ADV7511_REG_INT_ENABLE(x) (0x94 + (x)) +#define ADV7511_REG_INT(x) (0x96 + (x)) +#define ADV7511_REG_INPUT_CLK_DIV 0x9d +#define ADV7511_REG_PLL_STATUS 0x9e +#define ADV7511_REG_HDMI_POWER 0xa1 +#define ADV7511_REG_HDCP_HDMI_CFG 0xaf +#define ADV7511_REG_AN(x) (0xb0 + (x)) /* 0xb0 - 0xb7 */ +#define ADV7511_REG_HDCP_STATUS 0xb8 +#define ADV7511_REG_BCAPS 0xbe +#define ADV7511_REG_BKSV(x) (0xc0 + (x)) /* 0xc0 - 0xc3 */ +#define ADV7511_REG_EDID_SEGMENT 0xc4 +#define ADV7511_REG_DDC_STATUS 0xc8 +#define ADV7511_REG_EDID_READ_CTRL 0xc9 +#define ADV7511_REG_BSTATUS(x) (0xca + (x)) /* 0xca - 0xcb */ +#define ADV7511_REG_TIMING_GEN_SEQ 0xd0 +#define ADV7511_REG_POWER2 0xd6 +#define ADV7511_REG_HSYNC_PLACEMENT_MSB 0xfa + +#define ADV7511_REG_SYNC_ADJUSTMENT(x) (0xd7 + (x)) /* 0xd7 - 0xdc */ +#define ADV7511_REG_TMDS_CLOCK_INV 0xde +#define ADV7511_REG_ARC_CTRL 0xdf +#define ADV7511_REG_CEC_I2C_ADDR 0xe1 +#define ADV7511_REG_CEC_CTRL 0xe2 +#define ADV7511_REG_CHIP_ID_HIGH 0xf5 +#define ADV7511_REG_CHIP_ID_LOW 0xf6 + +#define ADV7511_CSC_ENABLE BIT(7) +#define ADV7511_CSC_UPDATE_MODE BIT(5) + +#define ADV7511_INT0_HDP BIT(7) +#define ADV7511_INT0_VSYNC BIT(5) +#define ADV7511_INT0_AUDIO_FIFO_FULL BIT(4) +#define ADV7511_INT0_EDID_READY BIT(2) +#define ADV7511_INT0_HDCP_AUTHENTICATED BIT(1) + +#define ADV7511_INT1_DDC_ERROR BIT(7) +#define ADV7511_INT1_BKSV BIT(6) +#define ADV7511_INT1_CEC_TX_READY BIT(5) +#define ADV7511_INT1_CEC_TX_ARBIT_LOST BIT(4) +#define ADV7511_INT1_CEC_TX_RETRY_TIMEOUT BIT(3) +#define ADV7511_INT1_CEC_RX_READY3 BIT(2) +#define ADV7511_INT1_CEC_RX_READY2 BIT(1) +#define ADV7511_INT1_CEC_RX_READY1 BIT(0) + +#define ADV7511_ARC_CTRL_POWER_DOWN BIT(0) + +#define ADV7511_CEC_CTRL_POWER_DOWN BIT(0) + +#define ADV7511_POWER_POWER_DOWN BIT(6) + +#define ADV7511_AUDIO_SELECT_I2C 0x0 +#define ADV7511_AUDIO_SELECT_SPDIF 0x1 +#define ADV7511_AUDIO_SELECT_DSD 0x2 +#define ADV7511_AUDIO_SELECT_HBR 0x3 +#define ADV7511_AUDIO_SELECT_DST 0x4 + +#define ADV7511_I2S_SAMPLE_LEN_16 0x2 +#define ADV7511_I2S_SAMPLE_LEN_20 0x3 +#define ADV7511_I2S_SAMPLE_LEN_18 0x4 +#define ADV7511_I2S_SAMPLE_LEN_22 0x5 +#define ADV7511_I2S_SAMPLE_LEN_19 0x8 +#define ADV7511_I2S_SAMPLE_LEN_23 0x9 +#define ADV7511_I2S_SAMPLE_LEN_24 0xb +#define ADV7511_I2S_SAMPLE_LEN_17 0xc +#define ADV7511_I2S_SAMPLE_LEN_21 0xd + +#define ADV7511_SAMPLE_FREQ_44100 0x0 +#define ADV7511_SAMPLE_FREQ_48000 0x2 +#define ADV7511_SAMPLE_FREQ_32000 0x3 +#define ADV7511_SAMPLE_FREQ_88200 0x8 +#define ADV7511_SAMPLE_FREQ_96000 0xa +#define ADV7511_SAMPLE_FREQ_176400 0xc +#define ADV7511_SAMPLE_FREQ_192000 0xe + +#define ADV7511_STATUS_POWER_DOWN_POLARITY BIT(7) +#define ADV7511_STATUS_HPD BIT(6) +#define ADV7511_STATUS_MONITOR_SENSE BIT(5) +#define ADV7511_STATUS_I2S_32BIT_MODE BIT(3) + +#define ADV7511_PACKET_ENABLE_N_CTS BIT(8+6) +#define ADV7511_PACKET_ENABLE_AUDIO_SAMPLE BIT(8+5) +#define ADV7511_PACKET_ENABLE_AVI_INFOFRAME BIT(8+4) +#define ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME BIT(8+3) +#define ADV7511_PACKET_ENABLE_GC BIT(7) +#define ADV7511_PACKET_ENABLE_SPD BIT(6) +#define ADV7511_PACKET_ENABLE_MPEG BIT(5) +#define ADV7511_PACKET_ENABLE_ACP BIT(4) +#define ADV7511_PACKET_ENABLE_ISRC BIT(3) +#define ADV7511_PACKET_ENABLE_GM BIT(2) +#define ADV7511_PACKET_ENABLE_SPARE2 BIT(1) +#define ADV7511_PACKET_ENABLE_SPARE1 BIT(0) + +#define ADV7511_REG_POWER2_HDP_SRC_MASK 0xc0 +#define ADV7511_REG_POWER2_HDP_SRC_BOTH 0x00 +#define ADV7511_REG_POWER2_HDP_SRC_HDP 0x40 +#define ADV7511_REG_POWER2_HDP_SRC_CEC 0x80 +#define ADV7511_REG_POWER2_HDP_SRC_NONE 0xc0 +#define ADV7511_REG_POWER2_TDMS_ENABLE BIT(4) +#define ADV7511_REG_POWER2_GATE_INPUT_CLK BIT(0) + +#define ADV7511_LOW_REFRESH_RATE_NONE 0x0 +#define ADV7511_LOW_REFRESH_RATE_24HZ 0x1 +#define ADV7511_LOW_REFRESH_RATE_25HZ 0x2 +#define ADV7511_LOW_REFRESH_RATE_30HZ 0x3 + +#define ADV7511_AUDIO_CFG3_LEN_MASK 0x0f +#define ADV7511_I2C_FREQ_ID_CFG_RATE_MASK 0xf0 + +#define ADV7511_AUDIO_SOURCE_I2S 0 +#define ADV7511_AUDIO_SOURCE_SPDIF 1 + +#define ADV7511_I2S_FORMAT_I2S 0 +#define ADV7511_I2S_FORMAT_RIGHT_J 1 +#define ADV7511_I2S_FORMAT_LEFT_J 2 + +#include + +struct i2c_client; +struct regmap; + +struct adv7511 { + struct i2c_client *i2c_main; + struct i2c_client *i2c_edid; + struct i2c_client *i2c_packet; + struct i2c_client *i2c_cec; + + struct regmap *regmap; + enum drm_connector_status status; + int dpms_mode; + + unsigned int f_tmds; + unsigned int f_audio; + + unsigned int audio_source; + + unsigned int current_edid_segment; + uint8_t edid_buf[256]; + + wait_queue_head_t wq; + struct drm_encoder *encoder; + + bool embedded_sync; +}; + +int adv7511_packet_enable(struct adv7511 *adv7511, unsigned int packet); +int adv7511_packet_disable(struct adv7511 *adv7511, unsigned int packet); + +int adv7511_audio_init(struct device *dev); +void adv7511_audio_exit(struct device *dev); + +enum adv7511_input_id { + ADV7511_INPUT_ID_24BIT_RGB444_YCbCr444 = 0, + ADV7511_INPUT_ID_16_20_24BIT_YCbCr422_SEPARATE_SYNC = 1, + ADV7511_INPUT_ID_16_20_24BIT_YCbCr422_EMBEDDED_SYNC = 2, + ADV7511_INPUT_ID_8_10_12BIT_YCbCr422_SEPARATE_SYNC = 3, + ADV7511_INPUT_ID_8_10_12BIT_YCbCr422_EMBEDDED_SYNC = 4, + ADV7511_INPUT_ID_12_15_16BIT_RGB444_YCbCr444 = 5, +}; + +enum adv7511_input_color_depth { + ADV7511_INPUT_COLOR_DEPTH_10BIT = 1, + ADV7511_INPUT_COLOR_DEPTH_12BIT = 2, + ADV7511_INPUT_COLOR_DEPTH_8BIT = 3, +}; + +enum adv7511_input_style { + ADV7511_INPUT_STYLE2 = 1, + ADV7511_INPUT_STYLE1 = 2, + ADV7511_INPUT_STYLE3 = 3, +}; + +enum adv7511_input_sync_pulse { + ADV7511_INPUT_SYNC_PULSE_DE = 0, + ADV7511_INPUT_SYNC_PULSE_HSYNC = 1, + ADV7511_INPUT_SYNC_PULSE_VSYNC = 2, + ADV7511_INPUT_SYNC_PULSE_NONE = 3, +}; + +enum adv7511_input_clock_delay { + ADV7511_INPUT_CLOCK_DELAY_MINUS_1200PS = 0, + ADV7511_INPUT_CLOCK_DELAY_MINUS_800PS = 1, + ADV7511_INPUT_CLOCK_DELAY_MINUS_400PS = 2, + ADV7511_INPUT_CLOCK_DELAY_NONE = 3, + ADV7511_INPUT_CLOCK_DELAY_PLUS_400PS = 4, + ADV7511_INPUT_CLOCK_DELAY_PLUS_800PS = 5, + ADV7511_INPUT_CLOCK_DELAY_PLUS_1200PS = 6, + ADV7511_INPUT_CLOCK_DELAY_PLUS_1600PS = 7, +}; + +enum adv7511_input_bit_justifiction { + ADV7511_INPUT_BIT_JUSTIFICATION_EVENLY = 0, + ADV7511_INPUT_BIT_JUSTIFICATION_RIGHT = 1, + ADV7511_INPUT_BIT_JUSTIFICATION_LEFT = 2, +}; + +enum adv7511_output_format { + ADV7511_OUTPUT_FORMAT_RGB_444 = 0, + ADV7511_OUTPUT_FORMAT_YCBCR_422 = 1, + ADV7511_OUTPUT_FORMAT_YCBCR_444 = 2, +}; + +enum adv7511_csc_scaling { + ADV7511_CSC_SCALING_1 = 0, + ADV7511_CSC_SCALING_2 = 1, + ADV7511_CSC_SCALING_4 = 2, +}; + +/** + * struct adv7511_video_input_config - Describes adv7511 hardware configuration + * @id: Video input format id + * @input_style: Video input format style + * @sync_pulse: Select the sync pulse + * @clock_delay: Clock delay for the input clock + * @reverse_bitorder: Reverse video input signal bitorder + * @bit_justification: Video input format bit justification + * @up_conversion_first_order_interpolation: + * @input_color_depth: Input video format color depth + * @tmds_clock_inversion: Whether to invert the TDMS clock + * @vsync_polartity_low: Whether the vsync polarity is low + * @hsync_polartity_low: Whether the hsync polarity is low + * @csc_enable: Whether to enable color space conversion + * @csc_scaling_factor: Color space conversion scaling factor + * @csc_coefficents: Color space conversion coefficents + * @output_format: Video output format + * @timing_gen_sequence: + * @hdmi_mode: Whether to use HDMI or DVI output mode + **/ +struct adv7511_video_input_config { + enum adv7511_input_id id; + enum adv7511_input_style input_style; + enum adv7511_input_sync_pulse sync_pulse; + enum adv7511_input_clock_delay clock_delay; + bool reverse_bitorder; + enum adv7511_input_bit_justifiction bit_justification; + bool up_conversion_first_order_interpolation; + enum adv7511_input_color_depth input_color_depth; + bool tmds_clock_inversion; + + bool vsync_polartity_low; + bool hsync_polartity_low; + + bool csc_enable; + enum adv7511_csc_scaling csc_scaling_factor; + uint16_t *csc_coefficents; + + enum adv7511_output_format output_format; + int timing_gen_sequence; + bool hdmi_mode; +}; + +#endif diff --git a/drivers/gpu/drm/i2c/adv7511_audio.c b/drivers/gpu/drm/i2c/adv7511_audio.c new file mode 100644 index 0000000000000..c7f65a75a2e10 --- /dev/null +++ b/drivers/gpu/drm/i2c/adv7511_audio.c @@ -0,0 +1,308 @@ +/** + * Analog Devices ADV7511 HDMI transmitter driver + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "adv7511.h" + +static const struct snd_kcontrol_new adv7511_controls[] = { + SOC_SINGLE("Master Playback Switch", 0, 0, 0, 0), +}; + +static const struct snd_soc_dapm_widget adv7511_dapm_widgets[] = { +}; + +static const struct snd_soc_dapm_route adv7511_routes[] = { + { "TMDS", NULL, "DAI IN" }, +}; + +static void adv7511_calc_cts_n(unsigned int f_tmds, unsigned int fs, + unsigned int *cts, unsigned int *n) +{ + switch (fs) { + case 32000: + *n = 4096; + break; + case 44100: + *n = 6272; + break; + case 48000: + *n = 6144; + break; + } + + *cts = ((f_tmds * *n) / (128 * fs)) * 1000; +} + +static int adv7511_update_cts_n(struct adv7511 *adv7511) +{ + unsigned int cts = 0; + unsigned int n = 0; + + adv7511_calc_cts_n(adv7511->f_tmds, adv7511->f_audio, &cts, &n); + + regmap_write(adv7511->regmap, ADV7511_REG_N0, (n >> 16) & 0xf); + regmap_write(adv7511->regmap, ADV7511_REG_N1, (n >> 8) & 0xff); + regmap_write(adv7511->regmap, ADV7511_REG_N2, n & 0xff); + + regmap_write(adv7511->regmap, ADV7511_REG_CTS_MANUAL0, (cts >> 16) & 0xf); + regmap_write(adv7511->regmap, ADV7511_REG_CTS_MANUAL1, (cts >> 8) & 0xff); + regmap_write(adv7511->regmap, ADV7511_REG_CTS_MANUAL2, cts & 0xff); + + return 0; +} + +static int adv7511_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_codec *codec = rtd->codec; + struct adv7511 *adv7511 = snd_soc_codec_get_drvdata(codec); + unsigned int rate; + unsigned int len; + + switch (params_rate(params)) { + case 32000: + rate = ADV7511_SAMPLE_FREQ_32000; + break; + case 44100: + rate = ADV7511_SAMPLE_FREQ_44100; + break; + case 48000: + rate = ADV7511_SAMPLE_FREQ_48000; + break; + case 88200: + rate = ADV7511_SAMPLE_FREQ_88200; + break; + case 96000: + rate = ADV7511_SAMPLE_FREQ_96000; + break; + case 176400: + rate = ADV7511_SAMPLE_FREQ_176400; + break; + case 192000: + rate = ADV7511_SAMPLE_FREQ_192000; + break; + default: + return -EINVAL; + } + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + len = ADV7511_I2S_SAMPLE_LEN_16; + break; + case SNDRV_PCM_FORMAT_S18_3LE: + len = ADV7511_I2S_SAMPLE_LEN_18; + break; + case SNDRV_PCM_FORMAT_S20_3LE: + len = ADV7511_I2S_SAMPLE_LEN_20; + break; + case SNDRV_PCM_FORMAT_S24_LE: + len = ADV7511_I2S_SAMPLE_LEN_24; + break; + default: + return -EINVAL; + } + + adv7511->f_audio = params_rate(params); + + adv7511_update_cts_n(adv7511); + + regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CFG3, + ADV7511_AUDIO_CFG3_LEN_MASK, len); + regmap_update_bits(adv7511->regmap, ADV7511_REG_I2C_FREQ_ID_CFG, + ADV7511_I2C_FREQ_ID_CFG_RATE_MASK, rate << 4); + + return 0; +} + +static int adv7511_set_dai_fmt(struct snd_soc_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct adv7511 *adv7511 = snd_soc_codec_get_drvdata(codec); + unsigned int audio_source, i2s_format = 0; + unsigned int invert_clock; + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + audio_source = ADV7511_AUDIO_SOURCE_I2S; + i2s_format = ADV7511_I2S_FORMAT_I2S; + break; + case SND_SOC_DAIFMT_RIGHT_J: + audio_source = ADV7511_AUDIO_SOURCE_I2S; + i2s_format = ADV7511_I2S_FORMAT_RIGHT_J; + break; + case SND_SOC_DAIFMT_LEFT_J: + audio_source = ADV7511_AUDIO_SOURCE_I2S; + i2s_format = ADV7511_I2S_FORMAT_LEFT_J; + break; + case SND_SOC_DAIFMT_SPDIF: + audio_source = ADV7511_AUDIO_SOURCE_SPDIF; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + invert_clock = 0; + break; + case SND_SOC_DAIFMT_IB_NF: + invert_clock = 1; + break; + default: + return -EINVAL; + } + + regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_SOURCE, 0x70, audio_source << 4); + regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG, BIT(6), invert_clock << 6); + regmap_update_bits(adv7511->regmap, ADV7511_REG_I2S_CONFIG, 0x03, i2s_format); + + adv7511->audio_source = audio_source; + + return 0; +} + +static int adv7511_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + struct adv7511 *adv7511 = snd_soc_codec_get_drvdata(codec); + + switch (level) { + case SND_SOC_BIAS_ON: + switch (adv7511->audio_source) { + case ADV7511_AUDIO_SOURCE_I2S: + break; + case ADV7511_AUDIO_SOURCE_SPDIF: + regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG, BIT(7), BIT(7)); + break; + } + break; + case SND_SOC_BIAS_PREPARE: + if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { + adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_AUDIO_SAMPLE); + adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME); + adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_N_CTS); + } else { + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_AUDIO_SAMPLE); + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME); + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_N_CTS); + } + break; + case SND_SOC_BIAS_STANDBY: + regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG, BIT(7), 0); + break; + case SND_SOC_BIAS_OFF: + break; + } + codec->dapm.bias_level = level; + return 0; +} + +#define ADV7511_RATES (SNDRV_PCM_RATE_32000 |\ + SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000) + +#define ADV7511_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE |\ + SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE) + +static const struct snd_soc_dai_ops adv7511_dai_ops = { + .hw_params = adv7511_hw_params, + /*.set_sysclk = adv7511_set_dai_sysclk,*/ + .set_fmt = adv7511_set_dai_fmt, +}; + +static struct snd_soc_dai_driver adv7511_dai = { + .name = "adv7511", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = ADV7511_RATES, + .formats = ADV7511_FORMATS, + }, + .ops = &adv7511_dai_ops, +}; + +static int adv7511_suspend(struct snd_soc_codec *codec) +{ + return adv7511_set_bias_level(codec, SND_SOC_BIAS_OFF); +} + +static int adv7511_resume(struct snd_soc_codec *codec) +{ + return adv7511_set_bias_level(codec, SND_SOC_BIAS_STANDBY); +} + +static int adv7511_probe(struct snd_soc_codec *codec) +{ + struct adv7511 *adv7511 = snd_soc_codec_get_drvdata(codec); + int ret; + + codec->control_data = adv7511->regmap; + ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); + if (ret < 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + return ret; + } + + return adv7511_set_bias_level(codec, SND_SOC_BIAS_STANDBY); +} + +static int adv7511_remove(struct snd_soc_codec *codec) +{ + adv7511_set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} + +static struct snd_soc_codec_driver adv7511_codec_driver = { + .probe = adv7511_probe, + .remove = adv7511_remove, + .suspend = adv7511_suspend, + .resume = adv7511_resume, + .set_bias_level = adv7511_set_bias_level, + + .dapm_widgets = adv7511_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(adv7511_dapm_widgets), + .dapm_routes = adv7511_routes, + .num_dapm_routes = ARRAY_SIZE(adv7511_routes), +}; + +int adv7511_audio_init(struct device *dev) +{ + return snd_soc_register_codec(dev, &adv7511_codec_driver, + &adv7511_dai, 1); +} + +void adv7511_audio_exit(struct device *dev) +{ + snd_soc_unregister_codec(dev); +} diff --git a/drivers/gpu/drm/i2c/adv7511_core.c b/drivers/gpu/drm/i2c/adv7511_core.c new file mode 100644 index 0000000000000..76dc7b121c3aa --- /dev/null +++ b/drivers/gpu/drm/i2c/adv7511_core.c @@ -0,0 +1,710 @@ +/** + * Analog Devices ADV7511 HDMI transmitter driver + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include + +#include "adv7511.h" + +#include +#include +#include +#include + +static uint8_t adv7511_register_defaults[] = { + 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00 */ + 0x00, 0x00, 0x01, 0x0e, 0xbc, 0x18, 0x01, 0x13, + 0x25, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10 */ + 0x46, 0x62, 0x04, 0xa8, 0x00, 0x00, 0x1c, 0x84, + 0x1c, 0xbf, 0x04, 0xa8, 0x1e, 0x70, 0x02, 0x1e, /* 20 */ + 0x00, 0x00, 0x04, 0xa8, 0x08, 0x12, 0x1b, 0xac, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 */ + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, + 0x00, 0x50, 0x90, 0x7e, 0x79, 0x70, 0x00, 0x00, /* 40 */ + 0x00, 0xa8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0d, 0x00, 0x00, 0x00, 0x00, /* 50 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 60 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 70 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 80 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 90 */ + 0x0b, 0x02, 0x00, 0x18, 0x5a, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x80, 0x08, 0x04, 0x00, 0x00, /* a0 */ + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c0 */ + 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x01, 0x04, + 0x30, 0xff, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, /* d0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, + 0x80, 0x75, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, /* e0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x11, 0x00, /* f0 */ + 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +/* ADI recommanded values for proper operation. */ +static uint8_t adv7511_fixed_registers[][2] = { + { 0x98, 0x03 }, + { 0x9a, 0xe0 }, + { 0x9c, 0x30 }, + { 0x9d, 0x61 }, + { 0xa2, 0xa4 }, + { 0xa3, 0xa4 }, + { 0xe0, 0xd0 }, + { 0xf9, 0x00 }, + { 0x55, 0x02 }, +}; + +static struct adv7511 *encoder_to_adv7511(struct drm_encoder *encoder) +{ + return to_encoder_slave(encoder)->slave_priv; +} + +static void adv7511_set_colormap(struct adv7511 *adv7511, bool enable, + uint16_t *coeff, unsigned int scaling_factor) +{ + unsigned int i; + + regmap_update_bits(adv7511->regmap, ADV7511_REG_CSC_UPPER(1), + ADV7511_CSC_UPDATE_MODE, ADV7511_CSC_UPDATE_MODE); + + if (enable) { + for (i = 0; i < 12; ++i) { + regmap_update_bits(adv7511->regmap, + ADV7511_REG_CSC_UPPER(i), + 0x1f, coeff[i] >> 8); + regmap_write(adv7511->regmap, + ADV7511_REG_CSC_LOWER(i), + coeff[i] & 0xff); + } + } + + regmap_update_bits(adv7511->regmap, ADV7511_REG_CSC_UPPER(0), + 0xe0, (enable << 7) | (scaling_factor << 5)); + + regmap_update_bits(adv7511->regmap, ADV7511_REG_CSC_UPPER(1), + ADV7511_CSC_UPDATE_MODE, 0); +} + +#define ADV7511_HDMI_CFG_MODE_MASK 0x2 +#define ADV7511_HDMI_CFG_MODE_DVI 0x0 +#define ADV7511_HDMI_CFG_MODE_HDMI 0x2 + +static void adv7511_set_config(struct drm_encoder *encoder, void *c) +{ + struct adv7511 *adv7511 = encoder_to_adv7511(encoder); + struct adv7511_video_input_config *config = c; + enum adv7511_input_sync_pulse sync_pulse; + bool output_format_422, output_format_ycbcr; + unsigned int mode; + + adv7511_set_colormap(adv7511, config->csc_enable, + config->csc_coefficents, config->csc_scaling_factor); + + switch (config->output_format) { + case ADV7511_OUTPUT_FORMAT_YCBCR_444: + output_format_422 = false; + output_format_ycbcr = true; + break; + case ADV7511_OUTPUT_FORMAT_YCBCR_422: + output_format_422 = true; + output_format_ycbcr = true; + break; + default: + output_format_422 = false; + output_format_ycbcr = false; + break; + } + + switch (config->id) { + case ADV7511_INPUT_ID_12_15_16BIT_RGB444_YCbCr444: + sync_pulse = ADV7511_INPUT_SYNC_PULSE_NONE; + break; + default: + sync_pulse = config->sync_pulse; + break; + } + + switch (config->id) { + case ADV7511_INPUT_ID_16_20_24BIT_YCbCr422_EMBEDDED_SYNC: + case ADV7511_INPUT_ID_8_10_12BIT_YCbCr422_EMBEDDED_SYNC: + adv7511->embedded_sync = true; + break; + default: + adv7511->embedded_sync = false; + break; + } + + regmap_update_bits(adv7511->regmap, ADV7511_REG_I2C_FREQ_ID_CFG, + 0xf, config->id); + regmap_write(adv7511->regmap, ADV7511_REG_VIDEO_INPUT_CFG1, + (output_format_422 << 7) | + (config->input_color_depth << 4) | + (config->input_style << 2) | + output_format_ycbcr); + regmap_write(adv7511->regmap, ADV7511_REG_VIDEO_INPUT_CFG2, + (config->reverse_bitorder << 6) | + (config->bit_justification << 3)); + regmap_write(adv7511->regmap, ADV7511_REG_TIMING_GEN_SEQ, + (sync_pulse << 2) | + (config->timing_gen_sequence << 1)); + regmap_write(adv7511->regmap, 0xba, + (config->clock_delay << 5)); + + regmap_update_bits(adv7511->regmap, ADV7511_REG_TMDS_CLOCK_INV, + 0x08, config->tmds_clock_inversion << 3); + + regmap_update_bits(adv7511->regmap, ADV7511_REG_AVI_INFOFRAME(0), + 0x60, config->output_format << 5); + + if (config->hdmi_mode) + mode = ADV7511_HDMI_CFG_MODE_HDMI; + else + mode = ADV7511_HDMI_CFG_MODE_DVI; + + regmap_update_bits(adv7511->regmap, ADV7511_REG_HDCP_HDMI_CFG, + 0x2, mode); +} + +int adv7511_packet_enable(struct adv7511 *adv7511, unsigned int packet) +{ + if (packet & 0xff) { + regmap_update_bits(adv7511->regmap, ADV7511_REG_PACKET_ENABLE0, + packet, 0xff); + } + + if (packet & 0xff00) { + packet >>= 8; + regmap_update_bits(adv7511->regmap, ADV7511_REG_PACKET_ENABLE1, + packet, 0xff); + } + + return 0; +} + +int adv7511_packet_disable(struct adv7511 *adv7511, unsigned int packet) +{ + if (packet & 0xff) { + regmap_update_bits(adv7511->regmap, ADV7511_REG_PACKET_ENABLE0, + packet, 0x00); + } + + if (packet & 0xff00) { + packet >>= 8; + regmap_update_bits(adv7511->regmap, ADV7511_REG_PACKET_ENABLE1, + packet, 0x00); + } + + return 0; +} + +static bool adv7511_register_volatile(struct device *dev, unsigned int reg) +{ + switch (reg) { + case ADV7511_REG_SPDIF_FREQ: + case ADV7511_REG_CTS_AUTOMATIC1: + case ADV7511_REG_CTS_AUTOMATIC2: + case ADV7511_REG_VIC_DETECTED: + case ADV7511_REG_VIC_SEND: + case ADV7511_REG_AUX_VIC_DETECTED: + case ADV7511_REG_STATUS: + case ADV7511_REG_GC(1): + case ADV7511_REG_INT(0): + case ADV7511_REG_INT(1): + case ADV7511_REG_PLL_STATUS: + case ADV7511_REG_AN(0): + case ADV7511_REG_AN(1): + case ADV7511_REG_AN(2): + case ADV7511_REG_AN(3): + case ADV7511_REG_AN(4): + case ADV7511_REG_AN(5): + case ADV7511_REG_AN(6): + case ADV7511_REG_AN(7): + case ADV7511_REG_HDCP_STATUS: + case ADV7511_REG_BCAPS: + case ADV7511_REG_BKSV(0): + case ADV7511_REG_BKSV(1): + case ADV7511_REG_BKSV(2): + case ADV7511_REG_BKSV(3): + case ADV7511_REG_BKSV(4): + case ADV7511_REG_DDC_STATUS: + case ADV7511_REG_BSTATUS(0): + case ADV7511_REG_BSTATUS(1): + case ADV7511_REG_CHIP_ID_HIGH: + case ADV7511_REG_CHIP_ID_LOW: + return true; + } + + return false; +} + +static bool adv7511_hpd(struct adv7511 *adv7511) +{ + unsigned int irq0; + int ret; + + ret = regmap_read(adv7511->regmap, ADV7511_REG_INT(0), &irq0); + if (ret < 0) + return false; + + if (irq0 & ADV7511_INT0_HDP) { + regmap_write(adv7511->regmap, ADV7511_REG_INT(0), ADV7511_INT0_HDP); + return true; + } + + return false; +} + +static irqreturn_t adv7511_irq_handler(int irq, void *devid) +{ + struct adv7511 *adv7511 = devid; + + if (adv7511_hpd(adv7511)) + drm_helper_hpd_irq_event(adv7511->encoder->dev); + + wake_up_all(&adv7511->wq); + + return IRQ_HANDLED; +} + +static unsigned int adv7511_is_interrupt_pending(struct adv7511 *adv7511, + unsigned int irq) +{ + unsigned int irq0, irq1; + unsigned int pending; + int ret; + + ret = regmap_read(adv7511->regmap, ADV7511_REG_INT(0), &irq0); + if (ret < 0) + return 0; + ret = regmap_read(adv7511->regmap, ADV7511_REG_INT(1), &irq1); + if (ret < 0) + return 0; + + pending = (irq1 << 8) | irq0; + + return pending & irq; +} + +static int adv7511_wait_for_interrupt(struct adv7511 *adv7511, int irq, int timeout) +{ + unsigned int pending = 0; + int ret; + + if (adv7511->i2c_main->irq) { + ret = wait_event_interruptible_timeout(adv7511->wq, + adv7511_is_interrupt_pending(adv7511, irq), + msecs_to_jiffies(timeout)); + if (ret <= 0) + return 0; + pending = adv7511_is_interrupt_pending(adv7511, irq); + } else { + if (timeout < 25) + timeout = 25; + do { + pending = adv7511_is_interrupt_pending(adv7511, irq); + if (pending) + break; + msleep(25); + timeout -= 25; + } while (timeout >= 25); + } + + return pending; +} + +static int adv7511_get_edid_block(void *data, unsigned char *buf, + int block, int len) +{ + struct drm_encoder *encoder = data; + struct adv7511 *adv7511 = encoder_to_adv7511(encoder); + struct i2c_msg xfer[2]; + uint8_t offset; + int i; + int ret; + + if (len > 128) + return -EINVAL; + + if (adv7511->current_edid_segment != block / 2) { + unsigned int status; + + ret = regmap_read(adv7511->regmap, ADV7511_REG_DDC_STATUS, &status); + if (ret < 0) + return ret; + + if (status != 2) { + regmap_write(adv7511->regmap, ADV7511_REG_EDID_SEGMENT, block); + ret = adv7511_wait_for_interrupt(adv7511, ADV7511_INT0_EDID_READY | + ADV7511_INT1_DDC_ERROR, 200); + + if (!(ret & ADV7511_INT0_EDID_READY)) + return -EIO; + } + + regmap_write(adv7511->regmap, ADV7511_REG_INT(0), + ADV7511_INT0_EDID_READY | ADV7511_INT1_DDC_ERROR); + + /* Break this apart, hopefully more I2C controllers will support 64 + * byte transfers than 256 byte transfers */ + + xfer[0].addr = adv7511->i2c_edid->addr; + xfer[0].flags = 0; + xfer[0].len = 1; + xfer[0].buf = &offset; + xfer[1].addr = adv7511->i2c_edid->addr; + xfer[1].flags = I2C_M_RD; + xfer[1].len = 64; + xfer[1].buf = adv7511->edid_buf; + + offset = 0; + + for (i = 0; i < 4; ++i) { + ret = i2c_transfer(adv7511->i2c_edid->adapter, xfer, ARRAY_SIZE(xfer)); + if (ret < 0) + return ret; + else if (ret != 2) + return -EIO; + + xfer[1].buf += 64; + offset += 64; + } + + adv7511->current_edid_segment = block / 2; + } + + if (block % 2 == 0) + memcpy(buf, adv7511->edid_buf, len); + else + memcpy(buf, adv7511->edid_buf + 128, len); + + return 0; +} + +static int adv7511_get_modes(struct drm_encoder *encoder, + struct drm_connector *connector) +{ + struct adv7511 *adv7511 = encoder_to_adv7511(encoder); + struct edid *edid; + unsigned int count; + + /* Reading the EDID only works if the device is powered */ + if (adv7511->dpms_mode != DRM_MODE_DPMS_ON) { + regmap_write(adv7511->regmap, ADV7511_REG_INT(0), + ADV7511_INT0_EDID_READY | ADV7511_INT1_DDC_ERROR); + regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, + ADV7511_POWER_POWER_DOWN, 0); + adv7511->current_edid_segment = -1; + } + + edid = drm_do_get_edid(connector, adv7511_get_edid_block, encoder); + + if (adv7511->dpms_mode != DRM_MODE_DPMS_ON) + regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, + ADV7511_POWER_POWER_DOWN, ADV7511_POWER_POWER_DOWN); + + if (!edid) + return 0; + + drm_mode_connector_update_edid_property(connector, edid); + count = drm_add_edid_modes(connector, edid); + + connector->display_info.raw_edid = (char *)edid; + + return count; +} + +static void adv7511_encoder_dpms(struct drm_encoder *encoder, int mode) +{ + struct adv7511 *adv7511 = encoder_to_adv7511(encoder); + + switch (mode) { + case DRM_MODE_DPMS_ON: + adv7511->current_edid_segment = -1; + + regmap_write(adv7511->regmap, ADV7511_REG_INT(0), + ADV7511_INT0_EDID_READY | ADV7511_INT1_DDC_ERROR); + regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, + ADV7511_POWER_POWER_DOWN, 0); + /* + * Per spec it is allowed to pulse the HDP signal to indicate + * that the EDID information has changed. Some monitors do this + * when they wakeup from standby or are enabled. When the HDP + * goes low the adv7511 is reset and the outputs are disabled + * which might cause the monitor to go to standby again. To + * avoid this we ignore the HDP pin for the first few seconds + * after enabeling the output. + */ + regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, + ADV7511_REG_POWER2_HDP_SRC_MASK, + ADV7511_REG_POWER2_HDP_SRC_NONE); + /* Most of the registers are reset during power down or when HPD is low */ + regcache_sync(adv7511->regmap); + break; + default: + /* TODO: setup additional power down modes */ + regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, + ADV7511_POWER_POWER_DOWN, ADV7511_POWER_POWER_DOWN); + regcache_mark_dirty(adv7511->regmap); + break; + } + + adv7511->dpms_mode = mode; +} + +static enum drm_connector_status adv7511_encoder_detect(struct drm_encoder *encoder, + struct drm_connector *connector) +{ + struct adv7511 *adv7511 = encoder_to_adv7511(encoder); + enum drm_connector_status status; + unsigned int val; + bool hpd; + + regmap_read(adv7511->regmap, ADV7511_REG_STATUS, &val); + + /* Cable connected and monitor turned on ? */ + if (val & (ADV7511_STATUS_HPD)) /* | ADV7511_STATUS_MONITOR_SENSE))*/ + status = connector_status_connected; + else + status = connector_status_disconnected; + + hpd = adv7511_hpd(adv7511); + + /* The chip resets itself when the cable is disconnected, so in case there is + * a pending HPD interrupt and the cable is connected there was at least on + * transition from disconnected to connected and the chip has to be + * reinitialized. */ + if (status == connector_status_connected && hpd && + adv7511->dpms_mode == DRM_MODE_DPMS_ON) { + regcache_mark_dirty(adv7511->regmap); + adv7511_encoder_dpms(encoder, adv7511->dpms_mode); + adv7511_get_modes(encoder, connector); + } else { + /* Renable HDP sensing */ + regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, + ADV7511_REG_POWER2_HDP_SRC_MASK, + ADV7511_REG_POWER2_HDP_SRC_BOTH); + } + + adv7511->status = status; + return status; +} + +static void adv7511_encoder_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adj_mode) +{ + struct adv7511 *adv7511 = encoder_to_adv7511(encoder); + unsigned int low_refresh_rate; + + if (adv7511->embedded_sync) { + unsigned int hsync_offset, hsync_len; + unsigned int vsync_offset, vsync_len; + + hsync_offset = adj_mode->crtc_hsync_start - adj_mode->crtc_hdisplay; + vsync_offset = adj_mode->crtc_vsync_start - adj_mode->crtc_vdisplay; + hsync_len = adj_mode->crtc_hsync_end - adj_mode->crtc_hsync_start; + vsync_len = adj_mode->crtc_vsync_end - adj_mode->crtc_vsync_start; + + regmap_write(adv7511->regmap, ADV7511_REG_HSYNC_PLACEMENT_MSB, + ((hsync_offset >> 10) & 0x7) << 5); + regmap_write(adv7511->regmap, ADV7511_REG_SYNC_DECODER(0), + (hsync_offset >> 2) & 0xff); + regmap_write(adv7511->regmap, ADV7511_REG_SYNC_DECODER(1), + ((hsync_offset & 0x3) << 2) | (hsync_len >> 4)); + regmap_write(adv7511->regmap, ADV7511_REG_SYNC_DECODER(2), + ((hsync_len & 0xf) << 4) | (vsync_offset >> 6)); + regmap_write(adv7511->regmap, ADV7511_REG_SYNC_DECODER(3), + ((vsync_offset & 0x3f) << 2) | (vsync_len >> 8)); + regmap_write(adv7511->regmap, ADV7511_REG_SYNC_DECODER(4), + vsync_len & 0xff); + } + + if (mode->vrefresh <= 24000) + low_refresh_rate = ADV7511_LOW_REFRESH_RATE_24HZ; + else if (mode->vrefresh <= 25000) + low_refresh_rate = ADV7511_LOW_REFRESH_RATE_25HZ; + else if (mode->vrefresh <= 30000) + low_refresh_rate = ADV7511_LOW_REFRESH_RATE_30HZ; + else + low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE; + + regmap_update_bits(adv7511->regmap, 0xfb, + 0x6, low_refresh_rate << 1); + + adv7511->f_tmds = mode->clock; + +/* + switch (adv7511->color_mode) { + case ADV7511_COLOR_MODE_30BIT: + adv7511->f_tmds = adv7511->f_tmds * 5 / 4; + break; + case ADV7511_COLOR_MODE_36BIT: + adv7511->f_tmds = adv7511->f_tmds * 3 / 2; + break; + case ADV7511_COLOR_MODE_48BIT: + adv7511->f_tmds = adv7511->f_tmds * 2; + break; + case ADV7511_COLOR_MODE_24BIT: + break; + } +*/ +} + +static struct drm_encoder_slave_funcs adv7511_encoder_funcs = { + .set_config = adv7511_set_config, + .dpms = adv7511_encoder_dpms, + /* .destroy = adv7511_encoder_destroy,*/ + .mode_set = adv7511_encoder_mode_set, + .detect = adv7511_encoder_detect, + .get_modes = adv7511_get_modes, +}; + +static const struct regmap_config adv7511_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = 0xff, + .cache_type = REGCACHE_RBTREE, + .reg_defaults_raw = adv7511_register_defaults, + .num_reg_defaults_raw = ARRAY_SIZE(adv7511_register_defaults), + + .volatile_reg = adv7511_register_volatile, +}; + +static const int edid_i2c_addr = 0x7e; +static const int packet_i2c_addr = 0x70; +static const int cec_i2c_addr = 0x78; + +static int __devinit adv7511_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct adv7511 *adv7511; + unsigned int val; + unsigned int i; + int ret; + + adv7511 = devm_kzalloc(&i2c->dev, sizeof(*adv7511), GFP_KERNEL); + if (!adv7511) + return -ENOMEM; + + adv7511->regmap = devm_regmap_init_i2c(i2c, &adv7511_regmap_config); + if (IS_ERR(adv7511->regmap)) + return PTR_ERR(adv7511->regmap); + + ret = regmap_read(adv7511->regmap, ADV7511_REG_CHIP_REVISION, &val); + dev_dbg(&i2c->dev, "Rev. %d\n", val); + + regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, edid_i2c_addr); + regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR, packet_i2c_addr); + regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR, cec_i2c_addr); + + adv7511->i2c_main = i2c; + adv7511->i2c_edid = i2c_new_dummy(i2c->adapter, edid_i2c_addr >> 1); + if (!adv7511->i2c_edid) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(adv7511_fixed_registers); ++i) { + regmap_write(adv7511->regmap, adv7511_fixed_registers[i][0], + adv7511_fixed_registers[i][1]); + } + + if (i2c->irq) { + ret = request_threaded_irq(i2c->irq, NULL, adv7511_irq_handler, + IRQF_ONESHOT, dev_name(&i2c->dev), adv7511); + if (ret) + goto err_i2c_unregister_device; + + init_waitqueue_head(&adv7511->wq); + } + + /* CEC is unused for now */ + regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL, + ADV7511_CEC_CTRL_POWER_DOWN); + + regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, + ADV7511_POWER_POWER_DOWN, ADV7511_POWER_POWER_DOWN); + + adv7511->current_edid_segment = -1; + + i2c_set_clientdata(i2c, adv7511); + adv7511_audio_init(&i2c->dev); + + return 0; + +err_i2c_unregister_device: + i2c_unregister_device(adv7511->i2c_edid); + + return ret; +} + +static int __devexit adv7511_remove(struct i2c_client *i2c) +{ + struct adv7511 *adv7511 = i2c_get_clientdata(i2c); + + i2c_unregister_device(adv7511->i2c_edid); + + if (i2c->irq) + free_irq(i2c->irq, adv7511); + + return 0; +} + +static int adv7511_encoder_init(struct i2c_client *i2c, + struct drm_device *dev, struct drm_encoder_slave *encoder) +{ + + struct adv7511 *adv7511 = i2c_get_clientdata(i2c); + + encoder->slave_priv = adv7511; + encoder->slave_funcs = &adv7511_encoder_funcs; + + adv7511->encoder = &encoder->base; + + return 0; +} + +static const struct i2c_device_id adv7511_ids[] = { + { "adv7511", 0 }, + {} +}; + +static struct drm_i2c_encoder_driver adv7511_driver = { + .i2c_driver = { + .driver = { + .name = "adv7511", + }, + .id_table = adv7511_ids, + .probe = adv7511_probe, + .remove = __devexit_p(adv7511_remove), + }, + + .encoder_init = adv7511_encoder_init, +}; + +static int __init adv7511_init(void) +{ + return drm_i2c_encoder_register(THIS_MODULE, &adv7511_driver); +} +module_init(adv7511_init); + +static void __exit adv7511_exit(void) +{ + drm_i2c_encoder_unregister(&adv7511_driver); +} +module_exit(adv7511_exit); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("ADV7511 HDMI transmitter driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index 641d0e5e33036..52f480e88b998 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -174,47 +174,32 @@ struct xiic_i2c { static void xiic_start_xfer(struct xiic_i2c *i2c); static void __xiic_start_xfer(struct xiic_i2c *i2c); -static inline void xiic_setreg8(struct xiic_i2c *i2c, int reg, u8 value) -{ - iowrite8(value, i2c->base + reg); -} - -static inline u8 xiic_getreg8(struct xiic_i2c *i2c, int reg) -{ - return ioread8(i2c->base + reg); -} - -static inline void xiic_setreg16(struct xiic_i2c *i2c, int reg, u16 value) -{ - iowrite16(value, i2c->base + reg); -} - -static inline void xiic_setreg32(struct xiic_i2c *i2c, int reg, int value) +static inline void xiic_setreg(struct xiic_i2c *i2c, int reg, int value) { iowrite32(value, i2c->base + reg); } -static inline int xiic_getreg32(struct xiic_i2c *i2c, int reg) +static inline int xiic_getreg(struct xiic_i2c *i2c, int reg) { return ioread32(i2c->base + reg); } static inline void xiic_irq_dis(struct xiic_i2c *i2c, u32 mask) { - u32 ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET); - xiic_setreg32(i2c, XIIC_IIER_OFFSET, ier & ~mask); + u32 ier = xiic_getreg(i2c, XIIC_IIER_OFFSET); + xiic_setreg(i2c, XIIC_IIER_OFFSET, ier & ~mask); } static inline void xiic_irq_en(struct xiic_i2c *i2c, u32 mask) { - u32 ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET); - xiic_setreg32(i2c, XIIC_IIER_OFFSET, ier | mask); + u32 ier = xiic_getreg(i2c, XIIC_IIER_OFFSET); + xiic_setreg(i2c, XIIC_IIER_OFFSET, ier | mask); } static inline void xiic_irq_clr(struct xiic_i2c *i2c, u32 mask) { - u32 isr = xiic_getreg32(i2c, XIIC_IISR_OFFSET); - xiic_setreg32(i2c, XIIC_IISR_OFFSET, isr & mask); + u32 isr = xiic_getreg(i2c, XIIC_IISR_OFFSET); + xiic_setreg(i2c, XIIC_IISR_OFFSET, isr & mask); } static inline void xiic_irq_clr_en(struct xiic_i2c *i2c, u32 mask) @@ -226,30 +211,30 @@ static inline void xiic_irq_clr_en(struct xiic_i2c *i2c, u32 mask) static void xiic_clear_rx_fifo(struct xiic_i2c *i2c) { u8 sr; - for (sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET); + for (sr = xiic_getreg(i2c, XIIC_SR_REG_OFFSET); !(sr & XIIC_SR_RX_FIFO_EMPTY_MASK); - sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET)) - xiic_getreg8(i2c, XIIC_DRR_REG_OFFSET); + sr = xiic_getreg(i2c, XIIC_SR_REG_OFFSET)) + xiic_getreg(i2c, XIIC_DRR_REG_OFFSET); } static void xiic_reinit(struct xiic_i2c *i2c) { - xiic_setreg32(i2c, XIIC_RESETR_OFFSET, XIIC_RESET_MASK); + xiic_setreg(i2c, XIIC_RESETR_OFFSET, XIIC_RESET_MASK); /* Set receive Fifo depth to maximum (zero based). */ - xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, IIC_RX_FIFO_DEPTH - 1); + xiic_setreg(i2c, XIIC_RFD_REG_OFFSET, IIC_RX_FIFO_DEPTH - 1); /* Reset Tx Fifo. */ - xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_TX_FIFO_RESET_MASK); + xiic_setreg(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_TX_FIFO_RESET_MASK); /* Enable IIC Device, remove Tx Fifo reset & disable general call. */ - xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_ENABLE_DEVICE_MASK); + xiic_setreg(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_ENABLE_DEVICE_MASK); /* make sure RX fifo is empty */ xiic_clear_rx_fifo(i2c); /* Enable interrupts */ - xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK); + xiic_setreg(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK); xiic_irq_clr_en(i2c, XIIC_INTR_AAS_MASK | XIIC_INTR_ARB_LOST_MASK); } @@ -258,11 +243,11 @@ static void xiic_deinit(struct xiic_i2c *i2c) { u8 cr; - xiic_setreg32(i2c, XIIC_RESETR_OFFSET, XIIC_RESET_MASK); + xiic_setreg(i2c, XIIC_RESETR_OFFSET, XIIC_RESET_MASK); /* Disable IIC Device. */ - cr = xiic_getreg8(i2c, XIIC_CR_REG_OFFSET); - xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, cr & ~XIIC_CR_ENABLE_DEVICE_MASK); + cr = xiic_getreg(i2c, XIIC_CR_REG_OFFSET); + xiic_setreg(i2c, XIIC_CR_REG_OFFSET, cr & ~XIIC_CR_ENABLE_DEVICE_MASK); } static void xiic_read_rx(struct xiic_i2c *i2c) @@ -270,22 +255,22 @@ static void xiic_read_rx(struct xiic_i2c *i2c) u8 bytes_in_fifo; int i; - bytes_in_fifo = xiic_getreg8(i2c, XIIC_RFO_REG_OFFSET) + 1; + bytes_in_fifo = xiic_getreg(i2c, XIIC_RFO_REG_OFFSET) + 1; dev_dbg(i2c->adap.dev.parent, "%s entry, bytes in fifo: %d, msg: %d" ", SR: 0x%x, CR: 0x%x\n", __func__, bytes_in_fifo, xiic_rx_space(i2c), - xiic_getreg8(i2c, XIIC_SR_REG_OFFSET), - xiic_getreg8(i2c, XIIC_CR_REG_OFFSET)); + xiic_getreg(i2c, XIIC_SR_REG_OFFSET), + xiic_getreg(i2c, XIIC_CR_REG_OFFSET)); if (bytes_in_fifo > xiic_rx_space(i2c)) bytes_in_fifo = xiic_rx_space(i2c); for (i = 0; i < bytes_in_fifo; i++) i2c->rx_msg->buf[i2c->rx_pos++] = - xiic_getreg8(i2c, XIIC_DRR_REG_OFFSET); + xiic_getreg(i2c, XIIC_DRR_REG_OFFSET); - xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, + xiic_setreg(i2c, XIIC_RFD_REG_OFFSET, (xiic_rx_space(i2c) > IIC_RX_FIFO_DEPTH) ? IIC_RX_FIFO_DEPTH - 1 : xiic_rx_space(i2c) - 1); } @@ -293,7 +278,7 @@ static void xiic_read_rx(struct xiic_i2c *i2c) static int xiic_tx_fifo_space(struct xiic_i2c *i2c) { /* return the actual space left in the FIFO */ - return IIC_TX_FIFO_DEPTH - xiic_getreg8(i2c, XIIC_TFO_REG_OFFSET) - 1; + return IIC_TX_FIFO_DEPTH - xiic_getreg(i2c, XIIC_TFO_REG_OFFSET) - 1; } static void xiic_fill_tx_fifo(struct xiic_i2c *i2c) @@ -313,9 +298,9 @@ static void xiic_fill_tx_fifo(struct xiic_i2c *i2c) data |= XIIC_TX_DYN_STOP_MASK; dev_dbg(i2c->adap.dev.parent, "%s TX STOP\n", __func__); - xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data); + xiic_setreg(i2c, XIIC_DTR_REG_OFFSET, data); } else - xiic_setreg8(i2c, XIIC_DTR_REG_OFFSET, data); + xiic_setreg(i2c, XIIC_DTR_REG_OFFSET, data); } } @@ -338,13 +323,13 @@ static void xiic_process(struct xiic_i2c *i2c) * To find which interrupts are pending; AND interrupts pending with * interrupts masked. */ - isr = xiic_getreg32(i2c, XIIC_IISR_OFFSET); - ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET); + isr = xiic_getreg(i2c, XIIC_IISR_OFFSET); + ier = xiic_getreg(i2c, XIIC_IIER_OFFSET); pend = isr & ier; dev_dbg(i2c->adap.dev.parent, "%s entry, IER: 0x%x, ISR: 0x%x, " "pend: 0x%x, SR: 0x%x, msg: %p, nmsgs: %d\n", - __func__, ier, isr, pend, xiic_getreg8(i2c, XIIC_SR_REG_OFFSET), + __func__, ier, isr, pend, xiic_getreg(i2c, XIIC_SR_REG_OFFSET), i2c->tx_msg, i2c->nmsgs); /* Do not processes a devices interrupts if the device has no @@ -408,6 +393,8 @@ static void xiic_process(struct xiic_i2c *i2c) "%s will start next...\n", __func__); __xiic_start_xfer(i2c); + } else { + xiic_wakeup(i2c, STATE_DONE); } } } else if (pend & XIIC_INTR_BNB_MASK) { @@ -470,12 +457,12 @@ static void xiic_process(struct xiic_i2c *i2c) out: dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr); - xiic_setreg32(i2c, XIIC_IISR_OFFSET, clr); + xiic_setreg(i2c, XIIC_IISR_OFFSET, clr); } static int xiic_bus_busy(struct xiic_i2c *i2c) { - u8 sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET); + u8 sr = xiic_getreg(i2c, XIIC_SR_REG_OFFSET); return (sr & XIIC_SR_BUS_BUSY_MASK) ? -EBUSY : 0; } @@ -518,22 +505,18 @@ static void xiic_start_recv(struct xiic_i2c *i2c) rx_watermark = msg->len; if (rx_watermark > IIC_RX_FIFO_DEPTH) rx_watermark = IIC_RX_FIFO_DEPTH; - xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, rx_watermark - 1); + xiic_setreg(i2c, XIIC_RFD_REG_OFFSET, rx_watermark - 1); if (!(msg->flags & I2C_M_NOSTART)) /* write the address */ - xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, + xiic_setreg(i2c, XIIC_DTR_REG_OFFSET, (msg->addr << 1) | XIIC_READ_OPERATION | XIIC_TX_DYN_START_MASK); xiic_irq_clr_en(i2c, XIIC_INTR_BNB_MASK); - xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, + xiic_setreg(i2c, XIIC_DTR_REG_OFFSET, msg->len | ((i2c->nmsgs == 1) ? XIIC_TX_DYN_STOP_MASK : 0)); - if (i2c->nmsgs == 1) - /* very last, enable bus not busy as well */ - xiic_irq_clr_en(i2c, XIIC_INTR_BNB_MASK); - /* the message is tx:ed */ i2c->tx_pos = msg->len; } @@ -546,8 +529,8 @@ static void xiic_start_send(struct xiic_i2c *i2c) dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, len: %d, " "ISR: 0x%x, CR: 0x%x\n", - __func__, msg, msg->len, xiic_getreg32(i2c, XIIC_IISR_OFFSET), - xiic_getreg8(i2c, XIIC_CR_REG_OFFSET)); + __func__, msg, msg->len, xiic_getreg(i2c, XIIC_IISR_OFFSET), + xiic_getreg(i2c, XIIC_CR_REG_OFFSET)); if (!(msg->flags & I2C_M_NOSTART)) { /* write the address */ @@ -557,7 +540,7 @@ static void xiic_start_send(struct xiic_i2c *i2c) /* no data and last message -> add STOP */ data |= XIIC_TX_DYN_STOP_MASK; - xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data); + xiic_setreg(i2c, XIIC_DTR_REG_OFFSET, data); } xiic_fill_tx_fifo(i2c); @@ -573,13 +556,13 @@ static irqreturn_t xiic_isr(int irq, void *dev_id) spin_lock(&i2c->lock); /* disable interrupts globally */ - xiic_setreg32(i2c, XIIC_DGIER_OFFSET, 0); + xiic_setreg(i2c, XIIC_DGIER_OFFSET, 0); dev_dbg(i2c->adap.dev.parent, "%s entry\n", __func__); xiic_process(i2c); - xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK); + xiic_setreg(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK); spin_unlock(&i2c->lock); return IRQ_HANDLED; @@ -636,11 +619,11 @@ static void xiic_start_xfer(struct xiic_i2c *i2c) spin_lock_irqsave(&i2c->lock, flags); xiic_reinit(i2c); /* disable interrupts globally */ - xiic_setreg32(i2c, XIIC_DGIER_OFFSET, 0); + xiic_setreg(i2c, XIIC_DGIER_OFFSET, 0); spin_unlock_irqrestore(&i2c->lock, flags); __xiic_start_xfer(i2c); - xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK); + xiic_setreg(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK); } static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) @@ -649,7 +632,7 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) int err; dev_dbg(adap->dev.parent, "%s entry SR: 0x%x\n", __func__, - xiic_getreg8(i2c, XIIC_SR_REG_OFFSET)); + xiic_getreg(i2c, XIIC_SR_REG_OFFSET)); err = xiic_busy(i2c); if (err) diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 8a78b4f3ef581..1d5d19b62f1c3 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -22,4 +22,24 @@ config AT91_ADC help Say yes here to build support for Atmel AT91 ADC. +config CF_AXI_ADC + tristate "Analog Devices AD9467 AD9643 High-Speed AXI ADC driver" + select IIO_BUFFER + help + Say yes here to build support for Analog Devices AD9467 and AD9643, + High-Speed LVDS analog to digital converters (ADC). + FPGA interface HDL is available here: + http://wiki.analog.com/resources/fpga/xilinx/fmc/ad9467 + If unsure, say N (but it's safe to say "Y"). + + To compile this driver as a module, choose M here: the + module will be called cf_axi_adc. + +config CF_AXI_FFT + tristate "Generic FFT driver" + +config AXI_JESD204B + tristate "Generic AXI JESD204B configuration driver" + + endmenu diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 52eec254c38c3..b1015dc420eed 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -4,3 +4,11 @@ obj-$(CONFIG_AD7266) += ad7266.o obj-$(CONFIG_AT91_ADC) += at91_adc.o + +cf_axi_adc-y := cf_axi_adc_core.o cf_axi_adc_ring.o +obj-$(CONFIG_CF_AXI_ADC) += cf_axi_adc.o ad9467.o +obj-$(CONFIG_CF_AXI_FFT) += cf_axi_fft_core.o + +obj-$(CONFIG_AXI_JESD204B) += cf_axi_jesd204b.o + +obj-$(CONFIG_AT91_ADC) += at91_adc.o diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c new file mode 100644 index 0000000000000..e6b7a08e75edb --- /dev/null +++ b/drivers/iio/adc/ad9467.c @@ -0,0 +1,199 @@ +/* + * AD9467 SPI DAC driver for DDS PCORE/COREFPGA Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "cf_axi_adc.h" + +#include +#include + +static int ad9467_spi_read(struct spi_device *spi, unsigned reg) +{ + unsigned char buf[3]; + int ret; + + if (spi) { + buf[0] = 0x80 | (reg >> 8); + buf[1] = reg & 0xFF; + + ret = spi_write_then_read(spi, &buf[0], 2, &buf[2], 1); + if (ret < 0) + return ret; + + return buf[2]; + } + return -ENODEV; +} + +static int ad9467_spi_write(struct spi_device *spi, unsigned reg, unsigned val) +{ + unsigned char buf[3]; + int ret; + + if (spi) { + buf[0] = reg >> 8; + buf[1] = reg & 0xFF; + buf[2] = val; + ret = spi_write_then_read(spi, buf, 3, NULL, 0); + if (ret < 0) + return ret; + + if ((reg == ADC_REG_TRANSFER) && (val == TRANSFER_SYNC) && + (spi_get_device_id(spi)->driver_data == CHIPID_AD9265)) + ad9467_spi_write(spi, ADC_REG_TRANSFER, 0); + + return 0; + } + + return -ENODEV; +} + +static int __devinit ad9250_setup(struct spi_device *spi) +{ + int ret; + unsigned pll_stat; + + ret = ad9467_spi_write(spi, 0x18, 0x0f); // max vref + ret |= ad9467_spi_write(spi, 0x64, 0xf0); // did + ret |= ad9467_spi_write(spi, 0x80, 0x0f); // powerdown + ret |= ad9467_spi_write(spi, 0x5f, 0x17); // char repl & ilas + ret |= ad9467_spi_write(spi, 0x09, 0x01); // clock control + ret |= ad9467_spi_write(spi, 0x82, 0x02); // lane b = 0, lane a = 2 + ret |= ad9467_spi_write(spi, 0x83, 0x31); // lane c = 1, lane d = 3 + ret |= ad9467_spi_write(spi, 0x6e, 0x81); // scr, 2-lane + ret |= ad9467_spi_write(spi, 0x70, 0x1f); // no. of frames per multi frame + ret |= ad9467_spi_write(spi, 0x5e, 0x22); // m=2, l=2 + ret |= ad9467_spi_write(spi, 0x5f, 0x16); // char repl & ilas + ret |= ad9467_spi_write(spi, 0x80, 0x09); // powerdown + ret |= ad9467_spi_write(spi, 0x3a, 0x10); // sysref ctrl + ret |= ad9467_spi_write(spi, 0x14, 0x00); // offset binary + ret |= ad9467_spi_write(spi, 0x0d, 0x00); // test patterns + ret |= ad9467_spi_write(spi, 0xff, 0x01); + ret |= ad9467_spi_write(spi, 0xff, 0x00); + + pll_stat = ad9467_spi_read(spi, 0x0A); + + dev_info(&spi->dev, "PLL %s, JESD204B Link %s\n", + pll_stat & 0x80 ? "LOCKED" : "UNLOCKED", + pll_stat & 0x01 ? "Ready" : "Fail"); + + return ret; +} + +static int __devinit ad9467_probe(struct spi_device *spi) +{ + struct axiadc_converter *conv; + struct clk *clk = NULL; + int ret; + + if (spi_get_device_id(spi)->driver_data == CHIPID_AD9250) { + clk = clk_get(&spi->dev, NULL); + if (IS_ERR(clk)) { + return -EPROBE_DEFER; + } + + ret = clk_prepare(clk); + if (ret < 0) + return ret; + + ret = clk_enable(clk); + if (ret < 0) { + clk_unprepare(clk); + return ret; + } + } + + conv = kzalloc(sizeof(*conv), GFP_KERNEL); + if (conv == NULL) + return -ENOMEM; + + spi->mode = SPI_MODE_0 | SPI_3WIRE; + + if (clk) + conv->clk = clk; + + conv->id = ad9467_spi_read(spi, ADC_REG_CHIP_ID); + if (conv->id != spi_get_device_id(spi)->driver_data) { + dev_err(&spi->dev, "Unrecognized CHIP_ID 0x%X\n", conv->id); + ret = -ENODEV; + goto out; + } + + if (conv->id == CHIPID_AD9250) { + ret = ad9250_setup(spi); + if (ret) { + dev_err(&spi->dev, "Failed to initialize\n"); + ret = -EIO; + goto out; + } + } + + conv->write = ad9467_spi_write; + conv->read = ad9467_spi_read; + conv->spi = spi; + spi_set_drvdata(spi, conv); + + return 0; + +out: + kfree(conv); + if (clk) { + clk_disable(clk); + clk_unprepare(clk); + clk_put(clk); + } + + return ret; +} + +static int ad9467_remove(struct spi_device *spi) +{ + struct axiadc_converter *conv = spi_get_drvdata(spi); + + if (conv->clk) { + clk_disable(conv->clk); + clk_unprepare(conv->clk); + clk_put(conv->clk); + } + spi_set_drvdata(spi, NULL); + + return 0; +} + +static const struct spi_device_id ad9467_id[] = { + {"ad9467", CHIPID_AD9467}, + {"ad9643", CHIPID_AD9643}, + {"ad9250", CHIPID_AD9250}, + {"ad9265", CHIPID_AD9265}, + {} +}; +MODULE_DEVICE_TABLE(spi, ad9467_id); + +static struct spi_driver ad9467_driver = { + .driver = { + .name = "ad9467", + .owner = THIS_MODULE, + }, + .probe = ad9467_probe, + .remove = __devexit_p(ad9467_remove), + .id_table = ad9467_id, +}; +module_spi_driver(ad9467_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD9467 ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/adc/cf_axi_adc.h b/drivers/iio/adc/cf_axi_adc.h new file mode 100644 index 0000000000000..2627a702a8ee6 --- /dev/null +++ b/drivers/iio/adc/cf_axi_adc.h @@ -0,0 +1,235 @@ +/* + * ADI-AIM ADI ADC Interface Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + * + * http://wiki.analog.com/resources/fpga/xilinx/fmc/ad9467 + */ + +#ifndef ADI_AXI_ADC_H_ +#define ADI_AXI_ADC_H_ + +/* PCORE CoreFPGA register map */ + +#define AXIADC_PCORE_VERSION 0x00 +#define AXIADC_PCORE_DMA_CHAN_SEL 0x08 +#define AXIADC_PCORE_DMA_CTRL 0x0C +#define AXIADC_PCORE_DMA_STAT 0x10 +#define AXIADC_PCORE_ADC_STAT 0x14 +#define AXIADC_PCORE_PN_ERR_CTRL 0x24 +#define AXIADC_PCORE_ADC_CTRL 0x2C +#define AXIADC_PCORE_IDENT 0x30 +#define AXIADC_PCORE_CA_OFFS_SCALE 0x40 +#define AXIADC_PCORE_CB_OFFS_SCALE 0x44 + +/* AXIADC_PCORE_DMA_CHAN_SEL */ +#define AXIADC_PCORE_DMA_CHAN_SEL0 (1 << 0) +#define AXIADC_PCORE_DMA_CHAN_SEL1 (1 << 1) + +/* AXIADC_PCORE_DMA_CTRL */ +#define AXIADC_DMA_CAP_EN (1 << 16) +#define AXIADC_DMA_CNT(x) (((x) & 0xFFFF) << 0) + +/* AXIADC_PCORE_DMA_STAT */ +#define AXIADC_DMA_STAT_BUSY (1 << 0) /* W1C */ +#define AXIADC_DMA_STAT_OVF (1 << 1) /* W1C */ +#define AXIADC_DMA_STAT_UNF (1 << 2) /* W1C */ + +/* AXIADC_PCORE_ADC_STAT */ +#define AXIADC_PCORE_ADC_STAT_OVR0 (1 << 0) /* W1C */ +#define AXIADC_PCORE_ADC_STAT_OVR1 (1 << 1) /* W1C */ +#define AXIADC_PCORE_ADC_STAT_PN_OOS0 (1 << 2) /* W1C */ +#define AXIADC_PCORE_ADC_STAT_PN_OOS1 (1 << 3) /* W1C */ +#define AXIADC_PCORE_ADC_STAT_PN_ERR0 (1 << 4) /* W1C */ +#define AXIADC_PCORE_ADC_STAT_PN_ERR1 (1 << 5) /* W1C */ +#define AXIADC_PCORE_ADC_STAT_MASK 0x3F + +/* AXIADC_PCORE_ADC_STAT */ +#define AXIADC_PCORE_ADC_STAT_OVR (1 << 0) /* W1C */ +#define AXIADC_PCORE_ADC_STAT_PN_OOS (1 << 1) /* W1C */ +#define AXIADC_PCORE_ADC_STAT_PN_ERR (1 << 2) /* W1C */ +#define AXIADC_PCORE_ADC_1C_STAT_MASK 0x7 + +/* AXIADC_PCORE_PN_ERR_CTRL */ +#define AXIADC_PN23_1_EN (1 << 1) +#define AXIADC_PN23_0_EN (1 << 0) +#define AXIADC_PN9_1_EN (0 << 1) +#define AXIADC_PN9_0_EN (0 << 0) +#define AXIADC_PN23_EN (AXIADC_PN23_0_EN | AXIADC_PN23_1_EN) +#define AXIADC_PN9_EN (AXIADC_PN9_0_EN | AXIADC_PN9_1_EN) + +/* AXIADC_PCORE_ADC_CTRL */ +#define AXIADC_INPUT_FMT_OFFSET_BIN (1 << 3) +#define AXIADC_INPUT_FMT_TWOS_COMPL (0 << 3) +#define AXIADC_SCALE_OFFSET_EN (1 << 2) +#define AXIADC_SIGNEXTEND (1 << 1) +#define AXIADC_STATUS_EN (1 << 0) + +/* AXIADC_PCORE_IDENT */ +#define AXIADC_PCORE_IDENT_SLAVE 0x1 + +/* AXIADC_PCORE_C[A|B]_OFFS_SCALE */ +#define AXIADC_OFFSET(x) (((x) & 0xFFFF) << 16) +#define AXIADC_SCALE(x) ((x) & 0xFFFF) + +/* + * ADI High-Speed ADC common spi interface registers + * See Application-Note AN-877 + */ + +#define ADC_REG_CHIP_PORT_CONF 0x00 +#define ADC_REG_CHIP_ID 0x01 +#define ADC_REG_CHIP_GRADE 0x02 +#define ADC_REG_CHAN_INDEX 0x05 +#define ADC_REG_TRANSFER 0xFF +#define ADC_REG_MODES 0x08 +#define ADC_REG_TEST_IO 0x0D +#define ADC_REG_ADC_INPUT 0x0F +#define ADC_REG_OFFSET 0x10 +#define ADC_REG_OUTPUT_MODE 0x14 +#define ADC_REG_OUTPUT_ADJUST 0x15 +#define ADC_REG_OUTPUT_PHASE 0x16 +#define ADC_REG_OUTPUT_DELAY 0x17 +#define ADC_REG_VREF 0x18 +#define ADC_REG_ANALOG_INPUT 0x2C + +/* ADC_REG_TRANSFER */ +#define TRANSFER_SYNC 0x1 + +/* ADC_REG_TEST_IO */ +#define TESTMODE_OFF 0x0 +#define TESTMODE_MIDSCALE_SHORT 0x1 +#define TESTMODE_POS_FULLSCALE 0x2 +#define TESTMODE_NEG_FULLSCALE 0x3 +#define TESTMODE_ALT_CHECKERBOARD 0x4 +#define TESTMODE_PN23_SEQ 0x5 +#define TESTMODE_PN9_SEQ 0x6 +#define TESTMODE_ONE_ZERO_TOGGLE 0x7 + +/* ADC_REG_OUTPUT_MODE */ +#define OUTPUT_MODE_OFFSET_BINARY 0x0 +#define OUTPUT_MODE_TWOS_COMPLEMENT 0x1 +#define OUTPUT_MODE_GRAY_CODE 0x2 + +/* ADC_REG_OUTPUT_PHASE */ +#define OUTPUT_EVEN_ODD_MODE_EN 0x20 + +/* + * Analog Devices AD9467 16-Bit, 200/250 MSPS ADC + */ + +#define CHIPID_AD9467 0x50 +#define AD9467_DEF_OUTPUT_MODE 0x08 +#define AD9467_REG_VREF_MASK 0x0F + +/* + * Analog Devices AD9643 Dual 14-Bit, 170/210/250 MSPS ADC + */ + +#define CHIPID_AD9643 0x82 +#define AD9643_REG_VREF_MASK 0x1F +#define AD9643_DEF_OUTPUT_MODE 0x00 + +/* + * Analog Devices AD9250 Dual 14-Bit, 170/250 MSPS ADC, JESD204B + */ + +#define CHIPID_AD9250 0xB9 +#define AD9250_REG_VREF_MASK 0x1F +#define AD9250_DEF_OUTPUT_MODE 0x00 + +/* + * Analog Devices AD9265 16-Bit, 125/105/80 MSPS ADC + */ + +#define CHIPID_AD9265 0x64 +#define AD9265_DEF_OUTPUT_MODE 0x40 +#define AD9265_REG_VREF_MASK 0xC0 + +/* debugfs direct register access */ +#define DEBUGFS_DRA_PCORE_REG_MAGIC 0x80000000 + +#include + +#define AXIADC_MAX_DMA_SIZE (4 * 1024 * 1024) /* Randomly picked */ + +enum { + ID_AD9467, + ID_AD9643, + ID_AD9250, + ID_AD9265, +}; + +struct axiadc_chip_info { + char name[8]; + unsigned num_channels; + unsigned long available_scan_masks[2]; + const int (*scale_table)[2]; + int num_scales; + struct iio_chan_spec channel[4]; +}; + +struct axiadc_state { + struct device *dev_spi; + struct mutex lock; + struct completion dma_complete; + struct dma_chan *rx_chan; + const struct axiadc_chip_info *chip_info; + void __iomem *regs; + void *buf_virt; + dma_addr_t buf_phys; + int compl_stat; + unsigned adc_def_output_mode; + unsigned ring_lenght; + unsigned rcount; + unsigned fftcount; +// unsigned bytes_per_datum; + unsigned id; + unsigned char testmode[2]; +}; + +struct axiadc_converter { + struct spi_device *spi; + struct clk *clk; + unsigned id; + int (*read)(struct spi_device *spi, unsigned reg); + int (*write)(struct spi_device *spi, + unsigned reg, unsigned val); + int (*setup)(struct spi_device *spi, unsigned mode); +}; + +static inline struct axiadc_converter *to_converter(struct device *dev) +{ + struct axiadc_converter *conv = spi_get_drvdata(to_spi_device(dev)); + + if (conv) + return conv; + + return ERR_PTR(-ENODEV); +}; + +struct axiadc_spidev { + struct device_node *of_nspi; + struct device *dev_spi; +}; + +/* + * IO accessors + */ + +static inline void axiadc_write(struct axiadc_state *st, unsigned reg, unsigned val) +{ + iowrite32(val, st->regs + reg); +} + +static inline unsigned int axiadc_read(struct axiadc_state *st, unsigned reg) +{ + return ioread32(st->regs + reg); +} + +int axiadc_configure_ring(struct iio_dev *indio_dev); +void axiadc_unconfigure_ring(struct iio_dev *indio_dev); + +#endif /* ADI_AXI_ADC_H_ */ diff --git a/drivers/iio/adc/cf_axi_adc_core.c b/drivers/iio/adc/cf_axi_adc_core.c new file mode 100644 index 0000000000000..e316bebda139d --- /dev/null +++ b/drivers/iio/adc/cf_axi_adc_core.c @@ -0,0 +1,1038 @@ +/* + * AXI_ADC ADI ADC Interface Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + * + * http://wiki.analog.com/resources/fpga/xilinx/fmc/ad9467 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "cf_axi_adc.h" +#define DCO_DEBUG + +static int axiadc_spi_read(struct axiadc_state *st, unsigned reg) +{ + struct axiadc_converter *conv = to_converter(st->dev_spi); + + if (IS_ERR(conv)) + return PTR_ERR(conv); + + return conv->read(conv->spi, reg); +} + +static int axiadc_spi_write(struct axiadc_state *st, unsigned reg, unsigned val) +{ + struct axiadc_converter *conv = to_converter(st->dev_spi); + + if (IS_ERR(conv)) + return PTR_ERR(conv); + + return conv->write(conv->spi, reg, val); +} + +static int axiadc_testmode_set(struct iio_dev *indio_dev, + unsigned chan_mask, unsigned mode) +{ + struct axiadc_state *st = iio_priv(indio_dev); + + switch (mode) { + case TESTMODE_PN23_SEQ: + case TESTMODE_PN9_SEQ: + case TESTMODE_ALT_CHECKERBOARD: + axiadc_write(st, AXIADC_PCORE_ADC_CTRL, 0); + axiadc_spi_write(st, ADC_REG_OUTPUT_MODE, + st->adc_def_output_mode & + ~OUTPUT_MODE_TWOS_COMPLEMENT); + break; + default: + axiadc_write(st, AXIADC_PCORE_ADC_CTRL, + (st->id == CHIPID_AD9643) ? AXIADC_SIGNEXTEND : 0); + axiadc_spi_write(st, ADC_REG_OUTPUT_MODE, st->adc_def_output_mode); + }; + + axiadc_spi_write(st, ADC_REG_CHAN_INDEX, chan_mask); + axiadc_spi_write(st, ADC_REG_TEST_IO, mode); + axiadc_spi_write(st, ADC_REG_CHAN_INDEX, 0x3); + axiadc_spi_write(st, ADC_REG_TRANSFER, TRANSFER_SYNC); + + if (chan_mask & BIT(0)) + st->testmode[0] = mode; + if (chan_mask & BIT(1)) + st->testmode[1] = mode; + + return 0; +} + +static void axiadc_toggle_scale_offset_en(struct axiadc_state *st) +{ + unsigned val = axiadc_read(st, AXIADC_PCORE_ADC_CTRL); + val &= ~AXIADC_SCALE_OFFSET_EN; + axiadc_write(st, AXIADC_PCORE_ADC_CTRL, val); + axiadc_write(st, AXIADC_PCORE_ADC_CTRL, val | AXIADC_SCALE_OFFSET_EN); +} + +static int axiadc_debugfs_open(struct inode *inode, struct file *file) +{ + if (inode->i_private) + file->private_data = inode->i_private; + + return 0; +} + +static int axiadc_dco_calibrate_2c(struct iio_dev *indio_dev) +{ + struct axiadc_state *st = iio_priv(indio_dev); + int dco, ret, cnt, start, max_start, max_cnt; + unsigned stat; + unsigned char err_field[33]; + + axiadc_testmode_set(indio_dev, 0x2, TESTMODE_PN23_SEQ); + axiadc_testmode_set(indio_dev, 0x1, TESTMODE_PN9_SEQ); + + axiadc_write(st, AXIADC_PCORE_PN_ERR_CTRL, AXIADC_PN23_1_EN | + AXIADC_PN9_0_EN); + + for(dco = 0; dco <= 32; dco++) { + ret = 0; + axiadc_spi_write(st, ADC_REG_OUTPUT_DELAY, + dco > 0 ? ((dco - 1) | 0x80) : 0); + axiadc_spi_write(st, ADC_REG_TRANSFER, TRANSFER_SYNC); + axiadc_write(st, AXIADC_PCORE_ADC_STAT, AXIADC_PCORE_ADC_STAT_MASK); + + cnt = 4; + + do { + mdelay(8); + stat = axiadc_read(st, AXIADC_PCORE_ADC_STAT); + if (cnt-- < 0) { + ret = -EIO; + break; + } + } while (stat & (AXIADC_PCORE_ADC_STAT_PN_OOS0 | + AXIADC_PCORE_ADC_STAT_PN_OOS1)); + + cnt = 4; + + if (!ret) + do { + mdelay(4); + stat = axiadc_read(st, AXIADC_PCORE_ADC_STAT); + if (stat & (AXIADC_PCORE_ADC_STAT_PN_ERR0 | + AXIADC_PCORE_ADC_STAT_PN_ERR1)) { + ret = -EIO; + break; + } + } while (cnt--); + + err_field[dco] = !!ret; + } + + for(dco = 0, cnt = 0, max_cnt = 0, start = -1, max_start = 0; + dco <= 32; dco++) { + if (err_field[dco] == 0) { + if (start == -1) + start = dco; + cnt++; + } else { + if (cnt > max_cnt) { + max_cnt = cnt; + max_start = start; + } + start = -1; + cnt = 0; + } + } + + if (cnt > max_cnt) { + max_cnt = cnt; + max_start = start; + } + + dco = max_start + (max_cnt / 2); + + axiadc_testmode_set(indio_dev, 0x3, TESTMODE_OFF); + axiadc_spi_write(st, ADC_REG_OUTPUT_DELAY, + dco > 0 ? ((dco - 1) | 0x80) : 0); + axiadc_spi_write(st, ADC_REG_TRANSFER, TRANSFER_SYNC); + +#ifdef DCO_DEBUG + for(cnt = 0; cnt <= 32; cnt++) + if (cnt == dco) + printk("|"); + else + printk("%c", err_field[cnt] ? '-' : 'o'); + printk(" DCO 0x%X\n", dco > 0 ? ((dco - 1) | 0x80) : 0); +#endif + + return 0; +} + +static int axiadc_dco_calibrate_1c(struct iio_dev *indio_dev) +{ + struct axiadc_state *st = iio_priv(indio_dev); + int dco, ret, cnt, start, max_start, max_cnt; + unsigned stat; + unsigned char err_field[33]; + + axiadc_testmode_set(indio_dev, 0x1, TESTMODE_PN9_SEQ); + + axiadc_write(st, AXIADC_PCORE_PN_ERR_CTRL, AXIADC_PN9_0_EN); + + for(dco = 0; dco <= 32; dco++) { + ret = 0; + axiadc_spi_write(st, ADC_REG_OUTPUT_DELAY, + dco > 0 ? ((dco - 1) | 0x80) : 0); + axiadc_spi_write(st, ADC_REG_TRANSFER, TRANSFER_SYNC); + axiadc_write(st, AXIADC_PCORE_ADC_STAT, AXIADC_PCORE_ADC_STAT_MASK); + + cnt = 4; + + do { + mdelay(8); + stat = axiadc_read(st, AXIADC_PCORE_ADC_STAT); + if (cnt-- < 0) { + ret = -EIO; + break; + } + } while (stat & AXIADC_PCORE_ADC_STAT_PN_OOS); + + cnt = 4; + + if (!ret) + do { + mdelay(4); + stat = axiadc_read(st, AXIADC_PCORE_ADC_STAT); + if (stat & AXIADC_PCORE_ADC_STAT_PN_ERR) { + ret = -EIO; + break; + } + } while (cnt--); + + err_field[dco] = !!ret; + } + + for(dco = 0, cnt = 0, max_cnt = 0, start = -1, max_start = 0; + dco <= 32; dco++) { + if (err_field[dco] == 0) { + if (start == -1) + start = dco; + cnt++; + } else { + if (cnt > max_cnt) { + max_cnt = cnt; + max_start = start; + } + start = -1; + cnt = 0; + } + } + + if (cnt > max_cnt) { + max_cnt = cnt; + max_start = start; + } + + dco = max_start + (max_cnt / 2); + + axiadc_testmode_set(indio_dev, 0x3, TESTMODE_OFF); + axiadc_spi_write(st, ADC_REG_OUTPUT_DELAY, + dco > 0 ? ((dco - 1) | 0x80) : 0); + axiadc_spi_write(st, ADC_REG_TRANSFER, TRANSFER_SYNC); + +#ifdef DCO_DEBUG + for(cnt = 0; cnt <= 32; cnt++) + if (cnt == dco) + printk("|"); + else + printk("%c", err_field[cnt] ? '-' : 'o'); + printk(" DCO 0x%X\n", dco > 0 ? ((dco - 1) | 0x80) : 0); +#endif + + return 0; +} + +static ssize_t axiadc_debugfs_pncheck_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct iio_dev *indio_dev = file->private_data; + struct axiadc_state *st = iio_priv(indio_dev); + char buf[80]; + ssize_t len; + unsigned stat; + + stat = axiadc_read(st, AXIADC_PCORE_ADC_STAT); + + switch (st->id) { + case CHIPID_AD9467: + len = sprintf(buf, "%s %s\n", (stat & AXIADC_PCORE_ADC_STAT_PN_OOS) ? + "Out of Sync :" : "In Sync :", + (stat & AXIADC_PCORE_ADC_STAT_PN_ERR) ? + "PN Error" : "No Error"); + break; + case CHIPID_AD9643: + len = sprintf(buf, "CH0 %s %s\nCH1 %s %s\n", (stat & AXIADC_PCORE_ADC_STAT_PN_OOS0) ? + "Out of Sync :" : "In Sync :", + (stat & AXIADC_PCORE_ADC_STAT_PN_ERR0) ? + "PN Error" : "No Error", + (stat & AXIADC_PCORE_ADC_STAT_PN_OOS1) ? + "Out of Sync :" : "In Sync :", + (stat & AXIADC_PCORE_ADC_STAT_PN_ERR1) ? + "PN Error" : "No Error"); + break; + default: + len = 0; + } + + axiadc_write(st, AXIADC_PCORE_ADC_STAT, AXIADC_PCORE_ADC_STAT_MASK); + + return simple_read_from_buffer(userbuf, count, ppos, buf, len); +} + +static ssize_t axiadc_debugfs_pncheck_write(struct file *file, + const char __user *userbuf, size_t count, loff_t *ppos) +{ + struct iio_dev *indio_dev = file->private_data; + struct axiadc_state *st = iio_priv(indio_dev); + unsigned mode = TESTMODE_OFF; + char buf[80], *p = buf; + + count = min_t(size_t, count, (sizeof(buf)-1)); + if (copy_from_user(p, userbuf, count)) + return -EFAULT; + + p[count] = 0; + + if (sysfs_streq(p, "PN9")) + mode = TESTMODE_PN9_SEQ; + else if (sysfs_streq(p, "PN23")) + mode = TESTMODE_PN23_SEQ; + else if (sysfs_streq(p, "CALIB")) + (st->id == CHIPID_AD9467) ? axiadc_dco_calibrate_1c(indio_dev) : + axiadc_dco_calibrate_2c(indio_dev); + else + mode = TESTMODE_OFF; + + mutex_lock(&indio_dev->mlock); + axiadc_testmode_set(indio_dev, 0x3, mode); + + axiadc_write(st, AXIADC_PCORE_PN_ERR_CTRL, (mode == TESTMODE_PN23_SEQ) ? + AXIADC_PN23_EN : AXIADC_PN9_EN); + + mdelay(1); /* FIXME */ + + axiadc_write(st, AXIADC_PCORE_ADC_STAT, AXIADC_PCORE_ADC_STAT_MASK); + mutex_unlock(&indio_dev->mlock); + + return count; +} + +static const struct file_operations axiadc_debugfs_pncheck_fops = { + .open = axiadc_debugfs_open, + .read = axiadc_debugfs_pncheck_read, + .write = axiadc_debugfs_pncheck_write, +}; + +static int axiadc_reg_access(struct iio_dev *indio_dev, + unsigned reg, unsigned writeval, + unsigned *readval) +{ + struct axiadc_state *st = iio_priv(indio_dev); + int ret; + + mutex_lock(&indio_dev->mlock); + if (readval == NULL) { + if (reg & DEBUGFS_DRA_PCORE_REG_MAGIC) { + axiadc_write(st, reg & 0xFFFF, writeval); + ret = 0; + } else { + ret = axiadc_spi_write(st, reg, writeval); + axiadc_spi_write(st, ADC_REG_TRANSFER, TRANSFER_SYNC); + } + } else { + if (reg & DEBUGFS_DRA_PCORE_REG_MAGIC) { + *readval = axiadc_read(st, reg & 0xFFFF); + } else { + ret = axiadc_spi_read(st, reg); + if (ret < 0) + return ret; + *readval = ret; + } + ret = 0; + } + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static int axiadc_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + struct axiadc_state *st = iio_priv(indio_dev); + int i; + unsigned vref_val, tmp, mask; + unsigned long long llval; + + switch (m) { + case IIO_CHAN_INFO_SCALE: + vref_val = axiadc_spi_read(st, ADC_REG_VREF); + + switch (st->id) { + case CHIPID_AD9467: + mask = AD9467_REG_VREF_MASK; + break; + case CHIPID_AD9643: + mask = AD9643_REG_VREF_MASK; + break; + case CHIPID_AD9250: + mask = AD9250_REG_VREF_MASK; + break; + case CHIPID_AD9265: + mask = AD9265_REG_VREF_MASK; + break; + default: + mask = 0xFFFF; + } + + vref_val &= mask; + + for (i = 0; i < st->chip_info->num_scales; i++) + if (vref_val == st->chip_info->scale_table[i][1]) + break; + + *val = 0; + *val2 = st->chip_info->scale_table[i][0]; + + return IIO_VAL_INT_PLUS_MICRO; + case IIO_CHAN_INFO_CALIBSCALE: + tmp = axiadc_read(st, (chan->channel == 0) ? + AXIADC_PCORE_CA_OFFS_SCALE : + AXIADC_PCORE_CB_OFFS_SCALE); + + tmp = AXIADC_SCALE(tmp); + if (tmp & 0x8000) + *val = 1; + else + *val = 0; + + tmp &= ~0x8000; + + llval = tmp * 1000000ULL; + do_div(llval, 0x8000); + *val2 = llval; + + return IIO_VAL_INT_PLUS_MICRO; + + case IIO_CHAN_INFO_CALIBBIAS: + tmp = axiadc_read(st, (chan->channel == 0) ? AXIADC_PCORE_CA_OFFS_SCALE : AXIADC_PCORE_CB_OFFS_SCALE); + tmp >>= 16; + *val = sign_extend32(tmp, 14); + + return IIO_VAL_INT; + } + + + return -EINVAL; +} + + +static int axiadc_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct axiadc_state *st = iio_priv(indio_dev); + unsigned fract, tmp; + unsigned long long llval; + int i; + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + if (val != 0) + return -EINVAL; + + for (i = 0; i < st->chip_info->num_scales; i++) + if (val2 == st->chip_info->scale_table[i][0]) { + axiadc_spi_write(st, ADC_REG_VREF, + st->chip_info->scale_table[i][1]); + axiadc_spi_write(st, ADC_REG_TRANSFER, + TRANSFER_SYNC); + return 0; + } + + return -EINVAL; + case IIO_CHAN_INFO_CALIBSCALE: + if (val == 0) + fract = 0; + else if (val == 1) + fract = 0x8000; + else + return -EINVAL; + + llval = (unsigned long long)val2 * 0x8000UL; + do_div(llval, 1000000); + fract |= llval; + tmp = axiadc_read(st, (chan->channel == 0) ? AXIADC_PCORE_CA_OFFS_SCALE : AXIADC_PCORE_CB_OFFS_SCALE); + tmp &= ~AXIADC_SCALE(~0); + tmp |= AXIADC_SCALE(fract); + axiadc_write(st, (chan->channel == 0) ? + AXIADC_PCORE_CA_OFFS_SCALE : + AXIADC_PCORE_CB_OFFS_SCALE, tmp); + axiadc_toggle_scale_offset_en(st); + + return 0; + + case IIO_CHAN_INFO_CALIBBIAS: + tmp = axiadc_read(st, (chan->channel == 0) ? AXIADC_PCORE_CA_OFFS_SCALE : AXIADC_PCORE_CB_OFFS_SCALE); + tmp &= ~AXIADC_OFFSET(~0); + tmp |= AXIADC_OFFSET((short)val); + + axiadc_write(st, (chan->channel == 0) ? + AXIADC_PCORE_CA_OFFS_SCALE : + AXIADC_PCORE_CB_OFFS_SCALE, tmp); + axiadc_toggle_scale_offset_en(st); + return 0; + + default: + return -EINVAL; + } +} + +static ssize_t axiadc_show_scale_available(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct axiadc_state *st = iio_priv(indio_dev); + int i, len = 0; + + for (i = 0; i < st->chip_info->num_scales; i++) + len += sprintf(buf + len, "0.%06u ", + st->chip_info->scale_table[i][0]); + + len += sprintf(buf + len, "\n"); + + return len; +} + +static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO, + axiadc_show_scale_available, NULL, 0); + +static struct attribute *axiadc_attributes[] = { + &iio_dev_attr_in_voltage_scale_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group axiadc_attribute_group = { + .attrs = axiadc_attributes, +}; + +static const int ad9265_scale_table[][2] = { + {19073, 0x00}, {22888, 0x40}, {26703, 0x80}, {30518, 0xC0}, +}; + +static const int ad9467_scale_table[][2] = { + {30517, 0}, {32043, 6}, {33569, 7}, + {35095, 8}, {36621, 9}, {38146, 10}, +}; + +static const int ad9643_scale_table[][2] = { + {31738, 0xF}, {31403, 0xE}, {31067, 0xD}, {30731, 0xC}, {30396, 0xB}, + {30060, 0xA}, {29724, 0x9}, {29388, 0x8}, {29053, 0x7}, {28717, 0x6}, + {28381, 0x5}, {28046, 0x4}, {27710, 0x3}, {27374, 0x2}, {27039, 0x1}, + {26703, 0x0}, {26367, 0x1F}, {26031, 0x1E}, {25696, 0x1D}, + {25360, 0x1C}, {25024, 0x1B}, {24689, 0x1A}, {24353, 0x19}, + {24017, 0x18}, {23682, 0x17}, {23346, 0x16}, {23010, 0x15}, + {22675, 0x14}, {22339, 0x13}, {22003, 0x12}, {21667, 0x11}, + {21332, 0x10}, +}; + +static const char testmodes[][16] = { + [TESTMODE_OFF] = "off", + [TESTMODE_MIDSCALE_SHORT] = "midscale_short", + [TESTMODE_POS_FULLSCALE] = "pos_fullscale", + [TESTMODE_NEG_FULLSCALE] = "neg_fullscale", + [TESTMODE_ALT_CHECKERBOARD] = "checkerboard", + [TESTMODE_PN23_SEQ] = "pn_long", + [TESTMODE_PN9_SEQ] = "pn_short", + [TESTMODE_ONE_ZERO_TOGGLE] = "one_zero_toggle", +}; + +static ssize_t axiadc_testmode_mode_available(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + char *buf) +{ + size_t len = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(testmodes); ++i) { + len += sprintf(buf + len, "%s ", testmodes[i]); + } + len += sprintf(buf + len, "\n"); + return len; +} + +static ssize_t axiadc_testmode_read(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, char *buf) +{ + struct axiadc_state *st = iio_priv(indio_dev); + + return sprintf(buf, "%s\n", + testmodes[st->testmode[chan->channel]]); +} + +static ssize_t axiadc_testmode_write(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + const char *buf, size_t len) +{ + unsigned int mode, i; + int ret; + + mode = 0; + + for (i = 0; i < ARRAY_SIZE(testmodes); ++i) { + if (sysfs_streq(buf, testmodes[i])) { + mode = i; + break; + } + } + + mutex_lock(&indio_dev->mlock); + ret = axiadc_testmode_set(indio_dev, 1 << chan->channel, mode); + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static struct iio_chan_spec_ext_info axiadc_ext_info[] = { + { + .name = "test_mode", + .read = axiadc_testmode_read, + .write = axiadc_testmode_write, + }, + { + .name = "test_mode_available", + .read = axiadc_testmode_mode_available, + .shared = true, + }, + { }, +}; + +#define AIM_CHAN(_chan, _si, _bits, _sign) \ + { .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = _chan, \ + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | \ + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \ + .ext_info = axiadc_ext_info, \ + .scan_index = _si, \ + .scan_type = IIO_ST(_sign, _bits, 16, 0)} + +#define AIM_CHAN_FD(_chan, _si, _bits, _sign) \ + { .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = _chan, \ + .extend_name = "frequency_domain", \ + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | \ + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \ + .scan_index = _si, \ + .scan_type = IIO_ST(_sign, _bits, 16, 0)} + +#define AIM_CHAN_NOCALIB(_chan, _si, _bits, _sign) \ + { .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = _chan, \ + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .ext_info = axiadc_ext_info, \ + .scan_index = _si, \ + .scan_type = IIO_ST(_sign, _bits, 16, 0)} + +#define AIM_CHAN_FD_NOCALIB(_chan, _si, _bits, _sign) \ + { .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = _chan, \ + .extend_name = "frequency_domain", \ + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .scan_index = _si, \ + .scan_type = IIO_ST(_sign, _bits, 16, 0)} + +static const struct axiadc_chip_info axiadc_chip_info_tbl[] = { + [ID_AD9467] = { + .name = "AD9467", + .scale_table = ad9467_scale_table, + .num_scales = ARRAY_SIZE(ad9467_scale_table), + .num_channels = 1, + .available_scan_masks[0] = BIT(0), + .channel[0] = AIM_CHAN(0, 0, 16, 's'), + }, + [ID_AD9643] = { + .name = "AD9643", + .scale_table = ad9643_scale_table, + .num_scales = ARRAY_SIZE(ad9643_scale_table), + .num_channels = 4, + .available_scan_masks[0] = BIT(0) | BIT(1), + .available_scan_masks[1] = BIT(2) | BIT(3), + .channel[0] = AIM_CHAN(0, 0, 14, 'u'), + .channel[1] = AIM_CHAN(1, 1, 14, 'u'), + .channel[2] = AIM_CHAN_FD(0, 2, 14, 'u'), + .channel[3] = AIM_CHAN_FD(1, 3, 14, 'u'), + }, + [ID_AD9250] = { + .name = "AD9250", + .scale_table = ad9643_scale_table, + .num_scales = ARRAY_SIZE(ad9643_scale_table), + .num_channels = 4, + .available_scan_masks[0] = BIT(0) | BIT(1), + .available_scan_masks[1] = BIT(2) | BIT(3), + .channel[0] = AIM_CHAN_NOCALIB(0, 0, 14, 'u'), + .channel[1] = AIM_CHAN_NOCALIB(1, 1, 14, 'u'), + .channel[2] = AIM_CHAN_FD_NOCALIB(0, 2, 14, 'u'), + .channel[3] = AIM_CHAN_FD_NOCALIB(1, 3, 14, 'u'), + }, + [ID_AD9265] = { + .name = "AD9265", + .scale_table = ad9265_scale_table, + .num_scales = ARRAY_SIZE(ad9265_scale_table), + .num_channels = 1, + .available_scan_masks[0] = BIT(0), + .channel[0] = AIM_CHAN_NOCALIB(0, 0, 16, 's'), + }, +}; + +static const struct iio_info axiadc_info = { + .driver_module = THIS_MODULE, + .read_raw = &axiadc_read_raw, + .write_raw = &axiadc_write_raw, + .attrs = &axiadc_attribute_group, + .debugfs_reg_access = &axiadc_reg_access, +}; + +struct axiadc_dma_params { + struct device_node *of_node; + int chan_id; +}; + +static bool axiadc_dma_filter(struct dma_chan *chan, void *param) +{ + struct axiadc_dma_params *p = param; + + return chan->device->dev->of_node == p->of_node && + chan->chan_id == p->chan_id; +} + +static int axiadc_attach_spi_client(struct device *dev, void *data) +{ + struct axiadc_spidev *axiadc_spidev = data; + + if ((axiadc_spidev->of_nspi == dev->of_node) && dev->driver) { + axiadc_spidev->dev_spi = dev; + return 1; + } + + return 0; +} + +/** + * axiadc_of_probe - probe method for the AIM device. + * @of_dev: pointer to OF device structure + * @match: pointer to the structure used for matching a device + * + * This function probes the AIM device in the device tree. + * It initializes the driver data structure and the hardware. + * It returns 0, if the driver is bound to the AIM device, or a negative + * value if there is an error. + */ +static int __devinit axiadc_of_probe(struct platform_device *op) +{ + struct iio_dev *indio_dev; + struct device *dev = &op->dev; + struct axiadc_state *st; + struct resource r_mem; /* IO mem resources */ + struct axiadc_dma_params dma_params; + struct of_phandle_args dma_spec; + struct axiadc_spidev axiadc_spidev; + dma_cap_mask_t mask; + resource_size_t remap_size, phys_addr; + int ret; + + dev_info(dev, "Device Tree Probing \'%s\'\n", + op->dev.of_node->name); + + /* Defer driver probe until matching spi + * converter driver is registered + */ + axiadc_spidev.of_nspi = of_parse_phandle(op->dev.of_node, + "spibus-connected", 0); + if (!axiadc_spidev.of_nspi) { + dev_err(&op->dev, "could not find spi node\n"); + return -ENODEV; + } + + ret = bus_for_each_dev(&spi_bus_type, NULL, &axiadc_spidev, + axiadc_attach_spi_client); + if (ret == 0) + return -EPROBE_DEFER; + + if (!try_module_get(axiadc_spidev.dev_spi->driver->owner)) + return -ENODEV; + + get_device(axiadc_spidev.dev_spi); + + /* Get iospace for the device */ + ret = of_address_to_resource(op->dev.of_node, 0, &r_mem); + if (ret) { + dev_err(dev, "invalid address\n"); + return ret; + } + + indio_dev = iio_device_alloc(sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + st->dev_spi = axiadc_spidev.dev_spi; + + dev_set_drvdata(dev, indio_dev); + mutex_init(&st->lock); + + phys_addr = r_mem.start; + remap_size = resource_size(&r_mem); + if (!request_mem_region(phys_addr, remap_size, KBUILD_MODNAME)) { + dev_err(dev, "Couldn't lock memory region at 0x%08llX\n", + (unsigned long long)phys_addr); + ret = -EBUSY; + goto failed1; + } + + st->regs = ioremap(phys_addr, remap_size); + if (st->regs == NULL) { + dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n", + (unsigned long long)phys_addr); + ret = -EFAULT; + goto failed2; + } + /* Get dma channel for the device */ + ret = of_parse_phandle_with_args(op->dev.of_node, "dma-request", + "#dma-cells", 0, &dma_spec); + if (ret) { + dev_err(dev, "Couldn't parse dma-request\n"); + goto failed2; + } + + dma_params.of_node = dma_spec.np; + dma_params.chan_id = dma_spec.args[0]; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE | DMA_PRIVATE, mask); + + st->rx_chan = dma_request_channel(mask, axiadc_dma_filter, &dma_params); + if (!st->rx_chan) { + dev_err(dev, "failed to find rx dma device\n"); + goto failed2; + } + + /* Probe device */ + st->id = axiadc_spi_read(st, ADC_REG_CHIP_ID); + + switch (st->id) { + case CHIPID_AD9467: + st->chip_info = &axiadc_chip_info_tbl[ID_AD9467]; + st->adc_def_output_mode = AD9467_DEF_OUTPUT_MODE | OUTPUT_MODE_TWOS_COMPLEMENT; + axiadc_write(st, AXIADC_PCORE_ADC_CTRL, AXIADC_SCALE_OFFSET_EN); + axiadc_write(st, AXIADC_PCORE_CA_OFFS_SCALE, + AXIADC_OFFSET(0) | AXIADC_SCALE(0x8000)); + axiadc_spi_write(st, ADC_REG_OUTPUT_MODE, st->adc_def_output_mode); + axiadc_spi_write(st, ADC_REG_TEST_IO, TESTMODE_OFF); + axiadc_spi_write(st, ADC_REG_TRANSFER, TRANSFER_SYNC); + axiadc_dco_calibrate_1c(indio_dev); + break; + case CHIPID_AD9643: + st->chip_info = &axiadc_chip_info_tbl[ID_AD9643]; + st->adc_def_output_mode = AD9643_DEF_OUTPUT_MODE | OUTPUT_MODE_TWOS_COMPLEMENT; + axiadc_spi_write(st, ADC_REG_OUTPUT_PHASE, OUTPUT_EVEN_ODD_MODE_EN); + axiadc_write(st, AXIADC_PCORE_ADC_CTRL, AXIADC_SIGNEXTEND | AXIADC_SCALE_OFFSET_EN); + axiadc_write(st, AXIADC_PCORE_CA_OFFS_SCALE, + AXIADC_OFFSET(0) | AXIADC_SCALE(0x8000)); + axiadc_write(st, AXIADC_PCORE_CB_OFFS_SCALE, + AXIADC_OFFSET(0) | AXIADC_SCALE(0x8000)); + axiadc_spi_write(st, ADC_REG_OUTPUT_MODE, st->adc_def_output_mode); + axiadc_spi_write(st, ADC_REG_TEST_IO, TESTMODE_OFF); + axiadc_spi_write(st, ADC_REG_TRANSFER, TRANSFER_SYNC); + axiadc_dco_calibrate_2c(indio_dev); + + break; + case CHIPID_AD9250: + st->chip_info = &axiadc_chip_info_tbl[ID_AD9250]; + st->adc_def_output_mode = AD9643_DEF_OUTPUT_MODE | OUTPUT_MODE_OFFSET_BINARY; + axiadc_spi_write(st, ADC_REG_OUTPUT_MODE, st->adc_def_output_mode); + axiadc_spi_write(st, ADC_REG_TRANSFER, TRANSFER_SYNC); + break; + case CHIPID_AD9265: + st->chip_info = &axiadc_chip_info_tbl[ID_AD9265]; + st->adc_def_output_mode = AD9265_DEF_OUTPUT_MODE | OUTPUT_MODE_TWOS_COMPLEMENT; + axiadc_spi_write(st, ADC_REG_OUTPUT_MODE, st->adc_def_output_mode); + axiadc_spi_write(st, ADC_REG_TEST_IO, TESTMODE_OFF); + axiadc_spi_write(st, ADC_REG_TRANSFER, TRANSFER_SYNC); + axiadc_dco_calibrate_1c(indio_dev); + break; + default: + dev_err(dev, "Unrecognized CHIP_ID 0x%X\n", st->id); + ret = -ENODEV; + goto failed3; + } + + axiadc_spi_write(st, ADC_REG_OUTPUT_PHASE, OUTPUT_EVEN_ODD_MODE_EN); + + indio_dev->dev.parent = dev; + indio_dev->name = op->dev.of_node->name; + indio_dev->channels = st->chip_info->channel; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->num_channels = st->chip_info->num_channels; + indio_dev->available_scan_masks = st->chip_info->available_scan_masks; + indio_dev->info = &axiadc_info; + + init_completion(&st->dma_complete); + + axiadc_configure_ring(indio_dev); + + ret = iio_buffer_register(indio_dev, + st->chip_info->channel, + st->chip_info->num_channels); + if (ret) + goto failed4; + + *indio_dev->buffer->scan_mask = st->chip_info->available_scan_masks[0]; + + axiadc_write(st, AXIADC_PCORE_DMA_CHAN_SEL, + st->chip_info->available_scan_masks[0]); + + ret = iio_device_register(indio_dev); + if (ret) + goto failed4; + + dev_info(dev, "ADI AIM (0x%X) at 0x%08llX mapped to 0x%p," + " DMA-%d probed ADC %s as %s\n", + axiadc_read(st, AXIADC_PCORE_VERSION), + (unsigned long long)phys_addr, st->regs, + st->rx_chan->chan_id, st->chip_info->name, + (axiadc_read(st, AXIADC_PCORE_IDENT) & + AXIADC_PCORE_IDENT_SLAVE) ? "SLAVE" : "MASTER"); + + if (iio_get_debugfs_dentry(indio_dev)) + debugfs_create_file("pseudorandom_err_check", 0644, + iio_get_debugfs_dentry(indio_dev), + indio_dev, &axiadc_debugfs_pncheck_fops); + + return 0; + +failed4: + axiadc_unconfigure_ring(indio_dev); +failed3: + dma_release_channel(st->rx_chan); +failed2: + release_mem_region(phys_addr, remap_size); +failed1: + put_device(st->dev_spi); + module_put(st->dev_spi->driver->owner); + iio_device_free(indio_dev); + dev_set_drvdata(dev, NULL); + + return ret; +} + +/** + * axiadc_of_remove - unbinds the driver from the AIM device. + * @of_dev: pointer to OF device structure + * + * This function is called if a device is physically removed from the system or + * if the driver module is being unloaded. It frees any resources allocated to + * the device. + */ +static int __devexit axiadc_of_remove(struct platform_device *op) +{ + struct device *dev = &op->dev; + struct resource r_mem; /* IO mem resources */ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct axiadc_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + iio_buffer_unregister(indio_dev); + axiadc_unconfigure_ring(indio_dev); + + dma_release_channel(st->rx_chan); + + put_device(st->dev_spi); + module_put(st->dev_spi->driver->owner); + + iounmap(st->regs); + + /* Get iospace of the device */ + if (of_address_to_resource(op->dev.of_node, 0, &r_mem)) + dev_err(dev, "invalid address\n"); + else + release_mem_region(r_mem.start, resource_size(&r_mem)); + + iio_device_free(indio_dev); + + dev_set_drvdata(dev, NULL); + + return 0; +} + +/* Match table for of_platform binding */ +static const struct of_device_id axiadc_of_match[] __devinitconst = { + { .compatible = "xlnx,cf-ad9467-core-1.00.a", }, + { .compatible = "xlnx,cf-ad9643-core-1.00.a", }, + { .compatible = "xlnx,axi-adc-2c-1.00.a", }, + { .compatible = "xlnx,axi-adc-1c-1.00.a", }, + { .compatible = "xlnx,axi-ad9250-1.00.a", }, + { .compatible = "xlnx,axi-ad9265-1.00.a", }, +{ /* end of list */ }, +}; +MODULE_DEVICE_TABLE(of, axiadc_of_match); + +static struct platform_driver axiadc_of_driver = { + .driver = { + .name = KBUILD_MODNAME, + .owner = THIS_MODULE, + .of_match_table = axiadc_of_match, + }, + .probe = axiadc_of_probe, + .remove = __devexit_p(axiadc_of_remove), +}; + +module_platform_driver(axiadc_of_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices ADI-AIM"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/adc/cf_axi_adc_ring.c b/drivers/iio/adc/cf_axi_adc_ring.c new file mode 100644 index 0000000000000..219074ecf6875 --- /dev/null +++ b/drivers/iio/adc/cf_axi_adc_ring.c @@ -0,0 +1,266 @@ +/* + * ADI-AIM ADC Interface Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "../../staging/iio/ring_hw.h" +#include "cf_axi_adc.h" +#include "cf_axi_fft_core.h" + +static int axiadc_read_first_n_hw_rb(struct iio_buffer *r, + size_t count, char __user *buf) +{ + struct iio_hw_buffer *hw_ring = iio_to_hw_buf(r); + struct iio_dev *indio_dev = hw_ring->private; + struct axiadc_state *st = iio_priv(indio_dev); + int ret; + unsigned stat, dma_stat; + + mutex_lock(&st->lock); + + ret = wait_for_completion_interruptible_timeout(&st->dma_complete, + 4 * HZ); + + stat = axiadc_read(st, AXIADC_PCORE_ADC_STAT); + dma_stat = axiadc_read(st, AXIADC_PCORE_DMA_STAT); + + if (st->compl_stat < 0) { + ret = st->compl_stat; + goto error_ret; + } else if (ret == 0) { + ret = -ETIMEDOUT; + dev_err(indio_dev->dev.parent, + "timeout: DMA_STAT 0x%X, ADC_STAT 0x%X\n", + dma_stat, stat); + goto error_ret; + } else if (ret < 0) { + goto error_ret; + } + +#if defined(CONFIG_CF_AXI_FFT) + if (st->fftcount) { + ret = fft_calculate(st->buf_phys, st->buf_phys + st->fftcount, + st->fftcount / 4, *r->scan_mask >> 2); + } +#endif + if (copy_to_user(buf, st->buf_virt + st->fftcount, count)) + ret = -EFAULT; + + if ((stat & (AXIADC_PCORE_ADC_STAT_OVR0 | ((st->id == CHIPID_AD9467) ? 0 : AXIADC_PCORE_ADC_STAT_OVR1))) + || dma_stat) + dev_warn(indio_dev->dev.parent, + "STATUS: DMA_STAT 0x%X, ADC_STAT 0x%X\n", + dma_stat, stat); + +error_ret: + r->stufftoread = 0; + + mutex_unlock(&st->lock); + + return ret < 0 ? ret : count; +} + +static int axiadc_ring_get_length(struct iio_buffer *r) +{ + struct iio_hw_buffer *hw_ring = iio_to_hw_buf(r); + struct iio_dev *indio_dev = hw_ring->private; + struct axiadc_state *st = iio_priv(indio_dev); + + return st->ring_lenght; +} + +static int axiadc_ring_set_length(struct iio_buffer *r, int lenght) +{ + struct iio_hw_buffer *hw_ring = iio_to_hw_buf(r); + struct axiadc_state *st = iio_priv(hw_ring->private); + + st->ring_lenght = lenght; + + return 0; +} + +static int axiadc_ring_get_bytes_per_datum(struct iio_buffer *r) +{ + return r->bytes_per_datum; +} + +static IIO_BUFFER_ENABLE_ATTR; +static IIO_BUFFER_LENGTH_ATTR; + +static struct attribute *axiadc_ring_attributes[] = { + &dev_attr_length.attr, + &dev_attr_enable.attr, + NULL, +}; + +static struct attribute_group axiadc_ring_attr = { + .attrs = axiadc_ring_attributes, + .name = "buffer", +}; + +static struct iio_buffer *axiadc_rb_allocate(struct iio_dev *indio_dev) +{ + struct iio_buffer *buf; + struct iio_hw_buffer *ring; + + ring = kzalloc(sizeof *ring, GFP_KERNEL); + if (!ring) + return NULL; + + ring->private = indio_dev; + buf = &ring->buf; + buf->attrs = &axiadc_ring_attr; + iio_buffer_init(buf); + + return buf; +} + +static inline void axiadc_rb_free(struct iio_buffer *r) +{ + kfree(iio_to_hw_buf(r)); +} + +static const struct iio_buffer_access_funcs axiadc_ring_access_funcs = { + .read_first_n = &axiadc_read_first_n_hw_rb, + .get_length = &axiadc_ring_get_length, + .set_length = &axiadc_ring_set_length, + .get_bytes_per_datum = &axiadc_ring_get_bytes_per_datum, +}; + +static int __axiadc_hw_ring_state_set(struct iio_dev *indio_dev, bool state) +{ + struct axiadc_state *st = iio_priv(indio_dev); + struct iio_buffer *buffer = indio_dev->buffer; + struct dma_async_tx_descriptor *desc; + dma_cookie_t cookie; + int ret = 0; + + + if (!state) { + if (!completion_done(&st->dma_complete)) { + st->compl_stat = -EPERM; + dmaengine_terminate_all(st->rx_chan); + complete(&st->dma_complete); + } + + return 0; + } + + st->compl_stat = 0; + if (st->ring_lenght == 0) { + ret = -EINVAL; + goto error_ret; + } + + if (st->ring_lenght % 8) + st->rcount = (st->ring_lenght + 8) & 0xFFFFFFF8; + else + st->rcount = st->ring_lenght; + +#if defined(CONFIG_CF_AXI_FFT) + if (*buffer->scan_mask & 0xC) + st->fftcount = st->rcount; + else + st->fftcount = 0; +#else + st->fftcount = 0; +#endif + + if (PAGE_ALIGN(st->rcount + st->fftcount) > AXIADC_MAX_DMA_SIZE) { + ret = -EINVAL; + goto error_ret; + } + + desc = dmaengine_prep_slave_single(st->rx_chan, st->buf_phys, st->rcount, + DMA_FROM_DEVICE, DMA_PREP_INTERRUPT); + if (!desc) { + dev_err(indio_dev->dev.parent, + "Failed to allocate a dma descriptor\n"); + ret = -ENOMEM; + goto error_ret; + } + + desc->callback = (dma_async_tx_callback) complete; + desc->callback_param = &st->dma_complete; + + cookie = dmaengine_submit(desc); + if (cookie < 0) { + dev_err(indio_dev->dev.parent, + "Failed to submit a dma transfer\n"); + ret = cookie; + goto error_ret; + } + INIT_COMPLETION(st->dma_complete); + dma_async_issue_pending(st->rx_chan); + + axiadc_write(st, AXIADC_PCORE_DMA_CTRL, 0); + axiadc_write(st, AXIADC_PCORE_ADC_STAT, 0xFF); + axiadc_write(st, AXIADC_PCORE_DMA_STAT, 0xFF); + axiadc_write(st, AXIADC_PCORE_DMA_CTRL, + AXIADC_DMA_CAP_EN | AXIADC_DMA_CNT((st->rcount / 8) - 1)); + + return 0; + +error_ret: + return ret; +} + +static int axiadc_hw_ring_preenable(struct iio_dev *indio_dev) +{ + return __axiadc_hw_ring_state_set(indio_dev, 1); +} + +static int axiadc_hw_ring_postdisable(struct iio_dev *indio_dev) +{ + return __axiadc_hw_ring_state_set(indio_dev, 0); +} + +static const struct iio_buffer_setup_ops axiadc_ring_setup_ops = { + .preenable = &axiadc_hw_ring_preenable, + .postdisable = &axiadc_hw_ring_postdisable, +}; + +int axiadc_configure_ring(struct iio_dev *indio_dev) +{ + struct axiadc_state *st = iio_priv(indio_dev); + indio_dev->buffer = axiadc_rb_allocate(indio_dev); + if (indio_dev->buffer == NULL) + return -ENOMEM; + + indio_dev->modes |= INDIO_BUFFER_HARDWARE; + indio_dev->buffer->access = &axiadc_ring_access_funcs; + indio_dev->setup_ops = &axiadc_ring_setup_ops; + + st->buf_virt = dma_alloc_coherent(indio_dev->dev.parent, + PAGE_ALIGN(AXIADC_MAX_DMA_SIZE), &st->buf_phys, + GFP_KERNEL); + if (st->buf_virt == NULL) { + dev_err(indio_dev->dev.parent, + "Failed to allocate a dma memory\n"); + return -ENOMEM; + } + + return 0; +} + +void axiadc_unconfigure_ring(struct iio_dev *indio_dev) +{ + struct axiadc_state *st = iio_priv(indio_dev); + + dma_free_coherent(indio_dev->dev.parent, PAGE_ALIGN(AXIADC_MAX_DMA_SIZE), + st->buf_virt, st->buf_phys); + axiadc_rb_free(indio_dev->buffer); +} diff --git a/drivers/iio/adc/cf_axi_fft_core.c b/drivers/iio/adc/cf_axi_fft_core.c new file mode 100644 index 0000000000000..e45d1a9a53165 --- /dev/null +++ b/drivers/iio/adc/cf_axi_fft_core.c @@ -0,0 +1,368 @@ +/* + * ADI-FFT Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + * + * http://wiki.analog.com/resources/fpga/xilinx/ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/*************************************************************************** + * register definitions (fft) + * 5'h00: + * [31: 0]: version(32'h00010061) + * 5'h01: + * [31: 0]: up_cfg_data, fft cfg data (refer Xilinx fft core for details). + * 5'h02: + * [ 3: 3]: up_status_ovf, fft overflow (mapped to Xilinx fft core outputs). + * [ 2: 2]: up_status_lm, fft tlast missing (mapped to core). + * [ 1: 1]: up_status_lu, fft tlast unexpected (mapped to core). + * [ 0: 0]: up_status_fs, fft frame start (mapped to core). + ***************************************************************************/ + +#define FFT_PCORE_VERSION 0x0 +#define FFT_PCORE_CFG 0x4 +#define FFT_PCORE_STAT 0x8 +#define FFT_PCORE_POSTPROC 0xC +#define FFT_PCORE_IRSEL 0x10 +#define FFT_PCORE_WINCFG 0x14 + +#define FFT_PCORE_CFG_DEFAULT 0xD5700 +#define FFT_PCORE_CFG_FW_FFT (1 << 8) +#define FFT_PCORE_CFG_INV_FFT (0 << 8) + +#define FFT_PCORE_POSTPROC_EN 0x1 + +#define FFT_PCORE_IRSEL_I(x) ((x) << 2) +#define FFT_PCORE_IRSEL_R(x) ((x) << 0) +#define FFT_PCORE_IRSEL_ZERO 0 +#define FFT_PCORE_IRSEL_CH0 1 +#define FFT_PCORE_IRSEL_CH1 2 + + +#define FFT_PCORE_WINCFG_INC(x) ((x) & 0xFFFF) +#define FFT_PCORE_WINCFG_ENB (1 << 16) + +struct fft_state { + struct device *dev; + struct mutex lock; + struct completion dma_complete; + struct dma_chan *rx_chan; + struct dma_chan *tx_chan; + void __iomem *regs; + int compl_stat; +}; + +struct fft_dma_params { + struct device_node *of_node; + enum dma_transfer_direction direction; + int chan_id; +}; + +struct fft_state *fft_state_glob; + +/* + * IO accessors + */ + +static inline void fft_write(struct fft_state *st, unsigned reg, unsigned val) +{ + iowrite32(val, st->regs + reg); +} + +static inline unsigned int fft_read(struct fft_state *st, unsigned reg) +{ + return ioread32(st->regs + reg); +} + +static bool fft_dma_filter(struct dma_chan *chan, void *param) +{ + struct fft_dma_params *p = param; + + return chan->device->dev->of_node == p->of_node && + chan->chan_id == p->chan_id; +} + +int fft_calculate(dma_addr_t src, dma_addr_t dest, unsigned int size, unsigned irsel) +{ + struct fft_state *st = fft_state_glob; + struct dma_async_tx_descriptor *tx_desc, *rx_desc; + dma_cookie_t tx_cookie, rx_cookie; + unsigned nfft = ilog2(size); + int ret = 0; + + if (st == NULL) + return -ENODEV; + + if (((1 << nfft) != size) || !src || !dest || !irsel) + return -EINVAL; + + switch (irsel) { + case FFT_PCORE_IRSEL_CH0: + case FFT_PCORE_IRSEL_CH1: + irsel = FFT_PCORE_IRSEL_R(irsel); + break; + case FFT_PCORE_IRSEL_CH0 | FFT_PCORE_IRSEL_CH1: + irsel = FFT_PCORE_IRSEL_R(FFT_PCORE_IRSEL_CH0) | + FFT_PCORE_IRSEL_I(FFT_PCORE_IRSEL_CH1); + break; + } + + mutex_lock(&st->lock); +// printk("%s: %d::: %d %x\n",__func__,__LINE__, size, irsel); + fft_write(st, FFT_PCORE_WINCFG, 0); + fft_write(st, FFT_PCORE_WINCFG, BIT(16) | (0x10000 >> nfft)); + fft_write(st, FFT_PCORE_POSTPROC, FFT_PCORE_POSTPROC_EN); + fft_write(st, FFT_PCORE_IRSEL, irsel); + fft_write(st, FFT_PCORE_STAT, 0xFF); + fft_write(st, FFT_PCORE_CFG, FFT_PCORE_CFG_DEFAULT | nfft); + + tx_desc = dmaengine_prep_slave_single(st->tx_chan, src, size * 4, + DMA_TO_DEVICE, 0); + if (!tx_desc) { + dev_err(st->dev, + "Failed to allocate a dma descriptor\n"); + ret = -ENOMEM; + goto error_ret; + } + + tx_cookie = dmaengine_submit(tx_desc); + if (tx_cookie < 0) { + dev_err(st->dev, + "Failed to submit a dma transfer\n"); + ret = tx_cookie; + goto error_ret; + } + + rx_desc = dmaengine_prep_slave_single(st->rx_chan, dest, size * 4, + DMA_FROM_DEVICE, DMA_PREP_INTERRUPT); + if (!rx_desc) { + dev_err(st->dev, + "Failed to allocate a dma descriptor\n"); + ret = -ENOMEM; + goto error_ret; + } + + rx_desc->callback = (dma_async_tx_callback) complete; + rx_desc->callback_param = &st->dma_complete; + + rx_cookie = dmaengine_submit(rx_desc); + if (rx_cookie < 0) { + dev_err(st->dev, + "Failed to submit a dma transfer\n"); + ret = rx_cookie; + goto error_ret; + } + + dma_async_issue_pending(st->tx_chan); + dma_async_issue_pending(st->rx_chan); + + ret = wait_for_completion_interruptible_timeout(&st->dma_complete, + 4 * HZ); + if (ret == 0) { + ret = -ETIMEDOUT; + goto error_ret; + } else if (ret < 0) { + goto error_ret; + } + + ret = 0; + +error_ret: + mutex_unlock(&st->lock); + return ret; +} +EXPORT_SYMBOL_GPL(fft_calculate); + +/** + * fft_of_probe - probe method for the AIM device. + * @of_dev: pointer to OF device structure + * @match: pointer to the structure used for matching a device + * + * This function probes the AIM device in the device tree. + * It initializes the driver data structure and the hardware. + * It returns 0, if the driver is bound to the AIM device, or a negative + * value if there is an error. + */ +static int __devinit fft_of_probe(struct platform_device *op) +{ + struct device *dev = &op->dev; + struct fft_state *st; + struct resource r_mem; /* IO mem resources */ + struct fft_dma_params dma_params; + struct of_phandle_args dma_spec; + dma_cap_mask_t mask; + resource_size_t remap_size, phys_addr; + int ret; + + dev_info(dev, "Device Tree Probing \'%s\'\n", + op->dev.of_node->name); + + st = devm_kzalloc(&op->dev, sizeof(*st), GFP_KERNEL); + if (!st) { + dev_err(dev, "Not enough memory for device\n"); + return -ENOMEM; + } + + st->dev = dev; + dev_set_drvdata(dev, st); + mutex_init(&st->lock); + + /* Get iospace for the device */ + ret = of_address_to_resource(op->dev.of_node, 0, &r_mem); + if (ret) { + dev_err(dev, "invalid address\n"); + return ret; + } + + phys_addr = r_mem.start; + remap_size = resource_size(&r_mem); + if (!request_mem_region(phys_addr, remap_size, KBUILD_MODNAME)) { + dev_err(dev, "Couldn't lock memory region at 0x%08llX\n", + (unsigned long long)phys_addr); + ret = -EBUSY; + goto failed1; + } + + st->regs = ioremap(phys_addr, remap_size); + if (st->regs == NULL) { + dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n", + (unsigned long long)phys_addr); + ret = -EFAULT; + goto failed2; + } + + /* Get dma channel for the device */ + ret = of_parse_phandle_with_args(op->dev.of_node, "dma-request", + "#dma-cells", 0, &dma_spec); + if (ret) { + dev_err(dev, "Couldn't parse dma-request\n"); + goto failed2; + } + + dma_params.of_node = dma_spec.np; + dma_params.chan_id = dma_spec.args[0]; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE | DMA_PRIVATE, mask); + + st->tx_chan = dma_request_channel(mask, fft_dma_filter, &dma_params); + if (!st->tx_chan) { + dev_err(dev, "failed to find tx dma device\n"); + goto failed2; + } + + /* Get dma channel for the device */ + ret = of_parse_phandle_with_args(op->dev.of_node, "dma-request", + "#dma-cells", 1, &dma_spec); + if (ret) { + dev_err(dev, "Couldn't parse dma-request\n"); + goto failed2; + } + + dma_params.of_node = dma_spec.np; + dma_params.chan_id = dma_spec.args[0]; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE | DMA_PRIVATE, mask); + + st->rx_chan = dma_request_channel(mask, fft_dma_filter, &dma_params); + if (!st->rx_chan) { + dev_err(dev, "failed to find rx dma device\n"); + goto failed2; + } + + init_completion(&st->dma_complete); + + dev_info(dev, "ADI-FFT (0x%X) at 0x%08llX mapped to 0x%p," + " DMA-%d, DMA-%d probed\n", + fft_read(st, FFT_PCORE_VERSION), + (unsigned long long)phys_addr, st->regs, + st->rx_chan->chan_id, st->tx_chan->chan_id); + + fft_state_glob = st; + + return 0; + +failed2: + release_mem_region(phys_addr, remap_size); +failed1: + dev_set_drvdata(dev, NULL); + + return ret; +} + +/** + * fft_of_remove - unbinds the driver from the AIM device. + * @of_dev: pointer to OF device structure + * + * This function is called if a device is physically removed from the system or + * if the driver module is being unloaded. It frees any resources allocated to + * the device. + */ +static int __devexit fft_of_remove(struct platform_device *op) +{ + struct device *dev = &op->dev; + struct resource r_mem; /* IO mem resources */ + struct fft_state *st = dev_get_drvdata(dev); + + dma_release_channel(st->rx_chan); + dma_release_channel(st->tx_chan); + + iounmap(st->regs); + + /* Get iospace of the device */ + if (of_address_to_resource(op->dev.of_node, 0, &r_mem)) + dev_err(dev, "invalid address\n"); + else + release_mem_region(r_mem.start, resource_size(&r_mem)); + + dev_set_drvdata(dev, NULL); + fft_state_glob = NULL; + + return 0; +} + +/* Match table for of_platform binding */ +static const struct of_device_id fft_of_match[] __devinitconst = { + { .compatible = "xlnx,cf-fft-core-1.00.a", }, + { .compatible = "xlnx,axi-fft-1.00.a", }, + { /* end of list */ }, +}; +MODULE_DEVICE_TABLE(of, fft_of_match); + +static struct platform_driver fft_of_driver = { + .driver = { + .name = KBUILD_MODNAME, + .owner = THIS_MODULE, + .of_match_table = fft_of_match, + }, + .probe = fft_of_probe, + .remove = __devexit_p(fft_of_remove), +}; + +module_platform_driver(fft_of_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices CF FFT"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/adc/cf_axi_fft_core.h b/drivers/iio/adc/cf_axi_fft_core.h new file mode 100644 index 0000000000000..7437dcc2a6f91 --- /dev/null +++ b/drivers/iio/adc/cf_axi_fft_core.h @@ -0,0 +1,17 @@ +/* + * ADI-FFT Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + * + * http://wiki.analog.com/resources/fpga/xilinx/ + */ + +#ifndef ADI_FFT_H_ +#define ADI_FFT_H_ + +int fft_calculate(dma_addr_t src, dma_addr_t dest, + unsigned int size, unsigned irsel); + +#endif /* ADI_FFT_H_ */ diff --git a/drivers/iio/adc/cf_axi_jesd204b.c b/drivers/iio/adc/cf_axi_jesd204b.c new file mode 100644 index 0000000000000..9e6cb5592ed64 --- /dev/null +++ b/drivers/iio/adc/cf_axi_jesd204b.c @@ -0,0 +1,209 @@ +/* + * ADI AXI-JESD204B Interface Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + * + * http://wiki.analog.com/resources/fpga/xilinx/ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "cf_axi_jesd204b.h" + +struct jesd204b_state { + struct device *dev; + void __iomem *regs; + struct clk *clk; +}; + +/* + * IO accessors + */ + +static inline void jesd204b_write(struct jesd204b_state *st, unsigned reg, unsigned val) +{ + iowrite32(val, st->regs + reg); +} + +static inline unsigned int jesd204b_read(struct jesd204b_state *st, unsigned reg) +{ + return ioread32(st->regs + reg); +} + + +static int __devinit jesd204b_of_probe(struct platform_device *op) +{ + struct device *dev = &op->dev; + struct jesd204b_state *st; + struct resource r_mem; /* IO mem resources */ + struct clk *clk; + resource_size_t remap_size, phys_addr; + unsigned frmcnt, bytecnt; + int ret; + + dev_info(dev, "Device Tree Probing \'%s\'\n", + op->dev.of_node->name); + + clk = clk_get(&op->dev, NULL); + if (IS_ERR(clk)) { + return -EPROBE_DEFER; + } + + st = devm_kzalloc(&op->dev, sizeof(*st), GFP_KERNEL); + if (!st) { + dev_err(dev, "Not enough memory for device\n"); + return -ENOMEM; + } + + st->dev = dev; + st->clk = clk; + dev_set_drvdata(dev, st); + + ret = clk_prepare(clk); + if (ret < 0) + return ret; + + ret = clk_enable(clk); + if (ret < 0) + goto err_clk_unprepare; + + /* Get iospace for the device */ + ret = of_address_to_resource(op->dev.of_node, 0, &r_mem); + if (ret) { + dev_err(dev, "invalid address\n"); + goto err_clk_disable; + } + + phys_addr = r_mem.start; + remap_size = resource_size(&r_mem); + if (!request_mem_region(phys_addr, remap_size, KBUILD_MODNAME)) { + dev_err(dev, "Couldn't lock memory region at 0x%08llX\n", + (unsigned long long)phys_addr); + ret = -EBUSY; + goto err_clk_disable; + } + + st->regs = ioremap(phys_addr, remap_size); + if (st->regs == NULL) { + dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n", + (unsigned long long)phys_addr); + ret = -EFAULT; + goto err_release_mem_region; + } + + jesd204b_write(st, AXI_JESD204B_REG_TEST_MODE, + AXI_JESD204B_REG_TEST_MODE_JESD_RESET | + AXI_JESD204B_REG_TEST_MODE_GTX_RESET); + + ret = of_property_read_u32(op->dev.of_node, + "jesd,frames-per-multiframe", &frmcnt); + if (ret) + goto err_release_mem_region; + + ret = of_property_read_u32(op->dev.of_node, + "jesd,bytes-per-frame", &bytecnt); + if (ret) + goto err_release_mem_region; + + jesd204b_write(st, AXI_JESD204B_REG_CTRL, + (of_property_read_bool(op->dev.of_node, "jesd,scramble_en") ? + AXI_JESD204B_CTRL_SCR_EN : 0) | + (of_property_read_bool(op->dev.of_node, "jesd,lanesync_en") ? + AXI_JESD204B_CTRL_LANESYNC_EN : 0)); + + jesd204b_write(st, AXI_JESD204B_REG_FRMCTRL, + AXI_JESD204B_FRMCTRL_FRMCNT(frmcnt - 1) | + AXI_JESD204B_FRMCTRL_BYTECNT(bytecnt - 1)); + + dev_info(dev, "AXI-JESD204B (0x%X) at 0x%08llX mapped to 0x%p,", + jesd204b_read(st, AXI_JESD204B_REG_VERSION), + (unsigned long long)phys_addr, st->regs); + + return 0; + +err_release_mem_region: + release_mem_region(phys_addr, remap_size); +err_clk_disable: + clk_disable(clk); +err_clk_unprepare: + clk_unprepare(clk); + clk_put(clk); + dev_set_drvdata(dev, NULL); + + return ret; +} + +/** + * jesd204b_of_remove - unbinds the driver from the AIM device. + * @of_dev: pointer to OF device structure + * + * This function is called if a device is physically removed from the system or + * if the driver module is being unloaded. It frees any resources allocated to + * the device. + */ +static int __devexit jesd204b_of_remove(struct platform_device *op) +{ + struct device *dev = &op->dev; + struct resource r_mem; /* IO mem resources */ + struct jesd204b_state *st = dev_get_drvdata(dev); + + iounmap(st->regs); + + /* Get iospace of the device */ + if (of_address_to_resource(op->dev.of_node, 0, &r_mem)) + dev_err(dev, "invalid address\n"); + else + release_mem_region(r_mem.start, resource_size(&r_mem)); + + clk_disable(st->clk); + clk_unprepare(st->clk); + clk_put(st->clk); + + dev_set_drvdata(dev, NULL); + + return 0; +} + +/* Match table for of_platform binding */ +static const struct of_device_id jesd204b_of_match[] __devinitconst = { + { .compatible = "xlnx,axi-jesd204b-rx2-1.00.a", }, + { .compatible = "xlnx,axi-jesd204b-rx4-1.00.a", }, +{ /* end of list */ }, +}; +MODULE_DEVICE_TABLE(of, jesd204b_of_match); + +static struct platform_driver jesd204b_of_driver = { + .driver = { + .name = KBUILD_MODNAME, + .owner = THIS_MODULE, + .of_match_table = jesd204b_of_match, + }, + .probe = jesd204b_of_probe, + .remove = __devexit_p(jesd204b_of_remove), +}; + +module_platform_driver(jesd204b_of_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AXI-JESD204B Interface Module"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/adc/cf_axi_jesd204b.h b/drivers/iio/adc/cf_axi_jesd204b.h new file mode 100644 index 0000000000000..51b4df564d021 --- /dev/null +++ b/drivers/iio/adc/cf_axi_jesd204b.h @@ -0,0 +1,87 @@ +/* + * ADI AXI-JESD204B Interface Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + * + * http://wiki.analog.com/resources/fpga/xilinx/ + */ + +/* + * 0x00 0x00 [31: 0] version[31:0] 32'h00010061 (1.0a) + * --------------------------------------------------------------------------- + * 0x01 0x04 [ 4: 4] sysref_sel Select sw(0x1) or hw(0x0) sysref generation + * [ 3: 3] lanesync_enb Enable (0x1) lane synchronization + * [ 2: 2] scr_enb Enable (0x1) scrambling + * [ 1: 1] sysref_enb Enable (0x1) re-alignment at every sysref pulses + * [ 0: 0] err_disb Disable (0x1) error reporting via sync + * --------------------------------------------------------------------------- + * 0x02 0x08 [ 0: 0] sysref_int Software controlled sysref (0->1 transition) + * --------------------------------------------------------------------------- + * 0x03 0x0c [12: 8] frmcnt Number of frames per multi-frame (n-1) + * [ 7: 0] bytecnt Number of bytes (octets) per frame (n-1) + * --------------------------------------------------------------------------- + * 0x04 0x10 [12: 0] buffdelay Buffer delay from multi-frame + * --------------------------------------------------------------------------- + * 0x05 0x14 [ 3: 2] test_mode Test mode (?) + * [ 1: 0] lane_sel Select lanes (0, 1, 2 or 3) for reporting + * --------------------------------------------------------------------------- + * The following registers are based on lane_sel + * --------------------------------------------------------------------------- + * 0x06 0x18 [31: 0] bufcnt Buffer count (latency) + * 0x07 0x1c [31: 0] init_data0 ILS Data 0 + * 0x08 0x20 [31: 0] init_data1 ILS Data 1 + * 0x09 0x24 [31: 0] init_data2 ILS Data 2 + * 0x0a 0x28 [31: 0] init_data3 ILS Data 3 + * 0x0b 0x2c [31: 0] test_mfcnt Test MF count (?) + * 0x0c 0x30 [31: 0] test_ilacnt Test ILA count (?) + * 0x0d 0x34 [31: 0] test_errcnt Test ERROR count (?) + */ + +#ifndef ADI_JESD204B_H_ +#define ADI_JESD204B_H_ + +/* PCORE CoreFPGA register map */ + +#define AXI_JESD204B_REG_VERSION 0x00 +#define AXI_JESD204B_REG_CTRL 0x04 +#define AXI_JESD204B_REG_SYSREF_TRIG 0x08 +#define AXI_JESD204B_REG_FRMCTRL 0x0C +#define AXI_JESD204B_REG_BUFDELAY 0x10 +#define AXI_JESD204B_REG_TEST_MODE 0x14 +#define AXI_JESD204B_REG_BUFCNT 0x18 +#define AXI_JESD204B_REG_INIT_DATA0 0x1C +#define AXI_JESD204B_REG_INIT_DATA1 0x20 +#define AXI_JESD204B_REG_INIT_DATA2 0x24 +#define AXI_JESD204B_REG_INIT_DATA3 0x28 +#define AXI_JESD204B_REG_TEST_MFCNT 0x2C +#define AXI_JESD204B_REG_TEST_ILACNT 0x30 +#define AXI_JESD204B_REG_TEST_ERRCNT 0x34 + +/* AXI_JESD204B_REG_CTRL */ +#define AXI_JESD204B_CTRL_ERR_DIS (1 << 0) +#define AXI_JESD204B_CTRL_SYSREF_EN (1 << 1) +#define AXI_JESD204B_CTRL_SCR_EN (1 << 2) +#define AXI_JESD204B_CTRL_LANESYNC_EN (1 << 3) +#define AXI_JESD204B_CTRL_SYSREF_SW_EN (1 << 4) +#define AXI_JESD204B_CTRL_SYSREF_HW_EN (0 << 4) + +/* AXI_JESD204B_REG_SYSREF_TRIG */ +#define AXI_JESD204B_SYSREF_TRIG (1 << 0) + +/* AXI_JESD204B_REG_FRMCTRL */ +#define AXI_JESD204B_FRMCTRL_FRMCNT(x) ((x) << 8) +#define AXI_JESD204B_FRMCTRL_BYTECNT(x) (((x) & 0xFF) << 0) + +/* AXI_JESD204B_REG_BUFDELAY */ +#define AXI_JESD204B_BUFDELAY(x) ((x) << 0) + +/* AXI_JESD204B_REG_TEST_MODE */ +#define AXI_JESD204B_REG_TEST_MODE_LS(x) ((x) << 0) +#define AXI_JESD204B_REG_TEST_MODE_EN(x) ((x) << 2) +#define AXI_JESD204B_REG_TEST_MODE_JESD_RESET (1 << 4) +#define AXI_JESD204B_REG_TEST_MODE_GTX_RESET (1 << 5) + + +#endif /* ADI_JESD204B_H_ */ diff --git a/drivers/iio/adc/cf_fft_core.c b/drivers/iio/adc/cf_fft_core.c new file mode 100644 index 0000000000000..17861136193ad --- /dev/null +++ b/drivers/iio/adc/cf_fft_core.c @@ -0,0 +1,368 @@ +/* + * ADI-FFT Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + * + * http://wiki.analog.com/resources/fpga/xilinx/ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/*************************************************************************** + * register definitions (fft) + * 5'h00: + * [31: 0]: version(32'h00010061) + * 5'h01: + * [31: 0]: up_cfg_data, fft cfg data (refer Xilinx fft core for details). + * 5'h02: + * [ 3: 3]: up_status_ovf, fft overflow (mapped to Xilinx fft core outputs). + * [ 2: 2]: up_status_lm, fft tlast missing (mapped to core). + * [ 1: 1]: up_status_lu, fft tlast unexpected (mapped to core). + * [ 0: 0]: up_status_fs, fft frame start (mapped to core). + ***************************************************************************/ + +#define FFT_PCORE_VERSION 0x0 +#define FFT_PCORE_CFG 0x4 +#define FFT_PCORE_STAT 0x8 +#define FFT_PCORE_POSTPROC 0xC +#define FFT_PCORE_IRSEL 0x10 +#define FFT_PCORE_WINCFG 0x14 + +#define FFT_PCORE_CFG_DEFAULT 0xD5700 +#define FFT_PCORE_CFG_FW_FFT (1 << 8) +#define FFT_PCORE_CFG_INV_FFT (0 << 8) + +#define FFT_PCORE_POSTPROC_EN 0x1 + +#define FFT_PCORE_IRSEL_I(x) ((x) << 2) +#define FFT_PCORE_IRSEL_R(x) ((x) << 0) +#define FFT_PCORE_IRSEL_ZERO 0 +#define FFT_PCORE_IRSEL_CH0 1 +#define FFT_PCORE_IRSEL_CH1 2 + + +#define FFT_PCORE_WINCFG_INC(x) ((x) & 0xFFFF) +#define FFT_PCORE_WINCFG_ENB (1 << 16) + +struct fft_state { + struct device *dev; + struct mutex lock; + struct completion dma_complete; + struct dma_chan *rx_chan; + struct dma_chan *tx_chan; + void __iomem *regs; + int compl_stat; +}; + +struct fft_dma_params { + struct device_node *of_node; + enum dma_transfer_direction direction; + int chan_id; +}; + +struct fft_state *fft_state_glob; + +/* + * IO accessors + */ + +static inline void fft_write(struct fft_state *st, unsigned reg, unsigned val) +{ + iowrite32(val, st->regs + reg); +} + +static inline unsigned int fft_read(struct fft_state *st, unsigned reg) +{ + return ioread32(st->regs + reg); +} + +static bool fft_dma_filter(struct dma_chan *chan, void *param) +{ + struct fft_dma_params *p = param; + + return chan->device->dev->of_node == p->of_node && + chan->chan_id == p->chan_id; +} + +int fft_calculate(dma_addr_t src, dma_addr_t dest, unsigned int size, unsigned irsel) +{ + struct fft_state *st = fft_state_glob; + struct dma_async_tx_descriptor *tx_desc, *rx_desc; + dma_cookie_t tx_cookie, rx_cookie; + unsigned nfft = ilog2(size); + int ret = 0; + + if (st == NULL) + return -ENODEV; + + if (((1 << nfft) != size) || !src || !dest || !irsel) + return -EINVAL; + + switch (irsel) { + case FFT_PCORE_IRSEL_CH0: + case FFT_PCORE_IRSEL_CH1: + irsel = FFT_PCORE_IRSEL_R(irsel); + break; + case FFT_PCORE_IRSEL_CH0 | FFT_PCORE_IRSEL_CH1: + irsel = FFT_PCORE_IRSEL_R(FFT_PCORE_IRSEL_CH0) | + FFT_PCORE_IRSEL_I(FFT_PCORE_IRSEL_CH1); + break; + } + + mutex_lock(&st->lock); + + fft_write(st, FFT_PCORE_WINCFG, 0); + fft_write(st, FFT_PCORE_WINCFG, BIT(16) | (0x10000 >> nfft)); + fft_write(st, FFT_PCORE_POSTPROC, 0);//FFT_PCORE_POSTPROC_EN); + fft_write(st, FFT_PCORE_IRSEL, irsel); + fft_write(st, FFT_PCORE_STAT, 0xFF); + fft_write(st, FFT_PCORE_CFG, FFT_PCORE_CFG_DEFAULT | nfft); + + tx_desc = dmaengine_prep_slave_single(st->tx_chan, src, size * 4, + DMA_TO_DEVICE, 0); + if (!tx_desc) { + dev_err(st->dev, + "Failed to allocate a dma descriptor\n"); + ret = -ENOMEM; + goto error_ret; + } + + tx_cookie = dmaengine_submit(tx_desc); + if (tx_cookie < 0) { + dev_err(st->dev, + "Failed to submit a dma transfer\n"); + ret = tx_cookie; + goto error_ret; + } + + rx_desc = dmaengine_prep_slave_single(st->rx_chan, dest, size * 4, + DMA_FROM_DEVICE, DMA_PREP_INTERRUPT); + if (!rx_desc) { + dev_err(st->dev, + "Failed to allocate a dma descriptor\n"); + ret = -ENOMEM; + goto error_ret; + } + + rx_desc->callback = (dma_async_tx_callback) complete; + rx_desc->callback_param = &st->dma_complete; + + rx_cookie = dmaengine_submit(rx_desc); + if (rx_cookie < 0) { + dev_err(st->dev, + "Failed to submit a dma transfer\n"); + ret = rx_cookie; + goto error_ret; + } + + dma_async_issue_pending(st->tx_chan); + dma_async_issue_pending(st->rx_chan); + + ret = wait_for_completion_interruptible_timeout(&st->dma_complete, + 4 * HZ); + if (ret == 0) { + ret = -ETIMEDOUT; + goto error_ret; + } else if (ret < 0) { + goto error_ret; + } + + ret = 0; + +error_ret: + mutex_unlock(&st->lock); + return ret; +} +EXPORT_SYMBOL_GPL(fft_calculate); + +/** + * fft_of_probe - probe method for the AIM device. + * @of_dev: pointer to OF device structure + * @match: pointer to the structure used for matching a device + * + * This function probes the AIM device in the device tree. + * It initializes the driver data structure and the hardware. + * It returns 0, if the driver is bound to the AIM device, or a negative + * value if there is an error. + */ +static int __devinit fft_of_probe(struct platform_device *op) +{ + struct device *dev = &op->dev; + struct fft_state *st; + struct resource r_mem; /* IO mem resources */ + struct fft_dma_params dma_params; + struct of_phandle_args dma_spec; + dma_cap_mask_t mask; + resource_size_t remap_size, phys_addr; + int ret; + + dev_info(dev, "Device Tree Probing \'%s\'\n", + op->dev.of_node->name); + + st = devm_kzalloc(&op->dev, sizeof(*st), GFP_KERNEL); + if (!st) { + dev_err(dev, "Not enough memory for device\n"); + return -ENOMEM; + } + + st->dev = dev; + dev_set_drvdata(dev, st); + mutex_init(&st->lock); + + /* Get iospace for the device */ + ret = of_address_to_resource(op->dev.of_node, 0, &r_mem); + if (ret) { + dev_err(dev, "invalid address\n"); + return ret; + } + + phys_addr = r_mem.start; + remap_size = resource_size(&r_mem); + if (!request_mem_region(phys_addr, remap_size, KBUILD_MODNAME)) { + dev_err(dev, "Couldn't lock memory region at 0x%08llX\n", + (unsigned long long)phys_addr); + ret = -EBUSY; + goto failed1; + } + + st->regs = ioremap(phys_addr, remap_size); + if (st->regs == NULL) { + dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n", + (unsigned long long)phys_addr); + ret = -EFAULT; + goto failed2; + } + + /* Get dma channel for the device */ + ret = of_parse_phandle_with_args(op->dev.of_node, "dma-request", + "#dma-cells", 0, &dma_spec); + if (ret) { + dev_err(dev, "Couldn't parse dma-request\n"); + goto failed2; + } + + dma_params.of_node = dma_spec.np; + dma_params.chan_id = dma_spec.args[0]; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE | DMA_PRIVATE, mask); + + st->tx_chan = dma_request_channel(mask, fft_dma_filter, &dma_params); + if (!st->tx_chan) { + dev_err(dev, "failed to find tx dma device\n"); + goto failed2; + } + + /* Get dma channel for the device */ + ret = of_parse_phandle_with_args(op->dev.of_node, "dma-request", + "#dma-cells", 1, &dma_spec); + if (ret) { + dev_err(dev, "Couldn't parse dma-request\n"); + goto failed2; + } + + dma_params.of_node = dma_spec.np; + dma_params.chan_id = dma_spec.args[0]; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE | DMA_PRIVATE, mask); + + st->rx_chan = dma_request_channel(mask, fft_dma_filter, &dma_params); + if (!st->rx_chan) { + dev_err(dev, "failed to find rx dma device\n"); + goto failed2; + } + + init_completion(&st->dma_complete); + + dev_info(dev, "ADI-FFT (0x%X) at 0x%08llX mapped to 0x%p," + " DMA-%d, DMA-%d probed\n", + fft_read(st, FFT_PCORE_VERSION), + (unsigned long long)phys_addr, st->regs, + st->rx_chan->chan_id, st->tx_chan->chan_id); + + fft_state_glob = st; + + return 0; + +failed2: + release_mem_region(phys_addr, remap_size); +failed1: + dev_set_drvdata(dev, NULL); + + return ret; +} + +/** + * fft_of_remove - unbinds the driver from the AIM device. + * @of_dev: pointer to OF device structure + * + * This function is called if a device is physically removed from the system or + * if the driver module is being unloaded. It frees any resources allocated to + * the device. + */ +static int __devexit fft_of_remove(struct platform_device *op) +{ + struct device *dev = &op->dev; + struct resource r_mem; /* IO mem resources */ + struct fft_state *st = dev_get_drvdata(dev); + + dma_release_channel(st->rx_chan); + dma_release_channel(st->tx_chan); + + iounmap(st->regs); + + /* Get iospace of the device */ + if (of_address_to_resource(op->dev.of_node, 0, &r_mem)) + dev_err(dev, "invalid address\n"); + else + release_mem_region(r_mem.start, resource_size(&r_mem)); + + dev_set_drvdata(dev, NULL); + fft_state_glob = NULL; + + return 0; +} + +/* Match table for of_platform binding */ +static const struct of_device_id fft_of_match[] __devinitconst = { + { .compatible = "xlnx,cf-fft-core-1.00.a", }, + { .compatible = "xlnx,axi-fft-1.00.a", }, + { /* end of list */ }, +}; +MODULE_DEVICE_TABLE(of, fft_of_match); + +static struct platform_driver fft_of_driver = { + .driver = { + .name = KBUILD_MODNAME, + .owner = THIS_MODULE, + .of_match_table = fft_of_match, + }, + .probe = fft_of_probe, + .remove = __devexit_p(fft_of_remove), +}; + +module_platform_driver(fft_of_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices CF FFT"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/adc/cf_fft_core.h b/drivers/iio/adc/cf_fft_core.h new file mode 100644 index 0000000000000..7437dcc2a6f91 --- /dev/null +++ b/drivers/iio/adc/cf_fft_core.h @@ -0,0 +1,17 @@ +/* + * ADI-FFT Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + * + * http://wiki.analog.com/resources/fpga/xilinx/ + */ + +#ifndef ADI_FFT_H_ +#define ADI_FFT_H_ + +int fft_calculate(dma_addr_t src, dma_addr_t dest, + unsigned int size, unsigned irsel); + +#endif /* ADI_FFT_H_ */ diff --git a/drivers/iio/amplifiers/ad8366.c b/drivers/iio/amplifiers/ad8366.c index d8281cdbfc4a0..9dd4114856f40 100644 --- a/drivers/iio/amplifiers/ad8366.c +++ b/drivers/iio/amplifiers/ad8366.c @@ -156,18 +156,21 @@ static int __devinit ad8366_probe(struct spi_device *spi) st->spi = spi; indio_dev->dev.parent = &spi->dev; - indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->name = spi->dev.platform_data ? spi->dev.platform_data : + spi_get_device_id(spi)->name; indio_dev->info = &ad8366_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = ad8366_channels; indio_dev->num_channels = ARRAY_SIZE(ad8366_channels); + ret = ad8366_write(indio_dev, 0 , 0); + if (ret < 0) + goto error_disable_reg; + ret = iio_device_register(indio_dev); if (ret) goto error_disable_reg; - ad8366_write(indio_dev, 0 , 0); - return 0; error_disable_reg: diff --git a/drivers/iio/frequency/Kconfig b/drivers/iio/frequency/Kconfig index 6aaa33ef4544a..58da849d45bf6 100644 --- a/drivers/iio/frequency/Kconfig +++ b/drivers/iio/frequency/Kconfig @@ -19,6 +19,44 @@ config AD9523 To compile this driver as a module, choose M here: the module will be called ad9523. +config AD9548 + tristate "Analog Devices AD9548 Network Clock Generator/Synchronizer" + depends on SPI + help + Say yes here to build support for Analog Devices AD9548 + Quad/Octal Input Network Clock Generator/Synchronizer. + + To compile this driver as a module, choose M here: the + module will be called ad9548. + +config AD9517 + tristate "Analog Devices AD9517 12-Output Clock Generator" + depends on SPI + help + Say yes here to build support for Analog Devices AD9517 + 12-Output Clock Generator. + + To compile this driver as a module, choose M here: the + module will be called ad9517. + +endmenu + +menu "Direct Digital Synthesis" + +config CF_AXI_DDS + tristate "Analog Devices CoreFPGA AXI DDS driver" + depends on SPI + help + Say yes here to build support for Analog Devices DDS chip + AD9122, provides direct access via sysfs. + +config CF_AXI_DDS_AD9122 + tristate "Analog Devices AD9122 DAC" + depends on CF_AXI_DDS + help + Say yes here to build support for Analog Devices AD9122 DAC chip + ad9122, provides direct access via sysfs. + endmenu # diff --git a/drivers/iio/frequency/Makefile b/drivers/iio/frequency/Makefile index 00d26e5d1dc2d..ec84635078d83 100644 --- a/drivers/iio/frequency/Makefile +++ b/drivers/iio/frequency/Makefile @@ -2,5 +2,9 @@ # Makefile iio/frequency # +obj-$(CONFIG_AD9517) += ad9517.o +obj-$(CONFIG_AD9548) += ad9548.o obj-$(CONFIG_AD9523) += ad9523.o obj-$(CONFIG_ADF4350) += adf4350.o +obj-$(CONFIG_CF_AXI_DDS) += cf_axi_dds.o cf_axi_dds_buffer.o +obj-$(CONFIG_CF_AXI_DDS_AD9122) += ad9122.o diff --git a/drivers/iio/frequency/ad9122.c b/drivers/iio/frequency/ad9122.c new file mode 100644 index 0000000000000..2913bb1468088 --- /dev/null +++ b/drivers/iio/frequency/ad9122.c @@ -0,0 +1,201 @@ +/* + * AD9122 SPI DAC driver for AXI DDS PCORE/COREFPGA Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "ad9122.h" +#include "cf_axi_dds.h" + +static const unsigned char ad9122_reg_defaults[][2] = { + {AD9122_REG_COMM, 0x00}, + {AD9122_REG_COMM, AD9122_COMM_RESET}, + {AD9122_REG_COMM, 0x00}, + {AD9122_REG_POWER_CTRL, AD9122_POWER_CTRL_PD_AUX_ADC}, + {AD9122_REG_DATA_FORMAT, AD9122_DATA_FORMAT_BINARY}, + {AD9122_REG_INTERRUPT_EN_1, 0x00}, + {AD9122_REG_INTERRUPT_EN_2, 0x00}, + {AD9122_REG_CLK_REC_CTRL, AD9122_CLK_REC_CTRL_DACCLK_CROSS_CORRECTION | + AD9122_CLK_REC_CTRL_REFCLK_CROSS_CORRECTION | + 0xF}, + {AD9122_REG_PLL_CTRL_1, AD9122_PLL_CTRL_1_PLL_MANUAL_EN}, + {AD9122_REG_PLL_CTRL_2, AD9122_PLL_CTRL_2_PLL_LOOP_BANDWIDTH(3) | + AD9122_PLL_CTRL_2_PLL_CHARGE_PUMP_CURRENT(0x11)}, + {AD9122_REG_PLL_CTRL_3, AD9122_PLL_CTRL_3_N2(3) | + AD9122_PLL_CTRL_3_PLL_CROSS_CTRL_EN | + AD9122_PLL_CTRL_3_N0(1) | + AD9122_PLL_CTRL_3_N1(2)}, + {AD9122_REG_SYNC_CTRL_1, AD9122_SYNC_CTRL_1_DATA_FIFO_RATE_TOGGLE | + AD9122_SYNC_CTRL_1_RISING_EDGE_SYNC}, + {AD9122_REG_SYNC_CTRL_2, 0x00}, + {AD9122_REG_DCI_DELAY, 0x00}, + {AD9122_REG_FIFO_CTRL, AD9122_FIFO_CTRL_FIFO_PHA_OFFSET(4)}, + {AD9122_REG_FIFO_STATUS_1, 0x00}, + {AD9122_REG_DATAPATH_CTRL, AD9122_DATAPATH_CTRL_BYPASS_PREMOD | + AD9122_DATAPATH_CTRL_BYPASS_INV_SINC | + AD9122_DATAPATH_CTRL_BYPASS_NCO}, + {AD9122_REG_HB1_CTRL, AD9122_HB1_CTRL_BYPASS_HB1}, + {AD9122_REG_HB2_CTRL, AD9122_HB2_CTRL_BYPASS_HB2}, + {AD9122_REG_HB3_CTRL, AD9122_HB3_CTRL_BYPASS_HB3}, + {AD9122_REG_FTW_7_0, 0x00}, + {AD9122_REG_FTW_15_8, 0x00}, + {AD9122_REG_FTW_23_16, 0x00}, + {AD9122_REG_FTW_31_24, 0x00}, + {AD9122_REG_NCO_PHA_OFFSET_LSB, 0x00}, + {AD9122_REG_NCO_PHA_OFFSET_MSB, 0x00}, + {AD9122_REG_NCO_FTW_UPDATE, 0x00}, + {AD9122_REG_I_PHA_ADJ_LSB, 0x00}, + {AD9122_REG_I_PHA_ADJ_MSB, 0x00}, + {AD9122_REG_Q_PHA_ADJ_LSB, 0x00}, + {AD9122_REG_Q_PHA_ADJ_MSB, 0x00}, + {AD9122_REG_I_DAC_OFFSET_LSB, 0x00}, + {AD9122_REG_I_DAC_OFFSET_MSB, 0x00}, + {AD9122_REG_Q_DAC_OFFSET_LSB, 0x00}, + {AD9122_REG_Q_DAC_OFFSET_MSB, 0x00}, + {AD9122_REG_I_DAC_FS_ADJ, 0xF9}, + {AD9122_REG_I_DAC_CTRL, 0x01}, + {AD9122_REG_I_AUX_DAC_DATA, 0x00}, + {AD9122_REG_I_AUX_DAC_CTRL, 0x00}, + {AD9122_REG_Q_DAC_FS_ADJ, 0xF9}, + {AD9122_REG_Q_DAC_CTRL, 0x01}, + {AD9122_REG_Q_AUX_DAC_DATA, 0x00}, + {AD9122_REG_Q_AUX_DAC_CTRL, 0x00}, + {AD9122_REG_DIE_TEMP_RANGE_CTRL, AD9122_DIE_TEMP_RANGE_CTRL_REF_CURRENT(1)}, + {AD9122_REG_FIFO_STATUS_1, AD9122_FIFO_STATUS_1_FIFO_SOFT_ALIGN_REQ}, +}; + +static int ad9122_read(struct spi_device *spi, unsigned reg) +{ + unsigned char buf[2]; + int ret; + + buf[0] = 0x80 | reg; + + ret = spi_write_then_read(spi, &buf[0], 1, &buf[1], 1); + if (ret < 0) + return ret; + + return buf[1]; +} + +static int ad9122_write(struct spi_device *spi, + unsigned reg, unsigned val) +{ + unsigned char buf[2]; + int ret; + + buf[0] = reg; + buf[1] = val; + ret = spi_write_then_read(spi, buf, 2, NULL, 0); + if (ret < 0) + return ret; + + return 0; +} + +static int ad9122_setup(struct spi_device *spi, unsigned mode) +{ + int ret, timeout, i; + + for (i = 0; i < ARRAY_SIZE(ad9122_reg_defaults); i++) + ad9122_write(spi, ad9122_reg_defaults[i][0], + ad9122_reg_defaults[i][1]); + timeout = 255; + do { + mdelay(1); + ret = ad9122_read(spi, AD9122_REG_FIFO_STATUS_1); + if (ret < 0) + return ret; + + } while (timeout-- && !(ret & AD9122_FIFO_STATUS_1_FIFO_SOFT_ALIGN_ACK)); + + ad9122_write(spi, AD9122_REG_FIFO_STATUS_1, 0x0); + ad9122_write(spi, AD9122_REG_SYNC_CTRL_1, + AD9122_SYNC_CTRL_1_SYNC_EN | + AD9122_SYNC_CTRL_1_RISING_EDGE_SYNC); + + timeout = 255; + do { + mdelay(1); + ret = ad9122_read(spi, AD9122_REG_SYNC_STATUS_1); + if (ret < 0) + return ret; + + } while (timeout-- && !(ret & AD9122_SYNC_STATUS_1_SYNC_LOCKED)); + + return 0; +} + +static int __devinit ad9122_probe(struct spi_device *spi) +{ + struct cf_axi_dds_converter *conv; + unsigned id; + int ret; + + conv = kzalloc(sizeof(*conv), GFP_KERNEL); + if (conv == NULL) + return -ENOMEM; + + + id = ad9122_read(spi, AD9122_REG_CHIP_ID); + if (id != CHIPID_AD9122) { + dev_err(&spi->dev, "Unrecognized CHIP_ID 0x%X\n", id); + ret = -ENODEV; + goto out; + } + + conv->write = ad9122_write; + conv->read = ad9122_read; + conv->setup = ad9122_setup; + conv->spi = spi; + conv->id = ID_AD9122; + spi_set_drvdata(spi, conv); + + return 0; +out: + kfree(conv); + return ret; +} + +static int ad9122_remove(struct spi_device *spi) +{ + struct cf_axi_dds_converter *conv = spi_get_drvdata(spi); + + spi_set_drvdata(spi, NULL); + kfree(conv); + + return 0; +} + +static const struct spi_device_id ad9122_id[] = { + {"ad9122", 0}, + {} +}; +MODULE_DEVICE_TABLE(spi, ad9122_id); + +static struct spi_driver ad9122_driver = { + .driver = { + .name = "ad9122", + .owner = THIS_MODULE, + }, + .probe = ad9122_probe, + .remove = __devexit_p(ad9122_remove), + .id_table = ad9122_id, +}; +module_spi_driver(ad9122_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD9122 ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/frequency/ad9122.h b/drivers/iio/frequency/ad9122.h new file mode 100644 index 0000000000000..281bc06c7458b --- /dev/null +++ b/drivers/iio/frequency/ad9122.h @@ -0,0 +1,282 @@ +/* + * AD9122 SPI DAC driver for AXI DDS PCORE/COREFPGA Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#ifndef IIO_FREQUENCY_AD9122_H_ +#define IIO_FREQUENCY_AD9122_H_ + +/* Registers */ +#define AD9122_REG_COMM 0x00 +#define AD9122_REG_POWER_CTRL 0x01 +#define AD9122_REG_DATA_FORMAT 0x03 +#define AD9122_REG_INTERRUPT_EN_1 0x04 +#define AD9122_REG_INTERRUPT_EN_2 0x05 +#define AD9122_REG_EVENT_FLAG_1 0x06 +#define AD9122_REG_EVENT_FLAG_2 0x07 +#define AD9122_REG_CLK_REC_CTRL 0x08 +#define AD9122_REG_PLL_CTRL_1 0x0A +#define AD9122_REG_PLL_CTRL_2 0x0C +#define AD9122_REG_PLL_CTRL_3 0x0D +#define AD9122_REG_PLL_STATUS_1 0x0E +#define AD9122_REG_PLL_STATUS_2 0x0F +#define AD9122_REG_SYNC_CTRL_1 0x10 +#define AD9122_REG_SYNC_CTRL_2 0x11 +#define AD9122_REG_SYNC_STATUS_1 0x12 +#define AD9122_REG_SYNC_STATUS_2 0x13 +#define AD9122_REG_DATA_REC_STATUS 0x15 +#define AD9122_REG_DCI_DELAY 0x16 +#define AD9122_REG_FIFO_CTRL 0x17 +#define AD9122_REG_FIFO_STATUS_1 0x18 +#define AD9122_REG_FIFO_STATUS_2 0x19 +#define AD9122_REG_DATAPATH_CTRL 0x1B +#define AD9122_REG_HB1_CTRL 0x1C +#define AD9122_REG_HB2_CTRL 0x1D +#define AD9122_REG_HB3_CTRL 0x1E +#define AD9122_REG_CHIP_ID 0x1F +#define AD9122_REG_FTW_7_0 0x30 +#define AD9122_REG_FTW_15_8 0x31 +#define AD9122_REG_FTW_23_16 0x32 +#define AD9122_REG_FTW_31_24 0x33 +#define AD9122_REG_NCO_PHA_OFFSET_LSB 0x34 +#define AD9122_REG_NCO_PHA_OFFSET_MSB 0x35 +#define AD9122_REG_NCO_FTW_UPDATE 0x36 +#define AD9122_REG_I_PHA_ADJ_LSB 0x38 +#define AD9122_REG_I_PHA_ADJ_MSB 0x39 +#define AD9122_REG_Q_PHA_ADJ_LSB 0x3A +#define AD9122_REG_Q_PHA_ADJ_MSB 0x3B +#define AD9122_REG_I_DAC_OFFSET_LSB 0x3C +#define AD9122_REG_I_DAC_OFFSET_MSB 0x3D +#define AD9122_REG_Q_DAC_OFFSET_LSB 0x3E +#define AD9122_REG_Q_DAC_OFFSET_MSB 0x3F +#define AD9122_REG_I_DAC_FS_ADJ 0x40 +#define AD9122_REG_I_DAC_CTRL 0x41 +#define AD9122_REG_I_AUX_DAC_DATA 0x42 +#define AD9122_REG_I_AUX_DAC_CTRL 0x43 +#define AD9122_REG_Q_DAC_FS_ADJ 0x44 +#define AD9122_REG_Q_DAC_CTRL 0x45 +#define AD9122_REG_Q_AUX_DAC_DATA 0x46 +#define AD9122_REG_Q_AUX_DAC_CTRL 0x47 +#define AD9122_REG_DIE_TEMP_RANGE_CTRL 0x48 +#define AD9122_REG_DIE_TEMP_LSB 0x49 +#define AD9122_REG_DIE_TEMP_MSB 0x4A +#define AD9122_REG_SED_CTRL 0x67 +#define AD9122_REG_COMPARE_I0_LSBS 0x68 +#define AD9122_REG_COMPARE_I0_MSBS 0x69 +#define AD9122_REG_COMPARE_Q0_LSBS 0x6A +#define AD9122_REG_COMPARE_Q0_MSBS 0x6B +#define AD9122_REG_COMPARE_I1_LSBS 0x6C +#define AD9122_REG_COMPARE_I1_MSBS 0x6D +#define AD9122_REG_COMPARE_Q1_LSBS 0x6E +#define AD9122_REG_COMPARE_Q1_MSBS 0x6F +#define AD9122_REG_SED_I_LSBS 0x70 +#define AD9122_REG_SED_I_MSBS 0x71 +#define AD9122_REG_SED_Q_LSBS 0x72 +#define AD9122_REG_SED_Q_MSBS 0x73 +#define AD9122_REG_REVISION 0x7F + +/* AD9122_REG_COMM definitions */ +#define AD9122_COMM_SDIO (1 << 7) +#define AD9122_COMM_LSB_FIRST (1 << 6) +#define AD9122_COMM_RESET (1 << 5) + +/* AD9122_REG_POWER_CTRL definitions */ +#define AD9122_POWER_CTRL_PD_I_DAC (1 << 7) +#define AD9122_POWER_CTRL_PD_Q_DAC (1 << 6) +#define AD9122_POWER_CTRL_PD_DATA_REC (1 << 5) +#define AD9122_POWER_CTRL_PD_AUX_ADC (1 << 4) + +/* AD9122_REG_DATA_FORMAT definitions */ +#define AD9122_DATA_FORMAT_BINARY (1 << 7) +#define AD9122_DATA_FORMAT_Q_DATA_FIRST (1 << 6) +#define AD9122_DATA_FORMAT_MSB_SWAP (1 << 5) +#define AD9122_DATA_FORMAT_BUS_WIDTH(x) (((x) & 0x3) << 0) + +/* AD9122_REG_INTERRUPT_EN_1 definitions */ +#define AD9122_INTERRUPT_EN_1_EN_PLL_LOCK_LOST (1 << 7) +#define AD9122_INTERRUPT_EN_1_EN_PLL_LOCKED (1 << 6) +#define AD9122_INTERRUPT_EN_1_EN_SYNC_SIGNAL_LOST (1 << 5) +#define AD9122_INTERRUPT_EN_1_EN_SYNC_SIGNAL_LOCKED (1 << 4) +#define AD9122_INTERRUPT_EN_1_EN_FIFO_WARNING_1 (1 << 1) +#define AD9122_INTERRUPT_EN_1_EN_FIFO_WARNING_2 (1 << 0) + +/* AD9122_REG_INTERRUPT_EN_2 definitions */ +#define AD9122_INTERRUPT_EN_2_EN_AED_COMPARE_PASS (1 << 4) +#define AD9122_INTERRUPT_EN_2_EN_AED_COMPARE_FAIL (1 << 3) +#define AD9122_INTERRUPT_EN_2_EN_SED_COMPARE_FAIL (1 << 2) + +/* AD9122_REG_EVENT_FLAG_1 definitions */ +#define AD9122_EVENT_FLAG_1_PLL_LOCK_LOST (1 << 7) +#define AD9122_EVENT_FLAG_1_PLL_LOCKED (1 << 6) +#define AD9122_EVENT_FLAG_1_SYNC_SIGNAL_LOST (1 << 5) +#define AD9122_EVENT_FLAG_1_SYNC_SIGNAL_LOCKED (1 << 4) +#define AD9122_EVENT_FLAG_1_FIFO_WARNING_1 (1 << 1) +#define AD9122_EVENT_FLAG_1_FIFO_WARNING_2 (1 << 0) + +/* AD9122_REG_EVENT_FLAG_2 definitions */ +#define AD9122_EVENT_FLAG_2_AED_COMPARE_PASS (1 << 4) +#define AD9122_EVENT_FLAG_2_AED_COMPARE_FAIL (1 << 3) +#define AD9122_EVENT_FLAG_2_SED_COMPARE_FAIL (1 << 2) + +/* AD9122_REG_CLK_REC_CTRL definitions */ +#define AD9122_CLK_REC_CTRL_DACCLK_DUTY_CORRECTION (1 << 7) +#define AD9122_CLK_REC_CTRL_REFCLK_DUTY_CORRECTION (1 << 6) +#define AD9122_CLK_REC_CTRL_DACCLK_CROSS_CORRECTION (1 << 5) +#define AD9122_CLK_REC_CTRL_REFCLK_CROSS_CORRECTION (1 << 4) + +/* AD9122_REG_PLL_CTRL_1 definitions */ +#define AD9122_PLL_CTRL_1_PLL_EN (1 << 7) +#define AD9122_PLL_CTRL_1_PLL_MANUAL_EN (1 << 6) +#define AD9122_PLL_CTRL_1_MANUAL_VCO_BAND(x) ((x) & 0x3F) << 0) + +/* AD9122_REG_PLL_CTRL_2 definitions */ +#define AD9122_PLL_CTRL_2_PLL_LOOP_BANDWIDTH(x) (((x) & 0x3) << 6) +#define AD9122_PLL_CTRL_2_PLL_CHARGE_PUMP_CURRENT(x) (((x) & 0x1F) << 0) + +/* AD9122_REG_PLL_CTRL_3 definitions */ +#define AD9122_PLL_CTRL_3_N2(x) (((x) & 0x3) << 6) +#define AD9122_PLL_CTRL_3_PLL_CROSS_CTRL_EN (1 << 4) +#define AD9122_PLL_CTRL_3_N0(x) (((x) & 0x3) << 2) +#define AD9122_PLL_CTRL_3_N1(x) (((x) & 0x3) << 0) + +/* AD9122_REG_PLL_STATUS_1 definitions */ +#define AD9122_PLL_STATUS_1_PLL_LOCKED (1 << 7) +#define AD9122_PLL_STATUS_1_VCO_CTRL_VOLTAGE(x) (((x) & 0xF) << 0) + +/* AD9122_REG_PLL_STATUS_2 definitions */ +#define AD9122_PLL_STATUS_2_VCO_BAND_READBACK(x) (((x) & 0x3F) << 0) + +/* AD9122_REG_SYNC_CTRL_1 definitions */ +#define AD9122_SYNC_CTRL_1_SYNC_EN (1 << 7) +#define AD9122_SYNC_CTRL_1_DATA_FIFO_RATE_TOGGLE (1 << 6) +#define AD9122_SYNC_CTRL_1_RISING_EDGE_SYNC (1 << 3) +#define AD9122_SYNC_CTRL_1_SYNC_AVERAGING(x) (((x) & 0x7) << 0) + +/* AD9122_REG_SYNC_CTRL_2 definitions */ +#define AD9122_SYNC_CTRL_2_SYNC_PHA_REQUEST(x) (((x) & 0x3F) << 0) + +/* AD9122_REG_SYNC_STATUS_1 definitions */ +#define AD9122_SYNC_STATUS_1_SYNC_LOST (1 << 7) +#define AD9122_SYNC_STATUS_1_SYNC_LOCKED (1 << 6) + +/* AD9122_REG_SYNC_STATUS_2 definitions */ +#define AD9122_SYNC_STATUS_2_SYNC_PHA_READBACK (((x) & 0xFF) << 0) + +/* AD9122_REG_DATA_REC_STATUS definitions */ +#define AD9122_DATA_REC_STATUS_LVDS_FRAME_LEVEL_H (1 << 5) +#define AD9122_DATA_REC_STATUS_LVDS_FRAME_LEVEL_L (1 << 4) +#define AD9122_DATA_REC_STATUS_LVDS_DCI_LEVEL_H (1 << 3) +#define AD9122_DATA_REC_STATUS_LVDS_DCI_LEVEL_L (1 << 2) +#define AD9122_DATA_REC_STATUS_LVDS_DATA_LEVEL_H (1 << 1) +#define AD9122_DATA_REC_STATUS_LVDS_DATA_LEVEL_L (1 << 0) + +/* AD9122_REG_DCI_DELAY definitions */ +#define AD9122_DCI_DELAY_DCI_DELAY(x) (((x) & 0x3) << 0) + +/* AD9122_REG_FIFO_CTRL definitions */ +#define AD9122_FIFO_CTRL_FIFO_PHA_OFFSET(x) (((x) & 0x7) << 0) + +/* AD9122_REG_FIFO_STATUS_1 definitions */ +#define AD9122_FIFO_STATUS_1_FIFO_WARNING_1 (1 << 7) +#define AD9122_FIFO_STATUS_1_FIFO_WARNING_2 (1 << 6) +#define AD9122_FIFO_STATUS_1_FIFO_SOFT_ALIGN_ACK (1 << 2) +#define AD9122_FIFO_STATUS_1_FIFO_SOFT_ALIGN_REQ (1 << 1) + +/* AD9122_REG_FIFO_STATUS_2 definitions */ +#define AD9122_FIFO_STATUS_2_FIFO_LEVEL (((x) & 0xFF) << 0) + +/* AD9122_REG_DATAPATH_CTRL definitions */ +#define AD9122_DATAPATH_CTRL_BYPASS_PREMOD (1 << 7) +#define AD9122_DATAPATH_CTRL_BYPASS_INV_SINC (1 << 6) +#define AD9122_DATAPATH_CTRL_BYPASS_NCO (1 << 5) +#define AD9122_DATAPATH_CTRL_NCO_GAIN (1 << 3) +#define AD9122_DATAPATH_CTRL_BYPASS_PHA_COMP_DC_OFFSET (1 << 2) +#define AD9122_DATAPATH_CTRL_SELECT_SIDEBAND (1 << 1) +#define AD9122_DATAPATH_CTRL_SEND_I_DATA_TO_Q_DATA (1 << 0) + +/* AD9122_REG_HB1_CTRL definitions */ +#define AD9122_HB1_CTRL_HB1(x) (((x) & 0x3) << 1) +#define AD9122_HB1_CTRL_BYPASS_HB1 (1 << 0) + +/* AD9122_REG_HB2_CTRL definitions */ +#define AD9122_HB2_CTRL_HB2(x) (((x) & 0x3F) << 1) +#define AD9122_HB2_CTRL_BYPASS_HB2 (1 << 0) + +/* AD9122_REG_HB3_CTRL definitions */ +#define AD9122_HB3_CTRL_HB3(x) (((x) & 0x3F) << 1) +#define AD9122_HB3_CTRL_BYPASS_HB3 (1 << 0) + +/* Value of AD9122_REG_CHIP_ID */ +#define AD9122_CHIP_ID 0x08 + +/* AD9122_REG_NCO_FTW_UPDATE definitions */ +#define AD9122_NCO_FTW_UPDATE_FRAME_FTW_ACK (1 << 5) +#define AD9122_NCO_FTW_UPDATE_FRAME_FTW_REQ (1 << 4) +#define AD9122_NCO_FTW_UPDATE_UPDATE_FTW_ACK (1 << 1) +#define AD9122_NCO_FTW_UPDATE_UPDATE_FTW_REQ (1 << 0) + +/* AD9122_REG_I_PHA_ADJ_LSB definitions */ +#define AD9122_REG_I_PHA_ADJ_7_0(x) (((x) & 0xFF) << 0) + +/* AD9122_REG_I_PHA_ADJ_MSB definitions */ +#define AD9122_REG_I_PHA_ADJ_9_8(x) (((x) & 0x3) << 0) + +/* AD9122_REG_Q_PHA_ADJ_LSB definitions */ +#define AD9122_REG_Q_PHA_ADJ_7_0(x) (((x) & 0xFF) << 0) + +/* AD9122_REG_Q_PHA_ADJ_MSB definitions */ +#define AD9122_REG_Q_PHA_ADJ_9_8(x) (((x) & 0x3) << 0) + +/* AD9122_REG_I_DAC_FS_ADJ definitions */ +#define AD9122_I_DAC_FS_ADJ_I_DAC_FS_ADJ_7_0(x) (((x) & 0xFF) << 0) + +/* AD9122_I_DAC_CTRL definitions */ +#define AD9122_I_DAC_CTRL_I_DAC_SLEEP (1 << 7) +#define AD9122_I_DAC_CTRL_I_DAC_FS_ADJ_9_8(x) (((x) & 0x3) << 0) + +/* AD9122_REG_I_AUX_DAC_DATA definitions */ +#define AD9122_I_AUX_DAC_DATA_I_AUX_DAC_7_0 (((x) & 0xFF) << 0) + +/* AD9122_REG_I_AUX_DAC_CTRL definitions */ +#define AD9122_I_AUX_DAC_CTRL_I_AUX_DAC_SIGN (1 << 7) +#define AD9122_I_AUX_DAC_CTRL_I_AUX_DAC_CURRENT_DIR (1 << 6) +#define AD9122_I_AUX_DAC_CTRL_I_AUX_DAC_SLEEP (1 << 5) +#define AD9122_I_AUX_DAC_CTRL_I_AUX_DAC_9_8(x) (((x) & 0x3) << 0) + +/* AD9122_REG_Q_DAC_FS_ADJ definitions */ +#define AD9122_Q_DAC_FS_ADJ_Q_DAC_FS_ADJ_7_0(x) (((x) & 0xFF) << 0) + +/* AD9122_Q_DAC_CTRL definitions */ +#define AD9122_Q_DAC_CTRL_Q_DAC_SLEEP (1 << 7) +#define AD9122_Q_DAC_CTRL_Q_DAC_FS_ADJ_9_8(x) (((x) & 0x3) << 0) + +/* AD9122_REG_Q_AUX_DAC_DATA definitions */ +#define AD9122_Q_AUX_DAC_DATA_Q_AUX_DAC_7_0 (((x) & 0xFF) << 0) + +/* AD9122_REG_Q_AUX_DAC_CTRL definitions */ +#define AD9122_Q_AUX_DAC_CTRL_Q_AUX_DAC_SIGN (1 << 7) +#define AD9122_Q_AUX_DAC_CTRL_Q_AUX_DAC_CURRENT_DIR (1 << 6) +#define AD9122_Q_AUX_DAC_CTRL_Q_AUX_DAC_SLEEP (1 << 5) +#define AD9122_Q_AUX_DAC_CTRL_Q_AUX_DAC_9_8(x) (((x) & 0x3) << 0) + +/* AD9122_REG_DIE_TEMP_RANGE_CTRL definitions */ +#define AD9122_DIE_TEMP_RANGE_CTRL_FS_CURRENT(x) (((x) & 0x7) << 4) +#define AD9122_DIE_TEMP_RANGE_CTRL_REF_CURRENT(x) (((x) & 0x7) << 1) +#define AD9122_DIE_TEMP_RANGE_CTRL_CAP_VALUE (1 << 0) + +/* AD9122_REG_SED_CTRL definitions */ +#define AD9122_SED_CTRL_SED_COMPARE_EN (1 << 7) +#define AD9122_SED_CTRL_SAMPLE_ERR_DETECTED (1 << 5) +#define AD9122_SED_CTRL_AUTOCLEAR_EN (1 << 3) +#define AD9122_SED_CTRL_COMPARE_FAIL (1 << 1) +#define AD9122_SED_CTRL_COMPARE_PASS (1 << 0) + +/* Values of AD9122_REG_REVISION */ +#define AD9122_DIE_REV_1 0x1 +#define AD9122_DIE_REV_2 0x3 + +#define CHIPID_AD9122 0x8 +#endif /* IIO_FREQUENCY_AD9122_H_ */ diff --git a/drivers/iio/frequency/ad9517.c b/drivers/iio/frequency/ad9517.c new file mode 100644 index 0000000000000..2d632bf148e89 --- /dev/null +++ b/drivers/iio/frequency/ad9517.c @@ -0,0 +1,676 @@ +/* + * AD9517 SPI Clock Generator with integrated VCO + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define FIRMWARE "ad9517.stp" + +#define AD_READ (1 << 15) +#define AD_WRITE (0 << 15) +#define AD_CNT(x) (((x) - 1) << 13) +#define AD_ADDR(x) ((x) & 0xFFF) + +/* +* AD9517-X Registers +*/ +#define AD9517_SERCONF 0x00 +#define AD9517_PARTID 0x03 +#define AD9517_RB_CTL 0x04 +#define AD9517_PFD_CP 0x10 +#define AD9517_RCNT_L 0x11 +#define AD9517_RCNT_H 0x12 +#define AD9517_ACNT 0x13 +#define AD9517_BCNT_L 0x14 +#define AD9517_BCNT_H 0x15 +#define AD9517_PLL1 0x16 +#define AD9517_PLL2 0x17 +#define AD9517_PLL3 0x18 +#define AD9517_PLL4 0x19 +#define AD9517_PLL5 0x1A +#define AD9517_PLL6 0x1B +#define AD9517_PLL7 0x1C +#define AD9517_PLL8 0x1D +#define AD9517_PLL9 0x1E +#define AD9517_PLL_RB 0x1F + +#define AD9517_OUT4_DELAY_BP 0xA0 +#define AD9517_OUT4_DELAY_FS 0xA1 +#define AD9517_OUT4_DELAY_FR 0xA2 +#define AD9517_OUT5_DELAY_BP 0xA3 +#define AD9517_OUT5_DELAY_FS 0xA4 +#define AD9517_OUT5_DELAY_FR 0xA5 +#define AD9517_OUT6_DELAY_BP 0xA6 +#define AD9517_OUT6_DELAY_FS 0xA7 +#define AD9517_OUT6_DELAY_FR 0xA8 +#define AD9517_OUT7_DELAY_BP 0xA9 +#define AD9517_OUT7_DELAY_FS 0xAA +#define AD9517_OUT7_DELAY_FR 0xAB + +#define AD9517_OUT0_LVPECL 0xF0 +#define AD9517_OUT1_LVPECL 0xF1 +#define AD9517_OUT2_LVPECL 0xF4 +#define AD9517_OUT3_LVPECL 0xF5 + +#define AD9517_OUT4_LVCMOS 0x140 +#define AD9517_OUT5_LVCMOS 0x141 +#define AD9517_OUT6_LVCMOS 0x142 +#define AD9517_OUT7_LVCMOS 0x143 + +/* LVPECL Channel Dividers */ +#define AD9517_PECLDIV0_1 0x190 +#define AD9517_PECLDIV0_2 0x191 +#define AD9517_PECLDIV0_3 0x192 +#define AD9517_PECLDIV1_1 0x196 +#define AD9517_PECLDIV1_2 0x197 +#define AD9517_PECLDIV1_3 0x198 + +/* LVDS/CMOS Channel Dividers */ +#define AD9517_CMOSDIV2_1 0x199 +#define AD9517_CMOSDIV2_1_PHO 0x19A +#define AD9517_CMOSDIV2_2 0x19B +#define AD9517_CMOSDIV2_BYPASS 0x19C +#define AD9517_CMOSDIV2_DCCOFF 0x19D +#define AD9517_CMOSDIV3_1 0x19E +#define AD9517_CMOSDIV3_PHO 0x19F +#define AD9517_CMOSDIV3_2 0x1A0 +#define AD9517_CMOSDIV3_BYPASS 0x1A1 +#define AD9517_CMOSDIV3_DCCOFF 0x1A2 + +/* VCO Divider and CLK Input */ +#define AD9517_VCO_DIVIDER 0x1E0 +#define AD9517_INPUT_CLKS 0x1E1 +#define AD9517_POWDOWN_SYNC 0x230 + +/* Update All Registers */ +#define AD9517_TRANSFER 0x232 + +#define AD9517_PLL3_VCO_CAL (1 << 0) +#define AD9517_TRANSFER_NOW (1 << 0) +#define AD9517_PLL1_BCNT_BP (1 << 3) +#define AD9517_VCO_DIVIDER_BP (1 << 0) +#define AD9517_VCO_DIVIDER_SEL (1 << 1) +#define AD9517_PECLDIV_VCO_SEL (1 << 1) +#define AD9517_PECLDIV_3_BP (1 << 7) +#define AD9517_CMOSDIV_BYPASS_2 (1 << 5) +#define AD9517_CMOSDIV_BYPASS_1 (1 << 4) +#define AD9517_SOFT_RESET (0x24) +#define AD9517_SDO_ACTIVE (0x81) +#define AD9517_LONG_INSTR (0x18) + +enum outputs { + OUT_0, + OUT_1, + OUT_2, + OUT_3, + OUT_4, + OUT_5, + OUT_6, + OUT_7, + NUM_OUTPUTS, +}; + +#define AD9517_REG(addr, val) ((addr << 16) | (val & 0xFF)) + +struct ad9517_platform_data { + unsigned long *regs; + unsigned num_regs; +}; + +struct ad9517_outputs { + struct ad9517_state *st; + struct clk_hw hw; + unsigned long freq; + const char *parent_name; + bool is_enabled; + unsigned char pwrdwn_reg; + unsigned char pwrdwn_bit; + +}; + +struct ad9517_state { + struct spi_device *spi; + unsigned char regs[AD9517_TRANSFER]; + struct ad9517_outputs output[NUM_OUTPUTS]; + unsigned long refin_freq; + unsigned long clkin_freq; + char *div0123_clk_parent_name; + char *vco_divin_clk_parent_name; +}; + +#define IS_FD (1 << 7) +#define AD9517_PLL1_PRESCALER_MASK 0x7 +static const unsigned char to_prescaler[] = { + 1 | IS_FD, + 2 | IS_FD, + 2, + 4, + 8, + 16, + 32, + 3 | IS_FD, +}; + +enum { + PWRDWN_REG, + PWRDWN_MASK, + PWRDWN_BIT, +}; + +static const unsigned short output_pwrdwn_lut[NUM_OUTPUTS][3] = { + {AD9517_OUT0_LVPECL, 0x3, 1}, + {AD9517_OUT1_LVPECL, 0x3, 1}, + {AD9517_OUT2_LVPECL, 0x3, 1}, + {AD9517_OUT3_LVPECL, 0x3, 1}, + {AD9517_OUT4_LVCMOS, 0x1, 0}, + {AD9517_OUT5_LVCMOS, 0x1, 0}, + {AD9517_OUT6_LVCMOS, 0x1, 0}, + {AD9517_OUT7_LVCMOS, 0x1, 0}, +}; + +#define to_ad9517_clk_output(_hw) container_of(_hw, struct ad9517_outputs, hw) + +static int ad9517_read(struct spi_device *spi, unsigned reg) +{ + unsigned char buf[3]; + int ret; + u16 cmd; + + cmd = AD_READ | AD_CNT(1) | AD_ADDR(reg); + buf[0] = cmd >> 8; + buf[1] = cmd & 0xFF; + + + ret = spi_write_then_read(spi, &buf[0], 2, &buf[2], 1); + if (ret < 0) + return ret; + + return buf[2]; +} + +static int ad9517_write(struct spi_device *spi, + unsigned reg, unsigned val) +{ + unsigned char buf[3]; + int ret; + u16 cmd; + + cmd = AD_WRITE | AD_CNT(1) | AD_ADDR(reg); + buf[0] = cmd >> 8; + buf[1] = cmd & 0xFF; + buf[2] = val; + + ret = spi_write(spi, buf, 3); + if (ret < 0) + return ret; + + return 0; +} + +static int ad9517_parse_firmware(struct ad9517_state *st, + char *data, unsigned size) +{ + char *line; + int ret; + unsigned addr, val1, val2; + + while ((line = strsep(&data, "\n"))) { + if (line >= data + size) + break; + + ret = sscanf(line, "\"%x\",\"%x\",\"%x\"", &addr, &val1, &val2); + if (ret == 3) { + if (addr > AD9517_TRANSFER) + return -EINVAL; + st->regs[addr] = val2 & 0xFF; + } + } + return 0; +} + +static int ad9517_parse_pdata(struct ad9517_state *st, + struct ad9517_platform_data *pdata) +{ + int i; + unsigned addr; + + if (!pdata->num_regs | (pdata->num_regs > AD9517_TRANSFER)) + return -EINVAL; + + for (i = 0; i < pdata->num_regs; i++) { + addr = pdata->regs[i] >> 16; + if (addr > AD9517_TRANSFER) + return -EINVAL; + st->regs[addr] = pdata->regs[i] & 0xFF; + } + return 0; +} + +static int ad9517_setup(struct ad9517_state *st) +{ + struct spi_device *spi = st->spi; + int ret, reg; + unsigned cal_delay_ms, d1, d2; + unsigned long pll_a_cnt, pll_b_cnt, pll_r_cnt, prescaler; + unsigned long vco_freq; + unsigned long vco_divin_freq; + unsigned long div0123_freq; + + /* Setup PLL */ + for (reg = AD9517_PFD_CP; reg <= AD9517_PLL8; reg++) { + ret = ad9517_write(spi, reg, st->regs[reg]); + if (ret < 0) + return ret; + } + + /* Setup fine delay adjust OUT4..OUT7 */ + for (reg = AD9517_OUT4_DELAY_BP; reg <= AD9517_OUT7_DELAY_FR; reg++) { + ret = ad9517_write(spi, reg, st->regs[reg]); + if (ret < 0) + return ret; + } + + /* Setup LVPECL outputs OUT0..OUT3 */ + for (reg = AD9517_OUT0_LVPECL; reg <= AD9517_OUT3_LVPECL; reg++) { + ret = ad9517_write(spi, reg, st->regs[reg]); + if (ret < 0) + return ret; + } + + /* Setup LVCMOS outputs OUT4..OUT7 */ + for (reg = AD9517_OUT4_LVCMOS; reg <= AD9517_OUT7_LVCMOS; reg++) { + ret = ad9517_write(spi, reg, st->regs[reg]); + if (ret < 0) + return ret; + } + + /* Setup PECL Channel Dividers */ + for (reg = AD9517_PECLDIV0_1; reg <= AD9517_PECLDIV1_3; reg++) { + ret = ad9517_write(spi, reg, st->regs[reg]); + if (ret < 0) + return ret; + } + + /* Setup LVDS/CMOS Channel Dividers */ + for (reg = AD9517_CMOSDIV2_1; reg <= AD9517_CMOSDIV3_DCCOFF; reg++) { + ret = ad9517_write(spi, reg, st->regs[reg]); + if (ret < 0) + return ret; + } + + /* Setup VCO Divier and CLK Input */ + ret = ad9517_write(spi, AD9517_VCO_DIVIDER, + st->regs[AD9517_VCO_DIVIDER]); + if (ret < 0) + return ret; + + ret = ad9517_write(spi, AD9517_INPUT_CLKS, st->regs[AD9517_INPUT_CLKS]); + if (ret < 0) + return ret; + + /* Setup System */ + ret = ad9517_write(spi, AD9517_POWDOWN_SYNC, + st->regs[AD9517_POWDOWN_SYNC]); + if (ret < 0) + return ret; + + ret = ad9517_write(spi, AD9517_PLL3, + st->regs[AD9517_PLL3] & ~AD9517_PLL3_VCO_CAL); + if (ret < 0) + return ret; + + /* Update all registers */ + ret = ad9517_write(spi, AD9517_TRANSFER, AD9517_TRANSFER_NOW); + if (ret < 0) + return ret; + + /* Calibrate VCO */ + ret = ad9517_write(spi, AD9517_PLL3, + st->regs[AD9517_PLL3] | AD9517_PLL3_VCO_CAL); + if (ret < 0) + return ret; + + /* Update all registers */ + ret = ad9517_write(spi, AD9517_TRANSFER, AD9517_TRANSFER_NOW); + if (ret < 0) + return ret; + + /* Get PLL settings */ + pll_r_cnt = st->regs[AD9517_RCNT_H] << 8 | st->regs[AD9517_RCNT_L]; + pll_a_cnt = st->regs[AD9517_ACNT]; + pll_b_cnt = st->regs[AD9517_BCNT_H] << 8 | st->regs[AD9517_BCNT_L]; + + if (st->regs[AD9517_PLL1] & AD9517_PLL1_BCNT_BP) + pll_b_cnt = 1; + + prescaler = to_prescaler[st->regs[AD9517_PLL1] & + AD9517_PLL1_PRESCALER_MASK]; + + if (prescaler & IS_FD) + pll_a_cnt = 0; + + prescaler &= ~IS_FD; + + vco_freq = (st->refin_freq * (prescaler * + pll_b_cnt + pll_a_cnt)) / pll_r_cnt; + + /* tcal = 4400 * Rdiv * cal_div / Refin */ + cal_delay_ms = (4400 * pll_r_cnt * + (2 << ((st->regs[AD9517_PLL3] >> 1) & 0x3))) / + (st->refin_freq / 1000); + + msleep(cal_delay_ms); + + /* Internal clock distribution */ + + if (st->regs[AD9517_INPUT_CLKS] & AD9517_VCO_DIVIDER_SEL) { + if (!vco_freq) + return -EINVAL; + vco_divin_freq = vco_freq; + st->vco_divin_clk_parent_name = "refclk"; + } else { + if (!st->clkin_freq) + return -EINVAL; + vco_divin_freq = st->clkin_freq; + st->vco_divin_clk_parent_name = "clkin"; + } + + if (st->regs[AD9517_INPUT_CLKS] & AD9517_VCO_DIVIDER_BP) { + if (!st->clkin_freq) + return -EINVAL; + div0123_freq = st->clkin_freq; + st->div0123_clk_parent_name = "clkin"; + } else { + div0123_freq = vco_divin_freq / + ((st->regs[AD9517_VCO_DIVIDER] & 0x7) + 2); + st->div0123_clk_parent_name = st->vco_divin_clk_parent_name; + } + + /* Outputs */ + /* 0..1 */ + + if (st->regs[AD9517_PECLDIV0_3] & AD9517_PECLDIV_VCO_SEL) { + st->output[OUT_0].freq = + st->output[OUT_1].freq = + vco_divin_freq; + st->output[OUT_0].parent_name = + st->output[OUT_1].parent_name = + st->vco_divin_clk_parent_name; + } else { + if (st->regs[AD9517_PECLDIV0_2] & AD9517_PECLDIV_3_BP) + d1 = 1; + else + d1 = (st->regs[AD9517_PECLDIV0_1] & 0xF) + + (st->regs[AD9517_PECLDIV0_1] >> 4) + 2; + + st->output[OUT_0].freq = + st->output[OUT_1].freq = + div0123_freq / d1; + + st->output[OUT_0].parent_name = + st->output[OUT_1].parent_name = + st->div0123_clk_parent_name; + } + + /* 2..3 */ + + if (st->regs[AD9517_PECLDIV1_3] & AD9517_PECLDIV_VCO_SEL) { + st->output[OUT_2].freq = + st->output[OUT_3].freq = + vco_divin_freq; + st->output[OUT_2].parent_name = + st->output[OUT_3].parent_name = + st->vco_divin_clk_parent_name; + } else { + if (st->regs[AD9517_PECLDIV1_2] & AD9517_PECLDIV_3_BP) + d1 = 1; + else + d1 = (st->regs[AD9517_PECLDIV1_1] & 0xF) + + (st->regs[AD9517_PECLDIV1_1] >> 4) + 2; + + st->output[OUT_2].freq = + st->output[OUT_3].freq = + div0123_freq / d1; + + st->output[OUT_2].parent_name = + st->output[OUT_3].parent_name = + st->div0123_clk_parent_name; + } + + /* 4..5 */ + + if (st->regs[AD9517_CMOSDIV2_BYPASS] & AD9517_CMOSDIV_BYPASS_1) + d1 = 1; + else + d1 = (st->regs[AD9517_CMOSDIV2_1] & 0xF) + + (st->regs[AD9517_CMOSDIV2_1] >> 4) + 2; + + if (st->regs[AD9517_CMOSDIV2_BYPASS] & AD9517_CMOSDIV_BYPASS_2) + d2 = 1; + else + d2 = (st->regs[AD9517_CMOSDIV2_2] & 0xF) + + (st->regs[AD9517_CMOSDIV2_2] >> 4) + 2; + + st->output[OUT_4].freq = + st->output[OUT_5].freq = + div0123_freq / (d1 * d2); + + st->output[OUT_4].parent_name = + st->output[OUT_5].parent_name = + st->div0123_clk_parent_name; + + /* 6..7 */ + + if (st->regs[AD9517_CMOSDIV3_BYPASS] & AD9517_CMOSDIV_BYPASS_1) + d1 = 1; + else + d1 = (st->regs[AD9517_CMOSDIV3_1] & 0xF) + + (st->regs[AD9517_CMOSDIV3_1] >> 4) + 2; + + if (st->regs[AD9517_CMOSDIV3_BYPASS] & AD9517_CMOSDIV_BYPASS_2) + d2 = 1; + else + d2 = (st->regs[AD9517_CMOSDIV3_2] & 0xF) + + (st->regs[AD9517_CMOSDIV3_2] >> 4) + 2; + + st->output[OUT_6].freq = + st->output[OUT_7].freq = + div0123_freq / (d1 * d2); + + st->output[OUT_6].parent_name = + st->output[OUT_7].parent_name = + st->div0123_clk_parent_name; + + return 0; +} + +static unsigned long ad9517_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return to_ad9517_clk_output(hw)->freq; +} + +static int ad9517_is_enabled(struct clk_hw *hw) +{ + return to_ad9517_clk_output(hw)->is_enabled; +} + +const struct clk_ops ad9517_clk_ops = { + .recalc_rate = ad9517_recalc_rate, + .is_enabled = ad9517_is_enabled, +}; + +struct clk *ad9517_clk_register(struct ad9517_state *st, unsigned num) +{ + struct clk_init_data init; + struct ad9517_outputs *output = &st->output[num]; + struct clk *clk; + char name[8]; + + sprintf(name, "out%d", num); + + init.name = name; + init.ops = &ad9517_clk_ops; + init.parent_names = &output->parent_name; + init.num_parents = 1; + + output->hw.init = &init; + output->st = st; + + /* register the clock */ + clk = clk_register(&st->spi->dev, &output->hw); + + if (!IS_ERR(clk)) + of_clk_add_provider(st->spi->dev.of_node, + of_clk_src_simple_get, clk); + + return clk; +} + +static int __devinit ad9517_probe(struct spi_device *spi) +{ + struct ad9517_platform_data *pdata = spi->dev.platform_data; + int out, ret, conf; + const struct firmware *fw; + struct ad9517_state *st; + struct clk *clk, *ref_clk, *clkin; + + st = devm_kzalloc(&spi->dev, sizeof(*st), GFP_KERNEL); + if (!st) { + dev_err(&spi->dev, "Not enough memory for device\n"); + return -ENOMEM; + } + + conf = AD9517_LONG_INSTR | + (spi->mode & SPI_3WIRE ? 0 : AD9517_SDO_ACTIVE); + + ret = ad9517_write(spi, AD9517_SERCONF, conf | AD9517_SOFT_RESET); + if (ret < 0) + return ret; + + ret = ad9517_write(spi, AD9517_SERCONF, conf); + if (ret < 0) + return ret; + + ret = ad9517_read(spi, AD9517_PARTID); + if (ret < 0) + return ret; + if (ret != spi_get_device_id(spi)->driver_data) { + dev_err(&spi->dev, "Unrecognized CHIP_ID 0x%X\n", ret); + return -ENODEV; + } + + if (!pdata) { + ret = request_firmware(&fw, FIRMWARE, &spi->dev); + if (ret) { + dev_err(&spi->dev, + "request_firmware() failed with %i\n", ret); + return ret; + } + ad9517_parse_firmware(st, (u8 *) fw->data, fw->size); + release_firmware(fw); + } else { + ret = ad9517_parse_pdata(st, pdata); + if (ret < 0) { + dev_err(&spi->dev, + "parse pdata failed with %i\n", ret); + return ret; + } + } + + st->spi = spi; + ref_clk = clk_get(&spi->dev, "refclk"); + clkin = clk_get(&spi->dev, "clkin"); + + if (IS_ERR(ref_clk) && IS_ERR(clkin)) { + ret = PTR_ERR(ref_clk); + dev_err(&spi->dev, "failed getting clock (%d)\n", ret); + goto out; + } + + + if (IS_ERR(ref_clk)) { + ret = PTR_ERR(ref_clk); + dev_warn(&spi->dev, "failed getting clock (%d)\n", ret); + } else { + st->refin_freq = clk_get_rate(ref_clk); + } + + if (IS_ERR(clkin)) { + ret = PTR_ERR(clkin); + dev_warn(&spi->dev, "failed getting clock (%d)\n", ret); + goto out; + } else { + st->clkin_freq = clk_get_rate(clkin); + } + + ret = ad9517_setup(st); + if (ret < 0) + return ret; + + for (out = 0; out < NUM_OUTPUTS; out++) { + st->output[out].is_enabled = + !(st->regs[output_pwrdwn_lut[out][PWRDWN_REG]] & + output_pwrdwn_lut[out][PWRDWN_MASK]); + clk = ad9517_clk_register(st, out); + if (IS_ERR(clk)) + return PTR_ERR(clk); + } + + spi_set_drvdata(spi, NULL); + dev_info(&spi->dev, "probed\n"); + +out: + return 0; +} + +static int ad9517_remove(struct spi_device *spi) +{ + spi_set_drvdata(spi, NULL); + + return 0; +} + +static const struct spi_device_id ad9517_id[] = { + {"ad9517-0", 0x11}, + {"ad9517-1", 0x51}, + {"ad9517-2", 0x91}, + {"ad9517-3", 0x53}, + {"ad9517-4", 0xD3}, + {} +}; +MODULE_DEVICE_TABLE(spi, ad9517_id); + +static struct spi_driver ad9517_driver = { + .driver = { + .name = "ad9517", + .owner = THIS_MODULE, + }, + .probe = ad9517_probe, + .remove = __devexit_p(ad9517_remove), + .id_table = ad9517_id, +}; +module_spi_driver(ad9517_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD9517"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/frequency/ad9548.c b/drivers/iio/frequency/ad9548.c new file mode 100644 index 0000000000000..9b985d7b0f500 --- /dev/null +++ b/drivers/iio/frequency/ad9548.c @@ -0,0 +1,287 @@ +/* + * AD9548 SPI Network Clock Generator/Synchronizer + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define AD_READ (1 << 15) +#define AD_WRITE (0 << 15) +#define AD_CNT(x) (((x) - 1) << 13) +#define AD_ADDR(x) ((x) & 0xFFF) +#define WAIT_B 0xFFFF +#define CHIPID_AD9548 0x48 + +static const unsigned short ad9548_regs[][2] = { + {0x0000, 0x30}, /* Reset */ + {0x0000, 0x10}, + {0x0000, 0x10}, + {0x0000, 0x10}, + {0x0000, 0x10}, + {0x0000, 0x10}, + {0x0100, 0x18}, /* System clock */ + {0x0101, 0x28}, + {0x0102, 0x45}, + {0x0103, 0x43}, + {0x0104, 0xDE}, + {0x0105, 0x13}, + {0x0106, 0x01}, + {0x0107, 0x00}, + {0x0108, 0x00}, + {0x0005, 0x01}, /* I/O Update */ + {0x0A02, 0x01}, /* Calibrate sysem clock */ + {0x0005, 0x01}, + {WAIT_B, 0x00}, + {0x0A02, 0x00}, + {0x0005, 0x01}, + {0x0208, 0x00}, /* IRQ Pin Output Mode */ + {0x0209, 0x00}, /* IRQ Masks */ + {0x020A, 0x00}, + {0x020B, 0x00}, + {0x020C, 0x00}, + {0x020D, 0x00}, + {0x020E, 0x00}, + {0x020F, 0x00}, + {0x0210, 0x00}, + {0x0211, 0x00}, /* Watchdog timer */ + {0x0212, 0x00}, + {0x0213, 0xFF}, /* Auxiliary DAC */ + {0x0214, 0x01}, + {0x0300, 0x29}, /* DPLL */ + {0x0301, 0x5C}, + {0x0302, 0x8F}, + {0x0303, 0xC2}, + {0x0304, 0xF5}, + {0x0305, 0x28}, + {0x0307, 0x00}, + {0x0308, 0x00}, + {0x0309, 0x00}, + {0x030A, 0xFF}, + {0x030B, 0xFF}, + {0x030C, 0xFF}, + {0x030D, 0x00}, + {0x030E, 0x00}, + {0x030F, 0x00}, + {0x0310, 0x00}, + {0x0311, 0x00}, + {0x0312, 0x00}, + {0x0313, 0x00}, + {0x0314, 0xE8}, + {0x0315, 0x03}, + {0x0316, 0x00}, + {0x0317, 0x00}, + {0x0318, 0x30}, + {0x0319, 0x75}, + {0x031A, 0x00}, + {0x031B, 0x00}, + {0x0306, 0x01}, /* Update TW */ + {0x0400, 0x0C}, /* Clock distribution output */ + {0x0401, 0x03}, + {0x0402, 0x00}, + {0x0403, 0x02}, + {0x0404, 0x04}, + {0x0405, 0x08}, + {0x0406, 0x03}, + {0x0407, 0x03}, + {0x0408, 0x03}, + {0x0409, 0x00}, + {0x040A, 0x00}, + {0x040B, 0x00}, + {0x040C, 0x03}, + {0x040D, 0x00}, + {0x040E, 0x00}, + {0x040F, 0x00}, + {0x0410, 0x00}, + {0x0411, 0x00}, + {0x0412, 0x00}, + {0x0413, 0x00}, + {0x0414, 0x00}, + {0x0415, 0x00}, + {0x0416, 0x00}, + {0x0417, 0x00}, + {0x0500, 0xFE}, /* Reference inputs */ + {0x0501, 0x00}, + {0x0502, 0x00}, + {0x0503, 0x08}, + {0x0504, 0x00}, + {0x0505, 0x00}, + {0x0506, 0x00}, + {0x0507, 0x00}, + {0x0600, 0x00}, /* Profiles are 0x0600-0x07FF */ + {0x0601, 0x55}, /* Profile 0 */ + {0x0602, 0xA0}, /* 30MHz input from FPGA, 122.880MHz output clock */ + {0x0603, 0xFC}, + {0x0604, 0x01}, + {0x0605, 0x00}, + {0x0606, 0x00}, + {0x0607, 0x00}, + {0x0608, 0xE8}, + {0x0609, 0x03}, + {0x060A, 0x00}, + {0x060B, 0xE8}, + {0x060C, 0x03}, + {0x060D, 0x00}, + {0x060E, 0x88}, + {0x060F, 0x13}, + {0x0610, 0x88}, + {0x0611, 0x13}, + {0x0612, 0x0E}, + {0x0613, 0xB2}, + {0x0614, 0x08}, + {0x0615, 0x82}, + {0x0616, 0x62}, + {0x0617, 0x42}, + {0x0618, 0xD8}, + {0x0619, 0x47}, + {0x061A, 0x21}, + {0x061B, 0xCB}, + {0x061C, 0xC4}, + {0x061D, 0x05}, + {0x061E, 0x7F}, + {0x061F, 0x00}, + {0x0620, 0x00}, + {0x0621, 0x00}, + {0x0622, 0x0B}, + {0x0623, 0x02}, + {0x0624, 0x00}, + {0x0625, 0x00}, + {0x0626, 0x26}, + {0x0627, 0xB0}, + {0x0628, 0x00}, + {0x0629, 0x10}, + {0x062A, 0x27}, + {0x062B, 0x20}, + {0x062C, 0x44}, + {0x062D, 0xF4}, + {0x062E, 0x01}, + {0x062F, 0x00}, + {0x0630, 0x20}, + {0x0631, 0x44}, + {0x0005, 0x01}, /* I/O Update */ + {0x0A0E, 0x01}, /* Force validation timeout */ + {0x0005, 0x01}, /* I/O Update */ + {0x0A02, 0x02}, /* Sync distribution */ + {0x0005, 0x01}, + {0x0A02, 0x00}, + {0x0005, 0x01}, +}; + +static int ad9548_read(struct spi_device *spi, unsigned reg) +{ + unsigned char buf[3]; + int ret; + u16 cmd; + + cmd = AD_READ | AD_CNT(1) | AD_ADDR(reg); + buf[0] = cmd >> 8; + buf[1] = cmd & 0xFF; + + + ret = spi_write_then_read(spi, &buf[0], 2, &buf[2], 1); + if (ret < 0) + return ret; + + return buf[2]; +} + +static int ad9548_write(struct spi_device *spi, + unsigned reg, unsigned val) +{ + unsigned char buf[3]; + int ret; + u16 cmd; + + cmd = AD_WRITE | AD_CNT(1) | AD_ADDR(reg); + buf[0] = cmd >> 8; + buf[1] = cmd & 0xFF; + buf[2] = val; + + ret = spi_write(spi, buf, 3); + if (ret < 0) + return ret; + + return 0; +} + +static int __devinit ad9548_probe(struct spi_device *spi) +{ + int i, ret, timeout; + + ret = ad9548_read(spi, 0x3); + if (ret < 0) + return ret; + if (ret != CHIPID_AD9548) { + dev_err(&spi->dev, "Unrecognized CHIP_ID 0x%X\n", ret); + return -ENODEV; + } + + for (i = 0; i < ARRAY_SIZE(ad9548_regs); i++) + switch (ad9548_regs[i][0]) { + case WAIT_B: + timeout = 100; + do { + ret = ad9548_read(spi, 0xD01); + if (ret < 0) + return ret; + if (ret & BIT(0)) + break; + mdelay(1); + } while (timeout--); + + if (timeout <= 0) + return -ETIMEDOUT; + break; + default: + ret = ad9548_write(spi, ad9548_regs[i][0], + ad9548_regs[i][1]); + if (ret < 0) + return ret; + break; + } + + spi_set_drvdata(spi, NULL); + dev_info(&spi->dev, "Rev. 0x%X probed\n", ad9548_read(spi, 0x2)); + + return 0; +} + +static int ad9548_remove(struct spi_device *spi) +{ + spi_set_drvdata(spi, NULL); + + return 0; +} + +static const struct spi_device_id ad9548_id[] = { + {"ad9548", 0}, + {} +}; +MODULE_DEVICE_TABLE(spi, ad9548_id); + +static struct spi_driver ad9548_driver = { + .driver = { + .name = "ad9548", + .owner = THIS_MODULE, + }, + .probe = ad9548_probe, + .remove = __devexit_p(ad9548_remove), + .id_table = ad9548_id, +}; +module_spi_driver(ad9548_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD9548"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c index e35bb8f6fe759..c7de8b5a01ff8 100644 --- a/drivers/iio/frequency/adf4350.c +++ b/drivers/iio/frequency/adf4350.c @@ -173,7 +173,7 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq) } while ((st->r1_mod > ADF4350_MAX_MODULUS) && r_cnt); } while (r_cnt == 0); - tmp = freq * (u64)st->r1_mod + (st->fpfd > 1); + tmp = freq * (u64)st->r1_mod + (st->fpfd >> 1); do_div(tmp, st->fpfd); /* Div round closest (n + d/2)/d */ st->r0_fract = do_div(tmp, st->r1_mod); st->r0_int = tmp; diff --git a/drivers/iio/frequency/cf_axi_dds.c b/drivers/iio/frequency/cf_axi_dds.c new file mode 100644 index 0000000000000..1200baa6f7a88 --- /dev/null +++ b/drivers/iio/frequency/cf_axi_dds.c @@ -0,0 +1,926 @@ +/* + * DDS PCORE/COREFPGA Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "cf_axi_dds.h" +#include "ad9122.h" + +#define DRIVER_NAME "cf_axi_dds" + +struct dds_spidev { + struct device_node *of_nspi; + struct device *dev_spi; +}; + +struct axi_dds_dma_params { + struct device_node *of_node; + int chan_id; +}; + +static bool cf_axi_dds_dma_filter(struct dma_chan *chan, void *param) +{ + struct axi_dds_dma_params *p = param; + + return chan->device->dev->of_node == p->of_node && + chan->chan_id == p->chan_id; +} + +static void cf_axi_dds_sync_frame(struct cf_axi_dds_state *st) { + dds_write(st, CF_AXI_DDS_FRAME, 0); + dds_write(st, CF_AXI_DDS_FRAME, CF_AXI_DDS_FRAME_SYNC); +} + +void cf_axi_dds_stop(struct cf_axi_dds_state *st) { + dds_write(st, CF_AXI_DDS_CTRL, (st->vers_id > 1) ? + CF_AXI_DDS_CTRL_DDS_CLK_EN_V2 : CF_AXI_DDS_CTRL_DDS_CLK_EN_V1); +} + +static u32 cf_axi_dds_calc(u32 phase, u32 freq, u32 dac_clk) { + + unsigned long long val64; + u32 val; + + val64 = (u64) freq * 0xFFFFULL; + do_div(val64, dac_clk); + val = ((val64 & 0xFFFF) | 1); + + val64 = (u64) phase * 0xFFFFULL; + do_div(val64, 360000); + val |= val64 << 16; + + return val; +} + +struct cf_axi_dds_sed { + unsigned short i0; + unsigned short q0; + unsigned short i1; + unsigned short q1; +}; + +static struct cf_axi_dds_sed dac_sed_pattern[5] = { + { + .i0 = 0x5555, + .q0 = 0xAAAA, + .i1 = 0xAAAA, + .q1 = 0x5555, + }, + { + .i0 = 0, + .q0 = 0, + .i1 = 0xFFFF, + .q1 = 0xFFFF, + }, + { + .i0 = 0, + .q0 = 0, + .i1 = 0, + .q1 = 0, + }, + { + .i0 = 0xFFFF, + .q0 = 0xFFFF, + .i1 = 0xFFFF, + .q1 = 0xFFFF, + }, + { + .i0 = 0x1248, + .q0 = 0xEDC7, + .i1 = 0xEDC7, + .q1 = 0x1248, + } +}; + +static int cf_axi_dds_find_dci(unsigned long *err_field, unsigned entries) +{ + int dci, cnt, start, max_start, max_cnt; + char str[33]; + int ret; + + for(dci = 0, cnt = 0, max_cnt = 0, start = -1, max_start = 0; + dci < entries; dci++) { + if (test_bit(dci, err_field) == 0) { + if (start == -1) + start = dci; + cnt++; + str[dci] = 'o'; + } else { + if (cnt > max_cnt) { + max_cnt = cnt; + max_start = start; + } + start = -1; + cnt = 0; + str[dci] = '-'; + } + } + str[dci] = 0; + + if (cnt > max_cnt) { + max_cnt = cnt; + max_start = start; + } + + + ret = max_start + ((max_cnt - 1) / 2); + + str[ret] = '|'; + + printk("%s DCI %d\n",str, ret); + + return ret; +} + +static int cf_axi_dds_tune_dci(struct cf_axi_dds_state *st) +{ + struct cf_axi_dds_converter *conv = to_converter(st->dev_spi); + unsigned reg, err_mask; + int i = 0, dci; + unsigned long err_bfield = 0; + + for (dci = 0; dci < 4; dci++) { + conv->write(conv->spi, AD9122_REG_DCI_DELAY, dci); + for (i = 0; i < ARRAY_SIZE(dac_sed_pattern); i++) { + + conv->write(conv->spi, AD9122_REG_SED_CTRL, 0); + + dds_write(st, CF_AXI_DDS_PAT_DATA1, + (dac_sed_pattern[i].i1 << 16) | + dac_sed_pattern[i].i0); + dds_write(st, CF_AXI_DDS_PAT_DATA2, + (dac_sed_pattern[i].q1 << 16) | + dac_sed_pattern[i].q0); + + dds_write(st, CF_AXI_DDS_CTRL, 0); + dds_write(st, CF_AXI_DDS_CTRL, CF_AXI_DDS_CTRL_DDS_CLK_EN_V2 | + CF_AXI_DDS_CTRL_PATTERN_EN); + dds_write(st, CF_AXI_DDS_CTRL, CF_AXI_DDS_CTRL_DDS_CLK_EN_V2 | + CF_AXI_DDS_CTRL_PATTERN_EN | CF_AXI_DDS_CTRL_DATA_EN); + + conv->write(conv->spi, AD9122_REG_COMPARE_I0_LSBS, + dac_sed_pattern[i].i0 & 0xFF); + conv->write(conv->spi, AD9122_REG_COMPARE_I0_MSBS, + dac_sed_pattern[i].i0 >> 8); + + conv->write(conv->spi, AD9122_REG_COMPARE_Q0_LSBS, + dac_sed_pattern[i].q0 & 0xFF); + conv->write(conv->spi, AD9122_REG_COMPARE_Q0_MSBS, + dac_sed_pattern[i].q0 >> 8); + + conv->write(conv->spi, AD9122_REG_COMPARE_I1_LSBS, + dac_sed_pattern[i].i1 & 0xFF); + conv->write(conv->spi, AD9122_REG_COMPARE_I1_MSBS, + dac_sed_pattern[i].i1 >> 8); + + conv->write(conv->spi, AD9122_REG_COMPARE_Q1_LSBS, + dac_sed_pattern[i].q1 & 0xFF); + conv->write(conv->spi, AD9122_REG_COMPARE_Q1_MSBS, + dac_sed_pattern[i].q1 >> 8); + + + conv->write(conv->spi, AD9122_REG_SED_CTRL, + AD9122_SED_CTRL_SED_COMPARE_EN); + + conv->write(conv->spi, AD9122_REG_EVENT_FLAG_2, + AD9122_EVENT_FLAG_2_AED_COMPARE_PASS | + AD9122_EVENT_FLAG_2_AED_COMPARE_FAIL | + AD9122_EVENT_FLAG_2_SED_COMPARE_FAIL); + + conv->write(conv->spi, AD9122_REG_SED_CTRL, + AD9122_SED_CTRL_SED_COMPARE_EN); + + msleep(100); + reg = conv->read(conv->spi, AD9122_REG_SED_CTRL); + err_mask = conv->read(conv->spi, AD9122_REG_SED_I_LSBS); + err_mask |= conv->read(conv->spi, AD9122_REG_SED_I_MSBS); + err_mask |= conv->read(conv->spi, AD9122_REG_SED_Q_LSBS); + err_mask |= conv->read(conv->spi, AD9122_REG_SED_Q_MSBS); + + if (err_mask || (reg & AD9122_SED_CTRL_SAMPLE_ERR_DETECTED)) + set_bit(dci, &err_bfield); + } + } + + conv->write(conv->spi, AD9122_REG_DCI_DELAY, + cf_axi_dds_find_dci(&err_bfield, 4)); + conv->write(conv->spi, AD9122_REG_SED_CTRL, 0); + dds_write(st, CF_AXI_DDS_CTRL, 0); + + return 0; +} + +static const int cf_axi_dds_scale_table[16] = { + 10000, 5000, 2500, 1250, 625, 313, 156, +}; + +static int cf_axi_dds_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + struct cf_axi_dds_state *st = iio_priv(indio_dev); + unsigned long long val64; + unsigned reg; + + switch (m) { + case 0: + if (!chan->output) { + return -EINVAL; + } + reg = dds_read(st, CF_AXI_DDS_CTRL); + if (st->vers_id > 1) { + if (reg & CF_AXI_DDS_CTRL_DATA_EN) + *val = 1; + else + *val = 0; + + } else { + if (reg & (1 << (chan->channel * 2))) + *val = 1; + else + *val = 0; + } + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + reg = dds_read(st, CF_AXI_DDS_SCALE); + reg = (reg >> (chan->channel * 4)) & 0xF; + if (!reg) { + *val = 1; + *val2 = 0; + } else { + *val = 0; + *val2 = 1000000 >> reg; + } + return IIO_VAL_INT_PLUS_MICRO; + case IIO_CHAN_INFO_FREQUENCY: + if (!chan->output) { + *val = st->dac_clk; + return IIO_VAL_INT; + } + reg = dds_read(st, chan->address); + val64 = (u64)(reg & 0xFFFF) * (u64)st->dac_clk; + do_div(val64, 0xFFFF); + *val = val64; + return IIO_VAL_INT; + case IIO_CHAN_INFO_PHASE: + reg = dds_read(st, chan->address); + val64 = (u64)(reg >> 16) * 360000ULL; + do_div(val64, 0xFFFF); + *val = val64; + return IIO_VAL_INT; + } + return -EINVAL; +} + +static int cf_axi_dds_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct cf_axi_dds_state *st = iio_priv(indio_dev); + unsigned long long val64; + unsigned reg, ctrl_reg; + int i; + + ctrl_reg = dds_read(st, CF_AXI_DDS_CTRL); + + switch (mask) { + case 0: + if (!chan->output) { + return -EINVAL; + } + + if (st->vers_id > 1) { + if (val) + ctrl_reg |= (CF_AXI_DDS_CTRL_DATA_EN | + CF_AXI_DDS_CTRL_DDS_CLK_EN_V2); + else + ctrl_reg &= ~(CF_AXI_DDS_CTRL_DATA_EN); + } else { + if (val) + ctrl_reg |= 1 << (chan->channel * 2); + else + ctrl_reg &= ~(1 << (chan->channel * 2)); + } + + dds_write(st, CF_AXI_DDS_CTRL, ctrl_reg); + break; + case IIO_CHAN_INFO_SCALE: + if (val == 1) { + i = 0; + } else { + for (i = 1; i < 16; i++) + if (val2 == (1000000 >> i)) + break; + } + cf_axi_dds_stop(st); + reg = dds_read(st, CF_AXI_DDS_SCALE); + + reg &= ~(0xF << (chan->channel * 4)); + reg |= (i << (chan->channel * 4)); + dds_write(st, CF_AXI_DDS_SCALE, reg); + dds_write(st, CF_AXI_DDS_CTRL, ctrl_reg); + break; + case IIO_CHAN_INFO_FREQUENCY: + if (!chan->output) { + st->dac_clk = val; + break; + } + if (val > (st->dac_clk / 2)) + return -EINVAL; + cf_axi_dds_stop(st); + reg = dds_read(st, chan->address); + reg &= 0xFFFF0000; + val64 = (u64) val * 0xFFFFULL; + do_div(val64, st->dac_clk); + reg |= (val64 & 0xFFFF) | 1; + dds_write(st, chan->address, reg); + dds_write(st, CF_AXI_DDS_CTRL, ctrl_reg); + break; + case IIO_CHAN_INFO_PHASE: + if (val < 0 || val > 360000) + return -EINVAL; + cf_axi_dds_stop(st); + reg = dds_read(st, chan->address); + reg &= 0x0000FFFF; + val64 = (u64) val * 0xFFFFULL; + do_div(val64, 360000); + reg |= val64 << 16; + dds_write(st, chan->address, reg); + dds_write(st, CF_AXI_DDS_CTRL, ctrl_reg); + break; + default: + return -EINVAL; + } +// cf_axi_dds_sync_frame(st); + + return 0; +} + +static int cf_axi_dds_reg_access(struct iio_dev *indio_dev, + unsigned reg, unsigned writeval, + unsigned *readval) +{ + struct cf_axi_dds_state *st = iio_priv(indio_dev); + struct cf_axi_dds_converter *conv = to_converter(st->dev_spi); + int ret; + + if (IS_ERR(conv)) + return PTR_ERR(conv); + + if ((reg & ~DEBUGFS_DRA_PCORE_REG_MAGIC) > 0xFF) + return -EINVAL; + + mutex_lock(&indio_dev->mlock); + if (readval == NULL) { + if (reg & DEBUGFS_DRA_PCORE_REG_MAGIC) { + dds_write(st, reg & 0xFFFF, writeval); + ret = 0; + } else { + ret = conv->write(conv->spi, reg, writeval & 0xFF); + } + } else { + if (reg & DEBUGFS_DRA_PCORE_REG_MAGIC) { + ret = dds_read(st, reg & 0xFFFF); + } else { + ret = conv->read(conv->spi, reg); + if (ret < 0) + return ret; + } + *readval = ret; + ret = 0; + + } + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t ad9122_dds_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct cf_axi_dds_state *st = iio_priv(indio_dev); + struct cf_axi_dds_converter *conv = to_converter(st->dev_spi); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + long readin; + int ret; + + ret = kstrtol(buf, 10, &readin); + if (ret) + return ret; + + mutex_lock(&indio_dev->mlock); + + switch ((u32)this_attr->address) { + case AD9122_REG_I_DAC_OFFSET_MSB: + case AD9122_REG_Q_DAC_OFFSET_MSB: + if (readin < 0 || readin > 0xFFFF) { + ret = -EINVAL; + goto out; + } + break; + case AD9122_REG_I_PHA_ADJ_MSB: + case AD9122_REG_Q_PHA_ADJ_MSB: + if (readin < -512 || readin > 511) { + ret = -EINVAL; + goto out; + } + break; + default: + if (readin < 0 || readin > 0x3FF) { + ret = -EINVAL; + goto out; + } + break; + } + + ret = conv->write(conv->spi, (u32)this_attr->address, readin >> 8); + if (ret < 0) + goto out; + + ret = conv->write(conv->spi, (u32)this_attr->address - 1, readin & 0xFF); + if (ret < 0) + goto out; + +out: + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static ssize_t ad9122_dds_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct cf_axi_dds_state *st = iio_priv(indio_dev); + struct cf_axi_dds_converter *conv = to_converter(st->dev_spi); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret = 0; + unsigned val; + + mutex_lock(&indio_dev->mlock); + ret = conv->read(conv->spi, (u32)this_attr->address); + if (ret < 0) + goto out; + val = ret << 8; + + ret = conv->read(conv->spi, (u32)this_attr->address - 1); + if (ret < 0) + goto out; + val |= ret & 0xFF; + + switch ((u32)this_attr->address) { + case AD9122_REG_I_PHA_ADJ_MSB: + case AD9122_REG_Q_PHA_ADJ_MSB: + val = sign_extend32(val, 9); + break; + } + + ret = sprintf(buf, "%d\n", val); +out: + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t ad9122_dds_interpolation_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct cf_axi_dds_state *st = iio_priv(indio_dev); + long readin; + int ret; + + ret = kstrtol(buf, 10, &readin); + if (ret) + return ret; + + mutex_lock(&indio_dev->mlock); + + switch (readin) { + case 1: + st->ddr_dds_interp_en = 0; + break; + case 3: + st->ddr_dds_interp_en = CF_AXI_DDS_CTRL_INTERPOLATE; + break; + default: + ret = -EINVAL; + } + + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static ssize_t ad9122_dds_interpolation_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct cf_axi_dds_state *st = iio_priv(indio_dev); + int ret = 0; + + mutex_lock(&indio_dev->mlock); + ret = sprintf(buf, "%d\n", st->ddr_dds_interp_en ? 3 : 1); + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static IIO_DEVICE_ATTR(out_voltage0_phase, S_IRUGO | S_IWUSR, + ad9122_dds_show, + ad9122_dds_store, + AD9122_REG_I_PHA_ADJ_MSB); + +static IIO_DEVICE_ATTR(out_voltage1_phase, S_IRUGO | S_IWUSR, + ad9122_dds_show, + ad9122_dds_store, + AD9122_REG_Q_PHA_ADJ_MSB); + +static IIO_DEVICE_ATTR(out_voltage0_calibbias, S_IRUGO | S_IWUSR, + ad9122_dds_show, + ad9122_dds_store, + AD9122_REG_I_DAC_OFFSET_MSB); + +static IIO_DEVICE_ATTR(out_voltage1_calibbias, S_IRUGO | S_IWUSR, + ad9122_dds_show, + ad9122_dds_store, + AD9122_REG_Q_DAC_OFFSET_MSB); + +static IIO_DEVICE_ATTR(out_voltage0_calibscale, S_IRUGO | S_IWUSR, + ad9122_dds_show, + ad9122_dds_store, + AD9122_REG_I_DAC_CTRL); + +static IIO_DEVICE_ATTR(out_voltage1_calibscale, S_IRUGO | S_IWUSR, + ad9122_dds_show, + ad9122_dds_store, + AD9122_REG_Q_DAC_CTRL); + +static IIO_DEVICE_ATTR(out_altvoltage_interpolation, S_IRUGO | S_IWUSR, + ad9122_dds_interpolation_show, + ad9122_dds_interpolation_store, + 0); + + +static IIO_CONST_ATTR(out_altvoltage_scale_available, + "1.000000 0.500000 0.250000 0.125000 ..."); + +static IIO_CONST_ATTR(out_altvoltage_interpolation_available, + "1 3"); + +static struct attribute *cf_axi_dds_attributes[] = { + &iio_dev_attr_out_voltage0_phase.dev_attr.attr, /* I */ + &iio_dev_attr_out_voltage0_calibscale.dev_attr.attr, + &iio_dev_attr_out_voltage0_calibbias.dev_attr.attr, + &iio_dev_attr_out_voltage1_phase.dev_attr.attr, /* Q */ + &iio_dev_attr_out_voltage1_calibscale.dev_attr.attr, + &iio_dev_attr_out_voltage1_calibbias.dev_attr.attr, + &iio_const_attr_out_altvoltage_scale_available.dev_attr.attr, + &iio_dev_attr_out_altvoltage_interpolation.dev_attr.attr, + &iio_const_attr_out_altvoltage_interpolation_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group cf_axi_dds_attribute_group = { + .attrs = cf_axi_dds_attributes, +}; + +#define CF_AXI_DDS_CHAN(_chan, _address, _extend_name) \ + { .type = IIO_ALTVOLTAGE, \ + .indexed = 1, \ + .channel = _chan, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ + IIO_CHAN_INFO_PHASE_SEPARATE_BIT | \ + IIO_CHAN_INFO_FREQUENCY_SEPARATE_BIT, \ + .address = _address, \ + .output = 1, \ + .extend_name = _extend_name, \ + } + +#define CF_AXI_DDS_CHAN_CLK_IN(_chan, _extend_name) \ + { .type = IIO_ALTVOLTAGE, \ + .indexed = 1, \ + .channel = _chan, \ + .info_mask = IIO_CHAN_INFO_FREQUENCY_SEPARATE_BIT, \ + .extend_name = _extend_name, \ + } + +#define CF_AXI_DDS_CHAN_BUF(_chan) \ + { .type = IIO_ALTVOLTAGE, \ + .indexed = 1, \ + .channel = _chan, \ + .info_mask = 0, \ + .output = 1, \ + .scan_index = _chan, \ + .scan_type = IIO_ST('s', 16, 16, 0), \ +} + +static const struct cf_axi_dds_chip_info cf_axi_dds_chip_info_tbl[] = { + [ID_AD9122] = { + .name = "AD9122", + .channel[0] = CF_AXI_DDS_CHAN(0, CF_AXI_DDS_1A_OUTPUT_CTRL, "1A"), + .channel[1] = CF_AXI_DDS_CHAN(1, CF_AXI_DDS_1B_OUTPUT_CTRL, "1B"), + .channel[2] = CF_AXI_DDS_CHAN(2, CF_AXI_DDS_2A_OUTPUT_CTRL, "2A"), + .channel[3] = CF_AXI_DDS_CHAN(3, CF_AXI_DDS_2B_OUTPUT_CTRL, "2B"), + .channel[4] = CF_AXI_DDS_CHAN_CLK_IN(0, "DAC_CLK"), + .buf_channel[0] = CF_AXI_DDS_CHAN_BUF(0), + .buf_channel[1] = CF_AXI_DDS_CHAN_BUF(1), + }, + [ID_AD9739A] = { + .name = "AD9739A", + .channel[0] = CF_AXI_DDS_CHAN(0, CF_AXI_DDS_1A_OUTPUT_CTRL, "1A"), + .channel[1] = CF_AXI_DDS_CHAN(1, CF_AXI_DDS_1B_OUTPUT_CTRL, "1B"), + .channel[2] = CF_AXI_DDS_CHAN(2, CF_AXI_DDS_2A_OUTPUT_CTRL, "2A"), + .channel[3] = CF_AXI_DDS_CHAN(3, CF_AXI_DDS_2B_OUTPUT_CTRL, "2B"), + .channel[4] = CF_AXI_DDS_CHAN_CLK_IN(0, "DAC_CLK"), + .buf_channel[0] = CF_AXI_DDS_CHAN_BUF(0), + .buf_channel[1] = CF_AXI_DDS_CHAN_BUF(1), + }, +}; + +static const struct iio_info cf_axi_dds_info = { + .driver_module = THIS_MODULE, + .read_raw = &cf_axi_dds_read_raw, + .write_raw = &cf_axi_dds_write_raw, + .debugfs_reg_access = &cf_axi_dds_reg_access, + .attrs = &cf_axi_dds_attribute_group, +}; + +static int dds_attach_spi_client(struct device *dev, void *data) +{ + struct dds_spidev *dds_spidev = data; + + if ((dds_spidev->of_nspi == dev->of_node) && dev->driver) { + dds_spidev->dev_spi = dev; + return 1; + } + + return 0; +} + +/* Match table for of_platform binding */ +static const struct of_device_id cf_axi_dds_of_match[] __devinitconst = { + { .compatible = "xlnx,cf-ad9122-core-1.00.a", .data = (void*) 1}, + { .compatible = "xlnx,cf-ad9739a-core-1.00.a", .data = (void*) 1}, + { .compatible = "xlnx,cf-ad9122x2-core-1.00.a", .data = (void*) 1}, + { .compatible = "xlnx,cf-ad9122-core-2.00.a", .data = (void*) 2}, + { .compatible = "xlnx,axi-dac-4d-2c-1.00.a", .data = (void*) 2}, +{ /* end of list */ }, +}; +MODULE_DEVICE_TABLE(of, cf_axi_dds_of_match); + +static int __devinit cf_axi_dds_of_probe(struct platform_device *op) +{ + struct cf_axi_dds_state *st; + struct iio_dev *indio_dev; + struct device *dev = &op->dev; + resource_size_t remap_size, phys_addr; + struct dds_spidev dds_spidev; + struct cf_axi_dds_converter *conv; + struct axi_dds_dma_params dma_params; + struct of_phandle_args dma_spec; + dma_cap_mask_t mask; + int ret; + + const struct of_device_id *of_id = + of_match_device(cf_axi_dds_of_match, &op->dev); + + dev_info(dev, "Device Tree Probing \'%s\'\n", + op->dev.of_node->name); + + /* Defer driver probe until matching spi + * converter driver is registered + */ + dds_spidev.of_nspi = of_parse_phandle(op->dev.of_node, + "spibus-connected", 0); + if (!dds_spidev.of_nspi) { + dev_err(&op->dev, "could not find spi node\n"); + return -ENODEV; + } + + ret = bus_for_each_dev(&spi_bus_type, NULL, &dds_spidev, + dds_attach_spi_client); + if (ret == 0) + return -EPROBE_DEFER; + + if (!try_module_get(dds_spidev.dev_spi->driver->owner)) + return -ENODEV; + get_device(dds_spidev.dev_spi); + + indio_dev = iio_device_alloc(sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + st->dev_spi = dds_spidev.dev_spi; + + dev_set_drvdata(dev, indio_dev); + + if (of_id && of_id->data) + st->vers_id = (unsigned) of_id->data; + else + goto failed1; + + /* Get iospace for the device */ + ret = of_address_to_resource(op->dev.of_node, 0, &st->r_mem); + if (ret) { + dev_err(dev, "invalid address\n"); + goto failed1; + } + + phys_addr = st->r_mem.start; + remap_size = resource_size(&st->r_mem); + if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) { + dev_err(dev, "Couldn't lock memory region at 0x%08llX\n", + (unsigned long long)phys_addr); + ret = -EBUSY; + goto failed1; + } + + /* Fill in configuration data and add them to the list */ + st->regs = ioremap(phys_addr, remap_size); + if (st->regs == NULL) { + dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n", + (unsigned long long)phys_addr); + ret = -EFAULT; + goto failed2; + } + + ret = of_property_read_u32(op->dev.of_node, + "dac-sample-frequency", + &st->dac_clk); + if (ret) + st->dac_clk = 491520000; + + conv = to_converter(st->dev_spi); + if (IS_ERR(conv)) { + ret = PTR_ERR(conv); + goto failed3; + } + + ret = conv->setup(conv->spi, 0); + if (ret) { + dev_err(&op->dev, "failed to setup spi device\n"); + goto failed3; + } + + st->chip_info = &cf_axi_dds_chip_info_tbl[conv->id]; + + indio_dev->dev.parent = dev; + indio_dev->name = op->dev.of_node->name; + indio_dev->channels = st->chip_info->channel; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->num_channels = 5; + indio_dev->info = &cf_axi_dds_info; + + cf_axi_dds_tune_dci(st); + + dds_write(st, CF_AXI_DDS_INTERPOL_CTRL, 0x2aaa5555); /* Lin. Interp. */ + + dds_write(st, CF_AXI_DDS_CTRL, 0x0); + dds_write(st, CF_AXI_DDS_SCALE, 0x1111); /* divide by 4 */ + dds_write(st, CF_AXI_DDS_1A_OUTPUT_CTRL, + cf_axi_dds_calc(90000, 40000000, st->dac_clk)); + dds_write(st, CF_AXI_DDS_1B_OUTPUT_CTRL, + cf_axi_dds_calc(90000, 40000000, st->dac_clk)); + dds_write(st, CF_AXI_DDS_2A_OUTPUT_CTRL, + cf_axi_dds_calc( 0, 40000000, st->dac_clk)); + dds_write(st, CF_AXI_DDS_2B_OUTPUT_CTRL, + cf_axi_dds_calc( 0, 40000000, st->dac_clk)); + + if (st->vers_id > 1) + dds_write(st, CF_AXI_DDS_CTRL, CF_AXI_DDS_CTRL_DATA_EN | + CF_AXI_DDS_CTRL_DDS_CLK_EN_V2); /* clk, dds enable & ddsx select */ + else + dds_write(st, CF_AXI_DDS_CTRL, 0x1ff); /* clk, dds enable & ddsx select */ + + cf_axi_dds_sync_frame(st); + + ret = of_parse_phandle_with_args(op->dev.of_node, "dma-request", + "#dma-cells", 0, &dma_spec); + if (ret) { + dev_warn(dev, "Couldn't parse dma-request\n"); + goto skip_writebuf; + } + + dma_params.of_node = dma_spec.np; + dma_params.chan_id = dma_spec.args[0]; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE | DMA_PRIVATE, mask); + + st->tx_chan = dma_request_channel(mask, cf_axi_dds_dma_filter, &dma_params); + if (!st->tx_chan) { + dev_err(dev, "failed to find vdma device\n"); + goto failed3; + } + + cf_axi_dds_configure_buffer(indio_dev); + + ret = iio_buffer_register(indio_dev, + st->chip_info->buf_channel, 2); + if (ret) + goto failed3; + +skip_writebuf: + ret = iio_device_register(indio_dev); + if (ret) + goto failed3; + + dev_info(dev, "Analog Devices CF_AXI_DDS_DDS %s (0x%X) at 0x%08llX mapped" + " to 0x%p, probed DDS %s\n", + (dds_read(st, CF_AXI_DDS_PCORE_IDENT) & + CF_AXI_DDS_PCORE_IDENT_SLAVE) ? "SLAVE" : "MASTER", + dds_read(st, CF_AXI_DDS_VERSION_ID), + (unsigned long long)phys_addr, st->regs, st->chip_info->name); + + return 0; /* success */ + +failed3: + iounmap(st->regs); +failed2: + release_mem_region(phys_addr, remap_size); +failed1: + put_device(st->dev_spi); + module_put(st->dev_spi->driver->owner); + dev_set_drvdata(dev, NULL); + iio_device_free(indio_dev); + + return ret; +} + +static int __devexit cf_axi_dds_of_remove(struct platform_device *op) +{ + struct device *dev = &op->dev; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct cf_axi_dds_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + put_device(st->dev_spi); + module_put(st->dev_spi->driver->owner); + iounmap(st->regs); + release_mem_region(st->r_mem.start, resource_size(&st->r_mem)); + + if (st->tx_chan == NULL) { + cf_axi_dds_unconfigure_buffer(indio_dev); + dma_release_channel(st->tx_chan); + } + + iio_device_free(indio_dev); + dev_set_drvdata(dev, NULL); + + return 0; +} + +static struct platform_driver cf_axi_dds_of_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = cf_axi_dds_of_match, + }, + .probe = cf_axi_dds_of_probe, + .remove = __devexit_p(cf_axi_dds_of_remove), +}; + +module_platform_driver(cf_axi_dds_of_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices DDS"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/frequency/cf_axi_dds.h b/drivers/iio/frequency/cf_axi_dds.h new file mode 100644 index 0000000000000..78179ab68e8fe --- /dev/null +++ b/drivers/iio/frequency/cf_axi_dds.h @@ -0,0 +1,119 @@ +/* + * DDS PCORE/COREFPGA Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#ifndef ADI_AXI_DDS_H_ +#define ADI_AXI_DDS_H_ + +#define CF_AXI_DDS_VERSION_ID 0x00 +#define CF_AXI_DDS_CTRL 0x04 +#define CF_AXI_DDS_1A_OUTPUT_CTRL 0x08 +#define CF_AXI_DDS_1B_OUTPUT_CTRL 0x0C +#define CF_AXI_DDS_2A_OUTPUT_CTRL 0x10 +#define CF_AXI_DDS_2B_OUTPUT_CTRL 0x14 +#define CF_AXI_DDS_INTERPOL_CTRL 0x18 +#define CF_AXI_DDS_SCALE 0x20 +#define CF_AXI_DDS_FRAME 0x24 +#define CF_AXI_DDS_DMA_STAT 0x28 +#define CF_AXI_DDS_PAT_DATA1 0x40 +#define CF_AXI_DDS_PAT_DATA2 0x44 +#define CF_AXI_DDS_PCORE_IDENT 0x48 + +/* CF_AXI_DDS_CTRL */ +#define CF_AXI_DDS_CTRL_PATTERN_EN (1 << 4) +#define CF_AXI_DDS_CTRL_INTERPOLATE (1 << 3) +#define CF_AXI_DDS_CTRL_DDS_SEL (1 << 2) +#define CF_AXI_DDS_CTRL_DATA_EN (1 << 1) +#define CF_AXI_DDS_CTRL_DDS_CLK_EN_V1 (1 << 8) +#define CF_AXI_DDS_CTRL_DDS_CLK_EN_V2 (1 << 0) + +/* CF_AXI_DDS_FRAME */ +#define CF_AXI_DDS_FRAME_SYNC 0x1 + +/* CF_AXI_DDS_PCORE_IDENT */ +#define CF_AXI_DDS_PCORE_IDENT_SLAVE 0x1 + +/* CF_AXI_DDS_DMA_STAT W1C */ +#define CF_AXI_DDS_DMA_STAT_OVF (1 << 0) +#define CF_AXI_DDS_DMA_STAT_UNF (1 << 1) + +#define AXIDDS_MAX_DMA_SIZE (4 * 1024 * 1024) /* Randomly picked */ + +/* debugfs direct register access */ +#define DEBUGFS_DRA_PCORE_REG_MAGIC 0x80000000 + +enum { + ID_AD9122, + ID_AD9739A, +}; + +struct cf_axi_dds_chip_info { + char name[8]; + struct iio_chan_spec channel[5]; + struct iio_chan_spec buf_channel[2]; +}; + +#include + +struct cf_axi_dds_state { + struct list_head list; + struct device *dev_spi; + struct resource r_mem; /* IO mem resources */ + const struct cf_axi_dds_chip_info *chip_info; + void *buf_virt; + dma_addr_t buf_phys; + struct dma_chan *tx_chan; + struct xilinx_dma_config dma_config; + u16 int_vref_mv; + int irq; + void __iomem *regs; + unsigned int flags; + u32 dac_clk; + unsigned vers_id; + unsigned buffer_lenght; + unsigned txcount; + unsigned ddr_dds_interp_en; +}; + +struct cf_axi_dds_converter { + struct spi_device *spi; + unsigned id; + int (*read)(struct spi_device *spi, unsigned reg); + int (*write)(struct spi_device *spi, + unsigned reg, unsigned val); + int (*setup)(struct spi_device *spi, unsigned mode); +}; + +static inline struct cf_axi_dds_converter *to_converter(struct device *dev) +{ + struct cf_axi_dds_converter *conv = spi_get_drvdata(to_spi_device(dev)); + + if (conv) + return conv; + + return ERR_PTR(-ENODEV); +}; + +int cf_axi_dds_configure_buffer(struct iio_dev *indio_dev); +void cf_axi_dds_unconfigure_buffer(struct iio_dev *indio_dev); +void cf_axi_dds_stop(struct cf_axi_dds_state *st); + +/* + * IO accessors + */ + +static inline void dds_write(struct cf_axi_dds_state *st, + unsigned reg, unsigned val) +{ + iowrite32(val, st->regs + reg); +} + +static inline unsigned int dds_read(struct cf_axi_dds_state *st, unsigned reg) +{ + return ioread32(st->regs + reg); +} +#endif /* ADI_AXI_DDS_H_ */ diff --git a/drivers/iio/frequency/cf_axi_dds_buffer.c b/drivers/iio/frequency/cf_axi_dds_buffer.c new file mode 100644 index 0000000000000..c978491ea7921 --- /dev/null +++ b/drivers/iio/frequency/cf_axi_dds_buffer.c @@ -0,0 +1,251 @@ +/* + * DDS PCORE/COREFPGA Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "../../staging/iio/ring_hw.h" +#include "cf_axi_dds.h" + +#define VDMA_MAX_HSIZE 0xFFFF +#define VDMA_MAX_VSIZE 0xFFF + + +static int __cf_axi_dds_hw_buffer_state_set(struct iio_dev *indio_dev, bool state); + +static int cf_axi_dds_write_buffer(struct iio_buffer *r, + size_t count, const char __user *buf) +{ + struct iio_hw_buffer *hw_buffer = iio_to_hw_buf(r); + struct iio_dev *indio_dev = hw_buffer->private; + struct cf_axi_dds_state *st = iio_priv(indio_dev); + int ret = 0; + + if (PAGE_ALIGN(count) > AXIDDS_MAX_DMA_SIZE || count % 8) { + ret = -EINVAL; + goto error_ret; + } + + mutex_lock(&indio_dev->mlock); + + if (copy_from_user (st->buf_virt, buf, count)) + ret = -EFAULT; + + st->txcount = count; + st->buffer_lenght = count / 4; + + if (iio_buffer_enabled(indio_dev)) { + dmaengine_terminate_all(st->tx_chan); + __cf_axi_dds_hw_buffer_state_set(indio_dev, 1); + } + + mutex_unlock(&indio_dev->mlock); + +error_ret: + + return ret < 0 ? ret : count; +} + +static int cf_axi_dds_buffer_get_length(struct iio_buffer *r) +{ + struct iio_hw_buffer *hw_buffer = iio_to_hw_buf(r); + struct iio_dev *indio_dev = hw_buffer->private; + struct cf_axi_dds_state *st = iio_priv(indio_dev); + + return st->buffer_lenght; +} + +static int cf_axi_dds_buffer_set_length(struct iio_buffer *r, int lenght) +{ + struct iio_hw_buffer *hw_buffer = iio_to_hw_buf(r); + struct cf_axi_dds_state *st = iio_priv(hw_buffer->private); + + st->buffer_lenght = lenght; + + return 0; +} + +static int cf_axi_dds_buffer_get_bytes_per_datum(struct iio_buffer *r) +{ + return r->bytes_per_datum; +} + +static IIO_BUFFER_ENABLE_ATTR; +static IIO_BUFFER_LENGTH_ATTR; + +static struct attribute *cf_axi_dds_buffer_attributes[] = { + &dev_attr_length.attr, + &dev_attr_enable.attr, + NULL, +}; + +static struct attribute_group cf_axi_dds_buffer_attr = { + .attrs = cf_axi_dds_buffer_attributes, + .name = "buffer", +}; + +static struct iio_buffer *cf_axi_dds_rb_allocate(struct iio_dev *indio_dev) +{ + struct iio_buffer *buf; + struct iio_hw_buffer *ring; + + ring = kzalloc(sizeof *ring, GFP_KERNEL); + if (!ring) + return NULL; + + ring->private = indio_dev; + buf = &ring->buf; + buf->attrs = &cf_axi_dds_buffer_attr; + iio_buffer_init(buf); + + return buf; +} + +static inline void cf_axi_dds_rb_free(struct iio_buffer *r) +{ + kfree(iio_to_hw_buf(r)); +} + +static const struct iio_buffer_access_funcs cf_axi_dds_buffer_access_funcs = { + .write = &cf_axi_dds_write_buffer, + .get_length = &cf_axi_dds_buffer_get_length, + .set_length = &cf_axi_dds_buffer_set_length, + .get_bytes_per_datum = &cf_axi_dds_buffer_get_bytes_per_datum, +}; + +static int __cf_axi_dds_hw_buffer_state_set(struct iio_dev *indio_dev, bool state) +{ + struct cf_axi_dds_state *st = iio_priv(indio_dev); + struct dma_async_tx_descriptor *desc; + unsigned tmp_reg, x; + +#if 0 + tmp_reg = dds_read(st, CF_AXI_DDS_DMA_STAT); + if (tmp_reg & (CF_AXI_DDS_DMA_STAT_OVF | CF_AXI_DDS_DMA_STAT_UNF)) + dev_warn(indio_dev->dev.parent, "VDMA Status: %s %s\n", + (tmp_reg & CF_AXI_DDS_DMA_STAT_OVF) ? "overflow" : "", + (tmp_reg & CF_AXI_DDS_DMA_STAT_OVF) ? "underflow" : ""); +#endif + tmp_reg = dds_read(st, CF_AXI_DDS_CTRL); + + if (!state) { + cf_axi_dds_stop(st); + tmp_reg = CF_AXI_DDS_CTRL_DATA_EN | CF_AXI_DDS_CTRL_DDS_CLK_EN_V2; + dds_write(st, CF_AXI_DDS_CTRL, tmp_reg); + dmaengine_terminate_all(st->tx_chan); + return 0; + } + + if (st->txcount == 0) { + return -EINVAL; + } + + tmp_reg = CF_AXI_DDS_CTRL_DDS_SEL | + CF_AXI_DDS_CTRL_DATA_EN | + CF_AXI_DDS_CTRL_DDS_CLK_EN_V2 | + st->ddr_dds_interp_en; + + + x = DIV_ROUND_UP(st->txcount, (VDMA_MAX_VSIZE + 1) * 8); + + do { + if (st->txcount % (x * 8)) + x++; + else + break; + } while (x <= 8192); + + if (x == 8192) { + return -EINVAL; + } + + cf_axi_dds_stop(st); + + st->dma_config.vsize = st->txcount / (x * 8); + st->dma_config.stride = st->dma_config.hsize = x * 8; + + dmaengine_device_control(st->tx_chan, DMA_SLAVE_CONFIG, + (unsigned long)&st->dma_config); + + desc = dmaengine_prep_slave_single(st->tx_chan, + st->buf_phys, + st->txcount, + DMA_MEM_TO_DEV, 0); + if (!desc) { + dev_err(indio_dev->dev.parent, "Failed to prepare DMA descriptor\n"); + return -ENOMEM; + } else { + dmaengine_submit(desc); + dma_async_issue_pending(st->tx_chan); + } + + dds_write(st, CF_AXI_DDS_CTRL, tmp_reg); + dds_write(st, CF_AXI_DDS_DMA_STAT, + CF_AXI_DDS_DMA_STAT_OVF | + CF_AXI_DDS_DMA_STAT_UNF); + + return 0; + +} + +static int cf_axi_dds_hw_buffer_preenable(struct iio_dev *indio_dev) +{ + return __cf_axi_dds_hw_buffer_state_set(indio_dev, 1); +} + +static int cf_axi_dds_hw_buffer_postdisable(struct iio_dev *indio_dev) +{ + return __cf_axi_dds_hw_buffer_state_set(indio_dev, 0); +} + +static const struct iio_buffer_setup_ops cf_axi_dds_buffer_setup_ops = { + .preenable = &cf_axi_dds_hw_buffer_preenable, + .postdisable = &cf_axi_dds_hw_buffer_postdisable, +}; + +int cf_axi_dds_configure_buffer(struct iio_dev *indio_dev) +{ + struct cf_axi_dds_state *st = iio_priv(indio_dev); + indio_dev->buffer = cf_axi_dds_rb_allocate(indio_dev); + if (indio_dev->buffer == NULL) + return -ENOMEM; + + indio_dev->modes |= INDIO_BUFFER_HARDWARE; + indio_dev->buffer->direction = IIO_BUFFER_DIRECTION_OUT; + indio_dev->buffer->access = &cf_axi_dds_buffer_access_funcs; + indio_dev->setup_ops = &cf_axi_dds_buffer_setup_ops; + + st->buf_virt = dma_alloc_coherent(indio_dev->dev.parent, + PAGE_ALIGN(AXIDDS_MAX_DMA_SIZE), &st->buf_phys, + GFP_KERNEL); + if (st->buf_virt == NULL) { + dev_err(indio_dev->dev.parent, + "Failed to allocate a dma memory\n"); + return -ENOMEM; + } + + return 0; +} + +void cf_axi_dds_unconfigure_buffer(struct iio_dev *indio_dev) +{ + struct cf_axi_dds_state *st = iio_priv(indio_dev); + + dma_free_coherent(indio_dev->dev.parent, PAGE_ALIGN(AXIDDS_MAX_DMA_SIZE), + st->buf_virt, st->buf_phys); + cf_axi_dds_rb_free(indio_dev->buffer); +} diff --git a/drivers/iio/iio_core.h b/drivers/iio/iio_core.h index f652e6ae5a359..4ddfdd5d8bf69 100644 --- a/drivers/iio/iio_core.h +++ b/drivers/iio/iio_core.h @@ -43,6 +43,8 @@ unsigned int iio_buffer_poll(struct file *filp, struct poll_table_struct *wait); ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf, size_t n, loff_t *f_ps); +ssize_t iio_buffer_chrdev_write(struct file *filp, const char __user *buf, + size_t n, loff_t *f_ps); #define iio_buffer_poll_addr (&iio_buffer_poll) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 4add9bb40eeb3..8f40bf7979a96 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -48,6 +48,23 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf, return rb->access->read_first_n(rb, n, buf); } +/** + * iio_buffer_read_first_n_outer() - chrdev read for buffer access + * + * This function relies on all buffer implementations having an + * iio_buffer as their first element. + **/ +ssize_t iio_buffer_chrdev_write(struct file *filp, const char __user *buf, + size_t n, loff_t *f_ps) +{ + struct iio_dev *indio_dev = filp->private_data; + struct iio_buffer *rb = indio_dev->buffer; + + if (!rb || !rb->access->write) + return -EINVAL; + return rb->access->write(rb, n, buf); +} + /** * iio_buffer_poll() - poll the buffer to find out if it has data */ diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 2ec266ef41a38..1927f065ddab0 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -23,7 +23,9 @@ #include #include #include + #include +#include #include "iio_core.h" #include "iio_core_trigger.h" #include @@ -156,7 +158,7 @@ static void __exit iio_exit(void) if (iio_devt) unregister_chrdev_region(iio_devt, IIO_DEV_MAX); bus_unregister(&iio_bus_type); - debugfs_remove(iio_debugfs_dentry); + debugfs_remove_recursive(iio_debugfs_dentry); } #if defined(CONFIG_DEBUG_FS) @@ -241,6 +243,9 @@ static int iio_device_register_debugfs(struct iio_dev *indio_dev) indio_dev->debugfs_dentry = debugfs_create_dir(dev_name(&indio_dev->dev), iio_debugfs_dentry); + if (IS_ERR(indio_dev->debugfs_dentry)) + return PTR_ERR(indio_dev->debugfs_dentry); + if (indio_dev->debugfs_dentry == NULL) { dev_warn(indio_dev->dev.parent, "Failed to create debugfs directory\n"); @@ -901,7 +906,16 @@ static long iio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return -EINVAL; } -static const struct file_operations iio_buffer_fileops = { +static const struct file_operations iio_buffer_none_fileops = { + .release = iio_chrdev_release, + .open = iio_chrdev_open, + .owner = THIS_MODULE, + .llseek = noop_llseek, + .unlocked_ioctl = iio_ioctl, + .compat_ioctl = iio_ioctl, +}; + +static const struct file_operations iio_buffer_in_fileops = { .read = iio_buffer_read_first_n_outer_addr, .release = iio_chrdev_release, .open = iio_chrdev_open, @@ -914,8 +928,20 @@ static const struct file_operations iio_buffer_fileops = { static const struct iio_buffer_setup_ops noop_ring_setup_ops; +static const struct file_operations iio_buffer_out_fileops = { + .write = iio_buffer_chrdev_write, + .release = iio_chrdev_release, + .open = iio_chrdev_open, + .poll = iio_buffer_poll_addr, + .owner = THIS_MODULE, + .llseek = noop_llseek, + .unlocked_ioctl = iio_ioctl, + .compat_ioctl = iio_ioctl, +}; + int iio_device_register(struct iio_dev *indio_dev) { + const struct file_operations *fops; int ret; /* configure elements for the chrdev */ @@ -945,11 +971,19 @@ int iio_device_register(struct iio_dev *indio_dev) if ((indio_dev->modes & INDIO_ALL_BUFFER_MODES) && indio_dev->setup_ops == NULL) indio_dev->setup_ops = &noop_ring_setup_ops; + if (indio_dev->buffer) { + if (indio_dev->buffer->direction == IIO_BUFFER_DIRECTION_IN) + fops = &iio_buffer_in_fileops; + else + fops = &iio_buffer_out_fileops; + } else { + fops = &iio_buffer_none_fileops; + } ret = device_add(&indio_dev->dev); if (ret < 0) goto error_unreg_eventset; - cdev_init(&indio_dev->chrdev, &iio_buffer_fileops); + cdev_init(&indio_dev->chrdev, fops); indio_dev->chrdev.owner = indio_dev->info->driver_module; ret = cdev_add(&indio_dev->chrdev, indio_dev->dev.devt, 1); if (ret < 0) diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index 4fe0ead84213e..aaa4e6e1ac64a 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -16,6 +16,7 @@ #include #include +#include #include #include "iio_core.h" #include "iio_core_trigger.h" @@ -494,3 +495,48 @@ int iio_triggered_buffer_predisable(struct iio_dev *indio_dev) indio_dev->pollfunc); } EXPORT_SYMBOL(iio_triggered_buffer_predisable); + +int iio_simple_trigger_handler(int irq, void *devid) +{ + struct iio_poll_func *pf = devid; + struct iio_dev *indio_dev = pf->indio_dev; + struct iio_buffer *buffer = indio_dev->buffer; + const struct iio_chan_spec *ch; + unsigned int val; + u8 sample[100]; + u8 *p = sample; + int ret; + int i; + + ret = iio_buffer_remove_sample(buffer, sample); + if (ret < 0) + return IRQ_HANDLED; + + for_each_set_bit(i, + indio_dev->active_scan_mask, + indio_dev->masklength) { + ch = iio_find_channel_from_si(indio_dev, i); + + p = PTR_ALIGN(p, ch->scan_type.storagebits / 8); + + switch (ch->scan_type.storagebits) { + case 32: + val = *((u32 *)p); + break; + case 16: + val = *((u16 *)p); + break; + case 8: + val = *((u8 *)p); + break; + default: + dev_err(&indio_dev->dev, "Unsupported storage size\n"); + return IRQ_HANDLED; + } + indio_dev->info->write_raw(indio_dev, ch, val, 0, 0); + + p += ch->scan_type.storagebits / 8; + } + + return IRQ_HANDLED; +} diff --git a/drivers/net/ethernet/xilinx/xilinx_emacps.c b/drivers/net/ethernet/xilinx/xilinx_emacps.c index e04cded7c55f0..7b4667ffb5b0c 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emacps.c +++ b/drivers/net/ethernet/xilinx/xilinx_emacps.c @@ -864,6 +864,11 @@ static int xemacps_mii_probe(struct net_device *ndev) xemacps_adjust_link, 0, PHY_INTERFACE_MODE_RGMII_ID); + + if (!phydev) { + printk(KERN_ERR "%s: no PHY found\n", ndev->name); + return -1; + } } if (!phydev) { dev_err(&lp->pdev->dev, "%s: no PHY found\n", ndev->name); @@ -2913,6 +2918,8 @@ static int __devinit xemacps_probe(struct platform_device *pdev) const void *prop; u32 regval = 0; int rc = -ENXIO; + int size = 0; + const u8* addr; r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); r_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); @@ -3059,6 +3066,13 @@ static int __devinit xemacps_probe(struct platform_device *pdev) goto err_out_unregister_clk_notifier; } + addr = of_get_property(lp->pdev->dev.of_node, "local-mac-address", &size); + if ((!addr) || (size != 6)) { + dev_warn(&lp->pdev->dev, "Could not find MAC address in device tree, use default\n"); + } else { + memcpy(lp->ndev->dev_addr, addr, sizeof(addr)); + xemacps_set_hwaddr(lp); + } xemacps_update_hwaddr(lp); platform_set_drvdata(pdev, ndev); diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index e91397e3c90e5..5d41b5630fc39 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -350,6 +350,24 @@ static int m88e1318_config_aneg(struct phy_device *phydev) return m88e1121_config_aneg(phydev); } +static int m88e1510_config_aneg(struct phy_device *phydev) +/* + Initialization for the 88E151x PHY. Note that the user can run an + additional initialization sequence on a PHY for an embedded system + after running the default configuration as defined for the 88E1318 PHY. + This additional initialization sequence is used for the Xilinx Zynq-based + ZED board. +*/ +{ + int err; + + err = m88e1318_config_aneg(phydev); + if (err < 0) + return err; + + return marvell_of_reg_init(phydev); +} + static int m88e1116r_config_init(struct phy_device *phydev) { int temp; @@ -887,6 +905,19 @@ static struct phy_driver marvell_drivers[] = { .config_intr = &marvell_config_intr, .driver = { .owner = THIS_MODULE }, }, + { + .phy_id = MARVELL_PHY_ID_88E1510, + .phy_id_mask = MARVELL_PHY_ID_MASK, + .name = "Marvell 88E1510", + .features = PHY_GBIT_FEATURES, + .flags = PHY_HAS_INTERRUPT, + .config_aneg = &m88e1510_config_aneg, + .read_status = &marvell_read_status, + .ack_interrupt = &marvell_ack_interrupt, + .config_intr = &marvell_config_intr, + .did_interrupt = &m88e1121_did_interrupt, + .driver = { .owner = THIS_MODULE }, + }, }; static int __init marvell_init(void) @@ -915,6 +946,7 @@ static struct mdio_device_id __maybe_unused marvell_tbl[] = { { 0x01410e30, 0xfffffff0 }, { 0x01410e90, 0xfffffff0 }, { 0x01410e40, 0xfffffff0 }, + { 0x01410dd0, 0xfffffff0 }, { } }; diff --git a/drivers/pmods/Kconfig b/drivers/pmods/Kconfig index 09706b712b5a5..47ea2778a0a66 100644 --- a/drivers/pmods/Kconfig +++ b/drivers/pmods/Kconfig @@ -14,7 +14,30 @@ config PMODOLED select SPI_BITBANG select SPI_GPIO help - The Digilent PmodOLED1, as well as ZED on-board OLED. Uses SPI over GPIO. + The Digilent PmodOLED1, as well as ZED on-board OLED. Uses SPI over GPIO. Configuration SPI_BITBANG and SPI_GPIO will be selected automatically. -endif # PMODS +config PMODCLS + tristate "pmodcls" + select 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" + select SPI_BITBANG + help + This is the Digilent PmodDA1 driver. Uses SPI over GPIO. + +config PMODAD1 + tristate "pmodad1" + select SPI_BITBANG + help + This is the Digilent PmodAD1 driver. Uses SPI over GPIO. + +endif # PMODS diff --git a/drivers/pmods/Makefile b/drivers/pmods/Makefile index ef90c23e7c72d..5f9542b7c0392 100644 --- a/drivers/pmods/Makefile +++ b/drivers/pmods/Makefile @@ -2,3 +2,8 @@ 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/pmods/pmodad1.c b/drivers/pmods/pmodad1.c new file mode 100644 index 0000000000000..0597c78179385 --- /dev/null +++ b/drivers/pmods/pmodad1.c @@ -0,0 +1,656 @@ +/* + * 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. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + + + +dev_t pmodad1_dev_id = 0; +static unsigned int device_num = 0; +static unsigned int cur_minor = 0; +static unsigned int spi_drv_registered = 0; +static struct class *pmodad1_class = NULL; + +/* Kernel space buffer size (in bytes) for the ad1_read function. + * Can be entered from the command line during insmod + */ +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((void *)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; +} + +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 __init 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); + printk(KERN_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; + printk(KERN_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 + printk(KERN_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) { + printk(KERN_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 + printk(KERN_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 __devexit 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 + printk(KERN_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 = __devexit_p(pmodad1_spi_remove), +}; + +static const struct of_device_id pmodad1_of_match[] __devinitconst = { + { .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 __devinit 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 = (struct pmodad1_device*) 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 = (unsigned short *)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 + printk(KERN_INFO DRIVER_NAME " %s: iSCLK: 0x%lx\n", np->name, pmodad1_dev->iSCLK); + printk(KERN_INFO DRIVER_NAME " %s: iSDOUT: 0x%lx\n", np->name, pmodad1_dev->iSDOUT); + printk(KERN_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 + printk(KERN_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 + printk(KERN_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 = (struct spi_gpio_platform_data*) 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 = (struct platform_device*) 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 + printk(KERN_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 + printk(KERN_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 + printk(KERN_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 + printk(KERN_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 + printk(KERN_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 + printk(KERN_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 + printk(KERN_INFO DRIVER_NAME " : Unregister SPI Driver.\n"); +#endif + spi_unregister_driver(&pmodad1_spi_driver); + spi_drv_registered = 0; + +#ifdef CONFIG_PMODS_DEBUG + printk(KERN_INFO DRIVER_NAME " : Destroy pmodad1 Class.\n"); +#endif + + if(pmodad1_class) { + class_destroy(pmodad1_class); + } + pmodad1_class = NULL; + +#ifdef CONFIG_PMODS_DEBUG + printk(KERN_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 = __devexit_p(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/pmods/pmodclp.c b/drivers/pmods/pmodclp.c new file mode 100644 index 0000000000000..896362624400b --- /dev/null +++ b/drivers/pmods/pmodclp.c @@ -0,0 +1,1185 @@ +/* + * 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. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 CONFIG_PMODS_DEBUG + +#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 + +dev_t pmodclp_dev_id = 0; +static unsigned int device_num = 0; +static unsigned int cur_minor = 0; +static struct class *pmodclp_class = NULL; + +// 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); +} + + +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. + */ +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<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. + */ +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. + */ +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. + */ +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. + */ +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. + */ +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. + */ +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'). + */ +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'). + */ +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'). + */ +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. + */ + +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: ; + // 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 + printk(KERN_INFO " Wrong command: %.*s \n", (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 + { + printk(KERN_INFO " Wrong command: %.*s \n", (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); +} + + +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) { + printk(KERN_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); + printk(KERN_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[] __devinitconst = { + { .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 __devinit 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 = (struct pmodclp_device*) kzalloc(sizeof(*pmodclp_dev), GFP_KERNEL); + if(!pmodclp_dev) { + status = -ENOMEM; + goto dev_alloc_err; + } + + /* Alloc Text Buffer for device */ + pmodclp_dev->txt_buf = (unsigned char*) 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 + printk(KERN_INFO DRIVER_NAME " %s: iRS: 0x%lx\n", np->name, pmodclp_dev->par_dev.iRS); + printk(KERN_INFO DRIVER_NAME " %s: iRW: 0x%lx\n", np->name, pmodclp_dev->par_dev.iRW); + printk(KERN_INFO DRIVER_NAME " %s: iE : 0x%lx\n", np->name, pmodclp_dev->par_dev.iE); + printk(KERN_INFO DRIVER_NAME " %s: iBK : 0x%lx\n", np->name, pmodclp_dev->par_dev.iBK); + + printk(KERN_INFO DRIVER_NAME " %s: iData[0] : 0x%lx\n", np->name, pmodclp_dev->par_dev.iData[0]); + printk(KERN_INFO DRIVER_NAME " %s: iData[1] : 0x%lx\n", np->name, pmodclp_dev->par_dev.iData[1]); + printk(KERN_INFO DRIVER_NAME " %s: iData[2] : 0x%lx\n", np->name, pmodclp_dev->par_dev.iData[2]); + printk(KERN_INFO DRIVER_NAME " %s: iData[3] : 0x%lx\n", np->name, pmodclp_dev->par_dev.iData[3]); + printk(KERN_INFO DRIVER_NAME " %s: iData[4] : 0x%lx\n", np->name, pmodclp_dev->par_dev.iData[4]); + printk(KERN_INFO DRIVER_NAME " %s: iData[5] : 0x%lx\n", np->name, pmodclp_dev->par_dev.iData[5]); + printk(KERN_INFO DRIVER_NAME " %s: iData[6] : 0x%lx\n", np->name, pmodclp_dev->par_dev.iData[6]); + printk(KERN_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 + printk(KERN_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 + printk(KERN_INFO DRIVER_NAME " : pmodclp device class registered.\n"); +#endif + } + + /* Setup char driver */ + status = pmodclp_setup_cdev(pmodclp_dev, &(pmodclp_dev->dev_id)); + if (status) { + printk(KERN_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) { + printk(KERN_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: + + printk(KERN_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) { + printk(KERN_INFO "!! gpio_is_valid for GPIO %d, %s FAILED!, status: %d\n", + pmodclp_ctrl[i].gpio, pmodclp_ctrl[i].label, status); + goto gpio_invalid; + } + } + + printk(KERN_INFO "** gpio_request_array array_size = %d, ARRAY_SIZE = %d\n", array_size, ARRAY_SIZE(pmodclp_ctrl)); + + status = gpio_request_array(pmodclp_ctrl, ARRAY_SIZE(pmodclp_ctrl)); + if(status) { + printk(KERN_INFO "!! gpio_request_array FAILED!\n"); + printk(KERN_INFO " status is: %d, array_size = %d, ARRAY_SIZE = %d\n", status, array_size, 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 + printk(KERN_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 + printk(KERN_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 + printk(KERN_INFO DRIVER_NAME " : Destroy pmodclp_gpio Class.\n"); +#endif + + if(pmodclp_class) { + class_destroy(pmodclp_class); + } + pmodclp_class = NULL; + +#ifdef CONFIG_PMODS_DEBUG + printk(KERN_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 = __devexit_p(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/pmods/pmodcls.c b/drivers/pmods/pmodcls.c new file mode 100644 index 0000000000000..17ec2d7c066df --- /dev/null +++ b/drivers/pmods/pmodcls.c @@ -0,0 +1,855 @@ +/* + * 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. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + + + +dev_t pmodcls_dev_id = 0; +static unsigned int device_num = 0; +static unsigned int cur_minor = 0; +static unsigned int spi_drv_registered = 0; +static struct class *pmodcls_class = NULL; + +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); +} + + +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 __init 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); + printk(KERN_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 + printk(KERN_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) { + printk(KERN_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 + printk(KERN_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 __devexit 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 + printk(KERN_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 = __devexit_p(pmodcls_spi_remove), +}; + +static const struct of_device_id pmodcls_of_match[] __devinitconst = { + { .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 __devinit 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 = (struct pmodcls_device*) kzalloc(sizeof(*pmodcls_dev), GFP_KERNEL); + if(!pmodcls_dev) { + status = -ENOMEM; + goto dev_alloc_err; + } + + /* Alloc Text Buffer for device */ + pmodcls_dev->txt_buf = (uint8_t*) 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 + printk(KERN_INFO DRIVER_NAME " %s: iSCLK: 0x%lx\n", np->name, pmodcls_dev->iSCLK); + printk(KERN_INFO DRIVER_NAME " %s: iSDIN: 0x%lx\n", np->name, pmodcls_dev->iSDIN); + printk(KERN_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 + printk(KERN_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 + printk(KERN_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 = (struct spi_gpio_platform_data*) 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 = (struct platform_device*) 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 + printk(KERN_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 + printk(KERN_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 + printk(KERN_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 + printk(KERN_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 + printk(KERN_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 + printk(KERN_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 + printk(KERN_INFO DRIVER_NAME " : Unregister SPI Driver.\n"); +#endif + spi_unregister_driver(&pmodcls_spi_driver); + spi_drv_registered = 0; + +#ifdef CONFIG_PMODS_DEBUG + printk(KERN_INFO DRIVER_NAME " : Destroy pmodcls_gpio Class.\n"); +#endif + + if(pmodcls_class) { + class_destroy(pmodcls_class); + } + pmodcls_class = NULL; + +#ifdef CONFIG_PMODS_DEBUG + printk(KERN_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 = __devexit_p(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/pmods/pmodda1.c b/drivers/pmods/pmodda1.c new file mode 100644 index 0000000000000..581a5ea319cc4 --- /dev/null +++ b/drivers/pmods/pmodda1.c @@ -0,0 +1,858 @@ +/* + * 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. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "pmodda1" +#define SPI_DRIVER_NAME "pmodda1-spi" + +#define DEFAULT_SPI_SPEED 625000 +#define PMODDA1_DEV_NUM 2 // only 2 channels as SPI does not allow write on Data In line. + +#define DEFAULT_BUF_SZ 512 +/* + * default size of the buffer for each DAC on the device. Can be + * changed from the default during insmod. + */ +int buf_sz = DEFAULT_BUF_SZ; +module_param(buf_sz, int, 0); + +dev_t pmodda1_first_dev_id = 0; +struct spi_device *spi_device; +static unsigned int spi_drv_registered = 0; +static struct class *pmodda1_class = NULL; + +struct pmodda1_device { + char *name; + + unsigned int minor_id; + /* Data Buffer */ + unsigned char *buf; // Device data buffer + /* 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); +int write_spi_16(struct spi_device *spi, uint16_t cmd_data); + +/* 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). + */ +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%08X\n", (unsigned int)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); +printk(KERN_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((void *)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); +} + + +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 __init 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); + printk(KERN_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); + } + printk(KERN_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 + printk(KERN_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 = (unsigned char *)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 + printk(KERN_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++) { + if(rgpmodda1_devices[i] && rgpmodda1_devices[i]->buf) + kfree(rgpmodda1_devices[i]->buf); + } +dev_alloc_err: + for (i = 0; i < PMODDA1_DEV_NUM; i++) { + if(rgpmodda1_devices[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 __devexit 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 + printk(KERN_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 = __devexit_p(pmodda1_spi_remove), +}; + +static const struct of_device_id pmodda1_of_match[] __devinitconst = { + { .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 __devinit 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 = (struct pmodda1_device*) kzalloc(sizeof(*pmodda1_dev), GFP_KERNEL); + if(!pmodda1_dev) { + status = -ENOMEM; + goto dev_alloc_err; + } + + pmodda1_dev->buf = (unsigned char *)kmalloc(buf_sz, GFP_KERNEL); + if (!pmodda1_dev->buf) { + status = -ENOMEM; + printk(KERN_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 + printk(KERN_INFO DRIVER_NAME " %s: iSCLK: 0x%lx\n", np->name, pmodda1_dev->iSCLK); + printk(KERN_INFO DRIVER_NAME " %s: iSDIN: 0x%lx\n", np->name, pmodda1_dev->iSDIN); + printk(KERN_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 + printk(KERN_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 + printk(KERN_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 = (struct spi_gpio_platform_data*) 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 = (struct platform_device*) 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 + printk(KERN_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 + printk(KERN_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 + printk(KERN_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 + printk(KERN_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 + printk(KERN_INFO DRIVER_NAME " %s : Free display buffer.\n", np->name); +#endif + + if(pmodda1_dev->buf != NULL) { + kfree(pmodda1_dev->buf); + } + +#ifdef CONFIG_PMODS_DEBUG + printk(KERN_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 + printk(KERN_INFO DRIVER_NAME " : Unregister SPI Driver.\n"); +#endif + spi_unregister_driver(&pmodda1_spi_driver); + spi_drv_registered = 0; + +#ifdef CONFIG_PMODS_DEBUG + printk(KERN_INFO DRIVER_NAME " : Destroy pmodda1_gpio Class.\n"); +#endif + + if(pmodda1_class) { + class_destroy(pmodda1_class); + } + pmodda1_class = NULL; + +#ifdef CONFIG_PMODS_DEBUG + printk(KERN_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 = __devexit_p(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/pmods/pmodoled-gpio.c b/drivers/pmods/pmodoled-gpio.c index 5cd330ba907ab..c409e4d998bd1 100644 --- a/drivers/pmods/pmodoled-gpio.c +++ b/drivers/pmods/pmodoled-gpio.c @@ -1,3 +1,24 @@ +/* + * 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 #include #include diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 4771dcb0df24c..b3201e649c5e0 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -400,6 +400,12 @@ config SPI_XCOMM Support for the SPI-I2C bridge found on the Analog Devices AD-FMCOMMS1-EBZ board. +config SPI_AD9250FMC + tristate "Analog Devices AD9250-FMC-250EBZ SPI-SPI-bridge driver" + help + Support for the SPI-SPI bridge CPLD found on the Analog Devices + AD9250-FMC-250EBZ and 4DSP FMC176 and FMX230 FMC cards. + config SPI_XILINX tristate "Xilinx SPI controller common module" depends on HAS_IOMEM && EXPERIMENTAL diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index f30ab112bae09..4aba25ec5ccd4 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -63,6 +63,7 @@ obj-$(CONFIG_SPI_TLE62X0) += spi-tle62x0.o obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o obj-$(CONFIG_SPI_TXX9) += spi-txx9.o obj-$(CONFIG_SPI_XCOMM) += spi-xcomm.o +obj-$(CONFIG_SPI_AD9250FMC) += spi-ad9250fmc.o obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o obj-$(CONFIG_SPI_XILINX_PS_SPI) += spi-xilinx-ps.o obj-$(CONFIG_SPI_XILINX_PS_QSPI) += spi-xilinx-qps.o diff --git a/drivers/spi/spi-ad9250fmc.c b/drivers/spi/spi-ad9250fmc.c new file mode 100644 index 0000000000000..1d3f67aec49e0 --- /dev/null +++ b/drivers/spi/spi-ad9250fmc.c @@ -0,0 +1,162 @@ +/* + * Analog Devices AD9250-FMC-250EBZ board SPI-SPI CPLD demux driver + * + * Copyright 2012 Analog Devices Inc. + * Author: Michael Hennerich + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define FMC_CPLD 0x00 /* chip_select 0 */ +#define FMC_AD9517 0x84 /* chip_select 1 */ +#define FMC_AD9250_0 0x80 /* chip_select 2 */ +#define FMC_AD9250_1 0x81 /* chip_select 3 */ +#define FMC_AD9129_0 0x82 /* chip_select 4 */ +#define FMC_AD9129_1 0x83 /* chip_select 5 */ +#define FMC_NUM_SLAVES 6 + +static const unsigned char cs_lut[FMC_NUM_SLAVES] = { + FMC_CPLD, + FMC_AD9517, + FMC_AD9250_0, + FMC_AD9250_1, + FMC_AD9129_0, + FMC_AD9129_1, +}; + +struct spi_ad9250 { + struct spi_device *spi; + struct work_struct work; + uint8_t data[32] ____cacheline_aligned; +}; + +static inline unsigned cs_to_cpld (unsigned chip_select) +{ + return cs_lut[chip_select]; +} + +static int spi_ad9250_transfer_one(struct spi_master *master, + struct spi_message *msg) +{ + struct spi_ad9250 *spi_ad9250 = spi_master_get_devdata(master); + struct spi_device *spi = msg->spi; + int status = 0, i = 1; + + struct spi_transfer *tn; + struct spi_message m; + struct spi_transfer x[8]; + + spi_message_init(&m); + memset(x, 0, sizeof x); + + x[0].len = 1; + x[0].tx_buf = spi_ad9250->data; + x[0].delay_usecs = 10; + spi_ad9250->data[0] = cs_to_cpld(spi->chip_select); + spi_message_add_tail(&x[0], &m); + + list_for_each_entry(tn, &msg->transfers, transfer_list) { + x[i] = *tn; + spi_message_add_tail(&x[i], &m); + i++; + if (i > 7) + return -EIO; + } + + spi_ad9250->spi->mode = spi->mode & ~SPI_3WIRE; + spi_setup(spi_ad9250->spi); + + spi_sync(spi_ad9250->spi, &m); + + msg->status = m.status; + spi_finalize_current_message(master); + + return status; +} + +static int spi_ad9250_setup(struct spi_device *spi) +{ + if (spi->bits_per_word != 8) + return -EINVAL; + + return 0; +} + +static void spi_ad9250_work(struct work_struct *work) +{ + struct spi_ad9250 *spi_ad9250 = + container_of(work,struct spi_ad9250, work); + struct spi_master *master = spi_get_drvdata(spi_ad9250->spi); + + int ret = spi_register_master(master); + if (ret < 0) + spi_master_put(master); +} + +static int __devinit spi_ad9250_probe(struct spi_device *spi) +{ + struct spi_ad9250 *spi_ad9250; + struct spi_master *master; + static int bus_num = 0; + + master = spi_alloc_master(&spi->dev, sizeof(*spi_ad9250)); + if (!master) + return -ENOMEM; + + spi_ad9250 = spi_master_get_devdata(master); + spi_ad9250->spi = spi; + master->num_chipselect = FMC_NUM_SLAVES; + master->bus_num = bus_num++; + master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_3WIRE; + master->setup = spi_ad9250_setup; + master->transfer_one_message = spi_ad9250_transfer_one; + master->dev.of_node = spi->dev.of_node; + spi_set_drvdata(spi, master); + + /* spi_add_lock in spi_add_device() prevents registering + * the master in place so defer this to an work queue + */ + INIT_WORK(&spi_ad9250->work, spi_ad9250_work); + schedule_work(&spi_ad9250->work); + + return 0; +} + +static int __devexit spi_ad9250_remove(struct spi_device *spi) +{ + struct spi_master *master = spi_get_drvdata(spi); + + spi_unregister_master(master); + + return 0; +} + +static const struct spi_device_id spi_ad9250_ids[] = { + { "spi-ad9250", 0 }, + { }, +}; + +MODULE_DEVICE_TABLE(spi, spi_ad9250_ids); + +static struct spi_driver spi_ad9250_driver = { + .driver = { + .name = "spi-ad9250", + .owner = THIS_MODULE, + }, + .id_table = spi_ad9250_ids, + .probe = spi_ad9250_probe, + .remove = __devexit_p(spi_ad9250_remove), +}; +module_spi_driver(spi_ad9250_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD9250-FMC board SPI mux driver"); diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index aef59b1a15f7f..f4ddf541aaaba 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c @@ -330,7 +330,8 @@ static void bitbang_work(struct work_struct *work) */ if (!m->is_dma_mapped) t->rx_dma = t->tx_dma = 0; - status = bitbang->txrx_bufs(spi, t); + status = bitbang->txrx_bufs(spi, t, t->transfer_list.next == &m->transfers); +// status = bitbang->txrx_bufs(spi, t); } if (status > 0) m->actual_length += status; diff --git a/drivers/spi/spi-xcomm.c b/drivers/spi/spi-xcomm.c index 266a847e2992d..3d95b61d600ec 100644 --- a/drivers/spi/spi-xcomm.c +++ b/drivers/spi/spi-xcomm.c @@ -220,6 +220,7 @@ static int spi_xcomm_setup(struct spi_device *spi) static int __devinit spi_xcomm_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { + static unsigned int bus_num; struct spi_xcomm *spi_xcomm; struct spi_master *master; int ret; @@ -236,6 +237,7 @@ static int __devinit spi_xcomm_probe(struct i2c_client *i2c, master->flags = SPI_MASTER_HALF_DUPLEX; master->setup = spi_xcomm_setup; master->transfer_one_message = spi_xcomm_transfer_one; + master->bus_num = bus_num++; master->dev.of_node = i2c->dev.of_node; i2c_set_clientdata(i2c, master); @@ -243,6 +245,10 @@ static int __devinit spi_xcomm_probe(struct i2c_client *i2c, if (ret < 0) spi_master_put(master); + /* Let the LED blink */ + spi_xcomm->buf[0] = 0x2; + i2c_master_send(i2c, spi_xcomm->buf, 1); + return ret; } diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 84c2861d6f4dd..403cc4a4671c7 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -798,6 +798,21 @@ static int spi_master_initialize_queue(struct spi_master *master) return ret; } +static void spi_master_release(struct device *dev) +{ + struct spi_master *master; + + master = container_of(dev, struct spi_master, dev); + kfree(master); +} + +struct class spi_master_class = { + .name = "spi_master", + .owner = THIS_MODULE, + .dev_release = spi_master_release, +}; +EXPORT_SYMBOL_GPL(spi_master_class); + /*-------------------------------------------------------------------------*/ #if defined(CONFIG_OF) && !defined(CONFIG_SPARC) @@ -855,6 +870,8 @@ static void of_register_spi_devices(struct spi_master *master) spi->mode |= SPI_CPOL; if (of_find_property(nc, "spi-cs-high", NULL)) spi->mode |= SPI_CS_HIGH; + if (of_find_property(nc, "spi-3wire", NULL)) + spi->mode |= SPI_3WIRE; /* Device speed */ prop = of_get_property(nc, "spi-max-frequency", &len); @@ -884,25 +901,38 @@ static void of_register_spi_devices(struct spi_master *master) } } -#else -static void of_register_spi_devices(struct spi_master *master) { } -#endif -static void spi_master_release(struct device *dev) +static int __spi_master_of_match(struct device *dev, void *data) { - struct spi_master *master; - - master = container_of(dev, struct spi_master, dev); - kfree(master); + struct device_node *of_node = data; + return dev->of_node == of_node; } -static struct class spi_master_class = { - .name = "spi_master", - .owner = THIS_MODULE, - .dev_release = spi_master_release, -}; +/** + * spi_of_node_to_master - look up master associated with of_node + * @of_node: pointer to the device tree node. + * Context: can sleep + * + * Returns a pointer to the relevant spi_master, or NULL if there is + * no such master registered. + */ +struct spi_master *spi_of_node_to_master(struct device_node *of_node) +{ + struct device *dev; + struct spi_master *master = NULL; + dev = class_find_device(&spi_master_class, NULL, of_node, + __spi_master_of_match); + if (dev) + master = container_of(dev, struct spi_master, dev); + return master; +} +EXPORT_SYMBOL_GPL(spi_of_node_to_master); + +#else +static void of_register_spi_devices(struct spi_master *master) { } +#endif /** * spi_alloc_master - allocate SPI master controller diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 3be59d02cae4b..04a4c34cb35f2 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -31,7 +31,7 @@ obj-$(CONFIG_VT6656) += vt6656/ obj-$(CONFIG_VME_BUS) += vme/ obj-$(CONFIG_IPACK_BUS) += ipack/ obj-$(CONFIG_DX_SEP) += sep/ -obj-$(CONFIG_IIO) += iio/ +#obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_ZRAM) += zram/ obj-$(CONFIG_ZCACHE) += zcache/ obj-$(CONFIG_ZSMALLOC) += zsmalloc/ diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index 04cd6ec1f70f1..9579b60e04a35 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -28,6 +28,7 @@ endif # IIO_BUFFER source "drivers/staging/iio/accel/Kconfig" source "drivers/staging/iio/adc/Kconfig" source "drivers/staging/iio/addac/Kconfig" +source "drivers/staging/iio/amplifiers/Kconfig" source "drivers/staging/iio/cdc/Kconfig" source "drivers/staging/iio/frequency/Kconfig" source "drivers/staging/iio/gyro/Kconfig" diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile index fa6937d92ee32..2057cda1ea40f 100644 --- a/drivers/staging/iio/Makefile +++ b/drivers/staging/iio/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_IIO_ST_HWMON) += iio_hwmon.o obj-y += accel/ obj-y += adc/ obj-y += addac/ +obj-y += amplifiers/ obj-y += cdc/ obj-y += frequency/ obj-y += gyro/ diff --git a/drivers/staging/iio/adc/cf_ad9467.h b/drivers/staging/iio/adc/cf_ad9467.h new file mode 100644 index 0000000000000..4ec7c77dced10 --- /dev/null +++ b/drivers/staging/iio/adc/cf_ad9467.h @@ -0,0 +1,169 @@ +/* + * ADI-AIM ADI ADC Interface Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + * + * http://wiki.analog.com/resources/fpga/xilinx/fmc/ad9467 + */ + +#ifndef ADI_AIM_H_ +#define ADI_AIM_H_ + +/* PCORE CoreFPGA register map */ + +#define AD9467_PCORE_VERSION 0x00 +#define AD9467_PCORE_SPI_CTRL 0x04 +#define AD9467_PCORE_SPI_RDSTAT 0x08 +#define AD9467_PCORE_DMA_CTRL 0x0C +#define AD9467_PCORE_DMA_STAT 0x10 +#define AD9467_PCORE_ADC_STAT 0x14 +#define AD9467_PCORE_PN_ERR_CTRL 0x24 +#define AD9467_PCORE_IDENT 0x28 + + +/* AD9467_PCORE_SPI_CTRL */ +#define AD9647_SPI_START (1 << 25) +#define AD9647_SPI_SEL(x) (((x) & 0x1) << 24) +#define AD9647_SPI_READ (1 << 23) +#define AD9647_SPI_WRITE (0 << 23) +#define AD9647_SPI_ADDR(x) (((x) & 0x1FFF) << 8) +#define AD9647_SPI_DATA(x) (((x) & 0xFF) << 0) + +/* AD9467_PCORE_SPI_RDSTAT */ +#define AD9647_SPI_IDLE (1 << 8) +#define AD9647_SPI_READVAL(x) ((x) & 0xFF) + +/* AD9467_PCORE_DMA_CTRL */ +#define AD9647_DMA_CAP_EN (1 << 16) +#define AD9647_DMA_CNT(x) (((x) & 0xFFFF) << 0) + +/* AD9467_PCORE_DMA_STAT */ +#define AD9647_DMA_STAT_BUSY (1 << 0) +#define AD9647_DMA_STAT_OVF (1 << 1) +#define AD9647_DMA_STAT_UNF (1 << 2) + +/* AD9467_PCORE_ADC_STAT */ +#define AD9467_PCORE_ADC_STAT_OVR (1 << 0) +#define AD9467_PCORE_ADC_STAT_PN_OOS (1 << 1) /* W1C */ +#define AD9467_PCORE_ADC_STAT_PN_ERR (1 << 2) /* W1C */ + +/* AD9467_PCORE_PN_ERR_CTRL */ +#define AD9467_PN23_EN (1 << 0) +#define AD9467_PN9_EN (0 << 0) + +/* AD9467_PCORE_IDENT */ +#define AD9467_PCORE_IDENT_SLAVE 0x1 + +/* + * ADI High-Speed ADC common spi interface registers + * See Application-Note AN-877 + */ + +#define ADC_REG_CHIP_PORT_CONF 0x00 +#define ADC_REG_CHIP_ID 0x01 +#define ADC_REG_CHIP_GRADE 0x02 +#define ADC_REG_TRANSFER 0xFF +#define ADC_REG_MODES 0x08 +#define ADC_REG_TEST_IO 0x0D +#define ADC_REG_ADC_INPUT 0x0F +#define ADC_REG_OFFSET 0x10 +#define ADC_REG_OUTPUT_MODE 0x14 +#define ADC_REG_OUTPUT_ADJUST 0x15 +#define ADC_REG_OUTPUT_PHASE 0x16 +#define ADC_REG_OUTPUT_DELAY 0x17 +#define ADC_REG_VREF 0x18 +#define ADC_REG_ANALOG_INPUT 0x2C + +/* ADC_REG_TRANSFER */ +#define TRANSFER_SYNC 0x1 + +/* ADC_REG_TEST_IO */ +#define TESTMODE_OFF 0x0 +#define TESTMODE_MIDSCALE_SHORT 0x1 +#define TESTMODE_POS_FULLSCALE 0x2 +#define TESTMODE_NEG_FULLSCALE 0x3 +#define TESTMODE_ALT_CHECKERBOARD 0x4 +#define TESTMODE_PN23_SEQ 0x5 +#define TESTMODE_PN9_SEQ 0x6 +#define TESTMODE_ONE_ZERO_TOGGLE 0x7 + +/* ADC_REG_OUTPUT_MODE */ +#define OUTPUT_MODE_OFFSET_BINARY 0x0 +#define OUTPUT_MODE_TWOS_COMPLEMENT 0x1 +#define OUTPUT_MODE_GRAY_CODE 0x2 + +/* + * Analog Devices AD9467 16-Bit, 200/250 MSPS ADC + */ + +#define AD9467_DEF_OUTPUT_MODE 0x08 +#define AD9467_REG_VREF_MASK 0x0F +#define CHIPID_AD9467 0x50 + +/* + * Analog Devices AD9643 Dual 14-Bit, 170/210/250 MSPS ADC + */ + +#define CHIPID_AD9643 0x82 +#define AD9643_REG_VREF_MASK 0x1F +#define AD9643_DEF_OUTPUT_MODE 0x04 + +enum { + ID_AD9467, + ID_AD9643, +}; + +struct aim_chip_info { + char name[8]; + unsigned num_channels; + unsigned long available_scan_masks[2]; + const int (*scale_table)[2]; + int num_scales; + struct iio_chan_spec channel[2]; +}; + +struct aim_state { + struct spi_device *spi; + struct mutex lock; + struct completion dma_complete; + struct dma_chan *rx_chan; + const struct aim_chip_info *chip_info; + void __iomem *regs; + void *buf_virt; + dma_addr_t buf_phys; + int compl_stat; + unsigned spi_ssel; + unsigned ring_lenght; + unsigned rcount; + unsigned fftcount; + unsigned bytes_per_datum; + unsigned id; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + + unsigned char data[3] ____cacheline_aligned; +}; + +/* + * IO accessors + */ + +static inline void aim_write(struct aim_state *st, unsigned reg, unsigned val) +{ + iowrite32(val, st->regs + reg); +} + +static inline unsigned int aim_read(struct aim_state *st, unsigned reg) +{ + return ioread32(st->regs + reg); +} + +int aim_configure_ring(struct iio_dev *indio_dev); +void aim_unconfigure_ring(struct iio_dev *indio_dev); + +#endif /* ADI_AIM_H_ */ diff --git a/drivers/staging/iio/adc/cf_ad9467_core.c b/drivers/staging/iio/adc/cf_ad9467_core.c new file mode 100644 index 0000000000000..731de0dca61cc --- /dev/null +++ b/drivers/staging/iio/adc/cf_ad9467_core.c @@ -0,0 +1,599 @@ +/* + * ADI-AIM ADI ADC Interface Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + * + * http://wiki.analog.com/resources/fpga/xilinx/fmc/ad9467 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../buffer.h" + +#include "cf_ad9467.h" + +static int aim_spi_read(struct aim_state *st, unsigned reg) +{ + unsigned long timeout = jiffies + HZ / 4; + int ret; + + if (st->spi) { + unsigned char *buf = st->data; + buf[0] = 0x80 | (reg >> 8); + buf[1] = reg & 0xFF; + + ret = spi_write_then_read(st->spi, &buf[0], 2, &buf[2], 1); + if (ret < 0) + return ret; + + return buf[2]; + } + + aim_write(st, AD9467_PCORE_SPI_CTRL, 0); + aim_write(st, AD9467_PCORE_SPI_CTRL, + AD9647_SPI_START | + AD9647_SPI_READ | + AD9647_SPI_SEL(st->spi_ssel) | + AD9647_SPI_ADDR(reg)); + + while (!(aim_read(st, AD9467_PCORE_SPI_RDSTAT) & AD9647_SPI_IDLE)) { + cpu_relax(); + if (time_after(jiffies, timeout)) + return -EIO; + } + + return AD9647_SPI_READVAL(aim_read(st, AD9467_PCORE_SPI_RDSTAT)); +} + +static int aim_spi_write(struct aim_state *st, unsigned reg, unsigned val) +{ + unsigned long timeout = jiffies + HZ / 4; + + int ret; + + if (st->spi) { + unsigned char *buf = st->data; + buf[0] = reg >> 8; + buf[1] = reg & 0xFF; + buf[2] = val; + ret = spi_write(st->spi, buf, 3); + if (ret < 0) + return ret; + + return 0; + } + + aim_write(st, AD9467_PCORE_SPI_CTRL, 0); + aim_write(st, AD9467_PCORE_SPI_CTRL, + AD9647_SPI_START | + AD9647_SPI_WRITE | + AD9647_SPI_SEL(st->spi_ssel) | + AD9647_SPI_ADDR(reg) | + AD9647_SPI_DATA(val)); + + + while (!(aim_read(st, AD9467_PCORE_SPI_RDSTAT) & AD9647_SPI_IDLE)) { + cpu_relax(); + if (time_after(jiffies, timeout)) + return -EIO; + } + + return 0; +} + +static int aim_debugfs_open(struct inode *inode, struct file *file) +{ + if (inode->i_private) + file->private_data = inode->i_private; + + return 0; +} + +static ssize_t aim_debugfs_pncheck_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct iio_dev *indio_dev = file->private_data; + struct aim_state *st = iio_priv(indio_dev); + char buf[80]; + ssize_t len; + unsigned stat; + + stat = aim_read(st, AD9467_PCORE_ADC_STAT); + len = sprintf(buf, "%s %s\n", (stat & AD9467_PCORE_ADC_STAT_PN_OOS) ? + "Out of Sync :" : "In Sync :", + (stat & AD9467_PCORE_ADC_STAT_PN_ERR) ? + "PN Error" : "No Error"); + + aim_write(st, AD9467_PCORE_ADC_STAT, 0xF); + + return simple_read_from_buffer(userbuf, count, ppos, buf, len); +} + +static ssize_t aim_debugfs_pncheck_write(struct file *file, + const char __user *userbuf, size_t count, loff_t *ppos) +{ + struct iio_dev *indio_dev = file->private_data; + struct aim_state *st = iio_priv(indio_dev); + unsigned mode; + char buf[80], *p = buf; + + count = min_t(size_t, count, (sizeof(buf)-1)); + if (copy_from_user(p, userbuf, count)) + return -EFAULT; + + p[count] = 0; + + if (sysfs_streq(p, "PN9")) + mode = TESTMODE_PN9_SEQ; + else if (sysfs_streq(p, "PN23")) + mode = TESTMODE_PN23_SEQ; + else + mode = TESTMODE_OFF; + + aim_spi_write(st, ADC_REG_TEST_IO, mode); + aim_spi_write(st, ADC_REG_TRANSFER, TRANSFER_SYNC); + + aim_write(st, AD9467_PCORE_PN_ERR_CTRL, (mode == TESTMODE_PN23_SEQ) ? + AD9467_PN23_EN : AD9467_PN9_EN); + + mdelay(1); /* FIXME */ + + aim_write(st, AD9467_PCORE_ADC_STAT, + AD9467_PCORE_ADC_STAT_PN_OOS | + AD9467_PCORE_ADC_STAT_PN_OOS | + AD9467_PCORE_ADC_STAT_OVR); + + return count; +} + +static const struct file_operations aim_debugfs_pncheck_fops = { + .open = aim_debugfs_open, + .read = aim_debugfs_pncheck_read, + .write = aim_debugfs_pncheck_write, +}; + +static int aim_reg_access(struct iio_dev *indio_dev, + unsigned reg, unsigned writeval, + unsigned *readval) +{ + struct aim_state *st = iio_priv(indio_dev); + int ret; + + mutex_lock(&indio_dev->mlock); + if (readval == NULL) { + ret = aim_spi_write(st, reg, writeval); + aim_spi_write(st, ADC_REG_TRANSFER, TRANSFER_SYNC); + } else { + ret = aim_spi_read(st, reg); + if (ret < 0) + return ret; + *readval = ret; + + ret = 0; + } + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static int aim_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + struct aim_state *st = iio_priv(indio_dev); + int i; + unsigned vref_val; + + switch (m) { + case IIO_CHAN_INFO_SCALE: + vref_val = aim_spi_read(st, ADC_REG_VREF) & + (st->id == CHIPID_AD9643 ? AD9643_REG_VREF_MASK : + AD9467_REG_VREF_MASK); + + for (i = 0; i < st->chip_info->num_scales; i++) + if (vref_val == st->chip_info->scale_table[i][1]) + break; + + *val = 0; + *val2 = st->chip_info->scale_table[i][0]; + + return IIO_VAL_INT_PLUS_MICRO; + } + return -EINVAL; +} + + +static int aim_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct aim_state *st = iio_priv(indio_dev); + int i; + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + if (val != 0) + return -EINVAL; + + for (i = 0; i < st->chip_info->num_scales; i++) + if (val2 == st->chip_info->scale_table[i][0]) { + aim_spi_write(st, ADC_REG_VREF, + st->chip_info->scale_table[i][1]); + aim_spi_write(st, ADC_REG_TRANSFER, + TRANSFER_SYNC); + return 0; + } + + return -EINVAL; + default: + return -EINVAL; + } +} + +static ssize_t aim_show_scale_available(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct aim_state *st = iio_priv(indio_dev); + int i, len = 0; + + for (i = 0; i < st->chip_info->num_scales; i++) + len += sprintf(buf + len, "0.%06u ", + st->chip_info->scale_table[i][0]); + + len += sprintf(buf + len, "\n"); + + return len; +} + +static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO, + aim_show_scale_available, NULL, 0); + +static struct attribute *aim_attributes[] = { + &iio_dev_attr_in_voltage_scale_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group aim_attribute_group = { + .attrs = aim_attributes, +}; + +static const int ad9467_scale_table[][2] = { + {30517, 0}, {32043, 6}, {33569, 7}, + {35095, 8}, {36621, 9}, {38146, 10}, +}; + +static const int ad9643_scale_table[][2] = { + {31738, 0xF}, {31403, 0xE}, {31067, 0xD}, {30731, 0xC}, {30396, 0xB}, + {30060, 0xA}, {29724, 0x9}, {29388, 0x8}, {29053, 0x7}, {28717, 0x6}, + {28381, 0x5}, {28046, 0x4}, {27710, 0x3}, {27374, 0x2}, {27039, 0x1}, + {26703, 0x0}, {26367, 0x1F}, {26031, 0x1E}, {25696, 0x1D}, + {25360, 0x1C}, {25024, 0x1B}, {24689, 0x1A}, {24353, 0x19}, + {24017, 0x18}, {23682, 0x17}, {23346, 0x16}, {23010, 0x15}, + {22675, 0x14}, {22339, 0x13}, {22003, 0x12}, {21667, 0x11}, + {21332, 0x10}, +}; + +#define AIM_CHAN(_chan, _si, _bits, _sign) \ + { .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = _chan, \ + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .scan_index = _si, \ + .scan_type = IIO_ST(_sign, _bits, 16, 0)} + +static const struct aim_chip_info aim_chip_info_tbl[] = { + [ID_AD9467] = { + .name = "AD9467", + .scale_table = ad9467_scale_table, + .num_scales = ARRAY_SIZE(ad9467_scale_table), + .num_channels = 1, + .available_scan_masks[0] = BIT(0), + .channel[0] = AIM_CHAN(0, 0, 16, 's'), + }, + [ID_AD9643] = { + .name = "AD9643", + .scale_table = ad9643_scale_table, + .num_scales = ARRAY_SIZE(ad9643_scale_table), + .num_channels = 2, + .available_scan_masks[0] = BIT(0) | BIT(1), + .channel[0] = AIM_CHAN(0, 0, 14, 'u'), + .channel[1] = AIM_CHAN(1, 1, 14, 'u'), + }, +}; + +static const struct iio_info aim_info = { + .driver_module = THIS_MODULE, + .read_raw = &aim_read_raw, + .write_raw = &aim_write_raw, + .attrs = &aim_attribute_group, + .debugfs_reg_access = &aim_reg_access, +}; + +struct aim_dma_params { + struct device_node *of_node; + int chan_id; +}; + +static bool aim_dma_filter(struct dma_chan *chan, void *param) +{ + struct aim_dma_params *p = param; + + return chan->device->dev->of_node == p->of_node && + chan->chan_id == p->chan_id; +} + +/** + * aim_of_probe - probe method for the AIM device. + * @of_dev: pointer to OF device structure + * @match: pointer to the structure used for matching a device + * + * This function probes the AIM device in the device tree. + * It initializes the driver data structure and the hardware. + * It returns 0, if the driver is bound to the AIM device, or a negative + * value if there is an error. + */ +static int __devinit aim_of_probe(struct platform_device *op) +{ + struct iio_dev *indio_dev; + struct device *dev = &op->dev; + struct aim_state *st; + struct resource r_mem; /* IO mem resources */ + struct spi_master *spi_master; + struct device_node *nspi; + struct aim_dma_params dma_params; + struct of_phandle_args dma_spec; + dma_cap_mask_t mask; + resource_size_t remap_size, phys_addr; + unsigned def_mode, dco_delay; + int ret; + + dev_info(dev, "Device Tree Probing \'%s\'\n", + op->dev.of_node->name); + + /* Get iospace for the device */ + ret = of_address_to_resource(op->dev.of_node, 0, &r_mem); + if (ret) { + dev_err(dev, "invalid address\n"); + return ret; + } + + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + + dev_set_drvdata(dev, indio_dev); + mutex_init(&st->lock); + + phys_addr = r_mem.start; + remap_size = resource_size(&r_mem); + if (!request_mem_region(phys_addr, remap_size, KBUILD_MODNAME)) { + dev_err(dev, "Couldn't lock memory region at 0x%08llX\n", + (unsigned long long)phys_addr); + ret = -EBUSY; + goto failed1; + } + + st->regs = ioremap(phys_addr, remap_size); + if (st->regs == NULL) { + dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n", + (unsigned long long)phys_addr); + ret = -EFAULT; + goto failed2; + } + /* Get dma channel for the device */ + ret = of_parse_phandle_with_args(op->dev.of_node, "dma-request", + "#dma-cells", 0, &dma_spec); + if (ret) { + dev_err(dev, "Couldn't parse dma-request\n"); + goto failed2; + } + + dma_params.of_node = dma_spec.np; + dma_params.chan_id = dma_spec.args[0]; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE | DMA_PRIVATE, mask); + + st->rx_chan = dma_request_channel(mask, aim_dma_filter, &dma_params); + if (!st->rx_chan) { + dev_err(dev, "failed to find rx dma device\n"); + goto failed2; + } + /* + * Get SPI configuration interface for the device + * We are platform_driver, so we need other means to get the + * associated control interface. + */ + ret = of_property_read_u32(op->dev.of_node, + "spibus-slaveselect-connected", + &st->spi_ssel); + if (ret) { + dev_err(dev, "failed to get connected SPI slave select\n"); + goto failed3; + } + + nspi = of_parse_phandle(op->dev.of_node, "spibus-connected", 0); + spi_master = spi_of_node_to_master(nspi); + + if (spi_master != NULL) { + struct spi_board_info info = { + .modalias = KBUILD_MODNAME, + .max_speed_hz = 1000000, + .chip_select = st->spi_ssel, + .mode = SPI_MODE_0 | SPI_3WIRE, + }; + st->spi = spi_new_device(spi_master, &info); + if (st->spi == NULL) { + dev_err(dev, "failed to add spi device\n"); + goto failed3; + } + } else { + dev_dbg(dev, "could not find SPI master node," + "using pcore spi implementation\n"); + } + + /* Probe device */ + st->id = aim_spi_read(st, ADC_REG_CHIP_ID); + + switch (st->id) { + case CHIPID_AD9467: + st->chip_info = &aim_chip_info_tbl[ID_AD9467]; + def_mode = AD9467_DEF_OUTPUT_MODE | OUTPUT_MODE_TWOS_COMPLEMENT; + break; + case CHIPID_AD9643: + st->chip_info = &aim_chip_info_tbl[ID_AD9643]; + def_mode = AD9643_DEF_OUTPUT_MODE | OUTPUT_MODE_OFFSET_BINARY; + break; + default: + dev_err(dev, "Unrecognized CHIP_ID 0x%X\n", st->id); + ret = -ENODEV; + goto failed3; + } + + indio_dev->dev.parent = dev; + indio_dev->name = op->dev.of_node->name; + indio_dev->channels = st->chip_info->channel; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->num_channels = st->chip_info->num_channels; + indio_dev->available_scan_masks = st->chip_info->available_scan_masks; + indio_dev->info = &aim_info; + + init_completion(&st->dma_complete); + + aim_spi_write(st, ADC_REG_OUTPUT_MODE, def_mode); + aim_spi_write(st, ADC_REG_TEST_IO, TESTMODE_OFF); + + ret = of_property_read_u32(op->dev.of_node, + "dco-output-delay", + &dco_delay); + if (!ret) { + aim_spi_write(st, ADC_REG_OUTPUT_DELAY, dco_delay); + } + aim_spi_write(st, ADC_REG_TRANSFER, TRANSFER_SYNC); + + aim_configure_ring(indio_dev); + ret = iio_buffer_register(indio_dev, + st->chip_info->channel, + ARRAY_SIZE(st->chip_info->channel)); + if (ret) + goto failed4; + + ret = iio_device_register(indio_dev); + if (ret) + goto failed4; + + dev_info(dev, "ADI AIM (0x%X) at 0x%08llX mapped to 0x%p," + " DMA-%d probed ADC %s as %s\n", + aim_read(st, AD9467_PCORE_VERSION), + (unsigned long long)phys_addr, st->regs, + st->rx_chan->chan_id, st->chip_info->name, + (aim_read(st, AD9467_PCORE_IDENT) & + AD9467_PCORE_IDENT_SLAVE) ? "SLAVE" : "MASTER"); + + if (iio_get_debugfs_dentry(indio_dev)) + debugfs_create_file("pseudorandom_err_check", 0644, + iio_get_debugfs_dentry(indio_dev), + indio_dev, &aim_debugfs_pncheck_fops); + + return 0; + +failed4: + aim_unconfigure_ring(indio_dev); +failed3: + dma_release_channel(st->rx_chan); +failed2: + release_mem_region(phys_addr, remap_size); +failed1: + iio_free_device(indio_dev); + dev_set_drvdata(dev, NULL); + + return ret; +} + +/** + * aim_of_remove - unbinds the driver from the AIM device. + * @of_dev: pointer to OF device structure + * + * This function is called if a device is physically removed from the system or + * if the driver module is being unloaded. It frees any resources allocated to + * the device. + */ +static int __devexit aim_of_remove(struct platform_device *op) +{ + struct device *dev = &op->dev; + struct resource r_mem; /* IO mem resources */ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct aim_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + iio_buffer_unregister(indio_dev); + aim_unconfigure_ring(indio_dev); + + dma_release_channel(st->rx_chan); + + iounmap(st->regs); + + /* Get iospace of the device */ + if (of_address_to_resource(op->dev.of_node, 0, &r_mem)) + dev_err(dev, "invalid address\n"); + else + release_mem_region(r_mem.start, resource_size(&r_mem)); + + iio_free_device(indio_dev); + + dev_set_drvdata(dev, NULL); + + return 0; +} + +/* Match table for of_platform binding */ +static const struct of_device_id aim_of_match[] __devinitconst = { + { .compatible = "xlnx,cf-ad9467-core-1.00.a", }, + { .compatible = "xlnx,cf-ad9643-core-1.00.a", }, + { /* end of list */ }, +}; +MODULE_DEVICE_TABLE(of, aim_of_match); + +static struct platform_driver aim_of_driver = { + .driver = { + .name = KBUILD_MODNAME, + .owner = THIS_MODULE, + .of_match_table = aim_of_match, + }, + .probe = aim_of_probe, + .remove = __devexit_p(aim_of_remove), +}; + +module_platform_driver(aim_of_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices ADI-AIM"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/cf_ad9467_ring.c b/drivers/staging/iio/adc/cf_ad9467_ring.c new file mode 100644 index 0000000000000..76746fe4eb310 --- /dev/null +++ b/drivers/staging/iio/adc/cf_ad9467_ring.c @@ -0,0 +1,259 @@ +/* + * ADI-AIM ADC Interface Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../buffer.h" +#include "../ring_hw.h" +#include "cf_ad9467.h" +#include "cf_fft_core.h" + +static int aim_read_first_n_hw_rb(struct iio_buffer *r, + size_t count, char __user *buf) +{ + struct iio_hw_buffer *hw_ring = iio_to_hw_buf(r); + struct iio_dev *indio_dev = hw_ring->private; + struct aim_state *st = iio_priv(indio_dev); + int ret; + unsigned stat, dma_stat; + + mutex_lock(&st->lock); + + ret = wait_for_completion_interruptible_timeout(&st->dma_complete, + 4 * HZ); + + stat = aim_read(st, AD9467_PCORE_ADC_STAT); + dma_stat = aim_read(st, AD9467_PCORE_DMA_STAT); + + if (st->compl_stat < 0) { + ret = st->compl_stat; + goto error_ret; + } else if (ret == 0) { + ret = -ETIMEDOUT; + dev_err(indio_dev->dev.parent, + "timeout: DMA_STAT 0x%X, ADC_STAT 0x%X\n", + dma_stat, stat); + goto error_ret; + } else if (ret < 0) { + goto error_ret; + } + +#if defined(CONFIG_CF_FFT) + if (st->fftcount) { + ret = fft_calculate(st->buf_phys, st->buf_phys + st->fftcount, st->fftcount / 4); + } +#endif + if (copy_to_user(buf, st->buf_virt + st->fftcount, count)) + ret = -EFAULT; + + if ((stat & AD9467_PCORE_ADC_STAT_OVR) || dma_stat) + dev_warn(indio_dev->dev.parent, + "STATUS: DMA_STAT 0x%X, ADC_STAT 0x%X\n", + dma_stat, stat); + +error_ret: + r->stufftoread = 0; + + mutex_unlock(&st->lock); + + return ret < 0 ? ret : count; +} + +static int aim_ring_get_length(struct iio_buffer *r) +{ + struct iio_hw_buffer *hw_ring = iio_to_hw_buf(r); + struct iio_dev *indio_dev = hw_ring->private; + struct aim_state *st = iio_priv(indio_dev); + + return st->ring_lenght; +} + +static int aim_ring_set_length(struct iio_buffer *r, int lenght) +{ + struct iio_hw_buffer *hw_ring = iio_to_hw_buf(r); + struct aim_state *st = iio_priv(hw_ring->private); + + st->ring_lenght = lenght; + + return 0; +} + +static int aim_ring_get_bytes_per_datum(struct iio_buffer *r) +{ + struct iio_hw_buffer *hw_ring = iio_to_hw_buf(r); + struct aim_state *st = iio_priv(hw_ring->private); + + return st->bytes_per_datum; +} + +static IIO_BUFFER_ENABLE_ATTR; +static IIO_BUFFER_LENGTH_ATTR; + +static struct attribute *aim_ring_attributes[] = { + &dev_attr_length.attr, + &dev_attr_enable.attr, + NULL, +}; + +static struct attribute_group aim_ring_attr = { + .attrs = aim_ring_attributes, + .name = "buffer", +}; + +static struct iio_buffer *aim_rb_allocate(struct iio_dev *indio_dev) +{ + struct iio_buffer *buf; + struct iio_hw_buffer *ring; + + ring = kzalloc(sizeof *ring, GFP_KERNEL); + if (!ring) + return NULL; + + ring->private = indio_dev; + buf = &ring->buf; + buf->attrs = &aim_ring_attr; + iio_buffer_init(buf); + + return buf; +} + +static inline void aim_rb_free(struct iio_buffer *r) +{ + kfree(iio_to_hw_buf(r)); +} + +static const struct iio_buffer_access_funcs aim_ring_access_funcs = { + .read_first_n = &aim_read_first_n_hw_rb, + .get_length = &aim_ring_get_length, + .set_length = &aim_ring_set_length, + .get_bytes_per_datum = &aim_ring_get_bytes_per_datum, +}; + +static int __aim_hw_ring_state_set(struct iio_dev *indio_dev, bool state) +{ + struct aim_state *st = iio_priv(indio_dev); + struct dma_async_tx_descriptor *desc; + dma_cookie_t cookie; + int ret = 0; + + if (!state) { + if (!completion_done(&st->dma_complete)) { + st->compl_stat = -EPERM; + dmaengine_terminate_all(st->rx_chan); + complete(&st->dma_complete); + } + + dma_free_coherent(indio_dev->dev.parent, + PAGE_ALIGN(st->rcount + st->fftcount), + st->buf_virt, st->buf_phys); + return 0; + } + + st->compl_stat = 0; + + if (st->ring_lenght == 0) { + ret = -EINVAL; + goto error_ret; + } + + if (st->ring_lenght % 8) + st->rcount = (st->ring_lenght + 8) & 0xFFFFFFF8; + else + st->rcount = st->ring_lenght; + +#if defined(CONFIG_CF_FFT) + st->fftcount = st->rcount; +#else + st->fftcount = 0; +#endif + + st->buf_virt = dma_alloc_coherent(indio_dev->dev.parent, + PAGE_ALIGN(st->rcount + st->fftcount), &st->buf_phys, + GFP_KERNEL); + if (st->buf_virt == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + desc = dmaengine_prep_slave_single(st->rx_chan, st->buf_phys, st->rcount, + DMA_FROM_DEVICE, DMA_PREP_INTERRUPT); + if (!desc) { + dev_err(indio_dev->dev.parent, + "Failed to allocate a dma descriptor\n"); + ret = -ENOMEM; + goto error_free; + } + + desc->callback = (dma_async_tx_callback) complete; + desc->callback_param = &st->dma_complete; + + cookie = dmaengine_submit(desc); + if (cookie < 0) { + dev_err(indio_dev->dev.parent, + "Failed to submit a dma transfer\n"); + ret = cookie; + goto error_free; + } + INIT_COMPLETION(st->dma_complete); + dma_async_issue_pending(st->rx_chan); + + aim_write(st, AD9467_PCORE_DMA_CTRL, 0); + aim_write(st, AD9467_PCORE_ADC_STAT, 0xFF); + aim_write(st, AD9467_PCORE_DMA_STAT, 0xFF); + aim_write(st, AD9467_PCORE_DMA_CTRL, + AD9647_DMA_CAP_EN | AD9647_DMA_CNT((st->rcount / 8) - 1)); + + return 0; + +error_free: + dma_free_coherent(indio_dev->dev.parent, PAGE_ALIGN(st->rcount), + st->buf_virt, st->buf_phys); +error_ret: + + return ret; +} + +static int aim_hw_ring_preenable(struct iio_dev *indio_dev) +{ + return __aim_hw_ring_state_set(indio_dev, 1); +} + +static int aim_hw_ring_postdisable(struct iio_dev *indio_dev) +{ + return __aim_hw_ring_state_set(indio_dev, 0); +} + +static const struct iio_buffer_setup_ops aim_ring_setup_ops = { + .preenable = &aim_hw_ring_preenable, + .postdisable = &aim_hw_ring_postdisable, +}; + +int aim_configure_ring(struct iio_dev *indio_dev) +{ + indio_dev->buffer = aim_rb_allocate(indio_dev); + if (indio_dev->buffer == NULL) + return -ENOMEM; + + indio_dev->modes |= INDIO_BUFFER_HARDWARE; + indio_dev->buffer->access = &aim_ring_access_funcs; + indio_dev->setup_ops = &aim_ring_setup_ops; + + return 0; +} + +void aim_unconfigure_ring(struct iio_dev *indio_dev) +{ + aim_rb_free(indio_dev->buffer); +} diff --git a/drivers/staging/iio/adc/cf_fft_core.c b/drivers/staging/iio/adc/cf_fft_core.c new file mode 100644 index 0000000000000..32de84fb701de --- /dev/null +++ b/drivers/staging/iio/adc/cf_fft_core.c @@ -0,0 +1,337 @@ +/* + * ADI-FFT Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + * + * http://wiki.analog.com/resources/fpga/xilinx/ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/*************************************************************************** + * register definitions (fft) + * 5'h00: + * [31: 0]: version(32'h00010061) + * 5'h01: + * [31: 0]: up_cfg_data, fft cfg data (refer Xilinx fft core for details). + * 5'h02: + * [ 3: 3]: up_status_ovf, fft overflow (mapped to Xilinx fft core outputs). + * [ 2: 2]: up_status_lm, fft tlast missing (mapped to core). + * [ 1: 1]: up_status_lu, fft tlast unexpected (mapped to core). + * [ 0: 0]: up_status_fs, fft frame start (mapped to core). + ***************************************************************************/ + +#define FFT_PCORE_VERSION 0x0 +#define FFT_PCORE_CFG 0x4 +#define FFT_PCORE_STAT 0x8 + +struct fft_state { + struct device *dev; + struct mutex lock; + struct completion dma_complete; + struct dma_chan *rx_chan; + struct dma_chan *tx_chan; + void __iomem *regs; + int compl_stat; +}; + +struct fft_dma_params { + struct device_node *of_node; + enum dma_transfer_direction direction; + int chan_id; +}; + +struct fft_state *fft_state_glob; + +/* + * IO accessors + */ + +static inline void fft_write(struct fft_state *st, unsigned reg, unsigned val) +{ + iowrite32(val, st->regs + reg); +} + +static inline unsigned int fft_read(struct fft_state *st, unsigned reg) +{ + return ioread32(st->regs + reg); +} + +static bool fft_dma_filter(struct dma_chan *chan, void *param) +{ + struct fft_dma_params *p = param; + + return chan->device->dev->of_node == p->of_node && + chan->chan_id == p->chan_id; +} + +int fft_calculate(dma_addr_t src, dma_addr_t dest, unsigned int size) +{ + struct fft_state *st = fft_state_glob; + struct dma_async_tx_descriptor *tx_desc, *rx_desc; + dma_cookie_t tx_cookie, rx_cookie; + unsigned nfft = ilog2(size); + int ret = 0; + + if (st == NULL) + return -ENODEV; + + if (((1 << nfft) != size) || !src || !dest) + return -EINVAL; + + /* printk("%s: %d: SRC: %p DEST: %p SIZE %d NFFT %d\n",__func__,__LINE__, src, dest, size, nfft); */ + + mutex_lock(&st->lock); + + fft_write(st, FFT_PCORE_CFG, 0x10000 | nfft); + + tx_desc = dmaengine_prep_slave_single(st->tx_chan, src, size * 4, + DMA_TO_DEVICE, 0); + if (!tx_desc) { + dev_err(st->dev, + "Failed to allocate a dma descriptor\n"); + ret = -ENOMEM; + goto error_ret; + } + + tx_cookie = dmaengine_submit(tx_desc); + if (tx_cookie < 0) { + dev_err(st->dev, + "Failed to submit a dma transfer\n"); + ret = tx_cookie; + goto error_ret; + } + + rx_desc = dmaengine_prep_slave_single(st->rx_chan, dest, size * 4, + DMA_FROM_DEVICE, DMA_PREP_INTERRUPT); + if (!rx_desc) { + dev_err(st->dev, + "Failed to allocate a dma descriptor\n"); + ret = -ENOMEM; + goto error_ret; + } + + rx_desc->callback = (dma_async_tx_callback) complete; + rx_desc->callback_param = &st->dma_complete; + + rx_cookie = dmaengine_submit(rx_desc); + if (rx_cookie < 0) { + dev_err(st->dev, + "Failed to submit a dma transfer\n"); + ret = rx_cookie; + goto error_ret; + } + + dma_async_issue_pending(st->tx_chan); + dma_async_issue_pending(st->rx_chan); + + ret = wait_for_completion_interruptible_timeout(&st->dma_complete, + 4 * HZ); + if (ret == 0) { + ret = -ETIMEDOUT; + goto error_ret; + } else if (ret < 0) { + goto error_ret; + } + + ret = 0; + +error_ret: + mutex_unlock(&st->lock); + return ret; +} +EXPORT_SYMBOL_GPL(fft_calculate); + +/** + * fft_of_probe - probe method for the AIM device. + * @of_dev: pointer to OF device structure + * @match: pointer to the structure used for matching a device + * + * This function probes the AIM device in the device tree. + * It initializes the driver data structure and the hardware. + * It returns 0, if the driver is bound to the AIM device, or a negative + * value if there is an error. + */ +static int __devinit fft_of_probe(struct platform_device *op) +{ + struct device *dev = &op->dev; + struct fft_state *st; + struct resource r_mem; /* IO mem resources */ + struct fft_dma_params dma_params; + struct of_phandle_args dma_spec; + dma_cap_mask_t mask; + resource_size_t remap_size, phys_addr; + int ret; + + dev_info(dev, "Device Tree Probing \'%s\'\n", + op->dev.of_node->name); + + st = devm_kzalloc(&op->dev, sizeof(*st), GFP_KERNEL); + if (!st) { + dev_err(dev, "Not enough memory for device\n"); + return -ENOMEM; + } + + st->dev = dev; + dev_set_drvdata(dev, st); + mutex_init(&st->lock); + + /* Get iospace for the device */ + ret = of_address_to_resource(op->dev.of_node, 0, &r_mem); + if (ret) { + dev_err(dev, "invalid address\n"); + return ret; + } + + phys_addr = r_mem.start; + remap_size = resource_size(&r_mem); + if (!request_mem_region(phys_addr, remap_size, KBUILD_MODNAME)) { + dev_err(dev, "Couldn't lock memory region at 0x%08llX\n", + (unsigned long long)phys_addr); + ret = -EBUSY; + goto failed1; + } + + st->regs = ioremap(phys_addr, remap_size); + if (st->regs == NULL) { + dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n", + (unsigned long long)phys_addr); + ret = -EFAULT; + goto failed2; + } + + /* Get dma channel for the device */ + ret = of_parse_phandle_with_args(op->dev.of_node, "dma-request", + "#dma-cells", 0, &dma_spec); + if (ret) { + dev_err(dev, "Couldn't parse dma-request\n"); + goto failed2; + } + + dma_params.of_node = dma_spec.np; + dma_params.chan_id = dma_spec.args[0]; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE | DMA_PRIVATE, mask); + + st->tx_chan = dma_request_channel(mask, fft_dma_filter, &dma_params); + if (!st->tx_chan) { + dev_err(dev, "failed to find tx dma device\n"); + goto failed2; + } + + /* Get dma channel for the device */ + ret = of_parse_phandle_with_args(op->dev.of_node, "dma-request", + "#dma-cells", 1, &dma_spec); + if (ret) { + dev_err(dev, "Couldn't parse dma-request\n"); + goto failed2; + } + + dma_params.of_node = dma_spec.np; + dma_params.chan_id = dma_spec.args[0]; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE | DMA_PRIVATE, mask); + + st->rx_chan = dma_request_channel(mask, fft_dma_filter, &dma_params); + if (!st->rx_chan) { + dev_err(dev, "failed to find rx dma device\n"); + goto failed2; + } + + init_completion(&st->dma_complete); + + dev_info(dev, "ADI-FFT (0x%X) at 0x%08llX mapped to 0x%p," + " DMA-%d, DMA-%d probed\n", + fft_read(st, FFT_PCORE_VERSION), + (unsigned long long)phys_addr, st->regs, + st->rx_chan->chan_id, st->tx_chan->chan_id); + + fft_state_glob = st; + + return 0; + +failed3: + dma_release_channel(st->rx_chan); +failed2: + release_mem_region(phys_addr, remap_size); +failed1: + dev_set_drvdata(dev, NULL); + + return ret; +} + +/** + * fft_of_remove - unbinds the driver from the AIM device. + * @of_dev: pointer to OF device structure + * + * This function is called if a device is physically removed from the system or + * if the driver module is being unloaded. It frees any resources allocated to + * the device. + */ +static int __devexit fft_of_remove(struct platform_device *op) +{ + struct device *dev = &op->dev; + struct resource r_mem; /* IO mem resources */ + struct fft_state *st = dev_get_drvdata(dev); + + dma_release_channel(st->rx_chan); + dma_release_channel(st->tx_chan); + + iounmap(st->regs); + + /* Get iospace of the device */ + if (of_address_to_resource(op->dev.of_node, 0, &r_mem)) + dev_err(dev, "invalid address\n"); + else + release_mem_region(r_mem.start, resource_size(&r_mem)); + + dev_set_drvdata(dev, NULL); + fft_state_glob = NULL; + + return 0; +} + +/* Match table for of_platform binding */ +static const struct of_device_id fft_of_match[] __devinitconst = { + { .compatible = "xlnx,cf-fft-core-1.00.a", }, + { /* end of list */ }, +}; +MODULE_DEVICE_TABLE(of, fft_of_match); + +static struct platform_driver fft_of_driver = { + .driver = { + .name = KBUILD_MODNAME, + .owner = THIS_MODULE, + .of_match_table = fft_of_match, + }, + .probe = fft_of_probe, + .remove = __devexit_p(fft_of_remove), +}; + +module_platform_driver(fft_of_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices CF FFT"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/cf_fft_core.h b/drivers/staging/iio/adc/cf_fft_core.h new file mode 100644 index 0000000000000..a39d9f9341e29 --- /dev/null +++ b/drivers/staging/iio/adc/cf_fft_core.h @@ -0,0 +1,16 @@ +/* + * ADI-FFT Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + * + * http://wiki.analog.com/resources/fpga/xilinx/ + */ + +#ifndef ADI_FFT_H_ +#define ADI_FFT_H_ + +int fft_calculate(dma_addr_t src, dma_addr_t dest, unsigned int size); + +#endif /* ADI_FFT_H_ */ diff --git a/drivers/staging/iio/amplifiers/Kconfig b/drivers/staging/iio/amplifiers/Kconfig new file mode 100644 index 0000000000000..05d707ed7d4f9 --- /dev/null +++ b/drivers/staging/iio/amplifiers/Kconfig @@ -0,0 +1,17 @@ +# +# Gain Amplifiers, etc. +# +menu "Amplifiers" + +config AD8366 + tristate "Analog Devices AD8366 VGA" + depends on SPI + select BITREVERSE + help + Say yes here to build support for Analog Devices AD8366 + SPI Dual-Digital Variable Gain Amplifier (VGA). + + To compile this driver as a module, choose M here: the + module will be called ad8366. + +endmenu diff --git a/drivers/staging/iio/amplifiers/Makefile b/drivers/staging/iio/amplifiers/Makefile new file mode 100644 index 0000000000000..a6ca366908e07 --- /dev/null +++ b/drivers/staging/iio/amplifiers/Makefile @@ -0,0 +1,5 @@ +# +# Makefile iio/amplifiers +# + +obj-$(CONFIG_AD8366) += ad8366.o diff --git a/drivers/staging/iio/amplifiers/ad8366.c b/drivers/staging/iio/amplifiers/ad8366.c new file mode 100644 index 0000000000000..b042b6ce24548 --- /dev/null +++ b/drivers/staging/iio/amplifiers/ad8366.c @@ -0,0 +1,223 @@ +/* + * AD8366 SPI Dual-Digital Variable Gain Amplifier (VGA) + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +struct ad8366_state { + struct spi_device *spi; + struct regulator *reg; + unsigned char ch[2]; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + unsigned char data[2] ____cacheline_aligned; +}; + +static int ad8366_write(struct iio_dev *indio_dev, + unsigned char ch_a, char unsigned ch_b) +{ + struct ad8366_state *st = iio_priv(indio_dev); + int ret; + + ch_a = bitrev8(ch_a & 0x3F); + ch_b = bitrev8(ch_b & 0x3F); + + st->data[0] = ch_b >> 4; + st->data[1] = (ch_b << 4) | (ch_a >> 2); + + ret = spi_write(st->spi, st->data, ARRAY_SIZE(st->data)); + if (ret < 0) + dev_err(&indio_dev->dev, "write failed (%d)", ret); + + return ret; +} + +static int ad8366_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + struct ad8366_state *st = iio_priv(indio_dev); + int ret; + unsigned code; + + mutex_lock(&indio_dev->mlock); + switch (m) { + case 0: + code = st->ch[chan->channel]; + + /* Values in dB */ + code = code * 253 + 4500; + *val = code / 1000; + *val2 = (code % 1000) * 1000; + + ret = IIO_VAL_INT_PLUS_MICRO; + break; + default: + ret = -EINVAL; + } + mutex_unlock(&indio_dev->mlock); + + return ret; +}; + +static int ad8366_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct ad8366_state *st = iio_priv(indio_dev); + unsigned code; + int ret; + + /* Values in dB */ + code = (((u8)val * 1000) + ((u32)val2 / 1000)); + + if (code > 20500 || code < 4500) + return -EINVAL; + + code = (code - 4500) / 253; + + mutex_lock(&indio_dev->mlock); + switch (mask) { + case 0: + st->ch[chan->channel] = code; + ret = ad8366_write(indio_dev, st->ch[0], st->ch[1]); + break; + default: + ret = -EINVAL; + } + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static const struct iio_info ad8366_info = { + .read_raw = &ad8366_read_raw, + .write_raw = &ad8366_write_raw, + .driver_module = THIS_MODULE, +}; + +#define AD8366_CHAN(_channel, _name) { \ + .type = IIO_ALTVOLTAGE, \ + .output = 1, \ + .indexed = 1, \ + .processed_val = 1, \ + .channel = _channel, \ + .extend_name = _name, \ +} + +static const struct iio_chan_spec ad8366_channels[] = { + AD8366_CHAN(0, "gain"), + AD8366_CHAN(1, "gain"), +}; + +static int __devinit ad8366_probe(struct spi_device *spi) +{ + struct iio_dev *indio_dev; + struct ad8366_state *st; + int ret; + + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + + st->reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + } + + spi_set_drvdata(spi, indio_dev); + st->spi = spi; + + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi->dev.platform_data ? spi->dev.platform_data : + spi_get_device_id(spi)->name; + indio_dev->info = &ad8366_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = ad8366_channels; + indio_dev->num_channels = ARRAY_SIZE(ad8366_channels); + + ret = ad8366_write(indio_dev, 0 , 0); + if (ret < 0) + goto error_disable_reg; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_disable_reg; + + return 0; + +error_disable_reg: + if (!IS_ERR(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR(st->reg)) + regulator_put(st->reg); + + iio_free_device(indio_dev); + + return ret; +} + +static int __devexit ad8366_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad8366_state *st = iio_priv(indio_dev); + struct regulator *reg = st->reg; + + iio_device_unregister(indio_dev); + + if (!IS_ERR(reg)) { + regulator_disable(reg); + regulator_put(reg); + } + + iio_free_device(indio_dev); + + return 0; +} + +static const struct spi_device_id ad8366_id[] = { + {"ad8366", 0}, + {} +}; + +static struct spi_driver ad8366_driver = { + .driver = { + .name = KBUILD_MODNAME, + .owner = THIS_MODULE, + }, + .probe = ad8366_probe, + .remove = __devexit_p(ad8366_remove), + .id_table = ad8366_id, +}; + +module_spi_driver(ad8366_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD8366 VGA"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/consumer.h b/drivers/staging/iio/consumer.h new file mode 100644 index 0000000000000..36a060cd3a21d --- /dev/null +++ b/drivers/staging/iio/consumer.h @@ -0,0 +1,96 @@ +/* + * Industrial I/O in kernel consumer interface + * + * Copyright (c) 2011 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ +#ifndef _IIO_INKERN_CONSUMER_H_ +#define _IIO_INKERN_CONSUMER_H +#include "types.h" + +struct iio_dev; +struct iio_chan_spec; + +/** + * struct iio_channel - everything needed for a consumer to use a channel + * @indio_dev: Device on which the channel exists. + * @channel: Full description of the channel. + */ +struct iio_channel { + struct iio_dev *indio_dev; + const struct iio_chan_spec *channel; +}; + +/** + * iio_channel_get() - get description of all that is needed to access channel. + * @name: Unique name of the device as provided in the iio_map + * with which the desired provider to consumer mapping + * was registered. + * @consumer_channel: Unique name to identify the channel on the consumer + * side. This typically describes the channels use within + * the consumer. E.g. 'battery_voltage' + */ +struct iio_channel *iio_st_channel_get(const char *name, + const char *consumer_channel); + +/** + * iio_st_channel_release() - release channels obtained via iio_st_channel_get + * @chan: The channel to be released. + */ +void iio_st_channel_release(struct iio_channel *chan); + +/** + * iio_st_channel_get_all() - get all channels associated with a client + * @name: name of consumer device. + * + * Returns an array of iio_channel structures terminated with one with + * null iio_dev pointer. + * This function is used by fairly generic consumers to get all the + * channels registered as having this consumer. + */ +struct iio_channel *iio_st_channel_get_all(const char *name); + +/** + * iio_st_channel_release_all() - reverse iio_st_get_all + * @chan: Array of channels to be released. + */ +void iio_st_channel_release_all(struct iio_channel *chan); + +/** + * iio_st_read_channel_raw() - read from a given channel + * @channel: The channel being queried. + * @val: Value read back. + * + * Note raw reads from iio channels are in adc counts and hence + * scale will need to be applied if standard units required. + */ +int iio_st_read_channel_raw(struct iio_channel *chan, + int *val); + +/** + * iio_st_get_channel_type() - get the type of a channel + * @channel: The channel being queried. + * @type: The type of the channel. + * + * returns the enum iio_chan_type of the channel + */ +int iio_st_get_channel_type(struct iio_channel *channel, + enum iio_chan_type *type); + +/** + * iio_st_read_channel_scale() - read the scale value for a channel + * @channel: The channel being queried. + * @val: First part of value read back. + * @val2: Second part of value read back. + * + * Note returns a description of what is in val and val2, such + * as IIO_VAL_INT_PLUS_MICRO telling us we have a value of val + * + val2/1e6 + */ +int iio_st_read_channel_scale(struct iio_channel *chan, int *val, + int *val2); + +#endif diff --git a/drivers/staging/iio/driver.h b/drivers/staging/iio/driver.h new file mode 100644 index 0000000000000..a4f8b2e05af5e --- /dev/null +++ b/drivers/staging/iio/driver.h @@ -0,0 +1,34 @@ +/* + * Industrial I/O in kernel access map interface. + * + * Copyright (c) 2011 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#ifndef _IIO_INKERN_H_ +#define _IIO_INKERN_H_ + +struct iio_map; + +/** + * iio_map_array_register() - tell the core about inkernel consumers + * @indio_dev: provider device + * @map: array of mappings specifying association of channel with client + */ +int iio_map_array_register(struct iio_dev *indio_dev, + struct iio_map *map); + +/** + * iio_map_array_unregister() - tell the core to remove consumer mappings + * @indio_dev: provider device + * @map: array of mappings to remove. Note these must have same memory + * addresses as those originally added not just equal parameter + * values. + */ +int iio_map_array_unregister(struct iio_dev *indio_dev, + struct iio_map *map); + +#endif diff --git a/drivers/staging/iio/frequency/Makefile b/drivers/staging/iio/frequency/Makefile index 147746176b9b7..3f82cd368c149 100644 --- a/drivers/staging/iio/frequency/Makefile +++ b/drivers/staging/iio/frequency/Makefile @@ -1,7 +1,8 @@ # -# Makefile for Direct Digital Synthesis drivers +# Makefile iio/frequency # +obj-$(CONFIG_AD9523) += ad9523.o obj-$(CONFIG_AD5930) += ad5930.o obj-$(CONFIG_AD9832) += ad9832.o obj-$(CONFIG_AD9834) += ad9834.o @@ -9,3 +10,7 @@ obj-$(CONFIG_AD9850) += ad9850.o obj-$(CONFIG_AD9852) += ad9852.o obj-$(CONFIG_AD9910) += ad9910.o obj-$(CONFIG_AD9951) += ad9951.o +obj-$(CONFIG_ADF4350) += adf4350.o +obj-$(CONFIG_AD9122_CF) += cf_ad9122.o +obj-$(CONFIG_AD9122_CF_DAC) += ad9122.o +obj-$(CONFIG_AD9548) += ad9548.o diff --git a/drivers/staging/iio/frequency/ad9122.c b/drivers/staging/iio/frequency/ad9122.c new file mode 100644 index 0000000000000..a245da8af80eb --- /dev/null +++ b/drivers/staging/iio/frequency/ad9122.c @@ -0,0 +1,189 @@ +/* + * AD9122 SPI DAC driver for DDS PCORE/COREFPGA Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "cf_ad9122.h" + +#define CHIPID_AD9122 0x8 + +static const unsigned char ad9122_reg_defaults[][2] = { + {0x00, 0x00}, + {0x00, 0x20}, + {0x00, 0x00}, + {0x01, 0x10}, + {0x03, 0x80}, + {0x04, 0x00}, + {0x05, 0x00}, + {0x08, 0x3F}, + {0x0A, 0x40}, + {0x0C, 0xD1}, + {0x0D, 0xD6}, + {0x10, 0x48}, + {0x11, 0x00}, + {0x16, 0x00}, + {0x17, 0x04}, + {0x18, 0x00}, + {0x1B, 0xE0}, + {0x1C, 0x01}, + {0x1D, 0x01}, + {0x1E, 0x01}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0x00}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3A, 0x00}, + {0x3B, 0x00}, + {0x3C, 0x00}, + {0x3D, 0x00}, + {0x3E, 0x00}, + {0x3F, 0x00}, + {0x40, 0xF9}, + {0x41, 0x01}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0xF9}, + {0x45, 0x01}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x02}, + {0x18, 0x02}, +}; + +static int ad9122_read(struct spi_device *spi, unsigned reg) +{ + unsigned char buf[2]; + int ret; + + buf[0] = 0x80 | reg; + + ret = spi_write_then_read(spi, &buf[0], 1, &buf[1], 1); + if (ret < 0) + return ret; + + return buf[1]; +} + +static int ad9122_write(struct spi_device *spi, + unsigned reg, unsigned val) +{ + unsigned char buf[2]; + int ret; + + buf[0] = reg; + buf[1] = val; + ret = spi_write(spi, buf, 2); + if (ret < 0) + return ret; + + return 0; +} + +static int ad9122_setup(struct spi_device *spi, unsigned mode) +{ + int ret, i; + + for (i = 0; i < ARRAY_SIZE(ad9122_reg_defaults); i++) + ad9122_write(spi, ad9122_reg_defaults[i][0], + ad9122_reg_defaults[i][1]); + i = 255; + do { + mdelay(1); + ret = ad9122_read(spi, 0x18); + if (ret < 0) + return ret; + + } while (i-- && ((ret & (1 << 2) == 0))); + + ad9122_write(spi, 0x18, 0x0); + ad9122_write(spi, 0x10, 0x88); + + i = 255; + do { + mdelay(1); + ret = ad9122_read(spi, 0x12); + if (ret < 0) + return ret; + + } while (i-- && ((ret & (1 << 6)) == 0)); + + return 0; +} + + +static int __devinit ad9122_probe(struct spi_device *spi) +{ + struct ad9122_converter *conv; + unsigned id; + int ret; + + conv = kzalloc(sizeof(*conv), GFP_KERNEL); + if (conv == NULL) + return -ENOMEM; + + + id = ad9122_read(spi, 0x1f); + if (id != CHIPID_AD9122) { + dev_err(&spi->dev, "Unrecognized CHIP_ID 0x%X\n", id); + ret = -ENODEV; + goto out; + } + + conv->write = ad9122_write; + conv->read = ad9122_read; + conv->setup = ad9122_setup; + conv->spi = spi; + conv->id = ID_AD9122; + spi_set_drvdata(spi, conv); + + return 0; +out: + kfree(conv); + return ret; +} + +static int ad9122_remove(struct spi_device *spi) +{ + spi_set_drvdata(spi, NULL); + + return 0; +} + +static const struct spi_device_id ad9122_id[] = { + {"ad9122", 0}, + {} +}; +MODULE_DEVICE_TABLE(spi, ad9122_id); + +static struct spi_driver ad9122_driver = { + .driver = { + .name = "ad9122", + .owner = THIS_MODULE, + }, + .probe = ad9122_probe, + .remove = __devexit_p(ad9122_remove), + .id_table = ad9122_id, +}; +module_spi_driver(ad9122_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD9122 ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/frequency/ad9523.c b/drivers/staging/iio/frequency/ad9523.c new file mode 100644 index 0000000000000..1c1fff657ac2c --- /dev/null +++ b/drivers/staging/iio/frequency/ad9523.c @@ -0,0 +1,851 @@ +/* + * AD9523 SPI Low Jitter Clock Generator + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +#include "ad9523.h" + +enum { + AD9523_STATUS0, + AD9523_VCO1_FREQ, + AD9523_VCO2_FREQ, + AD9523_VCO_FREQ_AVAIL, + AD9523_SYNC, + AD9523_EEPROM, + AD9523_ALT_SRC_CH0, + AD9523_ALT_SRC_CH1, + AD9523_ALT_SRC_CH2, + AD9523_ALT_SRC_CH3, + AD9523_ALT_SRC_CH4, + AD9523_ALT_SRC_CH5, + AD9523_ALT_SRC_CH6, + AD9523_ALT_SRC_CH7, + AD9523_ALT_SRC_CH8, + AD9523_ALT_SRC_CH9, +}; + +#define AD_IF(_pde, _a) ((pdata->_pde) ? _a : 0) +#define AD_IFE(_pde, _a, _b) ((pdata->_pde) ? _a : _b) + +struct ad9523_state { + struct spi_device *spi; + struct regulator *reg; + struct ad9523_platform_data *pdata; + struct iio_chan_spec ad9523_channels[14]; + + unsigned long vcxo_freq; + unsigned long vco_freq; + unsigned long vco_out_freq[3]; + unsigned char vco_out_map[14]; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + union { + __be32 d32; + u8 d8[4]; + } data[2] ____cacheline_aligned; +}; + +static struct ad9523_platform_data default_pdata = { + +}; + +static int ad9523_read(struct iio_dev *indio_dev, unsigned addr) +{ + struct ad9523_state *st = iio_priv(indio_dev); + struct spi_message m; + int ret; + struct spi_transfer t[] = { + { + .tx_buf = &st->data[0].d8[2], + .len = 2, + .cs_change = 0, + }, { + .rx_buf = &st->data[1].d8[4 - AD9523_TRANSFER_LEN(addr)], + .len = AD9523_TRANSFER_LEN(addr), + }, + }; + + spi_message_init(&m); + spi_message_add_tail(&t[0], &m); + spi_message_add_tail(&t[1], &m); + + st->data[0].d32 = cpu_to_be32(AD9523_READ | + AD9523_CNT(AD9523_TRANSFER_LEN(addr)) | + AD9523_ADDR(addr)); + + ret = spi_sync(st->spi, &m); + if (ret >= 0) + ret = be32_to_cpu(st->data[1].d32) & (0xFFFFFF >> + (8 * (3 - AD9523_TRANSFER_LEN(addr)))); + else + dev_err(&indio_dev->dev, "read failed (%d)", ret); + + return ret; +}; + +static int ad9523_write(struct iio_dev *indio_dev, unsigned addr, unsigned val) +{ + struct ad9523_state *st = iio_priv(indio_dev); + struct spi_message m; + int ret; + struct spi_transfer t[] = { + { + .tx_buf = &st->data[0].d8[2], + .len = 2, + .cs_change = 0, + }, { + .tx_buf = &st->data[1].d8[4 - AD9523_TRANSFER_LEN(addr)], + .len = AD9523_TRANSFER_LEN(addr), + }, + }; + + spi_message_init(&m); + spi_message_add_tail(&t[0], &m); + spi_message_add_tail(&t[1], &m); + + st->data[0].d32 = cpu_to_be32(AD9523_WRITE | + AD9523_CNT(AD9523_TRANSFER_LEN(addr)) | + AD9523_ADDR(addr)); + st->data[1].d32 = cpu_to_be32(val); + + ret = spi_sync(st->spi, &m); + + + if (ret < 0) + dev_err(&indio_dev->dev, "write failed (%d)", ret); + + return ret; +} + +static int ad9523_io_update(struct iio_dev *indio_dev) +{ + return ad9523_write(indio_dev, AD9523_IO_UPDATE, AD9523_IO_UPDATE_EN); +} + +static int ad9523_vco_out_map(struct iio_dev *indio_dev, + unsigned ch, unsigned out) +{ + struct ad9523_state *st = iio_priv(indio_dev); + int ret; + unsigned mask; + + switch (ch) { + case 0 ... 3: + ret = ad9523_read(indio_dev, AD9523_PLL1_OUTPUT_CHANNEL_CTRL); + if (ret < 0) + break; + mask = AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH0 << ch; + if (out) { + ret |= mask; + out = 2; + } else { + ret &= ~mask; + } + ret = ad9523_write(indio_dev, AD9523_PLL1_OUTPUT_CHANNEL_CTRL, ret); + break; + case 4 ... 6: + ret = ad9523_read(indio_dev, AD9523_PLL1_OUTPUT_CTRL); + if (ret < 0) + break; + mask = AD9523_PLL1_OUTP_CTRL_VCO_DIV_SEL_CH4_M2 << (ch - 4); + if (out) + ret |= mask; + else + ret &= ~mask; + ret = ad9523_write(indio_dev, AD9523_PLL1_OUTPUT_CTRL, ret); + break; + case 7 ... 9: + ret = ad9523_read(indio_dev, AD9523_PLL1_OUTPUT_CHANNEL_CTRL); + if (ret < 0) + break; + mask = AD9523_PLL1_OUTP_CH_CTRL_VCO_DIV_SEL_CH7_M2 << (ch - 7); + if (out) + ret |= mask; + else + ret &= ~mask; + ret = ad9523_write(indio_dev, AD9523_PLL1_OUTPUT_CHANNEL_CTRL, ret); + break; + default: + return 0; + } + + st->vco_out_map[ch] = out; + return ret; +} + + +static ssize_t ad9523_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad9523_state *st = iio_priv(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + unsigned long readin, tmp; + int ret; + + ret = kstrtoul(buf, 10, &readin); + if (ret) + return ret; + + mutex_lock(&indio_dev->mlock); + switch ((u32)this_attr->address) { + case AD9523_VCO1_FREQ: + ret = ad9523_read(indio_dev, AD9523_PLL2_VCO_DIVIDER); + if (ret < 0) + goto out; + + tmp = st->vco_freq / readin; + if (tmp < 3 || tmp > 5) { + ret = -EINVAL; + goto out; + } + + ret &= 0xFC; + ret |= AD9523_PLL2_VCO_DIV_M1(tmp); + ret = ad9523_write(indio_dev, AD9523_PLL2_VCO_DIVIDER, ret); + if (ret < 0) + goto out; + st->vco_out_freq[0] = st->vco_freq / tmp; + break; + case AD9523_VCO2_FREQ: + ret = ad9523_read(indio_dev, AD9523_PLL2_VCO_DIVIDER); + if (ret < 0) + goto out; + + tmp = st->vco_freq / readin; + if (tmp < 3 || tmp > 5) { + ret = -EINVAL; + goto out; + } + + ret &= 0xCF; + ret |= AD9523_PLL2_VCO_DIV_M2(tmp); + ret = ad9523_write(indio_dev, AD9523_PLL2_VCO_DIVIDER, ret); + if (ret < 0) + goto out; + st->vco_out_freq[1] = st->vco_freq / tmp; + break; + case AD9523_ALT_SRC_CH0 ... AD9523_ALT_SRC_CH9: + ret = ad9523_vco_out_map(indio_dev, (u32)this_attr->address - + AD9523_ALT_SRC_CH0, !!readin); + if (ret < 0) + goto out; + break; + case AD9523_SYNC: + ret = ad9523_read(indio_dev, AD9523_STATUS_SIGNALS); + if (ret < 0) + goto out; + tmp = ret; + tmp |= AD9523_STATUS_SIGNALS_SYNC_MAN_CTRL; + ret = ad9523_write(indio_dev, AD9523_STATUS_SIGNALS, tmp); + if (ret < 0) + goto out; + ad9523_io_update(indio_dev); + tmp &= ~AD9523_STATUS_SIGNALS_SYNC_MAN_CTRL; + ret = ad9523_write(indio_dev, AD9523_STATUS_SIGNALS, tmp); + if (ret < 0) + goto out; + break; + case AD9523_EEPROM: + ret = ad9523_write(indio_dev, AD9523_EEPROM_CTRL1, + AD9523_EEPROM_CTRL1_EEPROM_WRITE_PROT_DIS); + if (ret < 0) + goto out; + ret = ad9523_write(indio_dev, AD9523_EEPROM_CTRL2, + AD9523_EEPROM_CTRL2_REG2EEPROM); + if (ret < 0) + goto out; + + tmp = 4; + do { + msleep(16); + ret = ad9523_read(indio_dev, + AD9523_EEPROM_DATA_XFER_STATUS); + if (ret < 0) + goto out; + } while ((ret & AD9523_EEPROM_DATA_XFER_IN_PROGRESS) && tmp--); + + ret = ad9523_write(indio_dev, AD9523_EEPROM_CTRL1, 0); + if (ret < 0) + goto out; + + ret = ad9523_read(indio_dev, AD9523_EEPROM_ERROR_READBACK); + if (ret < 0) + goto out; + + if (ret & AD9523_EEPROM_ERROR_READBACK_FAIL) { + dev_err(&indio_dev->dev, "Verify EEPROM failed"); + ret = -EIO; + } + break; + default: + ret = -ENODEV; + goto out; + } + + ret = ad9523_io_update(indio_dev); +out: + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static ssize_t ad9523_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad9523_state *st = iio_priv(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret = 0; + + mutex_lock(&indio_dev->mlock); + switch ((u32)this_attr->address) { + case AD9523_STATUS0: + ret = ad9523_read(indio_dev, AD9523_READBACK_0); + if (ret >= 0) { + ret = sprintf(buf, "PLL2 reference clock:\t%s\nPLL2 feedback clock:\t%s\nVCXO:\t%s\nREF_TEST:\t%s\nREFB:\t%s\nREFA:\t%s\nPLL2 lock detect:\t%s\nPLL1 lock detect:\t%s\n", + ((ret & AD9523_READBACK_0_STAT_PLL2_REF_CLK) ? "OK" : "MISSING"), + ((ret & AD9523_READBACK_0_STAT_PLL2_FB_CLK) ? "OK" : "MISSING"), + ((ret & AD9523_READBACK_0_STAT_VCXO) ? "OK" : "MISSING"), + ((ret & AD9523_READBACK_0_STAT_REF_TEST) ? "OK" : "MISSING"), + ((ret & AD9523_READBACK_0_STAT_REFB) ? "OK" : "MISSING"), + ((ret & AD9523_READBACK_0_STAT_REFA) ? "OK" : "MISSING"), + ((ret & AD9523_READBACK_0_STAT_PLL2_LD) ? "OK" : "FAIL"), + ((ret & AD9523_READBACK_0_STAT_PLL1_LD) ? "OK" : "FAIL")); + } + + break; + case AD9523_VCO1_FREQ: + ret = ad9523_read(indio_dev, AD9523_PLL2_VCO_DIVIDER); + if (ret < 0) + break; + ret = sprintf(buf, "%lu\n", st->vco_freq / ((ret & 0x3) + 3)); + break; + case AD9523_VCO2_FREQ: + ret = ad9523_read(indio_dev, AD9523_PLL2_VCO_DIVIDER); + if (ret < 0) + break; + ret = sprintf(buf, "%lu\n", st->vco_freq / + (((ret >> 4) & 0x3) + 3)); + break; + case AD9523_VCO_FREQ_AVAIL: + ret = sprintf(buf, "%lu %lu %lu\n", st->vco_freq / 3, + st->vco_freq / 4, st->vco_freq / 5); + break; + } + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static IIO_DEVICE_ATTR(vco1_frequency, S_IRUGO | S_IWUSR, + ad9523_show, + ad9523_store, + AD9523_VCO1_FREQ); + +static IIO_DEVICE_ATTR(vco2_frequency, S_IRUGO | S_IWUSR, + ad9523_show, + ad9523_store, + AD9523_VCO2_FREQ); + +static IIO_DEVICE_ATTR(vco_frequency_available, S_IRUGO, + ad9523_show, + NULL, + AD9523_VCO_FREQ_AVAIL); + +static IIO_DEVICE_ATTR(status, S_IRUGO, + ad9523_show, + NULL, + AD9523_STATUS0); + +static IIO_DEVICE_ATTR(sync, S_IWUSR, + NULL, + ad9523_store, + AD9523_SYNC); + +static IIO_DEVICE_ATTR(store_eeprom, S_IWUSR, + NULL, + ad9523_store, + AD9523_EEPROM); + +#define IIO_DEV_ATTR_CLK_SRC(_channel, _name) \ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_clk_src_##_name##_en,\ + S_IRUGO | S_IWUSR, ad9523_show, ad9523_store, \ + AD9523_ALT_SRC_CH##_channel) + +static IIO_DEV_ATTR_CLK_SRC(0, vcxo); +static IIO_DEV_ATTR_CLK_SRC(1, vcxo); +static IIO_DEV_ATTR_CLK_SRC(2, vcxo); +static IIO_DEV_ATTR_CLK_SRC(3, vcxo); +static IIO_DEV_ATTR_CLK_SRC(4, vco2); +static IIO_DEV_ATTR_CLK_SRC(5, vco2); +static IIO_DEV_ATTR_CLK_SRC(6, vco2); +static IIO_DEV_ATTR_CLK_SRC(7, vco2); +static IIO_DEV_ATTR_CLK_SRC(8, vco2); +static IIO_DEV_ATTR_CLK_SRC(9, vco2); + +static struct attribute *ad9523_attributes[] = { + &iio_dev_attr_status.dev_attr.attr, + &iio_dev_attr_sync.dev_attr.attr, + &iio_dev_attr_store_eeprom.dev_attr.attr, + &iio_dev_attr_vco_frequency_available.dev_attr.attr, + &iio_dev_attr_vco1_frequency.dev_attr.attr, + &iio_dev_attr_vco2_frequency.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_clk_src_vcxo_en.dev_attr.attr, + &iio_dev_attr_out_altvoltage1_clk_src_vcxo_en.dev_attr.attr, + &iio_dev_attr_out_altvoltage2_clk_src_vcxo_en.dev_attr.attr, + &iio_dev_attr_out_altvoltage3_clk_src_vcxo_en.dev_attr.attr, + &iio_dev_attr_out_altvoltage4_clk_src_vco2_en.dev_attr.attr, + &iio_dev_attr_out_altvoltage5_clk_src_vco2_en.dev_attr.attr, + &iio_dev_attr_out_altvoltage6_clk_src_vco2_en.dev_attr.attr, + &iio_dev_attr_out_altvoltage7_clk_src_vco2_en.dev_attr.attr, + &iio_dev_attr_out_altvoltage8_clk_src_vco2_en.dev_attr.attr, + &iio_dev_attr_out_altvoltage9_clk_src_vco2_en.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad9523_attribute_group = { + .attrs = ad9523_attributes, +}; + +static int ad9523_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + struct ad9523_state *st = iio_priv(indio_dev); + int ret; + + mutex_lock(&indio_dev->mlock); + ret = ad9523_read(indio_dev, AD9523_CHANNEL_CLOCK_DIST(chan->channel)); + mutex_unlock(&indio_dev->mlock); + + if (ret < 0) + return ret; + + switch (m) { + case 0: + *val = !(ret & AD9523_CLOCK_DIST_PWR_DOWN_EN); + return IIO_VAL_INT; + case IIO_CHAN_INFO_FREQUENCY: + *val = st->vco_out_freq[st->vco_out_map[chan->channel]] / + (((ret >> 8) & 0x3FF) + 1); + return IIO_VAL_INT; + case IIO_CHAN_INFO_PHASE: + *val = (ret >> 18) & 0x3F; + return IIO_VAL_INT; + default: + return -EINVAL; + } +}; + +static int ad9523_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct ad9523_state *st = iio_priv(indio_dev); + unsigned reg; + int ret, tmp; + + mutex_lock(&indio_dev->mlock); + ret = ad9523_read(indio_dev, AD9523_CHANNEL_CLOCK_DIST(chan->channel)); + if (ret < 0) + goto out; + + reg = ret; + + switch (mask) { + case 0: + if (val) + reg &= ~AD9523_CLOCK_DIST_PWR_DOWN_EN; + else + reg |= AD9523_CLOCK_DIST_PWR_DOWN_EN; + break; + case IIO_CHAN_INFO_FREQUENCY: + tmp = st->vco_out_freq[st->vco_out_map[chan->channel]] / val; + tmp = clamp(tmp, 1, 1024); + reg &= ~(0x3FF << 8); + reg |= AD9523_CLOCK_DIST_DIV(tmp); + break; + case IIO_CHAN_INFO_PHASE: + if (val < 0 || val > 63) { + ret = -EINVAL; + goto out; + } + reg &= ~(0x3F << 18); + reg |= AD9523_CLOCK_DIST_DIV_PHASE(val); + break; + default: + ret = -EINVAL; + goto out; + } + + ret = ad9523_write(indio_dev, AD9523_CHANNEL_CLOCK_DIST(chan->channel), + reg); + if (ret < 0) + goto out; + + ad9523_io_update(indio_dev); +out: + mutex_unlock(&indio_dev->mlock); + return ret; +} + +static int ad9523_reg_access(struct iio_dev *indio_dev, + unsigned reg, unsigned writeval, + unsigned *readval) +{ + int ret; + + mutex_lock(&indio_dev->mlock); + if (readval == NULL) { + ret = ad9523_write(indio_dev, reg | AD9523_R1B, writeval); + ad9523_io_update(indio_dev); + } else { + ret = ad9523_read(indio_dev, reg | AD9523_R1B); + if (ret < 0) + return ret; + *readval = ret; + ret = 0; + } + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static const struct iio_info ad9523_info = { + .read_raw = &ad9523_read_raw, + .write_raw = &ad9523_write_raw, + .debugfs_reg_access = &ad9523_reg_access, + .attrs = &ad9523_attribute_group, + .driver_module = THIS_MODULE, +}; + +static int ad9523_setup(struct iio_dev *indio_dev) +{ + struct ad9523_state *st = iio_priv(indio_dev); + struct ad9523_platform_data *pdata = st->pdata; + struct ad9523_channel_spec *chan; + unsigned active_mask = 0; + int ret, i; + + ret = ad9523_write(indio_dev, AD9523_SERIAL_PORT_CONFIG, + AD9523_SER_CONF_SOFT_RESET | + (st->spi->mode & SPI_3WIRE ? 0 : AD9523_SER_CONF_SDO_ACTIVE)); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_READBACK_CTRL, + AD9523_READBACK_CTRL_READ_BUFFERED); + if (ret < 0) + return ret; + + ret = ad9523_io_update(indio_dev); + if (ret < 0) + return ret; + + /* + * PLL1 Setup + */ + ret = ad9523_write(indio_dev, AD9523_PLL1_REF_A_DIVIDER, + pdata->refa_r_div); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL1_REF_B_DIVIDER, + pdata->refb_r_div); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL1_FEEDBACK_DIVIDER, + pdata->pll1_feedback_div); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL1_CHARGE_PUMP_CTRL, + AD9523_PLL1_CHARGE_PUMP_CURRENT_nA(pdata->pll1_charge_pump_current_nA) | + AD9523_PLL1_CHARGE_PUMP_MODE_NORMAL | + AD9523_PLL1_BACKLASH_PW_MIN); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL1_INPUT_RECEIVERS_CTRL, + AD_IF(refa_diff_rcv_en, AD9523_PLL1_REFA_RCV_EN) | + AD_IF(refb_diff_rcv_en, AD9523_PLL1_REFB_RCV_EN) | + AD_IF(osc_in_diff_en, AD9523_PLL1_OSC_IN_DIFF_EN) | + AD_IF(osc_in_cmos_neg_inp_en, AD9523_PLL1_OSC_IN_CMOS_NEG_INP_EN) | + AD_IF(refa_diff_rcv_en, AD9523_PLL1_REFA_DIFF_RCV_EN) | + AD_IF(refb_diff_rcv_en, AD9523_PLL1_REFB_DIFF_RCV_EN)); + if (ret < 0) + return ret; + + + ret = ad9523_write(indio_dev, AD9523_PLL1_REF_CTRL, + AD_IF(zd_in_diff_en, AD9523_PLL1_ZD_IN_DIFF_EN) | + AD_IF(zd_in_cmos_neg_inp_en, AD9523_PLL1_ZD_IN_CMOS_NEG_INP_EN) | + AD_IF(zero_delay_mode_internal_en, AD9523_PLL1_ZERO_DELAY_MODE_INT) | + AD_IF(osc_in_feedback_en, AD9523_PLL1_OSC_IN_PLL_FEEDBACK_EN) | + AD_IF(refa_cmos_neg_inp_en, AD9523_PLL1_REFA_CMOS_NEG_INP_EN) | + AD_IF(refb_cmos_neg_inp_en, AD9523_PLL1_REFB_CMOS_NEG_INP_EN)); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL1_MISC_CTRL, + AD9523_PLL1_REFB_INDEP_DIV_CTRL_EN | + /*AD9523_PLL1_OSC_CTRL_FAIL_VCC_BY2_EN |*/ + AD9523_PLL1_REF_MODE(pdata->ref_mode)); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL1_LOOP_FILTER_CTRL, + AD9523_PLL1_LOOP_FILTER_RZERO(pdata->pll1_loop_filter_rzero)); + if (ret < 0) + return ret; + /* + * PLL2 Setup + */ + + ret = ad9523_write(indio_dev, AD9523_PLL2_CHARGE_PUMP, + AD9523_PLL2_CHARGE_PUMP_CURRENT_nA(pdata->pll2_charge_pump_current_nA)); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL2_FEEDBACK_DIVIDER_AB, + AD9523_PLL2_FB_NDIV_A_CNT(pdata->pll2_ndiv_a_cnt) | + AD9523_PLL2_FB_NDIV_B_CNT(pdata->pll2_ndiv_b_cnt)); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL2_CTRL, + AD9523_PLL2_CHARGE_PUMP_MODE_NORMAL | + AD9523_PLL2_BACKLASH_CTRL_EN | + AD_IF(pll2_freq_doubler_en, AD9523_PLL2_FREQ_DOUBLER_EN)); + if (ret < 0) + return ret; + + st->vco_freq = (pdata->vcxo_freq * (pdata->pll2_freq_doubler_en ? 2 : 1) + / pdata->pll2_r2_div) * + AD9523_PLL2_FB_NDIV(pdata->pll2_ndiv_a_cnt, pdata->pll2_ndiv_b_cnt); + + ret = ad9523_write(indio_dev, AD9523_PLL2_VCO_CTRL, + AD9523_PLL2_VCO_CALIBRATE); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL2_VCO_DIVIDER, + AD9523_PLL2_VCO_DIV_M1(pdata->pll2_vco_diff_m1) | + AD9523_PLL2_VCO_DIV_M2(pdata->pll2_vco_diff_m2) | + AD_IFE(pll2_vco_diff_m1, 0, AD9523_PLL2_VCO_DIV_M1_PWR_DOWN_EN) | + AD_IFE(pll2_vco_diff_m2, 0, AD9523_PLL2_VCO_DIV_M2_PWR_DOWN_EN)); + if (ret < 0) + return ret; + + if (pdata->pll2_vco_diff_m1) + st->vco_out_freq[0] = st->vco_freq / pdata->pll2_vco_diff_m1; + + if (pdata->pll2_vco_diff_m2) + st->vco_out_freq[1] = st->vco_freq / pdata->pll2_vco_diff_m2; + + st->vco_out_freq[2] = pdata->vcxo_freq; + + ret = ad9523_write(indio_dev, AD9523_PLL2_R2_DIVIDER, + AD9523_PLL2_R2_DIVIDER_VAL(pdata->pll2_r2_div)); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL2_LOOP_FILTER_CTRL, + AD9523_PLL2_LOOP_FILTER_CPOLE1(pdata->cpole1) | + AD9523_PLL2_LOOP_FILTER_RZERO(pdata->rzero) | + AD9523_PLL2_LOOP_FILTER_RPOLE2(pdata->rpole2) | + AD_IF(rzero_bypass_en, AD9523_PLL2_LOOP_FILTER_RZERO_BYPASS_EN)); + if (ret < 0) + return ret; + + for (i = 0; i < pdata->num_channels; i++) { + chan = &pdata->channels[i]; + if (chan->channel_num <= AD9523_NUM_CHAN) { + active_mask |= (1 << chan->channel_num); + ret = ad9523_write(indio_dev, + AD9523_CHANNEL_CLOCK_DIST(chan->channel_num), + AD9523_CLOCK_DIST_DRIVER_MODE(chan->driver_mode) | + AD9523_CLOCK_DIST_DIV(chan->channel_divider) | + AD9523_CLOCK_DIST_DIV_PHASE(chan->divider_phase) | + (chan->sync_ignore_en ? AD9523_CLOCK_DIST_IGNORE_SYNC_EN : 0) | + (chan->divider_output_invert_en ? AD9523_CLOCK_DIST_INV_DIV_OUTPUT_EN : 0) | + (chan->low_power_mode_en ? AD9523_CLOCK_DIST_LOW_PWR_MODE_EN : 0) | + (chan->output_dis ? AD9523_CLOCK_DIST_PWR_DOWN_EN : 0)); + if (ret < 0) + return ret; + + ret = ad9523_vco_out_map(indio_dev, chan->channel_num, + chan->use_alt_clock_src); + if (ret < 0) + return ret; + + st->ad9523_channels[i].type = IIO_ALTVOLTAGE; + st->ad9523_channels[i].output = 1; + st->ad9523_channels[i].indexed = 1; + st->ad9523_channels[i].channel = chan->channel_num; + st->ad9523_channels[i].extend_name = chan->extended_name; + st->ad9523_channels[i].info_mask = IIO_CHAN_INFO_PHASE_SEPARATE_BIT | + IIO_CHAN_INFO_FREQUENCY_SEPARATE_BIT; + + } + } + + for (i = 0; i <= AD9523_NUM_CHAN; i++) + if (!(active_mask & (1 << i))) + ad9523_write(indio_dev, + AD9523_CHANNEL_CLOCK_DIST(i), + AD9523_CLOCK_DIST_DRIVER_MODE(TRISTATE) | + AD9523_CLOCK_DIST_PWR_DOWN_EN); + + ret = ad9523_write(indio_dev, AD9523_POWER_DOWN_CTRL, 0); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_STATUS_SIGNALS, 0x000302); + if (ret < 0) + return ret; + + ret = ad9523_io_update(indio_dev); + if (ret < 0) + return ret; + + return 0; +} + +static int __devinit ad9523_probe(struct spi_device *spi) +{ + struct ad9523_platform_data *pdata = spi->dev.platform_data; + struct iio_dev *indio_dev; + struct ad9523_state *st; + int ret; + + if (!pdata) { + dev_dbg(&spi->dev, "no platform data?\n"); + pdata = &default_pdata; + } + + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + + st->reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + } + + spi_set_drvdata(spi, indio_dev); + st->spi = spi; + st->pdata = pdata; + + indio_dev->dev.parent = &spi->dev; + indio_dev->name = (pdata->name[0] != 0) ? pdata->name : + spi_get_device_id(spi)->name; + indio_dev->info = &ad9523_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = st->ad9523_channels; + indio_dev->num_channels = pdata->num_channels; + + ret = ad9523_setup(indio_dev); + if (ret < 0) + goto error_disable_reg; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_disable_reg; + + dev_info(&spi->dev, "probed %s\n", indio_dev->name); + + return 0; + +error_disable_reg: + if (!IS_ERR(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR(st->reg)) + regulator_put(st->reg); + + iio_free_device(indio_dev); + + return ret; +} + +static int __devexit ad9523_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad9523_state *st = iio_priv(indio_dev); + struct regulator *reg = st->reg; + + iio_device_unregister(indio_dev); + + if (!IS_ERR(reg)) { + regulator_disable(reg); + regulator_put(reg); + } + + iio_free_device(indio_dev); + + return 0; +} + +static const struct spi_device_id ad9523_id[] = { + {"ad9523", 9523}, + {} +}; + +static struct spi_driver ad9523_driver = { + .driver = { + .name = "ad9523", + .owner = THIS_MODULE, + }, + .probe = ad9523_probe, + .remove = __devexit_p(ad9523_remove), + .id_table = ad9523_id, +}; + +static int __init ad9523_init(void) +{ + return spi_register_driver(&ad9523_driver); +} +module_init(ad9523_init); + +static void __exit ad9523_exit(void) +{ + spi_unregister_driver(&ad9523_driver); +} +module_exit(ad9523_exit); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD9523 CLOCKDIST/PLL"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/frequency/ad9523.h b/drivers/staging/iio/frequency/ad9523.h new file mode 100644 index 0000000000000..47dd26f54aeb0 --- /dev/null +++ b/drivers/staging/iio/frequency/ad9523.h @@ -0,0 +1,319 @@ +/* + * AD9523 SPI Low Jitter Clock Generator + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#ifndef IIO_PLL_AD9523_H_ +#define IIO_PLL_AD9523_H_ + +#define AD9523_READ (1 << 15) +#define AD9523_WRITE (0 << 15) +#define AD9523_CNT(x) (((x) - 1) << 13) +#define AD9523_ADDR(x) ((x) & 0xFFF) + +#define AD9523_R1B (1 << 16) +#define AD9523_R2B (2 << 16) +#define AD9523_R3B (3 << 16) +#define AD9523_TRANSFER_LEN(x) ((x) >> 16) + +#define AD9523_SERIAL_PORT_CONFIG (AD9523_R1B | 0x0) +#define AD9523_VERSION_REGISTER (AD9523_R1B | 0x2) +#define AD9523_PART_REGISTER (AD9523_R1B | 0x3) +#define AD9523_READBACK_CTRL (AD9523_R1B | 0x4) + +#define AD9523_EEPROM_CUSTOMER_VERSION_ID (AD9523_R2B | 0x6) + +#define AD9523_PLL1_REF_A_DIVIDER (AD9523_R2B | 0x11) +#define AD9523_PLL1_REF_B_DIVIDER (AD9523_R2B | 0x13) +#define AD9523_PLL1_REF_TEST_DIVIDER (AD9523_R1B | 0x14) +#define AD9523_PLL1_FEEDBACK_DIVIDER (AD9523_R2B | 0x17) +#define AD9523_PLL1_CHARGE_PUMP_CTRL (AD9523_R2B | 0x19) +#define AD9523_PLL1_INPUT_RECEIVERS_CTRL (AD9523_R1B | 0x1A) +#define AD9523_PLL1_REF_CTRL (AD9523_R1B | 0x1B) +#define AD9523_PLL1_MISC_CTRL (AD9523_R1B | 0x1C) +#define AD9523_PLL1_LOOP_FILTER_CTRL (AD9523_R1B | 0x1D) + +#define AD9523_PLL2_CHARGE_PUMP (AD9523_R1B | 0xF0) +#define AD9523_PLL2_FEEDBACK_DIVIDER_AB (AD9523_R1B | 0xF1) +#define AD9523_PLL2_CTRL (AD9523_R1B | 0xF2) +#define AD9523_PLL2_VCO_CTRL (AD9523_R1B | 0xF3) +#define AD9523_PLL2_VCO_DIVIDER (AD9523_R1B | 0xF4) +#define AD9523_PLL2_LOOP_FILTER_CTRL (AD9523_R2B | 0xF6) +#define AD9523_PLL2_R2_DIVIDER (AD9523_R1B | 0xF7) + +#define AD9523_CHANNEL_CLOCK_DIST(ch) (AD9523_R3B | (0x192 + 3 * ch)) + +#define AD9523_PLL1_OUTPUT_CTRL (AD9523_R1B | 0x1BA) +#define AD9523_PLL1_OUTPUT_CHANNEL_CTRL (AD9523_R1B | 0x1BB) + +#define AD9523_READBACK_0 (AD9523_R1B | 0x22C) +#define AD9523_READBACK_1 (AD9523_R1B | 0x22D) + +#define AD9523_STATUS_SIGNALS (AD9523_R3B | 0x232) +#define AD9523_POWER_DOWN_CTRL (AD9523_R1B | 0x233) +#define AD9523_IO_UPDATE (AD9523_R1B | 0x234) + +#define AD9523_EEPROM_DATA_XFER_STATUS (AD9523_R1B | 0xB00) +#define AD9523_EEPROM_ERROR_READBACK (AD9523_R1B | 0xB01) +#define AD9523_EEPROM_CTRL1 (AD9523_R1B | 0xB02) +#define AD9523_EEPROM_CTRL2 (AD9523_R1B | 0xB03) + +/* AD9523_SERIAL_PORT_CONFIG */ + +#define AD9523_SER_CONF_SDO_ACTIVE (1 << 7) +#define AD9523_SER_CONF_SOFT_RESET (1 << 5) + +/* AD9523_READBACK_CTRL */ +#define AD9523_READBACK_CTRL_READ_BUFFERED (1 << 0) + +/* AD9523_PLL1_CHARGE_PUMP_CTRL */ +#define AD9523_PLL1_CHARGE_PUMP_CURRENT_nA(x) (((x) / 500) & 0x7F) /* 0,5uA..63,5uA */ +#define AD9523_PLL1_CHARGE_PUMP_TRISTATE (1 << 7) +#define AD9523_PLL1_CHARGE_PUMP_MODE_NORMAL (3 << 8) +#define AD9523_PLL1_CHARGE_PUMP_MODE_PUMP_DOWN (2 << 8) +#define AD9523_PLL1_CHARGE_PUMP_MODE_PUMP_UP (1 << 8) +#define AD9523_PLL1_CHARGE_PUMP_MODE_TRISTATE (0 << 8) +#define AD9523_PLL1_BACKLASH_PW_MIN (0 << 10) +#define AD9523_PLL1_BACKLASH_PW_LOW (1 << 10) +#define AD9523_PLL1_BACKLASH_PW_HIGH (2 << 10) +#define AD9523_PLL1_BACKLASH_PW_MAX (3 << 10) + +/* AD9523_PLL1_INPUT_RECEIVERS_CTRL */ +#define AD9523_PLL1_REF_TEST_RCV_EN (1 << 7) +#define AD9523_PLL1_REFB_DIFF_RCV_EN (1 << 6) +#define AD9523_PLL1_REFA_DIFF_RCV_EN (1 << 5) +#define AD9523_PLL1_REFB_RCV_EN (1 << 4) +#define AD9523_PLL1_REFA_RCV_EN (1 << 3) +#define AD9523_PLL1_REFA_REFB_PWR_CTRL_EN (1 << 2) +#define AD9523_PLL1_OSC_IN_CMOS_NEG_INP_EN (1 << 1) +#define AD9523_PLL1_OSC_IN_DIFF_EN (1 << 0) + +/* AD9523_PLL1_REF_CTRL */ +#define AD9523_PLL1_BYPASS_REF_TEST_DIV_EN (1 << 7) +#define AD9523_PLL1_BYPASS_FEEDBACK_DIV_EN (1 << 6) +#define AD9523_PLL1_ZERO_DELAY_MODE_INT (1 << 5) +#define AD9523_PLL1_ZERO_DELAY_MODE_EXT (0 << 5) +#define AD9523_PLL1_OSC_IN_PLL_FEEDBACK_EN (1 << 4) +#define AD9523_PLL1_ZD_IN_CMOS_NEG_INP_EN (1 << 3) +#define AD9523_PLL1_ZD_IN_DIFF_EN (1 << 2) +#define AD9523_PLL1_REFB_CMOS_NEG_INP_EN (1 << 1) +#define AD9523_PLL1_REFA_CMOS_NEG_INP_EN (1 << 0) + +/* AD9523_PLL1_MISC_CTRL */ +#define AD9523_PLL1_REFB_INDEP_DIV_CTRL_EN (1 << 7) +#define AD9523_PLL1_OSC_CTRL_FAIL_VCC_BY2_EN (1 << 6) +#define AD9523_PLL1_REF_MODE(x) ((x) << 2) +#define AD9523_PLL1_BYPASS_REFB_DIV (1 << 1) +#define AD9523_PLL1_BYPASS_REFA_DIV (1 << 0) + +/* AD9523_PLL1_LOOP_FILTER_CTRL */ +#define AD9523_PLL1_LOOP_FILTER_RZERO(x) ((x) & 0xF) + +/* AD9523_PLL2_CHARGE_PUMP */ +#define AD9523_PLL2_CHARGE_PUMP_CURRENT_nA(x) ((x) / 3500) /* 3,5uA..900uA */ + +/* AD9523_PLL2_FEEDBACK_DIVIDER_AB */ +#define AD9523_PLL2_FB_NDIV_A_CNT(x) (((x) & 0x3) << 6) +#define AD9523_PLL2_FB_NDIV_B_CNT(x) (((x) & 0x3F) << 0) +#define AD9523_PLL2_FB_NDIV(a, b) (4 * (b) + (a)) + +/* AD9523_PLL2_CTRL */ +#define AD9523_PLL2_CHARGE_PUMP_MODE_NORMAL (3 << 0) +#define AD9523_PLL2_CHARGE_PUMP_MODE_PUMP_DOWN (2 << 0) +#define AD9523_PLL2_CHARGE_PUMP_MODE_PUMP_UP (1 << 0) +#define AD9523_PLL2_CHARGE_PUMP_MODE_TRISTATE (0 << 0) +#define AD9523_PLL2_BACKLASH_PW_MIN (0 << 2) +#define AD9523_PLL2_BACKLASH_PW_LOW (1 << 2) +#define AD9523_PLL2_BACKLASH_PW_HIGH (2 << 2) +#define AD9523_PLL2_BACKLASH_PW_MAX (3 << 1) +#define AD9523_PLL2_BACKLASH_CTRL_EN (1 << 4) +#define AD9523_PLL2_FREQ_DOUBLER_EN (1 << 5) +#define AD9523_PLL2_LOCK_DETECT_PWR_DOWN_EN (1 << 7) + +/* AD9523_PLL2_VCO_CTRL */ +#define AD9523_PLL2_VCO_CALIBRATE (1 << 1) +#define AD9523_PLL2_FORCE_VCO_MIDSCALE (1 << 2) +#define AD9523_PLL2_FORCE_REFERENCE_VALID (1 << 3) +#define AD9523_PLL2_FORCE_RELEASE_SYNC (1 << 4) + +/* AD9523_PLL2_VCO_DIVIDER */ +#define AD9523_PLL2_VCO_DIV_M1(x) ((((x) - 3) & 0x3) << 0) +#define AD9523_PLL2_VCO_DIV_M2(x) ((((x) - 3) & 0x3) << 4) +#define AD9523_PLL2_VCO_DIV_M1_PWR_DOWN_EN (1 << 2) +#define AD9523_PLL2_VCO_DIV_M2_PWR_DOWN_EN (1 << 6) + +/* AD9523_PLL2_LOOP_FILTER_CTRL */ +#define AD9523_PLL2_LOOP_FILTER_CPOLE1(x) (((x) & 0x7) << 0) +#define AD9523_PLL2_LOOP_FILTER_RZERO(x) (((x) & 0x7) << 3) +#define AD9523_PLL2_LOOP_FILTER_RPOLE2(x) (((x) & 0x7) << 6) +#define AD9523_PLL2_LOOP_FILTER_RZERO_BYPASS_EN (1 << 8) + +/* AD9523_PLL2_R2_DIVIDER */ +#define AD9523_PLL2_R2_DIVIDER_VAL(x) (((x) & 0x1F) << 0) + +/* AD9523_CHANNEL_CLOCK_DIST */ +#define AD9523_CLOCK_DIST_DIV_PHASE(x) (((x) & 0x3F) << 18) +#define AD9523_CLOCK_DIST_DIV(x) ((((x) - 1) & 0x3FF) << 8) +#define AD9523_CLOCK_DIST_INV_DIV_OUTPUT_EN (1 << 7) +#define AD9523_CLOCK_DIST_IGNORE_SYNC_EN (1 << 6) +#define AD9523_CLOCK_DIST_PWR_DOWN_EN (1 << 5) +#define AD9523_CLOCK_DIST_LOW_PWR_MODE_EN (1 << 4) +#define AD9523_CLOCK_DIST_DRIVER_MODE(x) (((x) & 0xF) << 0) + +enum driver_mode { + TRISTATE, + LVPECL_8mA, + LVDS_4mA, + LVDS_7mA, + HSTL0_16mA, + HSTL1_8mA, + CMOS_CONF1, + CMOS_CONF2, + CMOS_CONF3, + CMOS_CONF4, + CMOS_CONF5, + CMOS_CONF6, + CMOS_CONF7, + CMOS_CONF8, + CMOS_CONF9 +}; + +/* AD9523_PLL1_OUTPUT_CTRL */ +#define AD9523_PLL1_OUTP_CTRL_VCO_DIV_SEL_CH6_M2 (1 << 7) +#define AD9523_PLL1_OUTP_CTRL_VCO_DIV_SEL_CH5_M2 (1 << 6) +#define AD9523_PLL1_OUTP_CTRL_VCO_DIV_SEL_CH4_M2 (1 << 5) +#define AD9523_PLL1_OUTP_CTRL_CMOS_DRV_WEAK (1 << 4) +#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_1 (0 << 0) +#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_2 (1 << 0) +#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_4 (2 << 0) +#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_8 (4 << 0) +#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_16 (8 << 0) + +/* AD9523_PLL1_OUTPUT_CHANNEL_CTRL */ +#define AD9523_PLL1_OUTP_CH_CTRL_OUTPUT_PWR_DOWN_EN (1 << 7) +#define AD9523_PLL1_OUTP_CH_CTRL_VCO_DIV_SEL_CH9_M2 (1 << 6) +#define AD9523_PLL1_OUTP_CH_CTRL_VCO_DIV_SEL_CH8_M2 (1 << 5) +#define AD9523_PLL1_OUTP_CH_CTRL_VCO_DIV_SEL_CH7_M2 (1 << 4) +#define AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH3 (1 << 3) +#define AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH2 (1 << 2) +#define AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH1 (1 << 1) +#define AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH0 (1 << 0) + +/* AD9523_READBACK_0 */ +#define AD9523_READBACK_0_STAT_PLL2_REF_CLK (1 << 7) +#define AD9523_READBACK_0_STAT_PLL2_FB_CLK (1 << 6) +#define AD9523_READBACK_0_STAT_VCXO (1 << 5) +#define AD9523_READBACK_0_STAT_REF_TEST (1 << 4) +#define AD9523_READBACK_0_STAT_REFB (1 << 3) +#define AD9523_READBACK_0_STAT_REFA (1 << 2) +#define AD9523_READBACK_0_STAT_PLL2_LD (1 << 1) +#define AD9523_READBACK_0_STAT_PLL1_LD (1 << 0) + +/* AD9523_READBACK_1 */ +#define AD9523_READBACK_1_HOLDOVER_ACTIVE (1 << 3) +#define AD9523_READBACK_1_AUTOMODE_SEL_REFB (1 << 2) +#define AD9523_READBACK_1_VCO_CALIB_IN_PROGRESS (1 << 0) + +/* AD9523_STATUS_SIGNALS */ +#define AD9523_STATUS_SIGNALS_SYNC_MAN_CTRL (1 << 16) +/* AD9523_POWER_DOWN_CTRL */ +#define AD9523_POWER_DOWN_CTRL_PLL1_PWR_DOWN (1 << 2) +#define AD9523_POWER_DOWN_CTRL_PLL2_PWR_DOWN (1 << 1) +#define AD9523_POWER_DOWN_CTRL_DIST_PWR_DOWN (1 << 0) + +/* AD9523_IO_UPDATE */ +#define AD9523_IO_UPDATE_EN (1 << 0) + +/* AD9523_EEPROM_DATA_XFER_STATUS */ +#define AD9523_EEPROM_DATA_XFER_IN_PROGRESS (1 << 0) + +/* AD9523_EEPROM_ERROR_READBACK */ +#define AD9523_EEPROM_ERROR_READBACK_FAIL (1 << 0) + +/* AD9523_EEPROM_CTRL1 */ +#define AD9523_EEPROM_CTRL1_SOFT_EEPROM (1 << 1) +#define AD9523_EEPROM_CTRL1_EEPROM_WRITE_PROT_DIS (1 << 0) + +/* AD9523_EEPROM_CTRL2 */ +#define AD9523_EEPROM_CTRL2_REG2EEPROM (1 << 0) + +#define AD9523_NUM_CHAN 13 + +struct ad9523_channel_spec { + unsigned channel_num; + bool divider_output_invert_en; + bool sync_ignore_en; + bool low_power_mode_en; + bool use_alt_clock_src; /* CH0..CH3 VCXO, CH4..CH9 VCO2 */ + bool output_dis; + unsigned char driver_mode; + unsigned char divider_phase; + unsigned short channel_divider; + char extended_name[16]; +}; + +/* + * TODO: struct adf4350_platform_data needs to go into include/linux/iio + */ + +/* + * struct ad9523_platform_data - platform specific information + * @clkin: REFin frequency in Hz. + */ + +struct ad9523_platform_data { + unsigned long vcxo_freq; + + /* Differential/ Single-Ended Input Configuration */ + bool refa_diff_rcv_en; + bool refb_diff_rcv_en; + bool zd_in_diff_en; + bool osc_in_diff_en; + + /* + * Valid if differential input disabled + * if not true defaults to pos input + */ + bool refa_cmos_neg_inp_en; + bool refb_cmos_neg_inp_en; + bool zd_in_cmos_neg_inp_en; + bool osc_in_cmos_neg_inp_en; + + /* PLL1 Setting */ + unsigned short refa_r_div; + unsigned short refb_r_div; + unsigned short pll1_feedback_div; + unsigned short pll1_charge_pump_current_nA; + bool zero_delay_mode_internal_en; + bool osc_in_feedback_en; + unsigned char pll1_loop_filter_rzero; + + /* Reference */ + unsigned char ref_mode; + + /* PLL2 Setting */ + unsigned int pll2_charge_pump_current_nA; + unsigned char pll2_ndiv_a_cnt; + unsigned char pll2_ndiv_b_cnt; + bool pll2_freq_doubler_en; + unsigned char pll2_r2_div; + unsigned char pll2_vco_diff_m1; /* 3..5 */ + unsigned char pll2_vco_diff_m2; /* 3..5 */ + + /* Loop Filter PLL2 */ + unsigned char rpole2; + unsigned char rzero; + unsigned char cpole1; + bool rzero_bypass_en; + + /* Output Channel Configuration */ + int num_channels; + struct ad9523_channel_spec *channels; + + char name[SPI_NAME_SIZE]; +}; + +#endif /* IIO_PLL_AD9523_H_ */ diff --git a/drivers/staging/iio/frequency/ad9548.c b/drivers/staging/iio/frequency/ad9548.c new file mode 100644 index 0000000000000..02cd754a9bcaa --- /dev/null +++ b/drivers/staging/iio/frequency/ad9548.c @@ -0,0 +1,287 @@ +/* + * AD9548 SPI Network Clock Generator/Synchronizer + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" + +#define AD_READ (1 << 15) +#define AD_WRITE (0 << 15) +#define AD_CNT(x) (((x) - 1) << 13) +#define AD_ADDR(x) ((x) & 0xFFF) +#define WAIT_B 0xFFFF +#define CHIPID_AD9548 0x48 + +static const unsigned short ad9548_regs[][2] = { + {0x0000, 0x30}, /* Reset */ + {0x0000, 0x10}, + {0x0000, 0x10}, + {0x0000, 0x10}, + {0x0000, 0x10}, + {0x0000, 0x10}, + {0x0100, 0x18}, /* System clock */ + {0x0101, 0x28}, + {0x0102, 0x45}, + {0x0103, 0x43}, + {0x0104, 0xDE}, + {0x0105, 0x13}, + {0x0106, 0x01}, + {0x0107, 0x00}, + {0x0108, 0x00}, + {0x0005, 0x01}, /* I/O Update */ + {0x0A02, 0x01}, /* Calibrate sysem clock */ + {0x0005, 0x01}, + {WAIT_B, 0x00}, + {0x0A02, 0x00}, + {0x0005, 0x01}, + {0x0208, 0x00}, /* IRQ Pin Output Mode */ + {0x0209, 0x00}, /* IRQ Masks */ + {0x020A, 0x00}, + {0x020B, 0x00}, + {0x020C, 0x00}, + {0x020D, 0x00}, + {0x020E, 0x00}, + {0x020F, 0x00}, + {0x0210, 0x00}, + {0x0211, 0x00}, /* Watchdog timer */ + {0x0212, 0x00}, + {0x0213, 0xFF}, /* Auxiliary DAC */ + {0x0214, 0x01}, + {0x0300, 0x29}, /* DPLL */ + {0x0301, 0x5C}, + {0x0302, 0x8F}, + {0x0303, 0xC2}, + {0x0304, 0xF5}, + {0x0305, 0x28}, + {0x0307, 0x00}, + {0x0308, 0x00}, + {0x0309, 0x00}, + {0x030A, 0xFF}, + {0x030B, 0xFF}, + {0x030C, 0xFF}, + {0x030D, 0x00}, + {0x030E, 0x00}, + {0x030F, 0x00}, + {0x0310, 0x00}, + {0x0311, 0x00}, + {0x0312, 0x00}, + {0x0313, 0x00}, + {0x0314, 0xE8}, + {0x0315, 0x03}, + {0x0316, 0x00}, + {0x0317, 0x00}, + {0x0318, 0x30}, + {0x0319, 0x75}, + {0x031A, 0x00}, + {0x031B, 0x00}, + {0x0306, 0x01}, /* Update TW */ + {0x0400, 0x0C}, /* Clock distribution output */ + {0x0401, 0x03}, + {0x0402, 0x00}, + {0x0403, 0x02}, + {0x0404, 0x04}, + {0x0405, 0x08}, + {0x0406, 0x03}, + {0x0407, 0x03}, + {0x0408, 0x03}, + {0x0409, 0x00}, + {0x040A, 0x00}, + {0x040B, 0x00}, + {0x040C, 0x03}, + {0x040D, 0x00}, + {0x040E, 0x00}, + {0x040F, 0x00}, + {0x0410, 0x00}, + {0x0411, 0x00}, + {0x0412, 0x00}, + {0x0413, 0x00}, + {0x0414, 0x00}, + {0x0415, 0x00}, + {0x0416, 0x00}, + {0x0417, 0x00}, + {0x0500, 0xFE}, /* Reference inputs */ + {0x0501, 0x00}, + {0x0502, 0x00}, + {0x0503, 0x08}, + {0x0504, 0x00}, + {0x0505, 0x00}, + {0x0506, 0x00}, + {0x0507, 0x00}, + {0x0600, 0x00}, /* Profiles are 0x0600-0x07FF */ + {0x0601, 0x55}, /* Profile 0 */ + {0x0602, 0xA0}, /* 30MHz input from FPGA, 122.880MHz output clock */ + {0x0603, 0xFC}, + {0x0604, 0x01}, + {0x0605, 0x00}, + {0x0606, 0x00}, + {0x0607, 0x00}, + {0x0608, 0xE8}, + {0x0609, 0x03}, + {0x060A, 0x00}, + {0x060B, 0xE8}, + {0x060C, 0x03}, + {0x060D, 0x00}, + {0x060E, 0x88}, + {0x060F, 0x13}, + {0x0610, 0x88}, + {0x0611, 0x13}, + {0x0612, 0x0E}, + {0x0613, 0xB2}, + {0x0614, 0x08}, + {0x0615, 0x82}, + {0x0616, 0x62}, + {0x0617, 0x42}, + {0x0618, 0xD8}, + {0x0619, 0x47}, + {0x061A, 0x21}, + {0x061B, 0xCB}, + {0x061C, 0xC4}, + {0x061D, 0x05}, + {0x061E, 0x7F}, + {0x061F, 0x00}, + {0x0620, 0x00}, + {0x0621, 0x00}, + {0x0622, 0x0B}, + {0x0623, 0x02}, + {0x0624, 0x00}, + {0x0625, 0x00}, + {0x0626, 0x26}, + {0x0627, 0xB0}, + {0x0628, 0x00}, + {0x0629, 0x10}, + {0x062A, 0x27}, + {0x062B, 0x20}, + {0x062C, 0x44}, + {0x062D, 0xF4}, + {0x062E, 0x01}, + {0x062F, 0x00}, + {0x0630, 0x20}, + {0x0631, 0x44}, + {0x0005, 0x01}, /* I/O Update */ + {0x0A0E, 0x01}, /* Force validation timeout */ + {0x0005, 0x01}, /* I/O Update */ + {0x0A02, 0x02}, /* Sync distribution */ + {0x0005, 0x01}, + {0x0A02, 0x00}, + {0x0005, 0x01}, +}; + +static int ad9548_read(struct spi_device *spi, unsigned reg) +{ + unsigned char buf[3]; + int ret; + u16 cmd; + + cmd = AD_READ | AD_CNT(1) | AD_ADDR(reg); + buf[0] = cmd >> 8; + buf[1] = cmd & 0xFF; + + + ret = spi_write_then_read(spi, &buf[0], 2, &buf[2], 1); + if (ret < 0) + return ret; + + return buf[2]; +} + +static int ad9548_write(struct spi_device *spi, + unsigned reg, unsigned val) +{ + unsigned char buf[3]; + int ret; + u16 cmd; + + cmd = AD_WRITE | AD_CNT(1) | AD_ADDR(reg); + buf[0] = cmd >> 8; + buf[1] = cmd & 0xFF; + buf[2] = val; + + ret = spi_write(spi, buf, 3); + if (ret < 0) + return ret; + + return 0; +} + +static int __devinit ad9548_probe(struct spi_device *spi) +{ + int i, ret, timeout; + + ret = ad9548_read(spi, 0x3); + if (ret < 0) + return ret; + if (ret != CHIPID_AD9548) { + dev_err(&spi->dev, "Unrecognized CHIP_ID 0x%X\n", ret); + return -ENODEV; + } + + for (i = 0; i < ARRAY_SIZE(ad9548_regs); i++) + switch (ad9548_regs[i][0]) { + case WAIT_B: + timeout = 100; + do { + ret = ad9548_read(spi, 0xD01); + if (ret < 0) + return ret; + if (ret & BIT(0)) + break; + mdelay(1); + } while (timeout--); + + if (timeout <= 0) + return -ETIMEDOUT; + break; + default: + ret = ad9548_write(spi, ad9548_regs[i][0], + ad9548_regs[i][1]); + if (ret < 0) + return ret; + break; + } + + spi_set_drvdata(spi, NULL); + dev_info(&spi->dev, "Rev. 0x%X probed\n", ad9548_read(spi, 0x2)); + + return 0; +} + +static int ad9548_remove(struct spi_device *spi) +{ + spi_set_drvdata(spi, NULL); + + return 0; +} + +static const struct spi_device_id ad9548_id[] = { + {"ad9548", 0}, + {} +}; +MODULE_DEVICE_TABLE(spi, ad9548_id); + +static struct spi_driver ad9548_driver = { + .driver = { + .name = "ad9548", + .owner = THIS_MODULE, + }, + .probe = ad9548_probe, + .remove = __devexit_p(ad9548_remove), + .id_table = ad9548_id, +}; +module_spi_driver(ad9548_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD9548"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/frequency/adf4350.c b/drivers/staging/iio/frequency/adf4350.c new file mode 100644 index 0000000000000..3d5c0bd3e5d1f --- /dev/null +++ b/drivers/staging/iio/frequency/adf4350.c @@ -0,0 +1,502 @@ +/* + * ADF4350/ADF4351 SPI Wideband Synthesizer driver + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +#include "adf4350.h" + +enum { + ADF4350_SET_FREQ, + ADF4350_SET_FREQ_REFIN, + ADF4350_SET_FREQ_RESOLUTION, + ADF4350_PLL_LOCKED, + ADF4350_PLL_PWRDOWN, +}; + +struct adf4350_state { + struct spi_device *spi; + struct regulator *reg; + struct adf4350_platform_data *pdata; + unsigned long clkin; + unsigned long chspc; /* Channel Spacing */ + unsigned long fpfd; /* Phase Frequency Detector */ + unsigned long min_out_freq; + unsigned r0_fract; + unsigned r0_int; + unsigned r1_mod; + unsigned r4_rf_div_sel; + unsigned long regs[6]; + unsigned long regs_hw[6]; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + __be32 val ____cacheline_aligned; +}; + +static struct adf4350_platform_data default_pdata = { + .clkin = 122880000, + .channel_spacing = 10000, + .r2_user_settings = ADF4350_REG2_PD_POLARITY_POS, + ADF4350_REG2_CHARGE_PUMP_CURR_uA(2500), + .r3_user_settings = ADF4350_REG3_12BIT_CLKDIV_MODE(0), + .r4_user_settings = ADF4350_REG4_OUTPUT_PWR(0) | + ADF4350_REG4_MUTE_TILL_LOCK_EN, + .gpio_lock_detect = -1, +}; + +static int adf4350_sync_config(struct adf4350_state *st) +{ + int ret, i, doublebuf = 0; + + for (i = ADF4350_REG5; i >= ADF4350_REG0; i--) { + if ((st->regs_hw[i] != st->regs[i]) || + ((i == ADF4350_REG0) && doublebuf)) { + + switch (i) { + case ADF4350_REG1: + case ADF4350_REG4: + doublebuf = 1; + break; + } + + st->val = cpu_to_be32(st->regs[i] | i); + ret = spi_write(st->spi, &st->val, 4); + if (ret < 0) + return ret; + st->regs_hw[i] = st->regs[i]; + dev_dbg(&st->spi->dev, "[%d] 0x%X\n", + i, (u32)st->regs[i] | i); + } + } + return 0; +} + +static int adf4350_reg_access(struct iio_dev *indio_dev, + unsigned reg, unsigned writeval, + unsigned *readval) +{ + struct adf4350_state *st = iio_priv(indio_dev); + int ret; + + if (reg > ADF4350_REG5) + return -EINVAL; + + mutex_lock(&indio_dev->mlock); + if (readval == NULL) { + st->regs[reg] = writeval & ~(BIT(0) | BIT(1) | BIT(2)); + ret = adf4350_sync_config(st); + } else { + *readval = st->regs_hw[reg]; + ret = 0; + } + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static int adf4350_tune_r_cnt(struct adf4350_state *st, unsigned short r_cnt) +{ + struct adf4350_platform_data *pdata = st->pdata; + + do { + r_cnt++; + st->fpfd = (st->clkin * (pdata->ref_doubler_en ? 2 : 1)) / + (r_cnt * (pdata->ref_div2_en ? 2 : 1)); + } while (st->fpfd > ADF4350_MAX_FREQ_PFD); + + return r_cnt; +} + +static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq) +{ + struct adf4350_platform_data *pdata = st->pdata; + u64 tmp; + u32 div_gcd, prescaler; + u16 mdiv, r_cnt = 0; + u8 band_sel_div; + + if (freq > ADF4350_MAX_OUT_FREQ || freq < st->min_out_freq) + return -EINVAL; + + if (freq > ADF4350_MAX_FREQ_45_PRESC) { + prescaler = ADF4350_REG1_PRESCALER; + mdiv = 75; + } else { + prescaler = 0; + mdiv = 23; + } + + st->r4_rf_div_sel = 0; + + while (freq < ADF4350_MIN_VCO_FREQ) { + freq <<= 1; + st->r4_rf_div_sel++; + } + + /* + * Allow a predefined reference division factor + * if not set, compute our own + */ + if (pdata->ref_div_factor) + r_cnt = pdata->ref_div_factor - 1; + + do { + r_cnt = adf4350_tune_r_cnt(st, r_cnt); + + st->r1_mod = st->fpfd / st->chspc; + while (st->r1_mod > ADF4350_MAX_MODULUS) { + r_cnt = adf4350_tune_r_cnt(st, r_cnt); + st->r1_mod = st->fpfd / st->chspc; + } + + tmp = freq * (u64)st->r1_mod + (st->fpfd > 1); + do_div(tmp, st->fpfd); /* Div round closest (n + d/2)/d */ + st->r0_fract = do_div(tmp, st->r1_mod); + st->r0_int = tmp; + } while (mdiv > st->r0_int); + + band_sel_div = DIV_ROUND_UP(st->fpfd, ADF4350_MAX_BANDSEL_CLK); + + if (st->r0_fract && st->r1_mod) { + div_gcd = gcd(st->r1_mod, st->r0_fract); + st->r1_mod /= div_gcd; + st->r0_fract /= div_gcd; + } else { + st->r0_fract = 0; + st->r1_mod = 1; + } + + dev_dbg(&st->spi->dev, "VCO: %llu Hz, PFD %lu Hz\n" + "REF_DIV %d, R0_INT %d, R0_FRACT %d\n" + "R1_MOD %d, RF_DIV %d\nPRESCALER %s, BAND_SEL_DIV %d\n", + freq, st->fpfd, r_cnt, st->r0_int, st->r0_fract, st->r1_mod, + 1 << st->r4_rf_div_sel, prescaler ? "8/9" : "4/5", + band_sel_div); + + st->regs[ADF4350_REG0] = ADF4350_REG0_INT(st->r0_int) | + ADF4350_REG0_FRACT(st->r0_fract); + + st->regs[ADF4350_REG1] = ADF4350_REG1_PHASE(0) | + ADF4350_REG1_MOD(st->r1_mod) | + prescaler; + + st->regs[ADF4350_REG2] = + ADF4350_REG2_10BIT_R_CNT(r_cnt) | + ADF4350_REG2_DOUBLE_BUFF_EN | + (pdata->ref_doubler_en ? ADF4350_REG2_RMULT2_EN : 0) | + (pdata->ref_div2_en ? ADF4350_REG2_RDIV2_EN : 0) | + (pdata->r2_user_settings & (ADF4350_REG2_PD_POLARITY_POS | + ADF4350_REG2_LDP_6ns | ADF4350_REG2_LDF_INT_N | + ADF4350_REG2_CHARGE_PUMP_CURR_uA(5000) | + ADF4350_REG2_MUXOUT(0x7) | ADF4350_REG2_NOISE_MODE(0x9))); + + st->regs[ADF4350_REG3] = pdata->r3_user_settings & + (ADF4350_REG3_12BIT_CLKDIV(0xFFF) | + ADF4350_REG3_12BIT_CLKDIV_MODE(0x3) | + ADF4350_REG3_12BIT_CSR_EN | + ADF4351_REG3_CHARGE_CANCELLATION_EN | + ADF4351_REG3_ANTI_BACKLASH_3ns_EN | + ADF4351_REG3_BAND_SEL_CLOCK_MODE_HIGH); + + st->regs[ADF4350_REG4] = + ADF4350_REG4_FEEDBACK_FUND | + ADF4350_REG4_RF_DIV_SEL(st->r4_rf_div_sel) | + ADF4350_REG4_8BIT_BAND_SEL_CLKDIV(band_sel_div) | + ADF4350_REG4_RF_OUT_EN | + (pdata->r4_user_settings & + (ADF4350_REG4_OUTPUT_PWR(0x3) | + ADF4350_REG4_AUX_OUTPUT_PWR(0x3) | + ADF4350_REG4_AUX_OUTPUT_EN | + ADF4350_REG4_AUX_OUTPUT_FUND | + ADF4350_REG4_MUTE_TILL_LOCK_EN)); + + st->regs[ADF4350_REG5] = ADF4350_REG5_LD_PIN_MODE_DIGITAL; + + return adf4350_sync_config(st); +} + +static ssize_t adf4350_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adf4350_state *st = iio_priv(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + unsigned long long readin; + int ret; + + ret = kstrtoull(buf, 10, &readin); + if (ret) + return ret; + + mutex_lock(&indio_dev->mlock); + switch ((u32)this_attr->address) { + case ADF4350_SET_FREQ: + ret = adf4350_set_freq(st, readin); + break; + case ADF4350_SET_FREQ_REFIN: + if (readin > ADF4350_MAX_FREQ_REFIN) + ret = -EINVAL; + else + st->clkin = readin; + break; + case ADF4350_SET_FREQ_RESOLUTION: + if (readin == 0) + ret = -EINVAL; + else + st->chspc = readin; + break; + case ADF4350_PLL_PWRDOWN: + if (readin) + st->regs[ADF4350_REG2] |= ADF4350_REG2_POWER_DOWN_EN; + else + st->regs[ADF4350_REG2] &= ~ADF4350_REG2_POWER_DOWN_EN; + + adf4350_sync_config(st); + break; + default: + ret = -ENODEV; + } + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static ssize_t adf4350_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adf4350_state *st = iio_priv(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + unsigned long long val; + int ret = 0; + + mutex_lock(&indio_dev->mlock); + switch ((u32)this_attr->address) { + case ADF4350_SET_FREQ: + val = (u64)((st->r0_int * st->r1_mod) + st->r0_fract) * + (u64)st->fpfd; + do_div(val, st->r1_mod * (1 << st->r4_rf_div_sel)); + break; + case ADF4350_SET_FREQ_REFIN: + val = st->clkin; + break; + case ADF4350_SET_FREQ_RESOLUTION: + val = st->chspc; + break; + case ADF4350_PLL_LOCKED: + if (gpio_is_valid(st->pdata->gpio_lock_detect)) + val = gpio_get_value(st->pdata->gpio_lock_detect); + else + ret = -ENODEV; + break; + case ADF4350_PLL_PWRDOWN: + val = !!(st->regs[ADF4350_REG2] & ADF4350_REG2_POWER_DOWN_EN); + break; + } + mutex_unlock(&indio_dev->mlock); + + return ret < 0 ? ret : sprintf(buf, "%llu\n", val); +} + +static IIO_DEVICE_ATTR(out_pll0_freq, S_IRUGO | S_IWUSR, + adf4350_show, + adf4350_store, + ADF4350_SET_FREQ); + +static IIO_DEVICE_ATTR(out_pll0_refin_freq, S_IRUGO | S_IWUSR, + adf4350_show, + adf4350_store, + ADF4350_SET_FREQ_REFIN); + +static IIO_DEVICE_ATTR(out_pll0_freq_resolution, S_IRUGO | S_IWUSR, + adf4350_show, + adf4350_store, + ADF4350_SET_FREQ_RESOLUTION); + +static IIO_DEVICE_ATTR(out_pll0_locked, S_IRUGO, + adf4350_show, + NULL, + ADF4350_PLL_LOCKED); + +static IIO_DEVICE_ATTR(out_pll0_powerdown, S_IRUGO | S_IWUSR, + adf4350_show, + adf4350_store, + ADF4350_PLL_PWRDOWN); + +static struct attribute *adf4350_attributes[] = { + &iio_dev_attr_out_pll0_freq.dev_attr.attr, + &iio_dev_attr_out_pll0_refin_freq.dev_attr.attr, + &iio_dev_attr_out_pll0_freq_resolution.dev_attr.attr, + &iio_dev_attr_out_pll0_locked.dev_attr.attr, + &iio_dev_attr_out_pll0_powerdown.dev_attr.attr, + NULL, +}; + +static const struct attribute_group adf4350_attribute_group = { + .attrs = adf4350_attributes, +}; + +static const struct iio_info adf4350_info = { + .attrs = &adf4350_attribute_group, + .debugfs_reg_access = &adf4350_reg_access, + .driver_module = THIS_MODULE, +}; + +static int __devinit adf4350_probe(struct spi_device *spi) +{ + struct adf4350_platform_data *pdata = spi->dev.platform_data; + struct iio_dev *indio_dev; + struct adf4350_state *st; + int ret; + + if (!pdata) { + dev_warn(&spi->dev, "no platform data? using default\n");/*FIXME*/ + pdata = &default_pdata; + } + + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + + st->reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + } + + spi_set_drvdata(spi, indio_dev); + st->spi = spi; + st->pdata = pdata; + + indio_dev->dev.parent = &spi->dev; + indio_dev->name = (pdata->name[0] != 0) ? pdata->name : spi_get_device_id(spi)->name; + + indio_dev->info = &adf4350_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + st->chspc = pdata->channel_spacing; + st->clkin = pdata->clkin; + + st->min_out_freq = spi_get_device_id(spi)->driver_data == 4351 ? + ADF4351_MIN_OUT_FREQ : ADF4350_MIN_OUT_FREQ; + + memset(st->regs_hw, 0xFF, sizeof(st->regs_hw)); + + if (gpio_is_valid(pdata->gpio_lock_detect)) { + ret = gpio_request(pdata->gpio_lock_detect, indio_dev->name); + if (ret) { + dev_err(&spi->dev, "fail to request lock detect GPIO-%d", + pdata->gpio_lock_detect); + goto error_disable_reg; + } + gpio_direction_input(pdata->gpio_lock_detect); + } + + if (pdata->power_up_frequency) { + ret = adf4350_set_freq(st, pdata->power_up_frequency); + if (ret) + goto error_free_gpio; + } + + ret = iio_device_register(indio_dev); + if (ret) + goto error_free_gpio; + + return 0; + +error_free_gpio: + if (gpio_is_valid(pdata->gpio_lock_detect)) + gpio_free(pdata->gpio_lock_detect); + +error_disable_reg: + if (!IS_ERR(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR(st->reg)) + regulator_put(st->reg); + + iio_free_device(indio_dev); + + return ret; +} + +static int __devexit adf4350_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct adf4350_state *st = iio_priv(indio_dev); + struct regulator *reg = st->reg; + + st->regs[ADF4350_REG2] |= ADF4350_REG2_POWER_DOWN_EN; + adf4350_sync_config(st); + + if (gpio_is_valid(st->pdata->gpio_lock_detect)) + gpio_free(st->pdata->gpio_lock_detect); + + iio_device_unregister(indio_dev); + + if (!IS_ERR(reg)) { + regulator_disable(reg); + regulator_put(reg); + } + + iio_free_device(indio_dev); + + return 0; +} + +static const struct spi_device_id adf4350_id[] = { + {"adf4350", 4350}, + {"adf4351", 4351}, + {} +}; + +static struct spi_driver adf4350_driver = { + .driver = { + .name = "adf4350", + .owner = THIS_MODULE, + }, + .probe = adf4350_probe, + .remove = __devexit_p(adf4350_remove), + .id_table = adf4350_id, +}; + +static int __init adf4350_init(void) +{ + return spi_register_driver(&adf4350_driver); +} +module_init(adf4350_init); + +static void __exit adf4350_exit(void) +{ + spi_unregister_driver(&adf4350_driver); +} +module_exit(adf4350_exit); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices ADF4350/ADF4351 PLL"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/frequency/adf4350.h b/drivers/staging/iio/frequency/adf4350.h new file mode 100644 index 0000000000000..5955f4fce06c2 --- /dev/null +++ b/drivers/staging/iio/frequency/adf4350.h @@ -0,0 +1,122 @@ +/* + * ADF4350/ADF4351 SPI PLL driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#ifndef IIO_PLL_ADF4350_H_ +#define IIO_PLL_ADF4350_H_ + +/* Registers */ +#define ADF4350_REG0 0 +#define ADF4350_REG1 1 +#define ADF4350_REG2 2 +#define ADF4350_REG3 3 +#define ADF4350_REG4 4 +#define ADF4350_REG5 5 + +/* REG0 Bit Definitions */ +#define ADF4350_REG0_FRACT(x) (((x) & 0xFFF) << 3) +#define ADF4350_REG0_INT(x) (((x) & 0xFFFF) << 15) + +/* REG1 Bit Definitions */ +#define ADF4350_REG1_MOD(x) (((x) & 0xFFF) << 3) +#define ADF4350_REG1_PHASE(x) (((x) & 0xFFF) << 15) +#define ADF4350_REG1_PRESCALER (1 << 27) + +/* REG2 Bit Definitions */ +#define ADF4350_REG2_COUNTER_RESET_EN (1 << 3) +#define ADF4350_REG2_CP_THREESTATE_EN (1 << 4) +#define ADF4350_REG2_POWER_DOWN_EN (1 << 5) +#define ADF4350_REG2_PD_POLARITY_POS (1 << 6) +#define ADF4350_REG2_LDP_6ns (1 << 7) +#define ADF4350_REG2_LDP_10ns (0 << 7) +#define ADF4350_REG2_LDF_FRACT_N (0 << 8) +#define ADF4350_REG2_LDF_INT_N (1 << 8) +#define ADF4350_REG2_CHARGE_PUMP_CURR_uA(x) (((((x)-312) / 312) & 0xF) << 9) +#define ADF4350_REG2_DOUBLE_BUFF_EN (1 << 13) +#define ADF4350_REG2_10BIT_R_CNT(x) ((x) << 14) +#define ADF4350_REG2_RDIV2_EN (1 << 24) +#define ADF4350_REG2_RMULT2_EN (1 << 25) +#define ADF4350_REG2_MUXOUT(x) ((x) << 26) +#define ADF4350_REG2_NOISE_MODE(x) ((x) << 29) + +/* REG3 Bit Definitions */ +#define ADF4350_REG3_12BIT_CLKDIV(x) ((x) << 3) +#define ADF4350_REG3_12BIT_CLKDIV_MODE(x) ((x) << 16) +#define ADF4350_REG3_12BIT_CSR_EN (1 << 18) +#define ADF4351_REG3_CHARGE_CANCELLATION_EN (1 << 21) +#define ADF4351_REG3_ANTI_BACKLASH_3ns_EN (1 << 22) +#define ADF4351_REG3_BAND_SEL_CLOCK_MODE_HIGH (1 << 23) + +/* REG4 Bit Definitions */ +#define ADF4350_REG4_OUTPUT_PWR(x) ((x) << 3) +#define ADF4350_REG4_RF_OUT_EN (1 << 5) +#define ADF4350_REG4_AUX_OUTPUT_PWR(x) ((x) << 6) +#define ADF4350_REG4_AUX_OUTPUT_EN (1 << 8) +#define ADF4350_REG4_AUX_OUTPUT_FUND (1 << 9) +#define ADF4350_REG4_AUX_OUTPUT_DIV (0 << 9) +#define ADF4350_REG4_MUTE_TILL_LOCK_EN (1 << 10) +#define ADF4350_REG4_VCO_PWRDOWN_EN (1 << 11) +#define ADF4350_REG4_8BIT_BAND_SEL_CLKDIV(x) ((x) << 12) +#define ADF4350_REG4_RF_DIV_SEL(x) ((x) << 20) +#define ADF4350_REG4_FEEDBACK_DIVIDED (0 << 23) +#define ADF4350_REG4_FEEDBACK_FUND (1 << 23) + +/* REG5 Bit Definitions */ +#define ADF4350_REG5_LD_PIN_MODE_LOW (0 << 22) +#define ADF4350_REG5_LD_PIN_MODE_DIGITAL (1 << 22) +#define ADF4350_REG5_LD_PIN_MODE_HIGH (3 << 22) + +/* Specifications */ +#define ADF4350_MAX_OUT_FREQ 4400000000ULL /* Hz */ +#define ADF4350_MIN_OUT_FREQ 137500000 /* Hz */ +#define ADF4351_MIN_OUT_FREQ 34375000 /* Hz */ +#define ADF4350_MIN_VCO_FREQ 2200000000ULL /* Hz */ +#define ADF4350_MAX_FREQ_45_PRESC 3000000000ULL /* Hz */ +#define ADF4350_MAX_FREQ_PFD 32000000 /* Hz */ +#define ADF4350_MAX_BANDSEL_CLK 125000 /* Hz */ +#define ADF4350_MAX_FREQ_REFIN 250000000 /* Hz */ +#define ADF4350_MAX_MODULUS 4095 + +/* + * TODO: struct adf4350_platform_data needs to go into include/linux/iio + */ + +/** + * struct adf4350_platform_data - platform specific information + * @clkin: REFin frequency in Hz. + * @channel_spacing: Channel spacing in Hz (influences MODULUS). + * @power_up_frequency: Optional, If set in Hz the PLL tunes to the desired + * frequency on probe. + * @ref_div_factor: Optional, if set the driver skips dynamic calculation + * and uses this default value instead. + * @ref_doubler_en: Enables reference doubler. + * @ref_div2_en: Enables reference divider. + * @r2_user_settings: User defined settings for ADF4350/1 REGISTER_2. + * @r3_user_settings: User defined settings for ADF4350/1 REGISTER_3. + * @r4_user_settings: User defined settings for ADF4350/1 REGISTER_4. + * @gpio_lock_detect: Optional, if set with a valid GPIO number, + * a PLL_LOCKED device attribute is created. + * If not used - set to -1. + */ + +struct adf4350_platform_data { + char name[32]; + unsigned long clkin; + unsigned long channel_spacing; + unsigned long long power_up_frequency; + + unsigned short ref_div_factor; /* 10-bit R counter */ + bool ref_doubler_en; + bool ref_div2_en; + + unsigned r2_user_settings; + unsigned r3_user_settings; + unsigned r4_user_settings; + int gpio_lock_detect; +}; + +#endif /* IIO_PLL_ADF4350_H_ */ diff --git a/drivers/staging/iio/frequency/cf_ad9122.c b/drivers/staging/iio/frequency/cf_ad9122.c new file mode 100644 index 0000000000000..100b03baa63fd --- /dev/null +++ b/drivers/staging/iio/frequency/cf_ad9122.c @@ -0,0 +1,544 @@ +/* + * DDS PCORE/COREFPGA Module + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../buffer.h" + +#define CF_AD9122_WAVDATA +#include "cf_ad9122.h" + +#define DRIVER_NAME "cf_ad9122" + +struct dds_spidev { + struct device_node *of_nspi; + struct device *dev_spi; +}; + +static void ad9122_dds_sync_frame(struct ad9122_dds_state *st) { + dds_write(st, AD9122_DDS_FRAME, 0); + dds_write(st, AD9122_DDS_FRAME, AD9122_DDS_FRAME_SYNC); +} + +static void ad9122_dds_stop(struct ad9122_dds_state *st) { + dds_write(st, AD9122_DDS_CTRL, (st->vers_id > 1) ? + AD9122_DDS_CTRL_DDS_CLK_EN_V2 : AD9122_DDS_CTRL_DDS_CLK_EN_V1); +} + +static u32 ad9122_ddsx(u32 phase, u32 sin_clk, u32 dac_clk) { + + u32 p_offset; + u32 p_incr; + + p_offset = (phase * 0xffff) / 360; + p_incr = ((sin_clk * 0xffff) / dac_clk) | 1; + + return((p_offset << 16) | p_incr); +} + +static void ad9122_dds_mem_init(struct ad9122_dds_state *st) { + + u32 i, sample, addr, data; + + sample = 0; + addr = 0; + + for (i = 0; i < ARRAY_SIZE(ad9122_ia_data); i++) { + data = (sample << 24) | (addr << 16); + dds_write(st, AD9122_DDS_MEM_CTRL, ((0 << 26) | data | ad9122_ia_data[i])); + dds_write(st, AD9122_DDS_MEM_CTRL, ((1 << 26) | data | ad9122_ib_data[i])); + dds_write(st, AD9122_DDS_MEM_CTRL, ((2 << 26) | data | ad9122_qa_data[i])); + dds_write(st, AD9122_DDS_MEM_CTRL, ((3 << 26) | data | ad9122_qb_data[i])); + sample++; + if (sample >= 3) { + addr++; + sample = 0; + } + } +} + +static const int ad9122_dds_scale_table[16] = { + 10000, 5000, 2500, 1250, 625, 313, 156, +}; + +static int ad9122_dds_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + struct ad9122_dds_state *st = iio_priv(indio_dev); + unsigned long long val64; + unsigned reg; + + switch (m) { + case 0: + if (!chan->output) { + return -EINVAL; + } + reg = dds_read(st, AD9122_DDS_CTRL); + if (st->vers_id > 1) { + if (reg & 0x2) + *val = 1; + else + *val = 0; + + } else { + if (reg & (1 << (chan->channel * 2))) + *val = 1; + else + *val = 0; + } + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + reg = dds_read(st, AD9122_DDS_SCALE); + reg = (reg >> (chan->channel * 4)) & 0xF; + if (!reg) { + *val = 1; + *val2 = 0; + } else { + *val = 0; + *val2 = 1000000 >> reg; + } + return IIO_VAL_INT_PLUS_MICRO; + case IIO_CHAN_INFO_FREQUENCY: + if (!chan->output) { + *val = st->dac_clk; + return IIO_VAL_INT; + } + reg = dds_read(st, chan->address); + val64 = (u64)(reg & 0xFFFF) * (u64)st->dac_clk; + do_div(val64, 0xFFFF); + *val = val64; + return IIO_VAL_INT; + case IIO_CHAN_INFO_PHASE: + reg = dds_read(st, chan->address); + val64 = (u64)(reg >> 16) * 360000ULL; + do_div(val64, 0xFFFF); + *val = val64; + return IIO_VAL_INT; + } + return -EINVAL; +} + +static int ad9122_dds_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct ad9122_dds_state *st = iio_priv(indio_dev); + unsigned long long val64; + unsigned reg, ctrl_reg; + int i; + + ctrl_reg = dds_read(st, AD9122_DDS_CTRL); + + switch (mask) { + case 0: + if (!chan->output) { + return -EINVAL; + } + + if (st->vers_id > 1) { + if (val) + ctrl_reg |= 0x3; + else + ctrl_reg &= ~(0x2); + } else { + if (val) + ctrl_reg |= 1 << (chan->channel * 2); + else + ctrl_reg &= ~(1 << (chan->channel * 2)); + } + + dds_write(st, AD9122_DDS_CTRL, ctrl_reg); + break; + case IIO_CHAN_INFO_SCALE: + if (val == 1) { + i = 0; + } else { + for (i = 1; i < 16; i++) + if (val2 == (1000000 >> i)) + break; + } + ad9122_dds_stop(st); + reg = dds_read(st, AD9122_DDS_SCALE); + + reg &= ~(0xF << (chan->channel * 4)); + reg |= (i << (chan->channel * 4)); + dds_write(st, AD9122_DDS_SCALE, reg); + dds_write(st, AD9122_DDS_CTRL, ctrl_reg); + break; + case IIO_CHAN_INFO_FREQUENCY: + if (!chan->output) { + st->dac_clk = val; + break; + } + if (val > (st->dac_clk / 2)) + return -EINVAL; + ad9122_dds_stop(st); + reg = dds_read(st, chan->address); + reg &= 0xFFFF0000; + val64 = (u64) val * 0xFFFFULL; + do_div(val64, st->dac_clk); + reg |= (val64 & 0xFFFF) | 1; + dds_write(st, chan->address, reg); + dds_write(st, AD9122_DDS_CTRL, ctrl_reg); + break; + case IIO_CHAN_INFO_PHASE: + if (val < 0 || val > 360000) + return -EINVAL; + ad9122_dds_stop(st); + reg = dds_read(st, chan->address); + reg &= 0x0000FFFF; + val64 = (u64) val * 0xFFFFULL; + do_div(val64, 360000); + reg |= val64 << 16; + dds_write(st, chan->address, reg); + dds_write(st, AD9122_DDS_CTRL, ctrl_reg); + break; + default: + return -EINVAL; + } + + ad9122_dds_sync_frame(st); + + return 0; +} + +static int ad9122_dds_reg_access(struct iio_dev *indio_dev, + unsigned reg, unsigned writeval, + unsigned *readval) +{ + struct ad9122_dds_state *st = iio_priv(indio_dev); + struct ad9122_converter *conv = to_converter(st->dev_spi); + int ret; + + if (IS_ERR(conv)) + return PTR_ERR(conv); + + if (reg > 0xFF) + return -EINVAL; + + mutex_lock(&indio_dev->mlock); + if (readval == NULL) { + ret = conv->write(conv->spi, reg, writeval & 0xFF); + } else { + ret = conv->read(conv->spi, reg); + if (ret < 0) + return ret; + *readval = ret; + ret = 0; + } + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static IIO_CONST_ATTR(out_altvoltage_scale_available, + "1.000000 0.500000 0.250000 0.125000 ..."); + +static struct attribute *ad9122_dds_attributes[] = { + &iio_const_attr_out_altvoltage_scale_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad9122_dds_attribute_group = { + .attrs = ad9122_dds_attributes, +}; + +#define AD9122_DDS_CHAN(_chan, _address, _extend_name) \ + { .type = IIO_ALTVOLTAGE, \ + .indexed = 1, \ + .channel = _chan, \ + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ + IIO_CHAN_INFO_PHASE_SEPARATE_BIT | \ + IIO_CHAN_INFO_FREQUENCY_SEPARATE_BIT, \ + .address = _address, \ + .output = 1, \ + .extend_name = _extend_name, \ + } + +#define AD9122_DDS_CHAN_CLK_IN(_chan, _extend_name) \ + { .type = IIO_ALTVOLTAGE, \ + .indexed = 1, \ + .channel = _chan, \ + .info_mask = IIO_CHAN_INFO_FREQUENCY_SEPARATE_BIT, \ + .extend_name = _extend_name, \ + } + +static const struct ad9122_dds_chip_info ad9122_dds_chip_info_tbl[] = { + [ID_AD9122] = { + .name = "AD9122", + .channel[0] = AD9122_DDS_CHAN(0, AD9122_DDS_1A_OUTPUT_CTRL, "1A"), + .channel[1] = AD9122_DDS_CHAN(1, AD9122_DDS_1B_OUTPUT_CTRL, "1B"), + .channel[2] = AD9122_DDS_CHAN(2, AD9122_DDS_2A_OUTPUT_CTRL, "2A"), + .channel[3] = AD9122_DDS_CHAN(3, AD9122_DDS_2B_OUTPUT_CTRL, "2B"), + .channel[4] = AD9122_DDS_CHAN_CLK_IN(0, "DAC_CLK"), + }, + [ID_AD9739A] = { + .name = "AD9739A", + .channel[0] = AD9122_DDS_CHAN(0, AD9122_DDS_1A_OUTPUT_CTRL, "1A"), + .channel[1] = AD9122_DDS_CHAN(1, AD9122_DDS_1B_OUTPUT_CTRL, "1B"), + .channel[2] = AD9122_DDS_CHAN(2, AD9122_DDS_2A_OUTPUT_CTRL, "2A"), + .channel[3] = AD9122_DDS_CHAN(3, AD9122_DDS_2B_OUTPUT_CTRL, "2B"), + .channel[4] = AD9122_DDS_CHAN_CLK_IN(0, "DAC_CLK"), + }, +}; + +static const struct iio_info ad9122_dds_info = { + .driver_module = THIS_MODULE, + .read_raw = &ad9122_dds_read_raw, + .write_raw = &ad9122_dds_write_raw, + .debugfs_reg_access = &ad9122_dds_reg_access, + .attrs = &ad9122_dds_attribute_group, +}; + +static int dds_attach_spi_client(struct device *dev, void *data) +{ + struct dds_spidev *dds_spidev = data; + + if ((dds_spidev->of_nspi == dev->of_node) && dev->driver) { + dds_spidev->dev_spi = dev; + return 1; + } + + return 0; +} + +/* Match table for of_platform binding */ +static const struct of_device_id ad9122_dds_of_match[] __devinitconst = { + { .compatible = "xlnx,cf-ad9122-core-1.00.a", .data = (void*) 1}, + { .compatible = "xlnx,cf-ad9739a-core-1.00.a", .data = (void*) 1}, + { .compatible = "xlnx,cf-ad9122x2-core-1.00.a", .data = (void*) 1}, + { .compatible = "xlnx,cf-ad9122-core-2.00.a", .data = (void*) 2}, +{ /* end of list */ }, +}; +MODULE_DEVICE_TABLE(of, ad9122_dds_of_match); + +/** + * ad9122_dds_of_probe - probe method for the AIM device. + * @of_dev: pointer to OF device structure + * @match: pointer to the stucture used for matching a device + * + * This function probes the AIM device in the device tree. + * It initializes the driver data structure and the hardware. + * It returns 0, if the driver is bound to the AIM device, or a negative + * value if there is an error. + */ +static int __devinit ad9122_dds_of_probe(struct platform_device *op) +{ + struct ad9122_dds_state *st; + struct iio_dev *indio_dev; + struct device *dev = &op->dev; + resource_size_t remap_size, phys_addr; + struct dds_spidev dds_spidev; + struct ad9122_converter *conv; + int ret; + + const struct of_device_id *of_id = + of_match_device(ad9122_dds_of_match, &op->dev); + + dev_info(dev, "Device Tree Probing \'%s\'\n", + op->dev.of_node->name); + + /* Defer driver probe until matching spi + * converter driver is registered + */ + dds_spidev.of_nspi = of_parse_phandle(op->dev.of_node, + "spibus-connected", 0); + if (!dds_spidev.of_nspi) { + dev_err(&op->dev, "could not find spi node\n"); + return -ENODEV; + } + + ret = bus_for_each_dev(&spi_bus_type, NULL, &dds_spidev, + dds_attach_spi_client); + if (ret == 0) + return -EPROBE_DEFER; + + if (!try_module_get(dds_spidev.dev_spi->driver->owner)) + return -ENODEV; + get_device(dds_spidev.dev_spi); + + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + st->dev_spi = dds_spidev.dev_spi; + + dev_set_drvdata(dev, indio_dev); + + if (of_id && of_id->data) + st->vers_id = (unsigned) of_id->data; + else + goto failed1; + + + /* Get iospace for the device */ + ret = of_address_to_resource(op->dev.of_node, 0, &st->r_mem); + if (ret) { + dev_err(dev, "invalid address\n"); + goto failed1; + } + + phys_addr = st->r_mem.start; + remap_size = resource_size(&st->r_mem); + if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) { + dev_err(dev, "Couldn't lock memory region at 0x%08llX\n", + (unsigned long long)phys_addr); + ret = -EBUSY; + goto failed1; + } + + /* Fill in configuration data and add them to the list */ + st->regs = ioremap(phys_addr, remap_size); + if (st->regs == NULL) { + dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n", + (unsigned long long)phys_addr); + ret = -EFAULT; + goto failed2; + } + + conv = to_converter(st->dev_spi); + if (IS_ERR(conv)) { + ret = PTR_ERR(conv); + goto failed3; + } + + ret = conv->setup(conv->spi, 0); + if (ret) { + dev_err(&op->dev, "failed to setup spi device\n"); + goto failed3; + } + + st->chip_info = &ad9122_dds_chip_info_tbl[conv->id]; + + indio_dev->dev.parent = dev; + indio_dev->name = op->dev.of_node->name; + indio_dev->channels = st->chip_info->channel; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->num_channels = 5; + indio_dev->info = &ad9122_dds_info; + + st->dac_clk = 491520000; + + ad9122_dds_mem_init(st); + + dds_write(st, AD9122_DDS_CTRL, 0x0); + dds_write(st, 0x20, 0x1111); /* divide by 4 */ + dds_write(st, 0x08, ad9122_ddsx(90, 40, 492)); + dds_write(st, 0x0c, ad9122_ddsx(90, 40, 492)); + dds_write(st, 0x10, ad9122_ddsx( 0, 40, 492)); + dds_write(st, 0x14, ad9122_ddsx( 0, 40, 492)); + if (st->vers_id > 1) + dds_write(st, AD9122_DDS_CTRL, 0x3); /* clk, dds enable & ddsx select */ + else + dds_write(st, AD9122_DDS_CTRL, 0x1ff); /* clk, dds enable & ddsx select */ + + ad9122_dds_sync_frame(st); + + ret = iio_device_register(indio_dev); + if (ret) + goto failed3; + + dev_info(dev, "Analog Devices AD9122_DDS %s (0x%X) at 0x%08llX mapped" + " to 0x%p, probed DDS %s\n", + (dds_read(st, AD9122_DDS_PCORE_IDENT) & + AD9122_DDS_PCORE_IDENT_SLAVE) ? "SLAVE" : "MASTER", + dds_read(st, AD9122_DDS_VERSION_ID), + (unsigned long long)phys_addr, st->regs, st->chip_info->name); + + return 0; /* success */ + +failed3: + iounmap(st->regs); +failed2: + release_mem_region(phys_addr, remap_size); +failed1: + put_device(st->dev_spi); + module_put(st->dev_spi->driver->owner); + dev_set_drvdata(dev, NULL); + iio_free_device(indio_dev); + + return ret; +} + +/** + * ad9122_dds_of_remove - unbinds the driver from the AIM device. + * @op: pointer to platform_device structure + * + * This function is called if a device is physically removed from the system or + * if the driver module is being unloaded. It frees any resources allocated to + * the device. + */ +static int __devexit ad9122_dds_of_remove(struct platform_device *op) +{ + struct device *dev = &op->dev; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad9122_dds_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + put_device(st->dev_spi); + module_put(st->dev_spi->driver->owner); + iounmap(st->regs); + release_mem_region(st->r_mem.start, resource_size(&st->r_mem)); + + iio_free_device(indio_dev); + dev_set_drvdata(dev, NULL); + + return 0; +} + +static struct platform_driver ad9122_dds_of_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = ad9122_dds_of_match, + }, + .probe = ad9122_dds_of_probe, + .remove = __devexit_p(ad9122_dds_of_remove), +}; + +static int __init ad9122_dds_init(void) +{ + return platform_driver_register(&ad9122_dds_of_driver); +} + +static void __exit ad9122_dds_cleanup(void) +{ + platform_driver_unregister(&ad9122_dds_of_driver); +} + +module_init(ad9122_dds_init); +module_exit(ad9122_dds_cleanup); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices DDS"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/frequency/cf_ad9122.h b/drivers/staging/iio/frequency/cf_ad9122.h new file mode 100644 index 0000000000000..932b9e37a7935 --- /dev/null +++ b/drivers/staging/iio/frequency/cf_ad9122.h @@ -0,0 +1,1170 @@ +/**************************************************************************** +* *************************************************************************** +* Rejeesh.Kutty@Analog.com (c) Analog Devices Inc. +* *************************************************************************** +* *************************************************************************** +* Address Map (AD9122) +* Address offset 0x00 +* [31: 0]: 0x00_01_00_61 +* Address offset 0x04 +* [ 8: 8]: dds clock enable (0x1) or disable (0x0). +* [ 7: 7]: dds-2b select dds-Xilinx(0x1) or dds-mem (0x0). +* [ 6: 6]: dds-2b enable (0x1) or disable (0x0). +* [ 5: 5]: dds-2a select dds-Xilinx(0x1) or dds-mem (0x0). +* [ 4: 4]: dds-2a enable (0x1) or disable (0x0). +* [ 3: 3]: dds-1b select dds-Xilinx(0x1) or dds-mem (0x0). +* [ 2: 2]: dds-1b enable (0x1) or disable (0x0). +* [ 1: 1]: dds-1a select dds-Xilinx(0x1) or dds-mem (0x0). +* [ 0: 0]: dds-1a enable (0x1) or disable (0x0). +* Address offset 0x08 +* [31:16]: dds-1a init (phase offset) count +* [15: 0]: dds-1a increment count +* Address offset 0x0c +* [31:16]: dds-1b init (phase offset) count +* [15: 0]: dds-1b increment count +* Address offset 0x10 +* [31:16]: dds-2a init (phase offset) count +* [15: 0]: dds-2a increment count +* Address offset 0x14 +* [31:16]: dds-2b init (phase offset) count +* [15: 0]: dds-2b increment count +* Address offset 0x18 +* [27:27]: dds mem select i/q (0 to 1). +* [26:26]: dds mem select a/b (0 to 1). +* [25:24]: dds mem sample select (0 to 2). +* [23:16]: dds mem write address +* [15: 0]: dds mem write data +* Address offset 0x20 (data = data >> scale) +* [15:12]: dds scale 2b +* [11: 8]: dds scale 2a +* [ 7: 4]: dds scale 1b +* [ 3: 0]: dds scale 1a +* ***************************************************************************/ + +#define AD9122_DDS_VERSION_ID 0x00 +#define AD9122_DDS_CTRL 0x04 +#define AD9122_DDS_1A_OUTPUT_CTRL 0x08 +#define AD9122_DDS_1B_OUTPUT_CTRL 0x0C +#define AD9122_DDS_2A_OUTPUT_CTRL 0x10 +#define AD9122_DDS_2B_OUTPUT_CTRL 0x14 +#define AD9122_DDS_MEM_CTRL 0x18 +#define AD9122_DDS_SCALE 0x20 +#define AD9122_DDS_FRAME 0x24 +#define AD9122_DDS_PCORE_IDENT 0x48 + +#define AD9122_DDS_CTRL_DDS_CLK_EN_V1 (1 << 8) +#define AD9122_DDS_CTRL_DDS_CLK_EN_V2 (1 << 0) + +/* AD9122_DDS_FRAME */ +#define AD9122_DDS_FRAME_SYNC 0x1 + +/* AD9122_DDS_PCORE_IDENT */ +#define AD9122_DDS_PCORE_IDENT_SLAVE 0x1 + +/* AD9122 internal registers */ + +#define AD9122_I_PHASE_ADJ 0x39 +#define AD9122_Q_PHASE_ADJ 0x3B + +#define AD9122_I_DAC_OFFS 0x3D +#define AD9122_Q_DAC_OFFS 0x3F + +#define AD9122_I_DAC_FS_ADJ 0x41 +#define AD9122_Q_DAC_FS_ADJ 0x45 +#define AD9122_I_AUX_DAC 0x43 + +enum { + ID_AD9122, + ID_AD9739A, +}; + +struct ad9122_dds_chip_info { + char name[8]; + struct iio_chan_spec channel[5]; +}; + +struct ad9122_dds_state { + struct list_head list; + struct device *dev_spi; + struct resource r_mem; /* IO mem resources */ + u16 int_vref_mv; + int irq; + void __iomem *regs; + unsigned int flags; + const struct ad9122_dds_chip_info *chip_info; + unsigned long dac_clk; + unsigned vers_id; +}; + +struct ad9122_converter { + struct spi_device *spi; + unsigned id; + int (*read)(struct spi_device *spi, unsigned reg); + int (*write)(struct spi_device *spi, + unsigned reg, unsigned val); + int (*setup)(struct spi_device *spi, unsigned mode); +}; + +static inline struct ad9122_converter *to_converter(struct device *dev) +{ + struct ad9122_converter *conv = spi_get_drvdata(to_spi_device(dev)); + + if (conv) + return conv; + + return ERR_PTR(-ENODEV); +}; + +/* + * IO accessors + */ + +static inline void dds_write(struct ad9122_dds_state *st, + unsigned reg, unsigned val) +{ + iowrite32(val, st->regs + reg); +} + +static inline unsigned int dds_read(struct ad9122_dds_state *st, unsigned reg) +{ + return ioread32(st->regs + reg); +} + + +#if defined(CF_AD9122_WAVDATA) +static u32 ad9122_ia_data[] = { + 0x7fff, 0xbf16, 0xedc8, + 0xfff4, 0xf0e1, 0xc479, + 0x8647, 0x4673, 0x1592, + 0x0059, 0x0c4a, 0x364b, + 0x7373, 0xb3de, 0xe6ce, + 0xff08, 0xf640, 0xcebe, + 0x92c7, 0x51ee, 0x1d0e, + 0x01e2, 0x077b, 0x2c64, + 0x6706, 0xa825, 0xded6, + 0xfce2, 0xfa7b, 0xd841, + 0x9f19, 0x5ddc, 0x257d, + 0x04a3, 0x03d6, 0x234c, + 0x5ad7, 0x9c0a, 0xd5f4, + 0xf988, 0xfd88, 0xe0ea, + 0xab1e, 0x6a1d, 0x2ecc, + 0x0894, 0x0163, 0x1b17, + 0x4f04, 0x8faa, 0xcc3e, + 0xf503, 0xff60, 0xe8a5, + 0xb6b9, 0x7695, 0x38e3, + 0x0dab, 0x0027, 0x13dc, + 0x43a9, 0x8323, 0xc1cd, + 0xef5d, 0xfffe, 0xef5d, + 0xc1cd, 0x8323, 0x43a9, + 0x13dc, 0x0027, 0x0dab, + 0x38e3, 0x7695, 0xb6b9, + 0xe8a5, 0xff60, 0xf503, + 0xcc3e, 0x8faa, 0x4f04, + 0x1b17, 0x0163, 0x0894, + 0x2ecc, 0x6a1d, 0xab1e, + 0xe0ea, 0xfd88, 0xf988, + 0xd5f4, 0x9c0a, 0x5ad7, + 0x234c, 0x03d6, 0x04a3, + 0x257d, 0x5ddc, 0x9f19, + 0xd841, 0xfa7b, 0xfce2, + 0xded6, 0xa825, 0x6706, + 0x2c64, 0x077b, 0x01e2, + 0x1d0e, 0x51ee, 0x92c7, + 0xcebe, 0xf640, 0xff08, + 0xe6ce, 0xb3de, 0x7373, + 0x364b, 0x0c4a, 0x0059, + 0x1592, 0x4673, 0x8647, + 0xc479, 0xf0e1, 0xfff4, + 0xedc8, 0xbf16, 0x7fff, + 0x40e8, 0x1236, 0x000a, + 0x0f1d, 0x3b85, 0x79b7, + 0xb98b, 0xea6c, 0xffa5, + 0xf3b4, 0xc9b3, 0x8c8b, + 0x4c20, 0x1930, 0x00f6, + 0x09be, 0x3140, 0x6d37, + 0xae10, 0xe2f0, 0xfe1c, + 0xf883, 0xd39a, 0x98f8, + 0x57d9, 0x2128, 0x031c, + 0x0583, 0x27bd, 0x60e5, + 0xa222, 0xda81, 0xfb5b, + 0xfc28, 0xdcb2, 0xa527, + 0x63f4, 0x2a0a, 0x0676, + 0x0276, 0x1f14, 0x54e0, + 0x95e1, 0xd132, 0xf76a, + 0xfe9b, 0xe4e7, 0xb0fa, + 0x7054, 0x33c0, 0x0afb, + 0x009e, 0x1759, 0x4945, + 0x8969, 0xc71b, 0xf253, + 0xffd7, 0xec22, 0xbc55, + 0x7cdb, 0x3e31, 0x10a1, + 0x0000, 0x10a1, 0x3e31, + 0x7cdb, 0xbc55, 0xec22, + 0xffd7, 0xf253, 0xc71b, + 0x8969, 0x4945, 0x1759, + 0x009e, 0x0afb, 0x33c0, + 0x7054, 0xb0fa, 0xe4e7, + 0xfe9b, 0xf76a, 0xd132, + 0x95e1, 0x54e0, 0x1f14, + 0x0276, 0x0676, 0x2a0a, + 0x63f4, 0xa527, 0xdcb2, + 0xfc28, 0xfb5b, 0xda81, + 0xa222, 0x60e5, 0x27bd, + 0x0583, 0x031c, 0x2128, + 0x57d9, 0x98f8, 0xd39a, + 0xf883, 0xfe1c, 0xe2f0, + 0xae10, 0x6d37, 0x3140, + 0x09be, 0x00f6, 0x1930, + 0x4c20, 0x8c8b, 0xc9b3, + 0xf3b4, 0xffa5, 0xea6c, + 0xb98b, 0x79b7, 0x3b85, + 0x0f1d, 0x000a, 0x1236, + 0x40e8, 0x7fff, 0xbf16, + 0xedc8, 0xfff4, 0xf0e1, + 0xc479, 0x8647, 0x4673, + 0x1592, 0x0059, 0x0c4a, + 0x364b, 0x7373, 0xb3de, + 0xe6ce, 0xff08, 0xf640, + 0xcebe, 0x92c7, 0x51ee, + 0x1d0e, 0x01e2, 0x077b, + 0x2c64, 0x6706, 0xa825, + 0xded6, 0xfce2, 0xfa7b, + 0xd841, 0x9f19, 0x5ddc, + 0x257d, 0x04a3, 0x03d6, + 0x234c, 0x5ad7, 0x9c0a, + 0xd5f4, 0xf988, 0xfd88, + 0xe0ea, 0xab1e, 0x6a1d, + 0x2ecc, 0x0894, 0x0163, + 0x1b17, 0x4f04, 0x8faa, + 0xcc3e, 0xf503, 0xff60, + 0xe8a5, 0xb6b9, 0x7695, + 0x38e3, 0x0dab, 0x0027, + 0x13dc, 0x43a9, 0x8323, + 0xc1cd, 0xef5d, 0xfffe, + 0xef5d, 0xc1cd, 0x8323, + 0x43a9, 0x13dc, 0x0027, + 0x0dab, 0x38e3, 0x7695, + 0xb6b9, 0xe8a5, 0xff60, + 0xf503, 0xcc3e, 0x8faa, + 0x4f04, 0x1b17, 0x0163, + 0x0894, 0x2ecc, 0x6a1d, + 0xab1e, 0xe0ea, 0xfd88, + 0xf988, 0xd5f4, 0x9c0a, + 0x5ad7, 0x234c, 0x03d6, + 0x04a3, 0x257d, 0x5ddc, + 0x9f19, 0xd841, 0xfa7b, + 0xfce2, 0xded6, 0xa825, + 0x6706, 0x2c64, 0x077b, + 0x01e2, 0x1d0e, 0x51ee, + 0x92c7, 0xcebe, 0xf640, + 0xff08, 0xe6ce, 0xb3de, + 0x7373, 0x364b, 0x0c4a, + 0x0059, 0x1592, 0x4673, + 0x8647, 0xc479, 0xf0e1, + 0xfff4, 0xedc8, 0xbf16, + 0x7fff, 0x40e8, 0x1236, + 0x000a, 0x0f1d, 0x3b85, + 0x79b7, 0xb98b, 0xea6c, + 0xffa5, 0xf3b4, 0xc9b3, + 0x8c8b, 0x4c20, 0x1930, + 0x00f6, 0x09be, 0x3140, + 0x6d37, 0xae10, 0xe2f0, + 0xfe1c, 0xf883, 0xd39a, + 0x98f8, 0x57d9, 0x2128, + 0x031c, 0x0583, 0x27bd, + 0x60e5, 0xa222, 0xda81, + 0xfb5b, 0xfc28, 0xdcb2, + 0xa527, 0x63f4, 0x2a0a, + 0x0676, 0x0276, 0x1f14, + 0x54e0, 0x95e1, 0xd132, + 0xf76a, 0xfe9b, 0xe4e7, + 0xb0fa, 0x7054, 0x33c0, + 0x0afb, 0x009e, 0x1759, + 0x4945, 0x8969, 0xc71b, + 0xf253, 0xffd7, 0xec22, + 0xbc55, 0x7cdb, 0x3e31, + 0x10a1, 0x0000, 0x10a1, + 0x3e31, 0x7cdb, 0xbc55, + 0xec22, 0xffd7, 0xf253, + 0xc71b, 0x8969, 0x4945, + 0x1759, 0x009e, 0x0afb, + 0x33c0, 0x7054, 0xb0fa, + 0xe4e7, 0xfe9b, 0xf76a, + 0xd132, 0x95e1, 0x54e0, + 0x1f14, 0x0276, 0x0676, + 0x2a0a, 0x63f4, 0xa527, + 0xdcb2, 0xfc28, 0xfb5b, + 0xda81, 0xa222, 0x60e5, + 0x27bd, 0x0583, 0x031c, + 0x2128, 0x57d9, 0x98f8, + 0xd39a, 0xf883, 0xfe1c, + 0xe2f0, 0xae10, 0x6d37, + 0x3140, 0x09be, 0x00f6, + 0x1930, 0x4c20, 0x8c8b, + 0xc9b3, 0xf3b4, 0xffa5, + 0xea6c, 0xb98b, 0x79b7, + 0x3b85, 0x0f1d, 0x000a, + 0x1236, 0x40e8, 0x7fff, + 0xbf16, 0xedc8, 0xfff4, + 0xf0e1, 0xc479, 0x8647, + 0x4673, 0x1592, 0x0059, + 0x0c4a, 0x364b, 0x7373, + 0xb3de, 0xe6ce, 0xff08, + 0xf640, 0xcebe, 0x92c7, + 0x51ee, 0x1d0e, 0x01e2, + 0x077b, 0x2c64, 0x6706, + 0xa825, 0xded6, 0xfce2, + 0xfa7b, 0xd841, 0x9f19, + 0x5ddc, 0x257d, 0x04a3, + 0x03d6, 0x234c, 0x5ad7, + 0x9c0a, 0xd5f4, 0xf988, + 0xfd88, 0xe0ea, 0xab1e, + 0x6a1d, 0x2ecc, 0x0894, + 0x0163, 0x1b17, 0x4f04, + 0x8faa, 0xcc3e, 0xf503, + 0xff60, 0xe8a5, 0xb6b9, + 0x7695, 0x38e3, 0x0dab, + 0x0027, 0x13dc, 0x43a9, + 0x8323, 0xc1cd, 0xef5d, + 0xfffe, 0xef5d, 0xc1cd, + 0x8323, 0x43a9, 0x13dc, + 0x0027, 0x0dab, 0x38e3, + 0x7695, 0xb6b9, 0xe8a5, + 0xff60, 0xf503, 0xcc3e, + 0x8faa, 0x4f04, 0x1b17, + 0x0163, 0x0894, 0x2ecc, + 0x6a1d, 0xab1e, 0xe0ea, + 0xfd88, 0xf988, 0xd5f4, + 0x9c0a, 0x5ad7, 0x234c, + 0x03d6, 0x04a3, 0x257d, + 0x5ddc, 0x9f19, 0xd841, + 0xfa7b, 0xfce2, 0xded6, + 0xa825, 0x6706, 0x2c64, + 0x077b, 0x01e2, 0x1d0e, + 0x51ee, 0x92c7, 0xcebe, + 0xf640, 0xff08, 0xe6ce, + 0xb3de, 0x7373, 0x364b, + 0x0c4a, 0x0059, 0x1592, + 0x4673, 0x8647, 0xc479, + 0xf0e1, 0xfff4, 0xedc8, + 0xbf16, 0x7fff, 0x40e8, + 0x1236, 0x000a, 0x0f1d, + 0x3b85, 0x79b7, 0xb98b, + 0xea6c, 0xffa5, 0xf3b4, + 0xc9b3, 0x8c8b, 0x4c20, + 0x1930, 0x00f6, 0x09be, + 0x3140, 0x6d37, 0xae10, + 0xe2f0, 0xfe1c, 0xf883, + 0xd39a, 0x98f8, 0x57d9, + 0x2128, 0x031c, 0x0583, + 0x27bd, 0x60e5, 0xa222, + 0xda81, 0xfb5b, 0xfc28, + 0xdcb2, 0xa527, 0x63f4, + 0x2a0a, 0x0676, 0x0276, + 0x1f14, 0x54e0, 0x95e1, + 0xd132, 0xf76a, 0xfe9b, + 0xe4e7, 0xb0fa, 0x7054, + 0x33c0, 0x0afb, 0x009e, + 0x1759, 0x4945, 0x8969, + 0xc71b, 0xf253, 0xffd7, + 0xec22, 0xbc55, 0x7cdb, + 0x3e31, 0x10a1, 0x0000, + 0x10a1, 0x3e31, 0x7cdb, + 0xbc55, 0xec22, 0xffd7, + 0xf253, 0xc71b, 0x8969, + 0x4945, 0x1759, 0x009e, + 0x0afb, 0x33c0, 0x7054, + 0xb0fa, 0xe4e7, 0xfe9b, + 0xf76a, 0xd132, 0x95e1, + 0x54e0, 0x1f14, 0x0276, + 0x0676, 0x2a0a, 0x63f4, + 0xa527, 0xdcb2, 0xfc28, + 0xfb5b, 0xda81, 0xa222, + 0x60e5, 0x27bd, 0x0583, + 0x031c, 0x2128, 0x57d9, + 0x98f8, 0xd39a, 0xf883, + 0xfe1c, 0xe2f0, 0xae10, + 0x6d37, 0x3140, 0x09be, + 0x00f6, 0x1930, 0x4c20, + 0x8c8b, 0xc9b3, 0xf3b4, + 0xffa5, 0xea6c, 0xb98b, + 0x79b7, 0x3b85, 0x0f1d, + 0x000a, 0x1236, 0x40e8 +}; + +static u32 ad9122_ib_data[] = { + 0x7fff, 0xbf16, 0xedc8, + 0xfff4, 0xf0e1, 0xc479, + 0x8647, 0x4673, 0x1592, + 0x0059, 0x0c4a, 0x364b, + 0x7373, 0xb3de, 0xe6ce, + 0xff08, 0xf640, 0xcebe, + 0x92c7, 0x51ee, 0x1d0e, + 0x01e2, 0x077b, 0x2c64, + 0x6706, 0xa825, 0xded6, + 0xfce2, 0xfa7b, 0xd841, + 0x9f19, 0x5ddc, 0x257d, + 0x04a3, 0x03d6, 0x234c, + 0x5ad7, 0x9c0a, 0xd5f4, + 0xf988, 0xfd88, 0xe0ea, + 0xab1e, 0x6a1d, 0x2ecc, + 0x0894, 0x0163, 0x1b17, + 0x4f04, 0x8faa, 0xcc3e, + 0xf503, 0xff60, 0xe8a5, + 0xb6b9, 0x7695, 0x38e3, + 0x0dab, 0x0027, 0x13dc, + 0x43a9, 0x8323, 0xc1cd, + 0xef5d, 0xfffe, 0xef5d, + 0xc1cd, 0x8323, 0x43a9, + 0x13dc, 0x0027, 0x0dab, + 0x38e3, 0x7695, 0xb6b9, + 0xe8a5, 0xff60, 0xf503, + 0xcc3e, 0x8faa, 0x4f04, + 0x1b17, 0x0163, 0x0894, + 0x2ecc, 0x6a1d, 0xab1e, + 0xe0ea, 0xfd88, 0xf988, + 0xd5f4, 0x9c0a, 0x5ad7, + 0x234c, 0x03d6, 0x04a3, + 0x257d, 0x5ddc, 0x9f19, + 0xd841, 0xfa7b, 0xfce2, + 0xded6, 0xa825, 0x6706, + 0x2c64, 0x077b, 0x01e2, + 0x1d0e, 0x51ee, 0x92c7, + 0xcebe, 0xf640, 0xff08, + 0xe6ce, 0xb3de, 0x7373, + 0x364b, 0x0c4a, 0x0059, + 0x1592, 0x4673, 0x8647, + 0xc479, 0xf0e1, 0xfff4, + 0xedc8, 0xbf16, 0x7fff, + 0x40e8, 0x1236, 0x000a, + 0x0f1d, 0x3b85, 0x79b7, + 0xb98b, 0xea6c, 0xffa5, + 0xf3b4, 0xc9b3, 0x8c8b, + 0x4c20, 0x1930, 0x00f6, + 0x09be, 0x3140, 0x6d37, + 0xae10, 0xe2f0, 0xfe1c, + 0xf883, 0xd39a, 0x98f8, + 0x57d9, 0x2128, 0x031c, + 0x0583, 0x27bd, 0x60e5, + 0xa222, 0xda81, 0xfb5b, + 0xfc28, 0xdcb2, 0xa527, + 0x63f4, 0x2a0a, 0x0676, + 0x0276, 0x1f14, 0x54e0, + 0x95e1, 0xd132, 0xf76a, + 0xfe9b, 0xe4e7, 0xb0fa, + 0x7054, 0x33c0, 0x0afb, + 0x009e, 0x1759, 0x4945, + 0x8969, 0xc71b, 0xf253, + 0xffd7, 0xec22, 0xbc55, + 0x7cdb, 0x3e31, 0x10a1, + 0x0000, 0x10a1, 0x3e31, + 0x7cdb, 0xbc55, 0xec22, + 0xffd7, 0xf253, 0xc71b, + 0x8969, 0x4945, 0x1759, + 0x009e, 0x0afb, 0x33c0, + 0x7054, 0xb0fa, 0xe4e7, + 0xfe9b, 0xf76a, 0xd132, + 0x95e1, 0x54e0, 0x1f14, + 0x0276, 0x0676, 0x2a0a, + 0x63f4, 0xa527, 0xdcb2, + 0xfc28, 0xfb5b, 0xda81, + 0xa222, 0x60e5, 0x27bd, + 0x0583, 0x031c, 0x2128, + 0x57d9, 0x98f8, 0xd39a, + 0xf883, 0xfe1c, 0xe2f0, + 0xae10, 0x6d37, 0x3140, + 0x09be, 0x00f6, 0x1930, + 0x4c20, 0x8c8b, 0xc9b3, + 0xf3b4, 0xffa5, 0xea6c, + 0xb98b, 0x79b7, 0x3b85, + 0x0f1d, 0x000a, 0x1236, + 0x40e8, 0x7fff, 0xbf16, + 0xedc8, 0xfff4, 0xf0e1, + 0xc479, 0x8647, 0x4673, + 0x1592, 0x0059, 0x0c4a, + 0x364b, 0x7373, 0xb3de, + 0xe6ce, 0xff08, 0xf640, + 0xcebe, 0x92c7, 0x51ee, + 0x1d0e, 0x01e2, 0x077b, + 0x2c64, 0x6706, 0xa825, + 0xded6, 0xfce2, 0xfa7b, + 0xd841, 0x9f19, 0x5ddc, + 0x257d, 0x04a3, 0x03d6, + 0x234c, 0x5ad7, 0x9c0a, + 0xd5f4, 0xf988, 0xfd88, + 0xe0ea, 0xab1e, 0x6a1d, + 0x2ecc, 0x0894, 0x0163, + 0x1b17, 0x4f04, 0x8faa, + 0xcc3e, 0xf503, 0xff60, + 0xe8a5, 0xb6b9, 0x7695, + 0x38e3, 0x0dab, 0x0027, + 0x13dc, 0x43a9, 0x8323, + 0xc1cd, 0xef5d, 0xfffe, + 0xef5d, 0xc1cd, 0x8323, + 0x43a9, 0x13dc, 0x0027, + 0x0dab, 0x38e3, 0x7695, + 0xb6b9, 0xe8a5, 0xff60, + 0xf503, 0xcc3e, 0x8faa, + 0x4f04, 0x1b17, 0x0163, + 0x0894, 0x2ecc, 0x6a1d, + 0xab1e, 0xe0ea, 0xfd88, + 0xf988, 0xd5f4, 0x9c0a, + 0x5ad7, 0x234c, 0x03d6, + 0x04a3, 0x257d, 0x5ddc, + 0x9f19, 0xd841, 0xfa7b, + 0xfce2, 0xded6, 0xa825, + 0x6706, 0x2c64, 0x077b, + 0x01e2, 0x1d0e, 0x51ee, + 0x92c7, 0xcebe, 0xf640, + 0xff08, 0xe6ce, 0xb3de, + 0x7373, 0x364b, 0x0c4a, + 0x0059, 0x1592, 0x4673, + 0x8647, 0xc479, 0xf0e1, + 0xfff4, 0xedc8, 0xbf16, + 0x7fff, 0x40e8, 0x1236, + 0x000a, 0x0f1d, 0x3b85, + 0x79b7, 0xb98b, 0xea6c, + 0xffa5, 0xf3b4, 0xc9b3, + 0x8c8b, 0x4c20, 0x1930, + 0x00f6, 0x09be, 0x3140, + 0x6d37, 0xae10, 0xe2f0, + 0xfe1c, 0xf883, 0xd39a, + 0x98f8, 0x57d9, 0x2128, + 0x031c, 0x0583, 0x27bd, + 0x60e5, 0xa222, 0xda81, + 0xfb5b, 0xfc28, 0xdcb2, + 0xa527, 0x63f4, 0x2a0a, + 0x0676, 0x0276, 0x1f14, + 0x54e0, 0x95e1, 0xd132, + 0xf76a, 0xfe9b, 0xe4e7, + 0xb0fa, 0x7054, 0x33c0, + 0x0afb, 0x009e, 0x1759, + 0x4945, 0x8969, 0xc71b, + 0xf253, 0xffd7, 0xec22, + 0xbc55, 0x7cdb, 0x3e31, + 0x10a1, 0x0000, 0x10a1, + 0x3e31, 0x7cdb, 0xbc55, + 0xec22, 0xffd7, 0xf253, + 0xc71b, 0x8969, 0x4945, + 0x1759, 0x009e, 0x0afb, + 0x33c0, 0x7054, 0xb0fa, + 0xe4e7, 0xfe9b, 0xf76a, + 0xd132, 0x95e1, 0x54e0, + 0x1f14, 0x0276, 0x0676, + 0x2a0a, 0x63f4, 0xa527, + 0xdcb2, 0xfc28, 0xfb5b, + 0xda81, 0xa222, 0x60e5, + 0x27bd, 0x0583, 0x031c, + 0x2128, 0x57d9, 0x98f8, + 0xd39a, 0xf883, 0xfe1c, + 0xe2f0, 0xae10, 0x6d37, + 0x3140, 0x09be, 0x00f6, + 0x1930, 0x4c20, 0x8c8b, + 0xc9b3, 0xf3b4, 0xffa5, + 0xea6c, 0xb98b, 0x79b7, + 0x3b85, 0x0f1d, 0x000a, + 0x1236, 0x40e8, 0x7fff, + 0xbf16, 0xedc8, 0xfff4, + 0xf0e1, 0xc479, 0x8647, + 0x4673, 0x1592, 0x0059, + 0x0c4a, 0x364b, 0x7373, + 0xb3de, 0xe6ce, 0xff08, + 0xf640, 0xcebe, 0x92c7, + 0x51ee, 0x1d0e, 0x01e2, + 0x077b, 0x2c64, 0x6706, + 0xa825, 0xded6, 0xfce2, + 0xfa7b, 0xd841, 0x9f19, + 0x5ddc, 0x257d, 0x04a3, + 0x03d6, 0x234c, 0x5ad7, + 0x9c0a, 0xd5f4, 0xf988, + 0xfd88, 0xe0ea, 0xab1e, + 0x6a1d, 0x2ecc, 0x0894, + 0x0163, 0x1b17, 0x4f04, + 0x8faa, 0xcc3e, 0xf503, + 0xff60, 0xe8a5, 0xb6b9, + 0x7695, 0x38e3, 0x0dab, + 0x0027, 0x13dc, 0x43a9, + 0x8323, 0xc1cd, 0xef5d, + 0xfffe, 0xef5d, 0xc1cd, + 0x8323, 0x43a9, 0x13dc, + 0x0027, 0x0dab, 0x38e3, + 0x7695, 0xb6b9, 0xe8a5, + 0xff60, 0xf503, 0xcc3e, + 0x8faa, 0x4f04, 0x1b17, + 0x0163, 0x0894, 0x2ecc, + 0x6a1d, 0xab1e, 0xe0ea, + 0xfd88, 0xf988, 0xd5f4, + 0x9c0a, 0x5ad7, 0x234c, + 0x03d6, 0x04a3, 0x257d, + 0x5ddc, 0x9f19, 0xd841, + 0xfa7b, 0xfce2, 0xded6, + 0xa825, 0x6706, 0x2c64, + 0x077b, 0x01e2, 0x1d0e, + 0x51ee, 0x92c7, 0xcebe, + 0xf640, 0xff08, 0xe6ce, + 0xb3de, 0x7373, 0x364b, + 0x0c4a, 0x0059, 0x1592, + 0x4673, 0x8647, 0xc479, + 0xf0e1, 0xfff4, 0xedc8, + 0xbf16, 0x7fff, 0x40e8, + 0x1236, 0x000a, 0x0f1d, + 0x3b85, 0x79b7, 0xb98b, + 0xea6c, 0xffa5, 0xf3b4, + 0xc9b3, 0x8c8b, 0x4c20, + 0x1930, 0x00f6, 0x09be, + 0x3140, 0x6d37, 0xae10, + 0xe2f0, 0xfe1c, 0xf883, + 0xd39a, 0x98f8, 0x57d9, + 0x2128, 0x031c, 0x0583, + 0x27bd, 0x60e5, 0xa222, + 0xda81, 0xfb5b, 0xfc28, + 0xdcb2, 0xa527, 0x63f4, + 0x2a0a, 0x0676, 0x0276, + 0x1f14, 0x54e0, 0x95e1, + 0xd132, 0xf76a, 0xfe9b, + 0xe4e7, 0xb0fa, 0x7054, + 0x33c0, 0x0afb, 0x009e, + 0x1759, 0x4945, 0x8969, + 0xc71b, 0xf253, 0xffd7, + 0xec22, 0xbc55, 0x7cdb, + 0x3e31, 0x10a1, 0x0000, + 0x10a1, 0x3e31, 0x7cdb, + 0xbc55, 0xec22, 0xffd7, + 0xf253, 0xc71b, 0x8969, + 0x4945, 0x1759, 0x009e, + 0x0afb, 0x33c0, 0x7054, + 0xb0fa, 0xe4e7, 0xfe9b, + 0xf76a, 0xd132, 0x95e1, + 0x54e0, 0x1f14, 0x0276, + 0x0676, 0x2a0a, 0x63f4, + 0xa527, 0xdcb2, 0xfc28, + 0xfb5b, 0xda81, 0xa222, + 0x60e5, 0x27bd, 0x0583, + 0x031c, 0x2128, 0x57d9, + 0x98f8, 0xd39a, 0xf883, + 0xfe1c, 0xe2f0, 0xae10, + 0x6d37, 0x3140, 0x09be, + 0x00f6, 0x1930, 0x4c20, + 0x8c8b, 0xc9b3, 0xf3b4, + 0xffa5, 0xea6c, 0xb98b, + 0x79b7, 0x3b85, 0x0f1d, + 0x000a, 0x1236, 0x40e8 +}; + +static u32 ad9122_qa_data[] = { + 0x0000, 0x10a1, 0x3e31, + 0x7cdb, 0xbc55, 0xec22, + 0xffd7, 0xf253, 0xc71b, + 0x8969, 0x4945, 0x1759, + 0x009e, 0x0afb, 0x33c0, + 0x7054, 0xb0fa, 0xe4e7, + 0xfe9b, 0xf76a, 0xd132, + 0x95e1, 0x54e0, 0x1f14, + 0x0276, 0x0676, 0x2a0a, + 0x63f4, 0xa527, 0xdcb2, + 0xfc28, 0xfb5b, 0xda81, + 0xa222, 0x60e5, 0x27bd, + 0x0583, 0x031c, 0x2128, + 0x57d9, 0x98f8, 0xd39a, + 0xf883, 0xfe1c, 0xe2f0, + 0xae10, 0x6d37, 0x3140, + 0x09be, 0x00f6, 0x1930, + 0x4c20, 0x8c8b, 0xc9b3, + 0xf3b4, 0xffa5, 0xea6c, + 0xb98b, 0x79b7, 0x3b85, + 0x0f1d, 0x000a, 0x1236, + 0x40e8, 0x7fff, 0xbf16, + 0xedc8, 0xfff4, 0xf0e1, + 0xc479, 0x8647, 0x4673, + 0x1592, 0x0059, 0x0c4a, + 0x364b, 0x7373, 0xb3de, + 0xe6ce, 0xff08, 0xf640, + 0xcebe, 0x92c7, 0x51ee, + 0x1d0e, 0x01e2, 0x077b, + 0x2c64, 0x6706, 0xa825, + 0xded6, 0xfce2, 0xfa7b, + 0xd841, 0x9f19, 0x5ddc, + 0x257d, 0x04a3, 0x03d6, + 0x234c, 0x5ad7, 0x9c0a, + 0xd5f4, 0xf988, 0xfd88, + 0xe0ea, 0xab1e, 0x6a1d, + 0x2ecc, 0x0894, 0x0163, + 0x1b17, 0x4f04, 0x8faa, + 0xcc3e, 0xf503, 0xff60, + 0xe8a5, 0xb6b9, 0x7695, + 0x38e3, 0x0dab, 0x0027, + 0x13dc, 0x43a9, 0x8323, + 0xc1cd, 0xef5d, 0xfffe, + 0xef5d, 0xc1cd, 0x8323, + 0x43a9, 0x13dc, 0x0027, + 0x0dab, 0x38e3, 0x7695, + 0xb6b9, 0xe8a5, 0xff60, + 0xf503, 0xcc3e, 0x8faa, + 0x4f04, 0x1b17, 0x0163, + 0x0894, 0x2ecc, 0x6a1d, + 0xab1e, 0xe0ea, 0xfd88, + 0xf988, 0xd5f4, 0x9c0a, + 0x5ad7, 0x234c, 0x03d6, + 0x04a3, 0x257d, 0x5ddc, + 0x9f19, 0xd841, 0xfa7b, + 0xfce2, 0xded6, 0xa825, + 0x6706, 0x2c64, 0x077b, + 0x01e2, 0x1d0e, 0x51ee, + 0x92c7, 0xcebe, 0xf640, + 0xff08, 0xe6ce, 0xb3de, + 0x7373, 0x364b, 0x0c4a, + 0x0059, 0x1592, 0x4673, + 0x8647, 0xc479, 0xf0e1, + 0xfff4, 0xedc8, 0xbf16, + 0x7fff, 0x40e8, 0x1236, + 0x000a, 0x0f1d, 0x3b85, + 0x79b7, 0xb98b, 0xea6c, + 0xffa5, 0xf3b4, 0xc9b3, + 0x8c8b, 0x4c20, 0x1930, + 0x00f6, 0x09be, 0x3140, + 0x6d37, 0xae10, 0xe2f0, + 0xfe1c, 0xf883, 0xd39a, + 0x98f8, 0x57d9, 0x2128, + 0x031c, 0x0583, 0x27bd, + 0x60e5, 0xa222, 0xda81, + 0xfb5b, 0xfc28, 0xdcb2, + 0xa527, 0x63f4, 0x2a0a, + 0x0676, 0x0276, 0x1f14, + 0x54e0, 0x95e1, 0xd132, + 0xf76a, 0xfe9b, 0xe4e7, + 0xb0fa, 0x7054, 0x33c0, + 0x0afb, 0x009e, 0x1759, + 0x4945, 0x8969, 0xc71b, + 0xf253, 0xffd7, 0xec22, + 0xbc55, 0x7cdb, 0x3e31, + 0x10a1, 0x0000, 0x10a1, + 0x3e31, 0x7cdb, 0xbc55, + 0xec22, 0xffd7, 0xf253, + 0xc71b, 0x8969, 0x4945, + 0x1759, 0x009e, 0x0afb, + 0x33c0, 0x7054, 0xb0fa, + 0xe4e7, 0xfe9b, 0xf76a, + 0xd132, 0x95e1, 0x54e0, + 0x1f14, 0x0276, 0x0676, + 0x2a0a, 0x63f4, 0xa527, + 0xdcb2, 0xfc28, 0xfb5b, + 0xda81, 0xa222, 0x60e5, + 0x27bd, 0x0583, 0x031c, + 0x2128, 0x57d9, 0x98f8, + 0xd39a, 0xf883, 0xfe1c, + 0xe2f0, 0xae10, 0x6d37, + 0x3140, 0x09be, 0x00f6, + 0x1930, 0x4c20, 0x8c8b, + 0xc9b3, 0xf3b4, 0xffa5, + 0xea6c, 0xb98b, 0x79b7, + 0x3b85, 0x0f1d, 0x000a, + 0x1236, 0x40e8, 0x7fff, + 0xbf16, 0xedc8, 0xfff4, + 0xf0e1, 0xc479, 0x8647, + 0x4673, 0x1592, 0x0059, + 0x0c4a, 0x364b, 0x7373, + 0xb3de, 0xe6ce, 0xff08, + 0xf640, 0xcebe, 0x92c7, + 0x51ee, 0x1d0e, 0x01e2, + 0x077b, 0x2c64, 0x6706, + 0xa825, 0xded6, 0xfce2, + 0xfa7b, 0xd841, 0x9f19, + 0x5ddc, 0x257d, 0x04a3, + 0x03d6, 0x234c, 0x5ad7, + 0x9c0a, 0xd5f4, 0xf988, + 0xfd88, 0xe0ea, 0xab1e, + 0x6a1d, 0x2ecc, 0x0894, + 0x0163, 0x1b17, 0x4f04, + 0x8faa, 0xcc3e, 0xf503, + 0xff60, 0xe8a5, 0xb6b9, + 0x7695, 0x38e3, 0x0dab, + 0x0027, 0x13dc, 0x43a9, + 0x8323, 0xc1cd, 0xef5d, + 0xfffe, 0xef5d, 0xc1cd, + 0x8323, 0x43a9, 0x13dc, + 0x0027, 0x0dab, 0x38e3, + 0x7695, 0xb6b9, 0xe8a5, + 0xff60, 0xf503, 0xcc3e, + 0x8faa, 0x4f04, 0x1b17, + 0x0163, 0x0894, 0x2ecc, + 0x6a1d, 0xab1e, 0xe0ea, + 0xfd88, 0xf988, 0xd5f4, + 0x9c0a, 0x5ad7, 0x234c, + 0x03d6, 0x04a3, 0x257d, + 0x5ddc, 0x9f19, 0xd841, + 0xfa7b, 0xfce2, 0xded6, + 0xa825, 0x6706, 0x2c64, + 0x077b, 0x01e2, 0x1d0e, + 0x51ee, 0x92c7, 0xcebe, + 0xf640, 0xff08, 0xe6ce, + 0xb3de, 0x7373, 0x364b, + 0x0c4a, 0x0059, 0x1592, + 0x4673, 0x8647, 0xc479, + 0xf0e1, 0xfff4, 0xedc8, + 0xbf16, 0x7fff, 0x40e8, + 0x1236, 0x000a, 0x0f1d, + 0x3b85, 0x79b7, 0xb98b, + 0xea6c, 0xffa5, 0xf3b4, + 0xc9b3, 0x8c8b, 0x4c20, + 0x1930, 0x00f6, 0x09be, + 0x3140, 0x6d37, 0xae10, + 0xe2f0, 0xfe1c, 0xf883, + 0xd39a, 0x98f8, 0x57d9, + 0x2128, 0x031c, 0x0583, + 0x27bd, 0x60e5, 0xa222, + 0xda81, 0xfb5b, 0xfc28, + 0xdcb2, 0xa527, 0x63f4, + 0x2a0a, 0x0676, 0x0276, + 0x1f14, 0x54e0, 0x95e1, + 0xd132, 0xf76a, 0xfe9b, + 0xe4e7, 0xb0fa, 0x7054, + 0x33c0, 0x0afb, 0x009e, + 0x1759, 0x4945, 0x8969, + 0xc71b, 0xf253, 0xffd7, + 0xec22, 0xbc55, 0x7cdb, + 0x3e31, 0x10a1, 0x0000, + 0x10a1, 0x3e31, 0x7cdb, + 0xbc55, 0xec22, 0xffd7, + 0xf253, 0xc71b, 0x8969, + 0x4945, 0x1759, 0x009e, + 0x0afb, 0x33c0, 0x7054, + 0xb0fa, 0xe4e7, 0xfe9b, + 0xf76a, 0xd132, 0x95e1, + 0x54e0, 0x1f14, 0x0276, + 0x0676, 0x2a0a, 0x63f4, + 0xa527, 0xdcb2, 0xfc28, + 0xfb5b, 0xda81, 0xa222, + 0x60e5, 0x27bd, 0x0583, + 0x031c, 0x2128, 0x57d9, + 0x98f8, 0xd39a, 0xf883, + 0xfe1c, 0xe2f0, 0xae10, + 0x6d37, 0x3140, 0x09be, + 0x00f6, 0x1930, 0x4c20, + 0x8c8b, 0xc9b3, 0xf3b4, + 0xffa5, 0xea6c, 0xb98b, + 0x79b7, 0x3b85, 0x0f1d, + 0x000a, 0x1236, 0x40e8, + 0x7fff, 0xbf16, 0xedc8, + 0xfff4, 0xf0e1, 0xc479, + 0x8647, 0x4673, 0x1592, + 0x0059, 0x0c4a, 0x364b, + 0x7373, 0xb3de, 0xe6ce, + 0xff08, 0xf640, 0xcebe, + 0x92c7, 0x51ee, 0x1d0e, + 0x01e2, 0x077b, 0x2c64, + 0x6706, 0xa825, 0xded6, + 0xfce2, 0xfa7b, 0xd841, + 0x9f19, 0x5ddc, 0x257d, + 0x04a3, 0x03d6, 0x234c, + 0x5ad7, 0x9c0a, 0xd5f4, + 0xf988, 0xfd88, 0xe0ea, + 0xab1e, 0x6a1d, 0x2ecc, + 0x0894, 0x0163, 0x1b17, + 0x4f04, 0x8faa, 0xcc3e, + 0xf503, 0xff60, 0xe8a5, + 0xb6b9, 0x7695, 0x38e3, + 0x0dab, 0x0027, 0x13dc, + 0x43a9, 0x8323, 0xc1cd, + 0xef5d, 0xfffe, 0xef5d, + 0xc1cd, 0x8323, 0x43a9, + 0x13dc, 0x0027, 0x0dab, + 0x38e3, 0x7695, 0xb6b9, + 0xe8a5, 0xff60, 0xf503, + 0xcc3e, 0x8faa, 0x4f04, + 0x1b17, 0x0163, 0x0894, + 0x2ecc, 0x6a1d, 0xab1e, + 0xe0ea, 0xfd88, 0xf988, + 0xd5f4, 0x9c0a, 0x5ad7, + 0x234c, 0x03d6, 0x04a3, + 0x257d, 0x5ddc, 0x9f19, + 0xd841, 0xfa7b, 0xfce2, + 0xded6, 0xa825, 0x6706, + 0x2c64, 0x077b, 0x01e2, + 0x1d0e, 0x51ee, 0x92c7, + 0xcebe, 0xf640, 0xff08, + 0xe6ce, 0xb3de, 0x7373, + 0x364b, 0x0c4a, 0x0059, + 0x1592, 0x4673, 0x8647, + 0xc479, 0xf0e1, 0xfff4, + 0xedc8, 0xbf16, 0x7fff, + 0x40e8, 0x1236, 0x000a, + 0x0f1d, 0x3b85, 0x79b7, + 0xb98b, 0xea6c, 0xffa5, + 0xf3b4, 0xc9b3, 0x8c8b, + 0x4c20, 0x1930, 0x00f6, + 0x09be, 0x3140, 0x6d37, + 0xae10, 0xe2f0, 0xfe1c, + 0xf883, 0xd39a, 0x98f8, + 0x57d9, 0x2128, 0x031c, + 0x0583, 0x27bd, 0x60e5, + 0xa222, 0xda81, 0xfb5b, + 0xfc28, 0xdcb2, 0xa527, + 0x63f4, 0x2a0a, 0x0676, + 0x0276, 0x1f14, 0x54e0, + 0x95e1, 0xd132, 0xf76a, + 0xfe9b, 0xe4e7, 0xb0fa, + 0x7054, 0x33c0, 0x0afb, + 0x009e, 0x1759, 0x4945, + 0x8969, 0xc71b, 0xf253, + 0xffd7, 0xec22, 0xbc55, + 0x7cdb, 0x3e31, 0x10a1 +}; + +static u32 ad9122_qb_data[] = { + 0x0000, 0x10a1, 0x3e31, + 0x7cdb, 0xbc55, 0xec22, + 0xffd7, 0xf253, 0xc71b, + 0x8969, 0x4945, 0x1759, + 0x009e, 0x0afb, 0x33c0, + 0x7054, 0xb0fa, 0xe4e7, + 0xfe9b, 0xf76a, 0xd132, + 0x95e1, 0x54e0, 0x1f14, + 0x0276, 0x0676, 0x2a0a, + 0x63f4, 0xa527, 0xdcb2, + 0xfc28, 0xfb5b, 0xda81, + 0xa222, 0x60e5, 0x27bd, + 0x0583, 0x031c, 0x2128, + 0x57d9, 0x98f8, 0xd39a, + 0xf883, 0xfe1c, 0xe2f0, + 0xae10, 0x6d37, 0x3140, + 0x09be, 0x00f6, 0x1930, + 0x4c20, 0x8c8b, 0xc9b3, + 0xf3b4, 0xffa5, 0xea6c, + 0xb98b, 0x79b7, 0x3b85, + 0x0f1d, 0x000a, 0x1236, + 0x40e8, 0x7fff, 0xbf16, + 0xedc8, 0xfff4, 0xf0e1, + 0xc479, 0x8647, 0x4673, + 0x1592, 0x0059, 0x0c4a, + 0x364b, 0x7373, 0xb3de, + 0xe6ce, 0xff08, 0xf640, + 0xcebe, 0x92c7, 0x51ee, + 0x1d0e, 0x01e2, 0x077b, + 0x2c64, 0x6706, 0xa825, + 0xded6, 0xfce2, 0xfa7b, + 0xd841, 0x9f19, 0x5ddc, + 0x257d, 0x04a3, 0x03d6, + 0x234c, 0x5ad7, 0x9c0a, + 0xd5f4, 0xf988, 0xfd88, + 0xe0ea, 0xab1e, 0x6a1d, + 0x2ecc, 0x0894, 0x0163, + 0x1b17, 0x4f04, 0x8faa, + 0xcc3e, 0xf503, 0xff60, + 0xe8a5, 0xb6b9, 0x7695, + 0x38e3, 0x0dab, 0x0027, + 0x13dc, 0x43a9, 0x8323, + 0xc1cd, 0xef5d, 0xfffe, + 0xef5d, 0xc1cd, 0x8323, + 0x43a9, 0x13dc, 0x0027, + 0x0dab, 0x38e3, 0x7695, + 0xb6b9, 0xe8a5, 0xff60, + 0xf503, 0xcc3e, 0x8faa, + 0x4f04, 0x1b17, 0x0163, + 0x0894, 0x2ecc, 0x6a1d, + 0xab1e, 0xe0ea, 0xfd88, + 0xf988, 0xd5f4, 0x9c0a, + 0x5ad7, 0x234c, 0x03d6, + 0x04a3, 0x257d, 0x5ddc, + 0x9f19, 0xd841, 0xfa7b, + 0xfce2, 0xded6, 0xa825, + 0x6706, 0x2c64, 0x077b, + 0x01e2, 0x1d0e, 0x51ee, + 0x92c7, 0xcebe, 0xf640, + 0xff08, 0xe6ce, 0xb3de, + 0x7373, 0x364b, 0x0c4a, + 0x0059, 0x1592, 0x4673, + 0x8647, 0xc479, 0xf0e1, + 0xfff4, 0xedc8, 0xbf16, + 0x7fff, 0x40e8, 0x1236, + 0x000a, 0x0f1d, 0x3b85, + 0x79b7, 0xb98b, 0xea6c, + 0xffa5, 0xf3b4, 0xc9b3, + 0x8c8b, 0x4c20, 0x1930, + 0x00f6, 0x09be, 0x3140, + 0x6d37, 0xae10, 0xe2f0, + 0xfe1c, 0xf883, 0xd39a, + 0x98f8, 0x57d9, 0x2128, + 0x031c, 0x0583, 0x27bd, + 0x60e5, 0xa222, 0xda81, + 0xfb5b, 0xfc28, 0xdcb2, + 0xa527, 0x63f4, 0x2a0a, + 0x0676, 0x0276, 0x1f14, + 0x54e0, 0x95e1, 0xd132, + 0xf76a, 0xfe9b, 0xe4e7, + 0xb0fa, 0x7054, 0x33c0, + 0x0afb, 0x009e, 0x1759, + 0x4945, 0x8969, 0xc71b, + 0xf253, 0xffd7, 0xec22, + 0xbc55, 0x7cdb, 0x3e31, + 0x10a1, 0x0000, 0x10a1, + 0x3e31, 0x7cdb, 0xbc55, + 0xec22, 0xffd7, 0xf253, + 0xc71b, 0x8969, 0x4945, + 0x1759, 0x009e, 0x0afb, + 0x33c0, 0x7054, 0xb0fa, + 0xe4e7, 0xfe9b, 0xf76a, + 0xd132, 0x95e1, 0x54e0, + 0x1f14, 0x0276, 0x0676, + 0x2a0a, 0x63f4, 0xa527, + 0xdcb2, 0xfc28, 0xfb5b, + 0xda81, 0xa222, 0x60e5, + 0x27bd, 0x0583, 0x031c, + 0x2128, 0x57d9, 0x98f8, + 0xd39a, 0xf883, 0xfe1c, + 0xe2f0, 0xae10, 0x6d37, + 0x3140, 0x09be, 0x00f6, + 0x1930, 0x4c20, 0x8c8b, + 0xc9b3, 0xf3b4, 0xffa5, + 0xea6c, 0xb98b, 0x79b7, + 0x3b85, 0x0f1d, 0x000a, + 0x1236, 0x40e8, 0x7fff, + 0xbf16, 0xedc8, 0xfff4, + 0xf0e1, 0xc479, 0x8647, + 0x4673, 0x1592, 0x0059, + 0x0c4a, 0x364b, 0x7373, + 0xb3de, 0xe6ce, 0xff08, + 0xf640, 0xcebe, 0x92c7, + 0x51ee, 0x1d0e, 0x01e2, + 0x077b, 0x2c64, 0x6706, + 0xa825, 0xded6, 0xfce2, + 0xfa7b, 0xd841, 0x9f19, + 0x5ddc, 0x257d, 0x04a3, + 0x03d6, 0x234c, 0x5ad7, + 0x9c0a, 0xd5f4, 0xf988, + 0xfd88, 0xe0ea, 0xab1e, + 0x6a1d, 0x2ecc, 0x0894, + 0x0163, 0x1b17, 0x4f04, + 0x8faa, 0xcc3e, 0xf503, + 0xff60, 0xe8a5, 0xb6b9, + 0x7695, 0x38e3, 0x0dab, + 0x0027, 0x13dc, 0x43a9, + 0x8323, 0xc1cd, 0xef5d, + 0xfffe, 0xef5d, 0xc1cd, + 0x8323, 0x43a9, 0x13dc, + 0x0027, 0x0dab, 0x38e3, + 0x7695, 0xb6b9, 0xe8a5, + 0xff60, 0xf503, 0xcc3e, + 0x8faa, 0x4f04, 0x1b17, + 0x0163, 0x0894, 0x2ecc, + 0x6a1d, 0xab1e, 0xe0ea, + 0xfd88, 0xf988, 0xd5f4, + 0x9c0a, 0x5ad7, 0x234c, + 0x03d6, 0x04a3, 0x257d, + 0x5ddc, 0x9f19, 0xd841, + 0xfa7b, 0xfce2, 0xded6, + 0xa825, 0x6706, 0x2c64, + 0x077b, 0x01e2, 0x1d0e, + 0x51ee, 0x92c7, 0xcebe, + 0xf640, 0xff08, 0xe6ce, + 0xb3de, 0x7373, 0x364b, + 0x0c4a, 0x0059, 0x1592, + 0x4673, 0x8647, 0xc479, + 0xf0e1, 0xfff4, 0xedc8, + 0xbf16, 0x7fff, 0x40e8, + 0x1236, 0x000a, 0x0f1d, + 0x3b85, 0x79b7, 0xb98b, + 0xea6c, 0xffa5, 0xf3b4, + 0xc9b3, 0x8c8b, 0x4c20, + 0x1930, 0x00f6, 0x09be, + 0x3140, 0x6d37, 0xae10, + 0xe2f0, 0xfe1c, 0xf883, + 0xd39a, 0x98f8, 0x57d9, + 0x2128, 0x031c, 0x0583, + 0x27bd, 0x60e5, 0xa222, + 0xda81, 0xfb5b, 0xfc28, + 0xdcb2, 0xa527, 0x63f4, + 0x2a0a, 0x0676, 0x0276, + 0x1f14, 0x54e0, 0x95e1, + 0xd132, 0xf76a, 0xfe9b, + 0xe4e7, 0xb0fa, 0x7054, + 0x33c0, 0x0afb, 0x009e, + 0x1759, 0x4945, 0x8969, + 0xc71b, 0xf253, 0xffd7, + 0xec22, 0xbc55, 0x7cdb, + 0x3e31, 0x10a1, 0x0000, + 0x10a1, 0x3e31, 0x7cdb, + 0xbc55, 0xec22, 0xffd7, + 0xf253, 0xc71b, 0x8969, + 0x4945, 0x1759, 0x009e, + 0x0afb, 0x33c0, 0x7054, + 0xb0fa, 0xe4e7, 0xfe9b, + 0xf76a, 0xd132, 0x95e1, + 0x54e0, 0x1f14, 0x0276, + 0x0676, 0x2a0a, 0x63f4, + 0xa527, 0xdcb2, 0xfc28, + 0xfb5b, 0xda81, 0xa222, + 0x60e5, 0x27bd, 0x0583, + 0x031c, 0x2128, 0x57d9, + 0x98f8, 0xd39a, 0xf883, + 0xfe1c, 0xe2f0, 0xae10, + 0x6d37, 0x3140, 0x09be, + 0x00f6, 0x1930, 0x4c20, + 0x8c8b, 0xc9b3, 0xf3b4, + 0xffa5, 0xea6c, 0xb98b, + 0x79b7, 0x3b85, 0x0f1d, + 0x000a, 0x1236, 0x40e8, + 0x7fff, 0xbf16, 0xedc8, + 0xfff4, 0xf0e1, 0xc479, + 0x8647, 0x4673, 0x1592, + 0x0059, 0x0c4a, 0x364b, + 0x7373, 0xb3de, 0xe6ce, + 0xff08, 0xf640, 0xcebe, + 0x92c7, 0x51ee, 0x1d0e, + 0x01e2, 0x077b, 0x2c64, + 0x6706, 0xa825, 0xded6, + 0xfce2, 0xfa7b, 0xd841, + 0x9f19, 0x5ddc, 0x257d, + 0x04a3, 0x03d6, 0x234c, + 0x5ad7, 0x9c0a, 0xd5f4, + 0xf988, 0xfd88, 0xe0ea, + 0xab1e, 0x6a1d, 0x2ecc, + 0x0894, 0x0163, 0x1b17, + 0x4f04, 0x8faa, 0xcc3e, + 0xf503, 0xff60, 0xe8a5, + 0xb6b9, 0x7695, 0x38e3, + 0x0dab, 0x0027, 0x13dc, + 0x43a9, 0x8323, 0xc1cd, + 0xef5d, 0xfffe, 0xef5d, + 0xc1cd, 0x8323, 0x43a9, + 0x13dc, 0x0027, 0x0dab, + 0x38e3, 0x7695, 0xb6b9, + 0xe8a5, 0xff60, 0xf503, + 0xcc3e, 0x8faa, 0x4f04, + 0x1b17, 0x0163, 0x0894, + 0x2ecc, 0x6a1d, 0xab1e, + 0xe0ea, 0xfd88, 0xf988, + 0xd5f4, 0x9c0a, 0x5ad7, + 0x234c, 0x03d6, 0x04a3, + 0x257d, 0x5ddc, 0x9f19, + 0xd841, 0xfa7b, 0xfce2, + 0xded6, 0xa825, 0x6706, + 0x2c64, 0x077b, 0x01e2, + 0x1d0e, 0x51ee, 0x92c7, + 0xcebe, 0xf640, 0xff08, + 0xe6ce, 0xb3de, 0x7373, + 0x364b, 0x0c4a, 0x0059, + 0x1592, 0x4673, 0x8647, + 0xc479, 0xf0e1, 0xfff4, + 0xedc8, 0xbf16, 0x7fff, + 0x40e8, 0x1236, 0x000a, + 0x0f1d, 0x3b85, 0x79b7, + 0xb98b, 0xea6c, 0xffa5, + 0xf3b4, 0xc9b3, 0x8c8b, + 0x4c20, 0x1930, 0x00f6, + 0x09be, 0x3140, 0x6d37, + 0xae10, 0xe2f0, 0xfe1c, + 0xf883, 0xd39a, 0x98f8, + 0x57d9, 0x2128, 0x031c, + 0x0583, 0x27bd, 0x60e5, + 0xa222, 0xda81, 0xfb5b, + 0xfc28, 0xdcb2, 0xa527, + 0x63f4, 0x2a0a, 0x0676, + 0x0276, 0x1f14, 0x54e0, + 0x95e1, 0xd132, 0xf76a, + 0xfe9b, 0xe4e7, 0xb0fa, + 0x7054, 0x33c0, 0x0afb, + 0x009e, 0x1759, 0x4945, + 0x8969, 0xc71b, 0xf253, + 0xffd7, 0xec22, 0xbc55, + 0x7cdb, 0x3e31, 0x10a1 +}; +#endif diff --git a/drivers/staging/iio/industrialio-event.c b/drivers/staging/iio/industrialio-event.c new file mode 100644 index 0000000000000..5fdf739e38f9d --- /dev/null +++ b/drivers/staging/iio/industrialio-event.c @@ -0,0 +1,453 @@ +/* Industrial I/O event handling + * + * Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * Based on elements of hwmon and input subsystems. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "iio.h" +#include "iio_core.h" +#include "sysfs.h" +#include "events.h" + +/** + * struct iio_event_interface - chrdev interface for an event line + * @wait: wait queue to allow blocking reads of events + * @det_events: list of detected events + * @dev_attr_list: list of event interface sysfs attribute + * @flags: file operations related flags including busy flag. + * @group: event interface sysfs attribute group + */ +struct iio_event_interface { + wait_queue_head_t wait; + DECLARE_KFIFO(det_events, struct iio_event_data, 16); + + struct list_head dev_attr_list; + unsigned long flags; + struct attribute_group group; +}; + +int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp) +{ + struct iio_event_interface *ev_int = indio_dev->event_interface; + struct iio_event_data ev; + int copied; + + /* Does anyone care? */ + spin_lock(&ev_int->wait.lock); + if (test_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { + + ev.id = ev_code; + ev.timestamp = timestamp; + + copied = kfifo_put(&ev_int->det_events, &ev); + if (copied != 0) + wake_up_locked_poll(&ev_int->wait, POLLIN); + } + spin_unlock(&ev_int->wait.lock); + + return 0; +} +EXPORT_SYMBOL(iio_push_event); + +/** + * iio_event_poll() - poll the event queue to find out if it has data + */ +static unsigned int iio_event_poll(struct file *filep, + struct poll_table_struct *wait) +{ + struct iio_event_interface *ev_int = filep->private_data; + unsigned int events = 0; + + poll_wait(filep, &ev_int->wait, wait); + + spin_lock(&ev_int->wait.lock); + if (!kfifo_is_empty(&ev_int->det_events)) + events = POLLIN | POLLRDNORM; + spin_unlock(&ev_int->wait.lock); + + return events; +} + +static ssize_t iio_event_chrdev_read(struct file *filep, + char __user *buf, + size_t count, + loff_t *f_ps) +{ + struct iio_event_interface *ev_int = filep->private_data; + unsigned int copied; + int ret; + + if (count < sizeof(struct iio_event_data)) + return -EINVAL; + + spin_lock(&ev_int->wait.lock); + if (kfifo_is_empty(&ev_int->det_events)) { + if (filep->f_flags & O_NONBLOCK) { + ret = -EAGAIN; + goto error_unlock; + } + /* Blocking on device; waiting for something to be there */ + ret = wait_event_interruptible_locked(ev_int->wait, + !kfifo_is_empty(&ev_int->det_events)); + if (ret) + goto error_unlock; + /* Single access device so no one else can get the data */ + } + + ret = kfifo_to_user(&ev_int->det_events, buf, count, &copied); + +error_unlock: + spin_unlock(&ev_int->wait.lock); + + return ret ? ret : copied; +} + +static int iio_event_chrdev_release(struct inode *inode, struct file *filep) +{ + struct iio_event_interface *ev_int = filep->private_data; + + spin_lock(&ev_int->wait.lock); + __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); + /* + * In order to maintain a clean state for reopening, + * clear out any awaiting events. The mask will prevent + * any new __iio_push_event calls running. + */ + kfifo_reset_out(&ev_int->det_events); + spin_unlock(&ev_int->wait.lock); + + return 0; +} + +static const struct file_operations iio_event_chrdev_fileops = { + .read = iio_event_chrdev_read, + .poll = iio_event_poll, + .release = iio_event_chrdev_release, + .owner = THIS_MODULE, + .llseek = noop_llseek, +}; + +int iio_event_getfd(struct iio_dev *indio_dev) +{ + struct iio_event_interface *ev_int = indio_dev->event_interface; + int fd; + + if (ev_int == NULL) + return -ENODEV; + + spin_lock(&ev_int->wait.lock); + if (__test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { + spin_unlock(&ev_int->wait.lock); + return -EBUSY; + } + spin_unlock(&ev_int->wait.lock); + fd = anon_inode_getfd("iio:event", + &iio_event_chrdev_fileops, ev_int, O_RDONLY); + if (fd < 0) { + spin_lock(&ev_int->wait.lock); + __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); + spin_unlock(&ev_int->wait.lock); + } + return fd; +} + +static const char * const iio_ev_type_text[] = { + [IIO_EV_TYPE_THRESH] = "thresh", + [IIO_EV_TYPE_MAG] = "mag", + [IIO_EV_TYPE_ROC] = "roc", + [IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive", + [IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive", +}; + +static const char * const iio_ev_dir_text[] = { + [IIO_EV_DIR_EITHER] = "either", + [IIO_EV_DIR_RISING] = "rising", + [IIO_EV_DIR_FALLING] = "falling" +}; + +static ssize_t iio_ev_state_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + bool val; + + ret = strtobool(buf, &val); + if (ret < 0) + return ret; + + ret = indio_dev->info->write_event_config(indio_dev, + this_attr->address, + val); + return (ret < 0) ? ret : len; +} + +static ssize_t iio_ev_state_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int val = indio_dev->info->read_event_config(indio_dev, + this_attr->address); + + if (val < 0) + return val; + else + return sprintf(buf, "%d\n", val); +} + +static ssize_t iio_ev_value_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int val, ret; + + ret = indio_dev->info->read_event_value(indio_dev, + this_attr->address, &val); + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", val); +} + +static ssize_t iio_ev_value_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + unsigned long val; + int ret; + + if (!indio_dev->info->write_event_value) + return -EINVAL; + + ret = strict_strtoul(buf, 10, &val); + if (ret) + return ret; + + ret = indio_dev->info->write_event_value(indio_dev, this_attr->address, + val); + if (ret < 0) + return ret; + + return len; +} + +static int iio_device_add_event_sysfs(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan) +{ + int ret = 0, i, attrcount = 0; + u64 mask = 0; + char *postfix; + if (!chan->event_mask) + return 0; + + for_each_set_bit(i, &chan->event_mask, sizeof(chan->event_mask)*8) { + postfix = kasprintf(GFP_KERNEL, "%s_%s_en", + iio_ev_type_text[i/IIO_EV_DIR_MAX], + iio_ev_dir_text[i%IIO_EV_DIR_MAX]); + if (postfix == NULL) { + ret = -ENOMEM; + goto error_ret; + } + if (chan->modified) + mask = IIO_MOD_EVENT_CODE(chan->type, 0, chan->channel, + i/IIO_EV_DIR_MAX, + i%IIO_EV_DIR_MAX); + else if (chan->differential) + mask = IIO_EVENT_CODE(chan->type, + 0, 0, + i%IIO_EV_DIR_MAX, + i/IIO_EV_DIR_MAX, + 0, + chan->channel, + chan->channel2); + else + mask = IIO_UNMOD_EVENT_CODE(chan->type, + chan->channel, + i/IIO_EV_DIR_MAX, + i%IIO_EV_DIR_MAX); + + ret = __iio_add_chan_devattr(postfix, + chan, + &iio_ev_state_show, + iio_ev_state_store, + mask, + 0, + &indio_dev->dev, + &indio_dev->event_interface-> + dev_attr_list); + kfree(postfix); + if (ret) + goto error_ret; + attrcount++; + postfix = kasprintf(GFP_KERNEL, "%s_%s_value", + iio_ev_type_text[i/IIO_EV_DIR_MAX], + iio_ev_dir_text[i%IIO_EV_DIR_MAX]); + if (postfix == NULL) { + ret = -ENOMEM; + goto error_ret; + } + ret = __iio_add_chan_devattr(postfix, chan, + iio_ev_value_show, + iio_ev_value_store, + mask, + 0, + &indio_dev->dev, + &indio_dev->event_interface-> + dev_attr_list); + kfree(postfix); + if (ret) + goto error_ret; + attrcount++; + } + ret = attrcount; +error_ret: + return ret; +} + +static inline void __iio_remove_event_config_attrs(struct iio_dev *indio_dev) +{ + struct iio_dev_attr *p, *n; + list_for_each_entry_safe(p, n, + &indio_dev->event_interface-> + dev_attr_list, l) { + kfree(p->dev_attr.attr.name); + kfree(p); + } +} + +static inline int __iio_add_event_config_attrs(struct iio_dev *indio_dev) +{ + int j, ret, attrcount = 0; + + INIT_LIST_HEAD(&indio_dev->event_interface->dev_attr_list); + /* Dynically created from the channels array */ + for (j = 0; j < indio_dev->num_channels; j++) { + ret = iio_device_add_event_sysfs(indio_dev, + &indio_dev->channels[j]); + if (ret < 0) + goto error_clear_attrs; + attrcount += ret; + } + return attrcount; + +error_clear_attrs: + __iio_remove_event_config_attrs(indio_dev); + + return ret; +} + +static bool iio_check_for_dynamic_events(struct iio_dev *indio_dev) +{ + int j; + + for (j = 0; j < indio_dev->num_channels; j++) + if (indio_dev->channels[j].event_mask != 0) + return true; + return false; +} + +static void iio_setup_ev_int(struct iio_event_interface *ev_int) +{ + INIT_KFIFO(ev_int->det_events); + init_waitqueue_head(&ev_int->wait); +} + +static const char *iio_event_group_name = "events"; +int iio_device_register_eventset(struct iio_dev *indio_dev) +{ + struct iio_dev_attr *p; + int ret = 0, attrcount_orig = 0, attrcount, attrn; + struct attribute **attr; + + if (!(indio_dev->info->event_attrs || + iio_check_for_dynamic_events(indio_dev))) + return 0; + + indio_dev->event_interface = + kzalloc(sizeof(struct iio_event_interface), GFP_KERNEL); + if (indio_dev->event_interface == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + iio_setup_ev_int(indio_dev->event_interface); + if (indio_dev->info->event_attrs != NULL) { + attr = indio_dev->info->event_attrs->attrs; + while (*attr++ != NULL) + attrcount_orig++; + } + attrcount = attrcount_orig; + if (indio_dev->channels) { + ret = __iio_add_event_config_attrs(indio_dev); + if (ret < 0) + goto error_free_setup_event_lines; + attrcount += ret; + } + + indio_dev->event_interface->group.name = iio_event_group_name; + indio_dev->event_interface->group.attrs = kcalloc(attrcount + 1, + sizeof(indio_dev->event_interface->group.attrs[0]), + GFP_KERNEL); + if (indio_dev->event_interface->group.attrs == NULL) { + ret = -ENOMEM; + goto error_free_setup_event_lines; + } + if (indio_dev->info->event_attrs) + memcpy(indio_dev->event_interface->group.attrs, + indio_dev->info->event_attrs->attrs, + sizeof(indio_dev->event_interface->group.attrs[0]) + *attrcount_orig); + attrn = attrcount_orig; + /* Add all elements from the list. */ + list_for_each_entry(p, + &indio_dev->event_interface->dev_attr_list, + l) + indio_dev->event_interface->group.attrs[attrn++] = + &p->dev_attr.attr; + indio_dev->groups[indio_dev->groupcounter++] = + &indio_dev->event_interface->group; + + return 0; + +error_free_setup_event_lines: + __iio_remove_event_config_attrs(indio_dev); + kfree(indio_dev->event_interface); +error_ret: + + return ret; +} + +void iio_device_unregister_eventset(struct iio_dev *indio_dev) +{ + if (indio_dev->event_interface == NULL) + return; + __iio_remove_event_config_attrs(indio_dev); + kfree(indio_dev->event_interface->group.attrs); + kfree(indio_dev->event_interface); +} diff --git a/drivers/staging/iio/inkern.c b/drivers/staging/iio/inkern.c new file mode 100644 index 0000000000000..de2c8ea649653 --- /dev/null +++ b/drivers/staging/iio/inkern.c @@ -0,0 +1,292 @@ +/* The industrial I/O core in kernel channel mapping + * + * Copyright (c) 2011 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ +#include +#include +#include +#include + +#include "iio.h" +#include "iio_core.h" +#include "machine.h" +#include "driver.h" +#include "consumer.h" + +struct iio_map_internal { + struct iio_dev *indio_dev; + struct iio_map *map; + struct list_head l; +}; + +static LIST_HEAD(iio_map_list); +static DEFINE_MUTEX(iio_map_list_lock); + +int iio_map_array_register(struct iio_dev *indio_dev, struct iio_map *maps) +{ + int i = 0, ret = 0; + struct iio_map_internal *mapi; + + if (maps == NULL) + return 0; + + mutex_lock(&iio_map_list_lock); + while (maps[i].consumer_dev_name != NULL) { + mapi = kzalloc(sizeof(*mapi), GFP_KERNEL); + if (mapi == NULL) { + ret = -ENOMEM; + goto error_ret; + } + mapi->map = &maps[i]; + mapi->indio_dev = indio_dev; + list_add(&mapi->l, &iio_map_list); + i++; + } +error_ret: + mutex_unlock(&iio_map_list_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(iio_map_array_register); + + +/* Assumes the exact same array (e.g. memory locations) + * used at unregistration as used at registration rather than + * more complex checking of contents. + */ +int iio_map_array_unregister(struct iio_dev *indio_dev, + struct iio_map *maps) +{ + int i = 0, ret = 0; + bool found_it; + struct iio_map_internal *mapi; + + if (maps == NULL) + return 0; + + mutex_lock(&iio_map_list_lock); + while (maps[i].consumer_dev_name != NULL) { + found_it = false; + list_for_each_entry(mapi, &iio_map_list, l) + if (&maps[i] == mapi->map) { + list_del(&mapi->l); + kfree(mapi); + found_it = true; + break; + } + if (found_it == false) { + ret = -ENODEV; + goto error_ret; + } + } +error_ret: + mutex_unlock(&iio_map_list_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(iio_map_array_unregister); + +static const struct iio_chan_spec +*iio_chan_spec_from_name(const struct iio_dev *indio_dev, + const char *name) +{ + int i; + const struct iio_chan_spec *chan = NULL; + + for (i = 0; i < indio_dev->num_channels; i++) + if (indio_dev->channels[i].datasheet_name && + strcmp(name, indio_dev->channels[i].datasheet_name) == 0) { + chan = &indio_dev->channels[i]; + break; + } + return chan; +} + + +struct iio_channel *iio_st_channel_get(const char *name, + const char *channel_name) +{ + struct iio_map_internal *c_i = NULL, *c = NULL; + struct iio_channel *channel; + + if (name == NULL && channel_name == NULL) + return ERR_PTR(-ENODEV); + + /* first find matching entry the channel map */ + mutex_lock(&iio_map_list_lock); + list_for_each_entry(c_i, &iio_map_list, l) { + if ((name && strcmp(name, c_i->map->consumer_dev_name) != 0) || + (channel_name && + strcmp(channel_name, c_i->map->consumer_channel) != 0)) + continue; + c = c_i; + get_device(&c->indio_dev->dev); + break; + } + mutex_unlock(&iio_map_list_lock); + if (c == NULL) + return ERR_PTR(-ENODEV); + + channel = kmalloc(sizeof(*channel), GFP_KERNEL); + if (channel == NULL) + return ERR_PTR(-ENOMEM); + + channel->indio_dev = c->indio_dev; + + if (c->map->adc_channel_label) + channel->channel = + iio_chan_spec_from_name(channel->indio_dev, + c->map->adc_channel_label); + + return channel; +} +EXPORT_SYMBOL_GPL(iio_st_channel_get); + +void iio_st_channel_release(struct iio_channel *channel) +{ + put_device(&channel->indio_dev->dev); + kfree(channel); +} +EXPORT_SYMBOL_GPL(iio_st_channel_release); + +struct iio_channel *iio_st_channel_get_all(const char *name) +{ + struct iio_channel *chans; + struct iio_map_internal *c = NULL; + int nummaps = 0; + int mapind = 0; + int i, ret; + + if (name == NULL) + return ERR_PTR(-EINVAL); + + mutex_lock(&iio_map_list_lock); + /* first count the matching maps */ + list_for_each_entry(c, &iio_map_list, l) + if (name && strcmp(name, c->map->consumer_dev_name) != 0) + continue; + else + nummaps++; + + if (nummaps == 0) { + ret = -ENODEV; + goto error_ret; + } + + /* NULL terminated array to save passing size */ + chans = kzalloc(sizeof(*chans)*(nummaps + 1), GFP_KERNEL); + if (chans == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + /* for each map fill in the chans element */ + list_for_each_entry(c, &iio_map_list, l) { + if (name && strcmp(name, c->map->consumer_dev_name) != 0) + continue; + chans[mapind].indio_dev = c->indio_dev; + chans[mapind].channel = + iio_chan_spec_from_name(chans[mapind].indio_dev, + c->map->adc_channel_label); + if (chans[mapind].channel == NULL) { + ret = -EINVAL; + put_device(&chans[mapind].indio_dev->dev); + goto error_free_chans; + } + get_device(&chans[mapind].indio_dev->dev); + mapind++; + } + mutex_unlock(&iio_map_list_lock); + if (mapind == 0) { + ret = -ENODEV; + goto error_free_chans; + } + return chans; + +error_free_chans: + for (i = 0; i < nummaps; i++) + if (chans[i].indio_dev) + put_device(&chans[i].indio_dev->dev); + kfree(chans); +error_ret: + mutex_unlock(&iio_map_list_lock); + + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(iio_st_channel_get_all); + +void iio_st_channel_release_all(struct iio_channel *channels) +{ + struct iio_channel *chan = &channels[0]; + + while (chan->indio_dev) { + put_device(&chan->indio_dev->dev); + chan++; + } + kfree(channels); +} +EXPORT_SYMBOL_GPL(iio_st_channel_release_all); + +int iio_st_read_channel_raw(struct iio_channel *chan, int *val) +{ + int val2, ret; + + mutex_lock(&chan->indio_dev->info_exist_lock); + if (chan->indio_dev->info == NULL) { + ret = -ENODEV; + goto err_unlock; + } + + ret = chan->indio_dev->info->read_raw(chan->indio_dev, chan->channel, + val, &val2, 0); +err_unlock: + mutex_unlock(&chan->indio_dev->info_exist_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(iio_st_read_channel_raw); + +int iio_st_read_channel_scale(struct iio_channel *chan, int *val, int *val2) +{ + int ret; + + mutex_lock(&chan->indio_dev->info_exist_lock); + if (chan->indio_dev->info == NULL) { + ret = -ENODEV; + goto err_unlock; + } + + ret = chan->indio_dev->info->read_raw(chan->indio_dev, + chan->channel, + val, val2, + IIO_CHAN_INFO_SCALE); +err_unlock: + mutex_unlock(&chan->indio_dev->info_exist_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(iio_st_read_channel_scale); + +int iio_st_get_channel_type(struct iio_channel *chan, + enum iio_chan_type *type) +{ + int ret = 0; + /* Need to verify underlying driver has not gone away */ + + mutex_lock(&chan->indio_dev->info_exist_lock); + if (chan->indio_dev->info == NULL) { + ret = -ENODEV; + goto err_unlock; + } + + *type = chan->channel->type; +err_unlock: + mutex_unlock(&chan->indio_dev->info_exist_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(iio_st_get_channel_type); diff --git a/drivers/staging/iio/machine.h b/drivers/staging/iio/machine.h new file mode 100644 index 0000000000000..0b1f19bfdc44c --- /dev/null +++ b/drivers/staging/iio/machine.h @@ -0,0 +1,24 @@ +/* + * Industrial I/O in kernel access map definitions for board files. + * + * Copyright (c) 2011 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +/** + * struct iio_map - description of link between consumer and device channels + * @adc_channel_label: Label used to identify the channel on the provider. + * This is matched against the datasheet_name element + * of struct iio_chan_spec. + * @consumer_dev_name: Name to uniquely identify the consumer device. + * @consumer_channel: Unique name used to idenitify the channel on the + * consumer side. + */ +struct iio_map { + const char *adc_channel_label; + const char *consumer_dev_name; + const char *consumer_channel; +}; diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index e97aa8dc5f789..f21cd78107eb2 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -1083,8 +1083,10 @@ static struct uart_port *xuartps_get_port(int id) **/ static void xuartps_console_wait_tx(struct uart_port *port) { + unsigned int timeout = 10000; + while ((xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_TXEMPTY) - != XUARTPS_SR_TXEMPTY) + != XUARTPS_SR_TXEMPTY && --timeout) barrier(); } diff --git a/drivers/usb/host/ehci-xilinx-usbps.c b/drivers/usb/host/ehci-xilinx-usbps.c index b5a00904bd8ae..51343060560a4 100644 --- a/drivers/usb/host/ehci-xilinx-usbps.c +++ b/drivers/usb/host/ehci-xilinx-usbps.c @@ -344,12 +344,12 @@ static int ehci_xusbps_setup(struct usb_hcd *hcd) hcd->has_tt = 1; - retval = ehci_halt(ehci); + /* data structure init */ + retval = ehci_init(hcd); if (retval) return retval; - /* data structure init */ - retval = ehci_init(hcd); + retval = ehci_halt(ehci); if (retval) return retval; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 0a19e479d3c5d..6b6cbbc544f4d 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -180,7 +180,7 @@ struct ehci_hcd { /* one per controller */ */ void (*start_hnp)(struct ehci_hcd *ehci); #ifdef CONFIG_XILINX_ZED_USB_OTG - struct otg_transceiver *ulpi; + struct usb_phy *ulpi; #endif #endif diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 0cac551c5347d..a3aa7a511fe02 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -254,4 +254,10 @@ struct drm_connector *drm_select_eld(struct drm_encoder *encoder, struct drm_display_mode *mode); int drm_load_edid_firmware(struct drm_connector *connector); +struct edid *drm_do_get_edid(struct drm_connector *connector, + int (*get_edid_block)(void *, unsigned char *buf, int, int), void *data); + +struct edid *drm_do_get_edid(struct drm_connector *connector, + int (*get_edid_block)(void *, unsigned char *buf, int, int), void *data); + #endif /* __DRM_EDID_H__ */ diff --git a/include/drm/drm_fb_cma_helper.h b/include/drm/drm_fb_cma_helper.h new file mode 100644 index 0000000000000..76c709837543f --- /dev/null +++ b/include/drm/drm_fb_cma_helper.h @@ -0,0 +1,27 @@ +#ifndef __DRM_FB_CMA_HELPER_H__ +#define __DRM_FB_CMA_HELPER_H__ + +struct drm_fbdev_cma; +struct drm_gem_cma_object; + +struct drm_framebuffer; +struct drm_device; +struct drm_file; +struct drm_mode_fb_cmd2; + +struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev, + unsigned int preferred_bpp, unsigned int num_crtc, + unsigned int max_conn_count); +void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma); + +void drm_fbdev_cma_restore_mode(struct drm_fbdev_cma *fbdev_cma); +void drm_fbdev_cma_hotplug_event(struct drm_fbdev_cma *fbdev_cma); + +struct drm_framebuffer *drm_fb_cma_create(struct drm_device *dev, + struct drm_file *file_priv, struct drm_mode_fb_cmd2 *mode_cmd); + +struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb, + unsigned int plane); + +#endif + diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h new file mode 100644 index 0000000000000..f0f6b1af25adf --- /dev/null +++ b/include/drm/drm_gem_cma_helper.h @@ -0,0 +1,44 @@ +#ifndef __DRM_GEM_CMA_HELPER_H__ +#define __DRM_GEM_CMA_HELPER_H__ + +struct drm_gem_cma_object { + struct drm_gem_object base; + dma_addr_t paddr; + void *vaddr; +}; + +static inline struct drm_gem_cma_object * +to_drm_gem_cma_obj(struct drm_gem_object *gem_obj) +{ + return container_of(gem_obj, struct drm_gem_cma_object, base); +} + +/* free gem object. */ +void drm_gem_cma_free_object(struct drm_gem_object *gem_obj); + +/* create memory region for drm framebuffer. */ +int drm_gem_cma_dumb_create(struct drm_file *file_priv, + struct drm_device *drm, struct drm_mode_create_dumb *args); + +/* map memory region for drm framebuffer to user space. */ +int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv, + struct drm_device *drm, uint32_t handle, uint64_t *offset); + +/* set vm_flags and we can change the vm attribute to other one at here. */ +int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma); + +/* + * destroy memory region allocated. + * - a gem handle and physical memory region pointed by a gem object + * would be released by drm_gem_handle_delete(). + */ +int drm_gem_cma_dumb_destroy(struct drm_file *file_priv, + struct drm_device *drm, unsigned int handle); + +/* allocate physical memory. */ +struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, + unsigned int size); + +extern const struct vm_operations_struct drm_gem_cma_vm_ops; + +#endif /* __DRM_GEM_CMA_HELPER_H__ */ diff --git a/include/linux/amba/xilinx_dma.h b/include/linux/amba/xilinx_dma.h index dca98af4b77c6..751a74339821a 100644 --- a/include/linux/amba/xilinx_dma.h +++ b/include/linux/amba/xilinx_dma.h @@ -1,11 +1,12 @@ /* - * Xilinx DMA Engines support header file + * Xilinx Central DMA Engine support * * Copyright (C) 2010 Xilinx, Inc. All rights reserved. * * Based on the Freescale DMA driver. * * Description: + * This driver supports three Xilinx DMA engines: * . Axi CDMA engine, it does transfers between memory and memory, it * only has one channel. * . Axi DMA engine, it does transfers between memory and device. It can be @@ -30,57 +31,63 @@ #include #include -/* Specific hardware configuration-related constants */ -#define XILINX_DMA_NO_CHANGE 0xFFFF; +/* Specific hardware configuration-related constants + */ +#define XILINX_DMA_NO_CHANGE 0xFFFF; -/* DMA IP masks */ -#define XILINX_DMA_IP_DMA 0x00100000 /* A DMA IP */ -#define XILINX_DMA_IP_CDMA 0x00200000 /* A Central DMA IP */ -#define XILINX_DMA_IP_VDMA 0x00400000 /* A Video DMA IP */ -#define XILINX_DMA_IP_MASK 0x00700000 /* DMA IP MASK */ +/* DMA IP masks + */ +#define XILINX_DMA_IP_DMA 0x00100000 /* A DMA IP */ +#define XILINX_DMA_IP_CDMA 0x00200000 /* A Central DMA IP */ +#define XILINX_DMA_IP_VDMA 0x00400000 /* A Video DMA IP */ +#define XILINX_DMA_IP_MASK 0x00700000 /* DMA IP MASK */ -/* - * Device configuration structure +/* shared by all Xilinx DMA engines + */ +/* Device configuration structure + * + * Xilinx CDMA and Xilinx DMA only use interrupt coalescing and delay counter + * settings. * * If used to start/stop parking mode for Xilinx VDMA, vsize must be -1 * If used to set interrupt coalescing and delay counter only for - * Xilinx VDMA, hsize must be -1 - */ -struct xilinx_vdma_config { - enum dma_transfer_direction direction; - /* Channel direction */ - int vsize; /* Vertical size */ - int hsize; /* Horizontal size */ - int stride; /* Stride */ - int frm_dly; /* Frame delay */ - int gen_lock; /* Whether in gen-lock mode */ - int master; /* Master that it syncs to */ - int frm_cnt_en; /* Enable frame count enable */ - int park; /* Whether wants to park */ - int park_frm; /* Frame to park on */ - int coalesc; /* Interrupt coalescing threshold */ - int delay; /* Delay counter */ - int disable_intr; /* Whether use interrupts */ - int reset; /* Reset Channel */ - int ext_fsync; /* External Frame Sync */ + * Xilinx VDMA, hsize must be -1 */ +struct xilinx_dma_config { + enum dma_transfer_direction direction; /* Channel direction */ + int vsize; /* Vertical size */ + int hsize; /* Horizontal size */ + int stride; /* Stride */ + int frm_dly; /* Frame delay */ + int gen_lock; /* Whether in gen-lock mode */ + int master; /* Master that it syncs to */ + int frm_cnt_en; /* Enable frame count enable */ + int park; /* Whether wants to park */ + int park_frm; /* Frame to park on */ + int coalesc; /* Interrupt coalescing threshold */ + int delay; /* Delay counter */ + int disable_intr; /* Whether use interrupts */ + int reset; /* Reset Channel */ + int ext_fsync; /* External Frame Sync */ }; -/* Device configuration structure for DMA */ -struct xilinx_dma_config { - enum dma_transfer_direction direction; - /* Channel direction */ - int coalesc; /* Interrupt coalescing threshold */ - int delay; /* Delay counter */ - int reset; /* Reset Channel */ +/* Platform data definition until ARM supports device tree */ + +struct dma_channel_config { + char *type; + unsigned int lite_mode; /* cdma only */ + unsigned int include_dre; + unsigned int genlock_mode; /* vdma only */ + unsigned int datawidth; + unsigned int max_burst_len; }; -/* Device configuration structure for CDMA */ -struct xilinx_cdma_config { - enum dma_transfer_direction direction; - /* Channel direction */ - int coalesc; /* Interrupt coalescing threshold */ - int delay; /* Delay counter */ - int reset; /* Reset Channel */ +struct dma_device_config { + char *type; + unsigned int include_sg; + unsigned int num_fstores; /* vdma only */ + unsigned int sg_include_stscntrl_strm; /* dma only */ + unsigned int channel_count; + struct dma_channel_config *channel_config; }; #endif diff --git a/include/linux/device.h b/include/linux/device.h index 52a5f15a2223e..b213fe5ff93ec 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -588,6 +588,10 @@ struct device_dma_parameters { * @mutex: Mutex to synchronize calls to its driver. * @bus: Type of bus device is on. * @driver: Which driver has allocated this + * @deferred_probe: entry in deferred_probe_list which is used to retry the + * binding of drivers which were unable to get all the resources + * needed by the device; typically because it depends on another + * driver getting probed first. * @platform_data: Platform data specific to the device. * Example: For devices on custom boards, as typical of embedded * and SOC based hardware, Linux often uses platform_data to point @@ -647,6 +651,7 @@ struct device { struct bus_type *bus; /* type of bus device is on */ struct device_driver *driver; /* which driver has allocated this device */ + struct list_head deferred_probe; void *platform_data; /* Platform specific data, device core doesn't touch it */ struct dev_pm_info power; diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h index 8ba516fc2ec6c..d85dc9157cd94 100644 --- a/include/linux/iio/buffer.h +++ b/include/linux/iio/buffer.h @@ -40,6 +40,8 @@ struct iio_buffer_access_funcs { int (*read_first_n)(struct iio_buffer *buffer, size_t n, char __user *buf); + int (*remove_from)(struct iio_buffer *buffer, u8 *data); + int (*write)(struct iio_buffer *buffer, size_t n, const char __user *buf); int (*request_update)(struct iio_buffer *buffer); @@ -49,6 +51,12 @@ struct iio_buffer_access_funcs { int (*set_length)(struct iio_buffer *buffer, int length); }; +enum iio_buffer_direction +{ + IIO_BUFFER_DIRECTION_IN, + IIO_BUFFER_DIRECTION_OUT, +}; + /** * struct iio_buffer - general buffer structure * @length: [DEVICE] number of datums in buffer @@ -81,8 +89,20 @@ struct iio_buffer { const struct attribute_group *attrs; struct list_head demux_list; unsigned char *demux_bounce; + enum iio_buffer_direction direction; }; +static inline int iio_buffer_write(struct iio_buffer *buffer, size_t n, + const char __user *buf) +{ + return buffer->access->write(buffer, n, buf); +} + +static inline int iio_buffer_remove_sample(struct iio_buffer *buffer, u8 *data) +{ + return buffer->access->remove_from(buffer, data); +} + /** * iio_buffer_init() - Initialize the buffer structure * @buffer: buffer to be initialized diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index be82936c4089e..220d04192495d 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -411,7 +411,7 @@ struct iio_buffer_setup_ops { * @flags: [INTERN] file ops related flags including busy flag. * @debugfs_dentry: [INTERN] device specific debugfs dentry. * @cached_reg_addr: [INTERN] cached register address for debugfs reads. - */ +**/ struct iio_dev { int id; diff --git a/include/linux/marvell_phy.h b/include/linux/marvell_phy.h index ec41025cb86e4..8e9a029e093d6 100644 --- a/include/linux/marvell_phy.h +++ b/include/linux/marvell_phy.h @@ -15,6 +15,7 @@ #define MARVELL_PHY_ID_88E1240 0x01410e30 #define MARVELL_PHY_ID_88E1318S 0x01410e90 #define MARVELL_PHY_ID_88E1116R 0x01410e40 +#define MARVELL_PHY_ID_88E1510 0x01410dd0 /* struct phy_device dev_flags definitions */ #define MARVELL_PHY_M1145_FLAGS_RESISTANCE 0x00000001 diff --git a/include/linux/of_i2c.h b/include/linux/of_i2c.h index 1cb775f8e663d..def36bfb5ff33 100644 --- a/include/linux/of_i2c.h +++ b/include/linux/of_i2c.h @@ -19,6 +19,7 @@ extern void of_i2c_register_devices(struct i2c_adapter *adap); /* must call put_device() when done with returned i2c_client device */ extern struct i2c_client *of_find_i2c_device_by_node(struct device_node *node); +extern struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node); /* must call put_device() when done with returned i2c_adapter device */ extern struct i2c_adapter *of_find_i2c_adapter_by_node( diff --git a/include/linux/of_spi.h b/include/linux/of_spi.h new file mode 100644 index 0000000000000..e1bafd279601b --- /dev/null +++ b/include/linux/of_spi.h @@ -0,0 +1,24 @@ +/* + * OpenFirmware SPI support routines + * Copyright (C) 2008 Secret Lab Technologies Ltd. + * + * Support routines for deriving SPI device attachments from the device + * tree. + */ + +#ifndef __LINUX_OF_SPI_H +#define __LINUX_OF_SPI_H + +#include + +#if defined(CONFIG_OF_SPI) || defined(CONFIG_OF_SPI_MODULE) +extern void of_register_spi_devices(struct spi_master *master); +extern struct spi_master *spi_of_node_to_master(struct device_node *of_node); +#else +static inline void of_register_spi_devices(struct spi_master *master) +{ + return; +} +#endif /* CONFIG_OF_SPI */ + +#endif /* __LINUX_OF_SPI */ diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h index f987a2bee16a8..392fe10d171f5 100644 --- a/include/linux/spi/spi_bitbang.h +++ b/include/linux/spi/spi_bitbang.h @@ -28,8 +28,8 @@ struct spi_bitbang { /* txrx_bufs() may handle dma mapping for transfers that don't * already have one (transfer.{tx,rx}_dma is zero), or use PIO */ - int (*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t); - +// int (*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t); + int (*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t, bool is_last); /* txrx_word[SPI_MODE_*]() just looks like a shift register */ u32 (*txrx_word[4])(struct spi_device *spi, unsigned nsecs, diff --git a/include/sound/adau17x1.h b/include/sound/adau17x1.h new file mode 100644 index 0000000000000..513f0c5721aad --- /dev/null +++ b/include/sound/adau17x1.h @@ -0,0 +1,90 @@ +/* + * Driver for ADAU1761/ADAU1461/ADAU1761/ADAU1961/ADAU1781/ADAU1781 codecs + * + * Copyright 2011 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __SOUND_ADAU17X1_H__ +#define __SOUND_ADAU17X1_H__ + +/** + * enum adau17x1_micbias_voltage - Microphone bias voltage + * @ADAU17X1_MICBIAS_0_90_AVDD: 0.9 * AVDD + * @ADAU17X1_MICBIAS_0_65_AVDD: 0.65 * AVDD + */ +enum adau17x1_micbias_voltage { + ADAU17X1_MICBIAS_0_90_AVDD = 0, + ADAU17X1_MICBIAS_0_65_AVDD = 1, +}; + +/** + * enum adau1761_digmic_jackdet_pin_mode - Configuration of the JACKDET/MICIN pin + * @ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE: Disable the pin + * @ADAU1761_DIGMIC_JACKDET_PIN_MODE_DIGMIC: Configure the pin for usage as + * digital microphone input. + * @ADAU1761_DIGMIC_JACKDET_PIN_MODE_JACKDETECT: Configure the pin for jack + * insertion detection. +*/ +enum adau1761_digmic_jackdet_pin_mode { + ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE = 0, + ADAU1761_DIGMIC_JACKDET_PIN_MODE_DIGMIC = 1, + ADAU1761_DIGMIC_JACKDET_PIN_MODE_JACKDETECT = 2, +}; + +/** + * adau1761_jackdetect_debounce_time - Jack insertion detection debounce time + * @ADAU1761_JACKDETECT_DEBOUNCE_5MS: 5 milliseconds + * @ADAU1761_JACKDETECT_DEBOUNCE_10MS: 10 milliseconds + * @ADAU1761_JACKDETECT_DEBOUNCE_20MS: 20 milliseconds + * @ADAU1761_JACKDETECT_DEBOUNCE_40MS: 40 milliseconds + */ +enum adau1761_jackdetect_debounce_time { + ADAU1761_JACKDETECT_DEBOUNCE_5MS = 0, + ADAU1761_JACKDETECT_DEBOUNCE_10MS = 1, + ADAU1761_JACKDETECT_DEBOUNCE_20MS = 2, + ADAU1761_JACKDETECT_DEBOUNCE_40MS = 3, +}; + +/** + * enum adau1761_output_mode - Output mode configuration + * @ADAU1761_OUTPUT_MODE_HEADPHONE: Headphone output + * @ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS: Capless headphone output + * @ADAU1761_OUTPUT_MODE_LINE: Line output + */ +enum adau1761_output_mode { + ADAU1761_OUTPUT_MODE_HEADPHONE = 0, + ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS = 1, + ADAU1761_OUTPUT_MODE_LINE = 2, +}; + +/** + * struct adau1761_platform_data - ADAU1761 Codec driver platform data + * @input_differential: If true the input pins will be configured in + * differential mode. + * @lineout_mode: Output mode for the LOUT/ROUT pins + * @headphone_mode: Output mode for the LHP/RHP pins + * @digmic_jackdetect_pin_mode: JACKDET/MICIN pin configuration + * @jackdetect_debounce_time: Jack insertion detection debounce time. + * Note: This value will only be used, if the JACKDET/MICIN pin is + * configured for jack insertion detection. + * @jackdetect_active_low: If true the jack insertion detection is active + * low. Othwise it will be active high. + * @micbias_voltage: Microphone voltage bias + */ +struct adau1761_platform_data { + bool input_differential; + enum adau1761_output_mode lineout_mode; + enum adau1761_output_mode headphone_mode; + + enum adau1761_digmic_jackdet_pin_mode digmic_jackdetect_pin_mode; + + enum adau1761_jackdetect_debounce_time jackdetect_debounce_time; + bool jackdetect_active_low; + + enum adau17x1_micbias_voltage micbias_voltage; +}; + +#endif diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 1f69e0af29418..18444fb5777bf 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -32,6 +32,7 @@ struct snd_soc_dapm_widget; #define SND_SOC_DAIFMT_DSP_B 5 /* L data MSB during FRM LRC */ #define SND_SOC_DAIFMT_AC97 6 /* AC97 */ #define SND_SOC_DAIFMT_PDM 7 /* Pulse density modulation */ +#define SND_SOC_DAIFMT_SPDIF 8 /* SPDIF */ /* left and right justified also known as MSB and LSB respectively */ #define SND_SOC_DAIFMT_MSB SND_SOC_DAIFMT_LEFT_J diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index c5de0a84566f1..3acc86c3d7e6e 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -49,6 +49,7 @@ source "sound/soc/sh/Kconfig" source "sound/soc/tegra/Kconfig" source "sound/soc/txx9/Kconfig" source "sound/soc/ux500/Kconfig" +source "sound/soc/xlnx/Kconfig" # Supported codecs source "sound/soc/codecs/Kconfig" diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 00a555a743b6a..f4a2bcb9fe2f0 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -27,3 +27,4 @@ obj-$(CONFIG_SND_SOC) += sh/ obj-$(CONFIG_SND_SOC) += tegra/ obj-$(CONFIG_SND_SOC) += txx9/ obj-$(CONFIG_SND_SOC) += ux500/ +obj-$(CONFIG_SND_SOC) += xlnx/ diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 9f8e8594aeb90..407091d98a2c9 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -19,6 +19,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_AD1980 if SND_SOC_AC97_BUS select SND_SOC_AD73311 select SND_SOC_ADAU1373 if I2C + select SND_SOC_ADAU1761 if SND_SOC_I2C_AND_SPI select SND_SOC_ADAV80X select SND_SOC_ADS117X select SND_SOC_AK4104 if SPI_MASTER @@ -170,6 +171,14 @@ config SND_SOC_ADAU1701 config SND_SOC_ADAU1373 tristate +config SND_SOC_ADAU17X1 + select SND_SOC_SIGMADSP + tristate + +config SND_SOC_ADAU1761 + select SND_SOC_ADAU17X1 + tristate + config SND_SOC_ADAV80X tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 34148bb59c68d..dee670f7d94c9 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -7,6 +7,8 @@ snd-soc-ad1980-objs := ad1980.o snd-soc-ad73311-objs := ad73311.o snd-soc-adau1701-objs := adau1701.o snd-soc-adau1373-objs := adau1373.o +snd-soc-adau17x1-objs := adau17x1.o +snd-soc-adau1761-objs := adau1761.o snd-soc-adav80x-objs := adav80x.o snd-soc-ads117x-objs := ads117x.o snd-soc-ak4104-objs := ak4104.o @@ -124,6 +126,8 @@ obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o +obj-$(CONFIG_SND_SOC_ADAU17X1) += snd-soc-adau17x1.o +obj-$(CONFIG_SND_SOC_ADAU1761) += snd-soc-adau1761.o obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o diff --git a/sound/soc/codecs/adau1761.c b/sound/soc/codecs/adau1761.c new file mode 100644 index 0000000000000..2ae441ef589fa --- /dev/null +++ b/sound/soc/codecs/adau1761.c @@ -0,0 +1,926 @@ +/* + * Driver for ADAU1761/ADAU1461/ADAU1761/ADAU1961 codec + * + * Copyright 2011-2012 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "adau17x1.h" + +#define ADAU1761_DIGMIC_JACKDETECT 0x4008 +#define ADAU1761_REC_MIXER_LEFT0 0x400a +#define ADAU1761_REC_MIXER_LEFT1 0x400b +#define ADAU1761_REC_MIXER_RIGHT0 0x400c +#define ADAU1761_REC_MIXER_RIGHT1 0x400d +#define ADAU1761_LEFT_DIFF_INPUT_VOL 0x400e +#define ADAU1761_RIGHT_DIFF_INPUT_VOL 0x400f +#define ADAU1761_PLAY_LR_MIXER_LEFT 0x4020 +#define ADAU1761_PLAY_MIXER_LEFT0 0x401c +#define ADAU1761_PLAY_MIXER_LEFT1 0x401d +#define ADAU1761_PLAY_MIXER_RIGHT0 0x401e +#define ADAU1761_PLAY_MIXER_RIGHT1 0x401f +#define ADAU1761_PLAY_LR_MIXER_RIGHT 0x4021 +#define ADAU1761_PLAY_MIXER_MONO 0x4022 +#define ADAU1761_PLAY_HP_LEFT_VOL 0x4023 +#define ADAU1761_PLAY_HP_RIGHT_VOL 0x4024 +#define ADAU1761_PLAY_LINE_LEFT_VOL 0x4025 +#define ADAU1761_PLAY_LINE_RIGHT_VOL 0x4026 +#define ADAU1761_PLAY_MONO_OUTPUT_VOL 0x4027 +#define ADAU1761_POP_CLICK_SUPPRESS 0x4028 +#define ADAU1761_JACK_DETECT_PIN 0x4031 +#define ADAU1761_DEJITTER 0x4036 +#define ADAU1761_CLK_ENABLE0 0x40f9 +#define ADAU1761_CLK_ENABLE1 0x40fa + +#define ADAU1761_DIGMIC_JACKDETECT_ACTIVE_LOW BIT(0) +#define ADAU1761_DIGMIC_JACKDETECT_DIGMIC BIT(5) + +#define ADAU1761_DIFF_INPUT_VOL_LDEN 0x01 + +#define ADAU1761_FIRMWARE "adau1761.bin" + +static struct reg_default adau1761_reg_defaults[] = { + { ADAU1761_DEJITTER, 0x03 }, + { ADAU1761_DIGMIC_JACKDETECT, 0x00 }, + { ADAU1761_REC_MIXER_LEFT0, 0x00 }, + { ADAU1761_REC_MIXER_LEFT1, 0x00 }, + { ADAU1761_REC_MIXER_RIGHT0, 0x00 }, + { ADAU1761_REC_MIXER_RIGHT1, 0x00 }, + { ADAU1761_LEFT_DIFF_INPUT_VOL, 0x00 }, + { ADAU1761_RIGHT_DIFF_INPUT_VOL, 0x00 }, + { ADAU1761_PLAY_LR_MIXER_LEFT, 0x00 }, + { ADAU1761_PLAY_MIXER_LEFT0, 0x00 }, + { ADAU1761_PLAY_MIXER_LEFT1, 0x00 }, + { ADAU1761_PLAY_MIXER_RIGHT0, 0x00 }, + { ADAU1761_PLAY_MIXER_RIGHT1, 0x00 }, + { ADAU1761_PLAY_LR_MIXER_RIGHT, 0x00 }, + { ADAU1761_PLAY_MIXER_MONO, 0x00 }, + { ADAU1761_PLAY_HP_LEFT_VOL, 0x00 }, + { ADAU1761_PLAY_HP_RIGHT_VOL, 0x00 }, + { ADAU1761_PLAY_LINE_LEFT_VOL, 0x00 }, + { ADAU1761_PLAY_LINE_RIGHT_VOL, 0x00 }, + { ADAU1761_PLAY_MONO_OUTPUT_VOL, 0x00 }, + { ADAU1761_POP_CLICK_SUPPRESS, 0x00 }, + { ADAU1761_JACK_DETECT_PIN, 0x00 }, + { ADAU1761_CLK_ENABLE0, 0x00 }, + { ADAU1761_CLK_ENABLE1, 0x00 }, + { ADAU17X1_CLOCK_CONTROL, 0x00 }, + { ADAU17X1_PLL_CONTROL, 0x00 }, + { ADAU17X1_REC_POWER_MGMT, 0x00 }, + { ADAU17X1_MICBIAS, 0x00 }, + { ADAU17X1_SERIAL_PORT0, 0x00 }, + { ADAU17X1_SERIAL_PORT1, 0x00 }, + { ADAU17X1_CONVERTER0, 0x00 }, + { ADAU17X1_CONVERTER1, 0x00 }, + { ADAU17X1_LEFT_INPUT_DIGITAL_VOL, 0x00 }, + { ADAU17X1_RIGHT_INPUT_DIGITAL_VOL, 0x00 }, + { ADAU17X1_ADC_CONTROL, 0x00 }, + { ADAU17X1_PLAY_POWER_MGMT, 0x00 }, + { ADAU17X1_DAC_CONTROL0, 0x00 }, + { ADAU17X1_DAC_CONTROL1, 0x00 }, + { ADAU17X1_DAC_CONTROL2, 0x00 }, + { ADAU17X1_SERIAL_PORT_PAD, 0x00 }, + { ADAU17X1_CONTROL_PORT_PAD0, 0x00 }, + { ADAU17X1_CONTROL_PORT_PAD1, 0x00 }, + { ADAU17X1_DSP_SAMPLING_RATE, 0x01 }, + { ADAU17X1_SERIAL_INPUT_ROUTE, 0x00 }, + { ADAU17X1_SERIAL_OUTPUT_ROUTE, 0x00 }, + { ADAU17X1_DSP_ENABLE, 0x00 }, + { ADAU17X1_DSP_RUN, 0x00 }, + { ADAU17X1_SERIAL_SAMPLING_RATE, 0x00 }, +}; + +static const DECLARE_TLV_DB_SCALE(adau1761_sing_in_tlv, -1500, 300, 1); +static const DECLARE_TLV_DB_SCALE(adau1761_diff_in_tlv, -1200, 75, 0); +static const DECLARE_TLV_DB_SCALE(adau1761_out_tlv, -5700, 100, 0); +static const DECLARE_TLV_DB_SCALE(adau1761_sidetone_tlv, -1800, 300, 1); +static const DECLARE_TLV_DB_SCALE(adau1761_boost_tlv, -600, 600, 1); +static const DECLARE_TLV_DB_SCALE(adau1761_pga_boost_tlv, -2000, 2000, 1); + +static const unsigned int adau1761_bias_select_values[] = { + 0, 2, 3, +}; + +static const char * const adau1761_bias_select_text[] = { + "Normal operation", "Enhanced performance", "Power saving", +}; + +static const char * const adau1761_bias_select_extreme_text[] = { + "Normal operation", "Extreme power saving", "Enhanced performance", + "Power saving", +}; + +static const SOC_ENUM_SINGLE_DECL(adau1761_adc_bias_enum, + ADAU17X1_REC_POWER_MGMT, 3, adau1761_bias_select_extreme_text); +static const SOC_ENUM_SINGLE_DECL(adau1761_hp_bias_enum, + ADAU17X1_PLAY_POWER_MGMT, 6, adau1761_bias_select_extreme_text); +static const SOC_ENUM_SINGLE_DECL(adau1761_dac_bias_enum, + ADAU17X1_PLAY_POWER_MGMT, 4, adau1761_bias_select_extreme_text); +static const SOC_VALUE_ENUM_SINGLE_DECL(adau1761_playback_bias_enum, + ADAU17X1_PLAY_POWER_MGMT, 2, 0x3, adau1761_bias_select_text, + adau1761_bias_select_values); +static const SOC_VALUE_ENUM_SINGLE_DECL(adau1761_capture_bias_enum, + ADAU17X1_REC_POWER_MGMT, 1, 0x3, adau1761_bias_select_text, + adau1761_bias_select_values); + +static const struct snd_kcontrol_new adau1761_jack_detect_controls[] = { + SOC_SINGLE("Jack Detect Switch", 4, 1, 0, ADAU1761_DIGMIC_JACKDETECT), +}; + +static const struct snd_kcontrol_new adau1761_differential_mode_controls[] = { + SOC_DOUBLE_R_TLV("Capture Volume", ADAU1761_LEFT_DIFF_INPUT_VOL, + ADAU1761_RIGHT_DIFF_INPUT_VOL, 2, 0x3f, 0, adau1761_diff_in_tlv), + SOC_DOUBLE_R("Capture Switch", ADAU1761_LEFT_DIFF_INPUT_VOL, + ADAU1761_RIGHT_DIFF_INPUT_VOL, 1, 1, 0), + + SOC_DOUBLE_R_TLV("PGA Boost Capture Volume", ADAU1761_REC_MIXER_LEFT1, + ADAU1761_REC_MIXER_RIGHT1, 3, 2, 0, adau1761_pga_boost_tlv), +}; + +static const struct snd_kcontrol_new adau1761_single_mode_controls[] = { + SOC_SINGLE_TLV("Input 1 Capture Volume", ADAU1761_REC_MIXER_LEFT0, + 4, 7, 0, adau1761_sing_in_tlv), + SOC_SINGLE_TLV("Input 2 Capture Volume", ADAU1761_REC_MIXER_LEFT0, + 1, 7, 0, adau1761_sing_in_tlv), + SOC_SINGLE_TLV("Input 3 Capture Volume", ADAU1761_REC_MIXER_RIGHT0, + 4, 7, 0, adau1761_sing_in_tlv), + SOC_SINGLE_TLV("Input 4 Capture Volume", ADAU1761_REC_MIXER_RIGHT0, + 1, 7, 0, adau1761_sing_in_tlv), +}; + +static const struct snd_kcontrol_new adau1761_controls[] = { + SOC_DOUBLE_R_TLV("Aux Capture Volume", ADAU1761_REC_MIXER_LEFT1, + ADAU1761_REC_MIXER_RIGHT1, 0, 7, 0, adau1761_sing_in_tlv), + + SOC_DOUBLE_R_TLV("Headphone Playback Volume", ADAU1761_PLAY_HP_LEFT_VOL, + ADAU1761_PLAY_HP_RIGHT_VOL, 2, 0x3f, 0, adau1761_out_tlv), + SOC_DOUBLE_R("Headphone Playback Switch", ADAU1761_PLAY_HP_LEFT_VOL, + ADAU1761_PLAY_HP_RIGHT_VOL, 1, 1, 0), + SOC_DOUBLE_R_TLV("Lineout Playback Volume", ADAU1761_PLAY_LINE_LEFT_VOL, + ADAU1761_PLAY_LINE_RIGHT_VOL, 2, 0x3f, 0, adau1761_out_tlv), + SOC_DOUBLE_R("Lineout Playback Switch", ADAU1761_PLAY_LINE_LEFT_VOL, + ADAU1761_PLAY_LINE_RIGHT_VOL, 1, 1, 0), + + SOC_ENUM("ADC Bias", adau1761_adc_bias_enum), + SOC_ENUM("DAC Bias", adau1761_dac_bias_enum), + SOC_VALUE_ENUM("Capture Bias", adau1761_capture_bias_enum), + SOC_VALUE_ENUM("Playback Bias", adau1761_playback_bias_enum), + SOC_ENUM("Headphone Bias", adau1761_hp_bias_enum), +}; + +static const struct snd_kcontrol_new adau1761_mono_controls[] = { + SOC_SINGLE_TLV("Mono Playback Volume", ADAU1761_PLAY_MONO_OUTPUT_VOL, + 2, 0x3f, 0, adau1761_out_tlv), + SOC_SINGLE("Mono Playback Switch", ADAU1761_PLAY_MONO_OUTPUT_VOL, + 1, 1, 0), +}; + +static const struct snd_kcontrol_new adau1761_left_mixer_controls[] = { + SOC_DAPM_SINGLE("Left DAC Switch", ADAU1761_PLAY_MIXER_LEFT0, 5, 1, 0), + SOC_DAPM_SINGLE("Right DAC Switch", ADAU1761_PLAY_MIXER_LEFT0, 6, 1, 0), + SOC_DAPM_SINGLE_TLV("Aux Bypass Volume", + ADAU1761_PLAY_MIXER_LEFT0, 1, 8, 0, adau1761_sidetone_tlv), + SOC_DAPM_SINGLE_TLV("Right Bypass Volume", + ADAU1761_PLAY_MIXER_LEFT1, 4, 8, 0, adau1761_sidetone_tlv), + SOC_DAPM_SINGLE_TLV("Left Bypass Volume", + ADAU1761_PLAY_MIXER_LEFT1, 0, 8, 0, adau1761_sidetone_tlv), +}; + +static const struct snd_kcontrol_new adau1761_right_mixer_controls[] = { + SOC_DAPM_SINGLE("Left DAC Switch", ADAU1761_PLAY_MIXER_RIGHT0, 5, 1, 0), + SOC_DAPM_SINGLE("Right DAC Switch", ADAU1761_PLAY_MIXER_RIGHT0, 6, 1, 0), + SOC_DAPM_SINGLE_TLV("Aux Bypass Volume", + ADAU1761_PLAY_MIXER_RIGHT0, 1, 8, 0, adau1761_sidetone_tlv), + SOC_DAPM_SINGLE_TLV("Right Bypass Volume", + ADAU1761_PLAY_MIXER_RIGHT1, 4, 8, 0, adau1761_sidetone_tlv), + SOC_DAPM_SINGLE_TLV("Left Bypass Volume", + ADAU1761_PLAY_MIXER_RIGHT1, 0, 8, 0, adau1761_sidetone_tlv), +}; + +static const struct snd_kcontrol_new adau1761_left_lr_mixer_controls[] = { + SOC_DAPM_SINGLE_TLV("Left Volume", + ADAU1761_PLAY_LR_MIXER_LEFT, 1, 2, 0, adau1761_boost_tlv), + SOC_DAPM_SINGLE_TLV("Right Volume", + ADAU1761_PLAY_LR_MIXER_LEFT, 3, 2, 0, adau1761_boost_tlv), +}; + +static const struct snd_kcontrol_new adau1761_right_lr_mixer_controls[] = { + SOC_DAPM_SINGLE_TLV("Left Volume", + ADAU1761_PLAY_LR_MIXER_RIGHT, 1, 2, 0, adau1761_boost_tlv), + SOC_DAPM_SINGLE_TLV("Right Volume", + ADAU1761_PLAY_LR_MIXER_RIGHT, 3, 2, 0, adau1761_boost_tlv), +}; + +static const char * const adau1761_input_mux_text[] = { + "ADC", "DMIC", +}; + +static const SOC_ENUM_SINGLE_DECL(adau1761_input_mux_enum, + ADAU17X1_ADC_CONTROL, 2, adau1761_input_mux_text); + +static const struct snd_kcontrol_new adau1761_input_mux_control = + SOC_DAPM_ENUM("Input Select", adau1761_input_mux_enum); + +static int adau1761_dejitter_fixup(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct adau *adau = snd_soc_codec_get_drvdata(w->codec); + + /* After any power changes have been made the dejitter circuit + * has to be reinitialized. */ + regmap_write(adau->regmap, ADAU1761_DEJITTER, 0); + if (!adau->master) + regmap_write(adau->regmap, ADAU1761_DEJITTER, 3); + + return 0; +} + +static const struct snd_soc_dapm_widget adau1x61_dapm_widgets[] = { + SND_SOC_DAPM_MIXER("Left Input Mixer", ADAU1761_REC_MIXER_LEFT0, 0, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("Right Input Mixer", ADAU1761_REC_MIXER_RIGHT0, 0, 0, + NULL, 0), + + SOC_MIXER_ARRAY("Left Playback Mixer", ADAU1761_PLAY_MIXER_LEFT0, + 0, 0, adau1761_left_mixer_controls), + SOC_MIXER_ARRAY("Right Playback Mixer", ADAU1761_PLAY_MIXER_RIGHT0, + 0, 0, adau1761_right_mixer_controls), + SOC_MIXER_ARRAY("Left LR Playback Mixer", ADAU1761_PLAY_LR_MIXER_LEFT, + 0, 0, adau1761_left_lr_mixer_controls), + SOC_MIXER_ARRAY("Right LR Playback Mixer", ADAU1761_PLAY_LR_MIXER_RIGHT, + 0, 0, adau1761_right_lr_mixer_controls), + + SND_SOC_DAPM_SUPPLY("Headphone", ADAU1761_PLAY_HP_LEFT_VOL, + 0, 0, NULL, 0), + + SND_SOC_DAPM_SUPPLY("SYSCLK", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_POST("Dejitter fixup", adau1761_dejitter_fixup), + + SND_SOC_DAPM_INPUT("LAUX"), + SND_SOC_DAPM_INPUT("RAUX"), + SND_SOC_DAPM_INPUT("LINP"), + SND_SOC_DAPM_INPUT("LINN"), + SND_SOC_DAPM_INPUT("RINP"), + SND_SOC_DAPM_INPUT("RINN"), + + SND_SOC_DAPM_OUTPUT("LOUT"), + SND_SOC_DAPM_OUTPUT("ROUT"), + SND_SOC_DAPM_OUTPUT("LHP"), + SND_SOC_DAPM_OUTPUT("RHP"), +}; + +static const struct snd_soc_dapm_widget adau1761_mono_dapm_widgets[] = { + SND_SOC_DAPM_MIXER("Mono Playback Mixer", ADAU1761_PLAY_MIXER_MONO, + 0, 0, NULL, 0), + + SND_SOC_DAPM_OUTPUT("MONOOUT"), +}; + +static const struct snd_soc_dapm_widget adau1761_capless_dapm_widgets[] = { + SND_SOC_DAPM_SUPPLY("Headphone VGND", ADAU1761_PLAY_MIXER_MONO, + 0, 0, NULL, 0), +}; + +static const struct snd_soc_dapm_widget adau1761_dmic_widgets[] = { + SND_SOC_DAPM_MUX("Input Select", SND_SOC_NOPM, 0, 0, + &adau1761_input_mux_control), + + SND_SOC_DAPM_INPUT("DMIC"), +}; + +static const struct snd_soc_dapm_route adau1x61_dapm_routes[] = { + { "Left Input Mixer", NULL, "LINP" }, + { "Left Input Mixer", NULL, "LINN" }, + { "Left Input Mixer", NULL, "LAUX" }, + + { "Right Input Mixer", NULL, "RINP" }, + { "Right Input Mixer", NULL, "RINN" }, + { "Right Input Mixer", NULL, "RAUX" }, + + { "Left Playback Mixer", NULL, "Left Playback Enable"}, + { "Right Playback Mixer", NULL, "Right Playback Enable"}, + { "Left LR Playback Mixer", NULL, "Left Playback Enable"}, + { "Right LR Playback Mixer", NULL, "Right Playback Enable"}, + + { "Left Playback Mixer", "Left DAC Switch", "Left DAC" }, + { "Left Playback Mixer", "Right DAC Switch", "Right DAC" }, + + { "Right Playback Mixer", "Left DAC Switch", "Left DAC" }, + { "Right Playback Mixer", "Right DAC Switch", "Right DAC" }, + + { "Left LR Playback Mixer", "Left Volume", "Left Playback Mixer" }, + { "Left LR Playback Mixer", "Right Volume", "Right Playback Mixer" }, + + { "Right LR Playback Mixer", "Left Volume", "Left Playback Mixer" }, + { "Right LR Playback Mixer", "Right Volume", "Right Playback Mixer" }, + + { "Left ADC", NULL, "Left Input Mixer" }, + { "Right ADC", NULL, "Right Input Mixer" }, + + { "LHP", NULL, "Left Playback Mixer" }, + { "RHP", NULL, "Right Playback Mixer" }, + + { "LHP", NULL, "Headphone" }, + { "RHP", NULL, "Headphone" }, + + { "LOUT", NULL, "Left LR Playback Mixer" }, + { "ROUT", NULL, "Right LR Playback Mixer" }, + + { "Left Playback Mixer", "Aux Bypass Volume", "LAUX" }, + { "Left Playback Mixer", "Left Bypass Volume", "Left Input Mixer" }, + { "Left Playback Mixer", "Right Bypass Volume", "Right Input Mixer" }, + { "Right Playback Mixer", "Aux Bypass Volume", "RAUX" }, + { "Right Playback Mixer", "Left Bypass Volume", "Left Input Mixer" }, + { "Right Playback Mixer", "Right Bypass Volume", "Right Input Mixer" }, +}; + +static const struct snd_soc_dapm_route adau1761_mono_dapm_routes[] = { + { "Mono Playback Mixer", NULL, "Left Playback Mixer" }, + { "Mono Playback Mixer", NULL, "Right Playback Mixer" }, + + { "MONOOUT", NULL, "Mono Playback Mixer" }, +}; + +static const struct snd_soc_dapm_route adau1761_capless_dapm_routes[] = { + { "Headphone", NULL, "Headphone VGND" }, +}; + +static const struct snd_soc_dapm_route adau1761_dmic_routes[] = { + { "Input Select", "ADC", "Left ADC" }, + { "Input Select", "ADC", "Right ADC" }, + { "Input Select", "DMIC", "DMIC" }, + { "AIFOUT", NULL, "Input Select" }, +}; + +static const struct snd_soc_dapm_route adau1761_no_dmic_routes[] = { + { "AIFOUT", NULL, "Left ADC" }, + { "AIFOUT", NULL, "Right ADC" }, +}; + +static const struct snd_soc_dapm_widget adau1761_dapm_widgets[] = { + SND_SOC_DAPM_SUPPLY("Serial Port Clock", ADAU1761_CLK_ENABLE0, + 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("Serial Input Routing Clock", ADAU1761_CLK_ENABLE0, + 1, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("Serial Output Routing Clock", ADAU1761_CLK_ENABLE0, + 3, 0, NULL, 0), + + SND_SOC_DAPM_SUPPLY("Decimator Resync Clock", ADAU1761_CLK_ENABLE0, + 4, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("Interpolator Resync Clock", ADAU1761_CLK_ENABLE0, + 2, 0, NULL, 0), + + SND_SOC_DAPM_SUPPLY("Slew Clock", ADAU1761_CLK_ENABLE0, 6, 0, NULL, 0), + + SND_SOC_DAPM_SUPPLY("Digital Clock 0", ADAU1761_CLK_ENABLE1, + 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("Digital Clock 1", ADAU1761_CLK_ENABLE1, + 1, 0, NULL, 0), +}; + +static int adau1761_is_slave_mode(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct adau *adau = snd_soc_codec_get_drvdata(source->codec); + + return !adau->master; +} + +static const struct snd_soc_dapm_route adau1761_dapm_routes[] = { + { "Left ADC", NULL, "Digital Clock 0", }, + { "Right ADC", NULL, "Digital Clock 0", }, + { "Left DAC", NULL, "Digital Clock 0", }, + { "Right DAC", NULL, "Digital Clock 0", }, + + { "AIFCLK", NULL, "Digital Clock 1" }, + + { "AIFIN", NULL, "Serial Port Clock" }, + { "AIFOUT", NULL, "Serial Port Clock" }, + { "AIFIN", NULL, "Serial Input Routing Clock" }, + { "AIFOUT", NULL, "Serial Output Routing Clock" }, + + { "AIFIN", NULL, "Decimator Resync Clock" }, + { "AIFOUT", NULL, "Interpolator Resync Clock" }, + + { "DSP", NULL, "Decimator Resync Clock" }, + { "DSP", NULL, "Interpolator Resync Clock" }, + { "DSP", NULL, "Digital Clock 0" }, + + { "Slew Clock", NULL, "Digital Clock 0" }, + { "Right Playback Mixer", NULL, "Slew Clock" }, + { "Left Playback Mixer", NULL, "Slew Clock" }, + + { "Digital Clock 0", NULL, "SYSCLK" }, + { "Digital Clock 1", NULL, "SYSCLK" }, + + { "AIFOUT", NULL, "Decimator Resync Clock" }, +}; + +static int adau1761_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + struct adau *adau = snd_soc_codec_get_drvdata(codec); + + switch (level) { + case SND_SOC_BIAS_ON: + break; + case SND_SOC_BIAS_PREPARE: + break; + case SND_SOC_BIAS_STANDBY: + regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL, + ADAU17X1_CLOCK_CONTROL_SYSCLK_EN, + ADAU17X1_CLOCK_CONTROL_SYSCLK_EN); + break; + case SND_SOC_BIAS_OFF: + regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL, + ADAU17X1_CLOCK_CONTROL_SYSCLK_EN, 0); + break; + + } + codec->dapm.bias_level = level; + return 0; +} + +static enum adau1761_output_mode adau1761_get_lineout_mode( + struct snd_soc_codec *codec) +{ + struct adau1761_platform_data *pdata = codec->dev->platform_data; + + if (pdata) + return pdata->lineout_mode; + + return ADAU1761_OUTPUT_MODE_LINE; +} + +static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec) +{ + struct adau1761_platform_data *pdata = codec->dev->platform_data; + struct adau *adau = snd_soc_codec_get_drvdata(codec); + enum adau1761_digmic_jackdet_pin_mode mode; + unsigned int val = 0; + int ret; + + if (pdata) + mode = pdata->digmic_jackdetect_pin_mode; + else + mode = ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE; + + switch (mode) { + case ADAU1761_DIGMIC_JACKDET_PIN_MODE_JACKDETECT: + switch (pdata->jackdetect_debounce_time) { + case ADAU1761_JACKDETECT_DEBOUNCE_5MS: + case ADAU1761_JACKDETECT_DEBOUNCE_10MS: + case ADAU1761_JACKDETECT_DEBOUNCE_20MS: + case ADAU1761_JACKDETECT_DEBOUNCE_40MS: + val |= pdata->jackdetect_debounce_time << 6; + break; + default: + return -EINVAL; + } + if (pdata->jackdetect_active_low) + val |= ADAU1761_DIGMIC_JACKDETECT_ACTIVE_LOW; + + ret = snd_soc_add_controls(codec, + adau1761_jack_detect_controls, + ARRAY_SIZE(adau1761_jack_detect_controls)); + if (ret) + return ret; + case ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE: /* fall-through */ + ret = snd_soc_dapm_add_routes(&codec->dapm, + adau1761_no_dmic_routes, + ARRAY_SIZE(adau1761_no_dmic_routes)); + if (ret) + return ret; + break; + case ADAU1761_DIGMIC_JACKDET_PIN_MODE_DIGMIC: + ret = snd_soc_dapm_new_controls(&codec->dapm, + adau1761_dmic_widgets, + ARRAY_SIZE(adau1761_dmic_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(&codec->dapm, + adau1761_dmic_routes, + ARRAY_SIZE(adau1761_dmic_routes)); + if (ret) + return ret; + val |= ADAU1761_DIGMIC_JACKDETECT_DIGMIC; + break; + default: + return -EINVAL; + } + + regmap_write(adau->regmap, ADAU1761_DIGMIC_JACKDETECT, val); + + return 0; +} + +static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec) +{ + struct adau *adau = snd_soc_codec_get_drvdata(codec); + struct adau1761_platform_data *pdata = codec->dev->platform_data; + enum adau1761_output_mode mode; + int ret; + + if (pdata) + mode = pdata->headphone_mode; + else + mode = ADAU1761_OUTPUT_MODE_HEADPHONE; + + switch (mode) { + case ADAU1761_OUTPUT_MODE_LINE: + break; + case ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS: + regmap_update_bits(adau->regmap, ADAU1761_PLAY_MONO_OUTPUT_VOL, 3, 3); + case ADAU1761_OUTPUT_MODE_HEADPHONE: /* fall-through */ + regmap_update_bits(adau->regmap, ADAU1761_PLAY_HP_RIGHT_VOL, 1, 1); + break; + default: + return -EINVAL; + } + + if (mode == ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS) { + ret = snd_soc_dapm_new_controls(&codec->dapm, + adau1761_capless_dapm_widgets, + ARRAY_SIZE(adau1761_capless_dapm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(&codec->dapm, + adau1761_capless_dapm_routes, + ARRAY_SIZE(adau1761_capless_dapm_routes)); + } else { + ret = snd_soc_dapm_new_controls(&codec->dapm, + adau1761_mono_dapm_widgets, + ARRAY_SIZE(adau1761_mono_dapm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(&codec->dapm, + adau1761_mono_dapm_routes, + ARRAY_SIZE(adau1761_mono_dapm_routes)); + } + + return ret; +} + +static bool adau1761_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case ADAU1761_DIGMIC_JACKDETECT: + case ADAU1761_REC_MIXER_LEFT0: + case ADAU1761_REC_MIXER_LEFT1: + case ADAU1761_REC_MIXER_RIGHT0: + case ADAU1761_REC_MIXER_RIGHT1: + case ADAU1761_LEFT_DIFF_INPUT_VOL: + case ADAU1761_RIGHT_DIFF_INPUT_VOL: + case ADAU1761_PLAY_LR_MIXER_LEFT: + case ADAU1761_PLAY_MIXER_LEFT0: + case ADAU1761_PLAY_MIXER_LEFT1: + case ADAU1761_PLAY_MIXER_RIGHT0: + case ADAU1761_PLAY_MIXER_RIGHT1: + case ADAU1761_PLAY_LR_MIXER_RIGHT: + case ADAU1761_PLAY_MIXER_MONO: + case ADAU1761_PLAY_HP_LEFT_VOL: + case ADAU1761_PLAY_HP_RIGHT_VOL: + case ADAU1761_PLAY_LINE_LEFT_VOL: + case ADAU1761_PLAY_LINE_RIGHT_VOL: + case ADAU1761_PLAY_MONO_OUTPUT_VOL: + case ADAU1761_POP_CLICK_SUPPRESS: + case ADAU1761_JACK_DETECT_PIN: + case ADAU1761_DEJITTER: + case ADAU1761_CLK_ENABLE0: + case ADAU1761_CLK_ENABLE1: + return true; + default: + break; + } + + return adau17x1_readable_register(dev, reg); +} + +static struct adau1761_platform_data def_pdata = { + .input_differential = true, + .lineout_mode = ADAU1761_OUTPUT_MODE_LINE, + .headphone_mode = ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS, + .digmic_jackdetect_pin_mode = ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE, +}; + +static int adau1761_probe(struct snd_soc_codec *codec) +{ + struct adau1761_platform_data *pdata = codec->dev->platform_data; + struct adau *adau = snd_soc_codec_get_drvdata(codec); + int ret; + + pdata = &def_pdata; + codec->dev->platform_data = &def_pdata; + + ret = adau17x1_probe(codec); + if (ret < 0) + return ret; + + adau1761_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + if (pdata && pdata->input_differential) { + regmap_update_bits(adau->regmap, ADAU1761_LEFT_DIFF_INPUT_VOL, + ADAU1761_DIFF_INPUT_VOL_LDEN, + ADAU1761_DIFF_INPUT_VOL_LDEN); + regmap_update_bits(adau->regmap, ADAU1761_RIGHT_DIFF_INPUT_VOL, + ADAU1761_DIFF_INPUT_VOL_LDEN, + ADAU1761_DIFF_INPUT_VOL_LDEN); + ret = snd_soc_add_controls(codec, + adau1761_differential_mode_controls, + ARRAY_SIZE(adau1761_differential_mode_controls)); + if (ret) + return ret; + } else { + ret = snd_soc_add_controls(codec, + adau1761_single_mode_controls, + ARRAY_SIZE(adau1761_single_mode_controls)); + if (ret) + return ret; + } + + switch (adau1761_get_lineout_mode(codec)) { + case ADAU1761_OUTPUT_MODE_LINE: + break; + case ADAU1761_OUTPUT_MODE_HEADPHONE: + regmap_update_bits(adau->regmap, ADAU1761_PLAY_LINE_LEFT_VOL, 1, 1); + regmap_update_bits(adau->regmap, ADAU1761_PLAY_LINE_RIGHT_VOL, 1, 1); + break; + default: + return -EINVAL; + } + + ret = adau1761_setup_headphone_mode(codec); + if (ret) + return ret; + + ret = adau1761_setup_digmic_jackdetect(codec); + if (ret) + return ret; + + if (adau->type == ADAU1761) { + ret = snd_soc_dapm_new_controls(&codec->dapm, + adau1761_dapm_widgets, + ARRAY_SIZE(adau1761_dapm_widgets)); + if (ret) + return ret; + + ret = snd_soc_dapm_add_routes(&codec->dapm, + adau1761_dapm_routes, + ARRAY_SIZE(adau1761_dapm_routes)); + if (ret) + return ret; + + ret = adau17x1_load_firmware(adau, codec->dev, + ADAU1761_FIRMWARE); + if (ret) + dev_warn(codec->dev, "Failed to firmware\n"); + } + + return 0; +} + +static struct snd_soc_codec_driver adau1761_codec_driver = { + .probe = adau1761_probe, + .remove = adau17x1_suspend, + .suspend = adau17x1_suspend, + .resume = adau17x1_resume, + .set_bias_level = adau1761_set_bias_level, + + .controls = adau1761_controls, + .num_controls = ARRAY_SIZE(adau1761_controls), + .dapm_widgets = adau1x61_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(adau1x61_dapm_widgets), + .dapm_routes = adau1x61_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(adau1x61_dapm_routes), +}; + +#define ADAU1761_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver adau1361_dai_driver = { + .name = "adau-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 4, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = ADAU1761_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 2, + .channels_max = 4, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = ADAU1761_FORMATS, + }, + .ops = &adau17x1_dai_ops, +}; + +static struct snd_soc_dai_driver adau1761_dai_driver = { + .name = "adau-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = ADAU1761_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 2, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = ADAU1761_FORMATS, + }, + .ops = &adau17x1_dai_ops, +}; + +static int __devinit adau1761_bus_probe(struct device *dev, + struct regmap *regmap, enum adau17x1_type type, + enum snd_soc_control_type control_type) +{ + struct snd_soc_dai_driver *dai_drv; + int ret; + + ret = adau17x1_bus_probe(dev, regmap, type, control_type); + if (ret) + return ret; + + if (type == ADAU1361) + dai_drv = &adau1361_dai_driver; + else + dai_drv = &adau1761_dai_driver; + + return snd_soc_register_codec(dev, &adau1761_codec_driver, + dai_drv, 1); +} + +#if IS_ENABLED(CONFIG_SPI_MASTER) + +static const struct regmap_config adau1761_spi_regmap_config = { + .val_bits = 8, + .reg_bits = 24, + .read_flag_mask = 0x01, + .max_register = 0x40fa, + .reg_defaults = adau1761_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(adau1761_reg_defaults), + .readable_reg = adau1761_readable_register, + .volatile_reg = adau17x1_volatile_register, + .cache_type = REGCACHE_RBTREE, +}; + +static int __devinit adau1761_spi_probe(struct spi_device *spi) +{ + enum adau17x1_type type = spi_get_device_id(spi)->driver_data; + struct regmap *regmap; + + regmap = devm_regmap_init_spi(spi, &adau1761_spi_regmap_config); + + return adau1761_bus_probe(&spi->dev, regmap, type, SND_SOC_SPI); +} + +static int __devexit adau1761_spi_remove(struct spi_device *spi) +{ + snd_soc_unregister_codec(&spi->dev); + return 0; +} + +static const struct spi_device_id adau1761_spi_id[] = { + { "adau1361", ADAU1361 }, + { "adau1461", ADAU1761 }, + { "adau1761", ADAU1761 }, + { "adau1961", ADAU1361 }, + { } +}; +MODULE_DEVICE_TABLE(spi, adau1761_spi_id); + +static struct spi_driver adau1761_spi_driver = { + .driver = { + .name = "adau1761", + .owner = THIS_MODULE, + }, + .probe = adau1761_spi_probe, + .remove = __devexit_p(adau1761_spi_remove), + .id_table = adau1761_spi_id, +}; + +static int adau1761_spi_register_driver(void) +{ + return spi_register_driver(&adau1761_spi_driver); +} + +static void adau1761_spi_unregister_driver(void) +{ + spi_unregister_driver(&adau1761_spi_driver); +} + +#else +static int adau1761_spi_register_driver(void) { return 0; } +static void adau1761_spi_unregister_driver(void) {} +#endif + +#if IS_ENABLED(CONFIG_I2C) + +static const struct regmap_config adau1761_i2c_regmap_config = { + .val_bits = 8, + .reg_bits = 16, + .max_register = 0x40fa, + .reg_defaults = adau1761_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(adau1761_reg_defaults), + .readable_reg = adau1761_readable_register, + .volatile_reg = adau17x1_volatile_register, + .cache_type = REGCACHE_RBTREE, +}; + +static int __devinit adau1761_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + enum adau17x1_type type = id->driver_data; + struct regmap *regmap; + + regmap = devm_regmap_init_i2c(client, &adau1761_i2c_regmap_config); + + return adau1761_bus_probe(&client->dev, regmap, type, SND_SOC_I2C); +} + +static int __devexit adau1761_i2c_remove(struct i2c_client *client) +{ + snd_soc_unregister_codec(&client->dev); + return 0; +} + +static const struct i2c_device_id adau1761_i2c_id[] = { + { "adau1361", ADAU1361 }, + { "adau1461", ADAU1761 }, + { "adau1761", ADAU1761 }, + { "adau1961", ADAU1361 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, adau1761_i2c_id); + +static struct i2c_driver adau1761_i2c_driver = { + .driver = { + .name = "adau1761", + .owner = THIS_MODULE, + }, + .probe = adau1761_i2c_probe, + .remove = __devexit_p(adau1761_i2c_remove), + .id_table = adau1761_i2c_id, +}; + +static int adau1761_i2c_register_driver(void) +{ + return i2c_add_driver(&adau1761_i2c_driver); +} + +static void adau1761_i2c_unregister_driver(void) +{ + i2c_del_driver(&adau1761_i2c_driver); +} + +#else +static int adau1761_i2c_register_driver(void) { return 0; } +static void adau1761_i2c_unregister_driver(void) {} +#endif + +static int __init adau1761_init(void) +{ + int ret; + + ret = adau1761_spi_register_driver(); + if (ret) + return ret; + + ret = adau1761_i2c_register_driver(); + if (ret) + adau1761_spi_unregister_driver(); + + return ret; +} +module_init(adau1761_init); + +static void __exit adau1761_exit(void) +{ + adau1761_i2c_unregister_driver(); + adau1761_spi_unregister_driver(); +} +module_exit(adau1761_exit); + +MODULE_DESCRIPTION("ASoC ADAU1361/ADAU1461/ADAU1761/ADAU1961 CODEC driver"); +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c new file mode 100644 index 0000000000000..7e2a1a6106814 --- /dev/null +++ b/sound/soc/codecs/adau17x1.c @@ -0,0 +1,861 @@ +/* + * Common code for ADAU1X61 and ADAU1X81 codecs + * + * Copyright 2011 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sigmadsp.h" +#include "adau17x1.h" + +static const char * const adau17x1_capture_mixer_boost_text[] = { + "Normal operation", "Boost Level 1", "Boost Level 2", "Boost Level 3", +}; + +static const SOC_ENUM_SINGLE_DECL(adau17x1_capture_boost_enum, + ADAU17X1_REC_POWER_MGMT, 5, adau17x1_capture_mixer_boost_text); + +static const char *const adau17x1_mic_bias_mode_text[] = { + "Normal operation", "High performance", +}; + +static SOC_ENUM_SINGLE_DECL(adau17x1_mic_bias_mode_enum, + ADAU17X1_MICBIAS, 3, adau17x1_mic_bias_mode_text); + +static const char * const adau17x1_mono_stereo_text[] = { + "Stereo", + "Mono Left Channel (L+R)", + "Mono Right Channel (L+R)", + "Mono (L+R)", +}; + +static const SOC_ENUM_SINGLE_DECL(adau17x1_dac_mode_enum, + ADAU17X1_DAC_CONTROL0, 6, adau17x1_mono_stereo_text); + +static const DECLARE_TLV_DB_MINMAX(adau17x1_digital_tlv, -9563, 0); + +static const struct snd_kcontrol_new adau17x1_controls[] = { + SOC_DOUBLE_R_TLV("Digital Capture Volume", + ADAU17X1_LEFT_INPUT_DIGITAL_VOL, ADAU17X1_RIGHT_INPUT_DIGITAL_VOL, + 0, 0xff, 1, adau17x1_digital_tlv), + SOC_DOUBLE_R_TLV("Digital Playback Volume", ADAU17X1_DAC_CONTROL1, + ADAU17X1_DAC_CONTROL2, 0, 0xff, 1, adau17x1_digital_tlv), + + SOC_SINGLE("ADC High Pass Filter Switch", ADAU17X1_ADC_CONTROL, + 5, 1, 0), + SOC_SINGLE("Playback De-emphasis Switch", ADAU17X1_DAC_CONTROL0, + 2, 1, 0), + + SOC_ENUM("Capture Boost", adau17x1_capture_boost_enum), + + SOC_ENUM("Mic Bias Mode", adau17x1_mic_bias_mode_enum), + + SOC_ENUM("DAC Mono Stereo", adau17x1_dac_mode_enum), +}; + +static int adau17x1_pll_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct adau *adau = snd_soc_codec_get_drvdata(w->codec); + int ret; + + if (SND_SOC_DAPM_EVENT_ON(event)) { + adau->pll_regs[5] = 1; + } else { + adau->pll_regs[5] = 0; + /* Bypass the PLL when disabled, otherwise registers will become + * inaccessible. */ + regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL, + ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL, 0); + } + + /* The PLL register is 6 bytes long and can only be written at once. */ + ret = regmap_raw_write(adau->regmap, ADAU17X1_PLL_CONTROL, + adau->pll_regs, ARRAY_SIZE(adau->pll_regs)); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + mdelay(5); + regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL, + ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL, + ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL); + } + + return 0; +} + +static const struct snd_soc_dapm_widget adau17x1_dapm_widgets[] = { + SND_SOC_DAPM_SUPPLY_S("PLL", 0, SND_SOC_NOPM, 0, 0, adau17x1_pll_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("AIFCLK", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_SUPPLY("MICBIAS", ADAU17X1_MICBIAS, 0, 0, NULL, 0), + + SND_SOC_DAPM_SUPPLY("Left Playback Enable", ADAU17X1_PLAY_POWER_MGMT, + 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("Right Playback Enable", ADAU17X1_PLAY_POWER_MGMT, + 1, 0, NULL, 0), + + SND_SOC_DAPM_DAC("Left DAC", NULL, ADAU17X1_DAC_CONTROL0, 0, 0), + SND_SOC_DAPM_DAC("Right DAC", NULL, ADAU17X1_DAC_CONTROL0, 1, 0), + SND_SOC_DAPM_ADC("Left ADC", NULL, ADAU17X1_ADC_CONTROL, 0, 0), + SND_SOC_DAPM_ADC("Right ADC", NULL, ADAU17X1_ADC_CONTROL, 1, 0), + + SND_SOC_DAPM_AIF_OUT("AIFOUT", "Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("AIFIN", "Playback", 0, SND_SOC_NOPM, 0, 0), +}; + +static int adau17x1_check_sysclk_pll(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct adau *adau = snd_soc_codec_get_drvdata(source->codec); + + return adau->clk_src == ADAU17X1_CLK_SRC_PLL; +} + +static const struct snd_soc_dapm_route adau17x1_dapm_routes[] = { + { "SYSCLK", NULL, "PLL", adau17x1_check_sysclk_pll }, + + { "Left ADC", NULL, "SYSCLK" }, + { "Right ADC", NULL, "SYSCLK" }, + { "Left DAC", NULL, "SYSCLK" }, + { "Right DAC", NULL, "SYSCLK" }, + { "AIFOUT", NULL, "SYSCLK" }, + { "AIFIN", NULL, "SYSCLK" }, + + { "AIFOUT", NULL, "AIFCLK" }, + { "AIFIN", NULL, "AIFCLK" }, + + { "Left DAC", NULL, "AIFIN" }, + { "Right DAC", NULL, "AIFIN" }, +}; + +static int adau17x1_check_dsp_caputure(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct adau *adau = snd_soc_codec_get_drvdata(source->codec); + + return !adau->dsp_capture_bypass; +} + +static int adau17x1_check_dsp_playback(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct adau *adau = snd_soc_codec_get_drvdata(source->codec); + + return !adau->dsp_playback_bypass; +} + +/* This is not exacly by the book. It would be better to provide MIXER or MUX + * widgets for the DSP capture and playback path. */ +static const struct snd_soc_dapm_widget adau17x1_dsp_dapm_widgets[] = { + SND_SOC_DAPM_SUPPLY("DSP", ADAU17X1_DSP_RUN, 0, 0, NULL, 0), +}; + +static const struct snd_soc_dapm_route adau17x1_dsp_dapm_routes[] = { + { "AIFOUT", NULL, "DSP", adau17x1_check_dsp_caputure }, + { "AIFIN", NULL, "DSP", adau17x1_check_dsp_playback }, +}; + +static int adau17x1_dsp_bypass_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct adau *adau = snd_soc_codec_get_drvdata(codec); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + bool bypass = ucontrol->value.integer.value[0]; + unsigned int tdm_slot; + + switch (mc->reg) { + case ADAU17X1_SERIAL_INPUT_ROUTE: + adau->dsp_playback_bypass = bypass; + tdm_slot = adau->tdm_dac_slot; + break; + case ADAU17X1_SERIAL_OUTPUT_ROUTE: + adau->dsp_capture_bypass = bypass; + tdm_slot = adau->tdm_adc_slot; + break; + default: + return -EINVAL; + } + + if (bypass) + regmap_write(adau->regmap, mc->reg, (tdm_slot * 2) + 1); + else + regmap_write(adau->regmap, mc->reg, 0x00); + + return 0; +} + +static int adau17x1_dsp_bypass_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct adau *adau = snd_soc_codec_get_drvdata(codec); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + bool bypass; + + switch (mc->reg) { + case ADAU17X1_SERIAL_INPUT_ROUTE: + bypass = adau->dsp_playback_bypass; + break; + case ADAU17X1_SERIAL_OUTPUT_ROUTE: + bypass = adau->dsp_capture_bypass; + break; + default: + return -EINVAL; + } + + ucontrol->value.integer.value[0] = bypass; + + return 0; +} + +static const struct snd_kcontrol_new adau17x1_dsp_controls[] = { + SOC_SINGLE_EXT("DSP Bypass Playback Switch", ADAU17X1_SERIAL_INPUT_ROUTE, + 0, 1, 0, adau17x1_dsp_bypass_get, adau17x1_dsp_bypass_put), + SOC_SINGLE_EXT("DSP Bypass Capture Switch", ADAU17X1_SERIAL_OUTPUT_ROUTE, + 0, 1, 0, adau17x1_dsp_bypass_get, adau17x1_dsp_bypass_put), +}; + +static void adau17x1_check_aifclk(struct snd_soc_codec *codec) +{ + struct adau *adau = snd_soc_codec_get_drvdata(codec); + + /* If we are in master mode we need to generate bit- and frameclock, + * regardless of whether the AIF itself is powered or not */ + if (codec->active && adau->master) + snd_soc_dapm_force_enable_pin(&codec->dapm, "AIFCLK"); + else + snd_soc_dapm_disable_pin(&codec->dapm, "AIFCLK"); + snd_soc_dapm_sync(&codec->dapm); +} + +static bool adau17x1_has_dsp(struct adau *adau) +{ + switch (adau->type) { + case ADAU1761: + case ADAU1381: + case ADAU1781: + return true; + default: + return false; + } +} + +static int adau17x1_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct adau *adau = snd_soc_codec_get_drvdata(codec); + unsigned int val, div, dsp_div; + unsigned int freq; + + if (adau->clk_src == ADAU17X1_CLK_SRC_PLL) + freq = adau->pll_freq; + else + freq = adau->sysclk / adau->sysclk_div; + + if (freq % params_rate(params) != 0) + return -EINVAL; + + switch (freq / params_rate(params)) { + case 1024: /* fs */ + div = 0; + dsp_div = 1; + break; + case 6144: /* fs / 6 */ + div = 1; + dsp_div = 6; + break; + case 4096: /* fs / 4 */ + div = 2; + dsp_div = 5; + break; + case 3072: /* fs / 3 */ + div = 3; + dsp_div = 4; + break; + case 2048: /* fs / 2 */ + div = 4; + dsp_div = 3; + break; + case 1536: /* fs / 1.5 */ + div = 5; + dsp_div = 2; + break; + case 512: /* fs / 0.5 */ + div = 6; + dsp_div = 0; + break; + default: + return -EINVAL; + } + + regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER0, 7, div); + if (adau17x1_has_dsp(adau)) { + regmap_write(adau->regmap, ADAU17X1_SERIAL_SAMPLING_RATE, div); + regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, dsp_div); + } + + adau17x1_check_aifclk(codec); + + if (adau->dai_fmt != SND_SOC_DAIFMT_RIGHT_J) + return 0; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + val = ADAU17X1_SERIAL_PORT1_DELAY16; + break; + case SNDRV_PCM_FORMAT_S24_LE: + val = ADAU17X1_SERIAL_PORT1_DELAY8; + break; + case SNDRV_PCM_FORMAT_S32_LE: + val = ADAU17X1_SERIAL_PORT1_DELAY0; + break; + default: + return -EINVAL; + } + + return regmap_update_bits(adau->regmap, ADAU17X1_SERIAL_PORT1, + ADAU17X1_SERIAL_PORT1_DELAY_MASK, val); +} + +static int adau17x1_dai_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + adau17x1_check_aifclk(dai->codec); + + return 0; +} + +static void adau17x1_dai_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + adau17x1_check_aifclk(dai->codec); +} + +static int adau17x1_set_dai_pll(struct snd_soc_dai *dai, int pll_id, + int source, unsigned int freq_in, unsigned int freq_out) +{ + struct snd_soc_codec *codec = dai->codec; + struct adau *adau = snd_soc_codec_get_drvdata(codec); + unsigned int div; + unsigned int r, n, m, i, j; + + if (freq_in < 8000000 || freq_in > 27000000) + return -EINVAL; + + if (!freq_out) { + r = 0; + n = 0; + m = 0; + div = 0; + } else { + if (freq_out % freq_in != 0) { + div = DIV_ROUND_UP(freq_in, 13500000); + freq_in /= div; + r = freq_out / freq_in; + i = freq_out % freq_in; + j = gcd(i, freq_in); + n = i / j; + m = freq_in / j; + div--; + } else { + r = freq_out / freq_in; + n = 0; + m = 0; + div = 0; + } + if (n > 0xffff || m > 0xffff || div > 3 || r > 8 || r < 2) + return -EINVAL; + } + + adau->pll_regs[0] = m >> 8; + adau->pll_regs[1] = m & 0xff; + adau->pll_regs[2] = n >> 8; + adau->pll_regs[3] = n & 0xff; + adau->pll_regs[4] = (r << 3) | (div << 1); + if (m != 0) + adau->pll_regs[4] |= 1; /* Fractional mode */ + adau->pll_regs[5] = 0; + + adau->pll_freq = freq_out; + + return 0; +} + +static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct adau *adau = snd_soc_codec_get_drvdata(dai->codec); + + switch (clk_id) { + case ADAU17X1_CLK_SRC_MCLK: + case ADAU17X1_CLK_SRC_PLL: + break; + default: + return -EINVAL; + } + + adau->sysclk = freq; + adau->clk_src = clk_id; + + return 0; +} + +static int adau17x1_set_dai_clkdiv(struct snd_soc_dai *dai, int div_id, int div) +{ + struct adau *adau = snd_soc_codec_get_drvdata(dai->codec); + + switch (div) { + case 1: + case 2: + case 3: + case 4: + break; + default: + return -EINVAL; + } + + adau->sysclk_div = div; + + return regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL, + ADAU17X1_CLOCK_CONTROL_INFREQ_MASK, (div - 1) << 1); +} + +static int adau17x1_set_dai_fmt(struct snd_soc_dai *dai, + unsigned int fmt) +{ + struct adau *adau = snd_soc_codec_get_drvdata(dai->codec); + unsigned int ctrl0, ctrl1; + int lrclk_pol; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + ctrl0 = ADAU17X1_SERIAL_PORT0_MASTER; + adau->master = true; + break; + case SND_SOC_DAIFMT_CBS_CFS: + ctrl0 = 0; + adau->master = false; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + lrclk_pol = 0; + ctrl1 = ADAU17X1_SERIAL_PORT1_DELAY1; + break; + case SND_SOC_DAIFMT_LEFT_J: + case SND_SOC_DAIFMT_RIGHT_J: + lrclk_pol = 1; + ctrl1 = ADAU17X1_SERIAL_PORT1_DELAY0; + break; + case SND_SOC_DAIFMT_DSP_A: + lrclk_pol = 1; + ctrl0 |= ADAU17X1_SERIAL_PORT0_PULSE_MODE; + ctrl1 = ADAU17X1_SERIAL_PORT1_DELAY1; + break; + case SND_SOC_DAIFMT_DSP_B: + lrclk_pol = 1; + ctrl0 |= ADAU17X1_SERIAL_PORT0_PULSE_MODE; + ctrl1 = ADAU17X1_SERIAL_PORT1_DELAY0; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_NF: + ctrl0 |= ADAU17X1_SERIAL_PORT0_BCLK_POL; + break; + case SND_SOC_DAIFMT_NB_IF: + lrclk_pol = !lrclk_pol; + break; + case SND_SOC_DAIFMT_IB_IF: + ctrl0 |= ADAU17X1_SERIAL_PORT0_BCLK_POL; + lrclk_pol = !lrclk_pol; + break; + default: + return -EINVAL; + } + + if (lrclk_pol) + ctrl0 |= ADAU17X1_SERIAL_PORT0_LRCLK_POL; + + regmap_write(adau->regmap, ADAU17X1_SERIAL_PORT0, ctrl0); + regmap_write(adau->regmap, ADAU17X1_SERIAL_PORT1, ctrl1); + + adau->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK; + + return 0; +} + +static int adau17x1_set_dai_tdm_slot(struct snd_soc_dai *dai, + unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) +{ + struct adau *adau = snd_soc_codec_get_drvdata(dai->codec); + unsigned int ser_ctrl0, ser_ctrl1; + unsigned int conv_ctrl0, conv_ctrl1; + + /* I2S mode */ + if (slots == 0) { + slots = 2; + rx_mask = 3; + tx_mask = 3; + slot_width = 32; + } + + switch (slots) { + case 2: + ser_ctrl0 = ADUA_SERIAL_PORT0_STEREO; + break; + case 4: + ser_ctrl0 = ADUA_SERIAL_PORT0_TDM4; + break; + case 8: + if (adau->type == ADAU1361) + return -EINVAL; + + ser_ctrl0 = ADUA_SERIAL_PORT0_TDM8; + break; + default: + return -EINVAL; + } + + switch (slot_width * slots) { + case 32: + if (adau->type == ADAU1761) + return -EINVAL; + + ser_ctrl1 = ADUA_SERIAL_PORT1_BCLK32; + break; + case 64: + ser_ctrl1 = ADUA_SERIAL_PORT1_BCLK64; + break; + case 48: + ser_ctrl1 = ADUA_SERIAL_PORT1_BCLK48; + break; + case 128: + ser_ctrl1 = ADUA_SERIAL_PORT1_BCLK128; + break; + case 256: + if (adau->type == ADAU1361) + return -EINVAL; + + ser_ctrl1 = ADUA_SERIAL_PORT1_BCLK256; + break; + default: + return -EINVAL; + } + + switch (rx_mask) { + case 0x03: + conv_ctrl1 = ADAU17X1_CONVERTER1_ADC_PAIR(1); + adau->tdm_adc_slot = 0; + break; + case 0x0c: + conv_ctrl1 = ADAU17X1_CONVERTER1_ADC_PAIR(2); + adau->tdm_adc_slot = 1; + break; + case 0x30: + conv_ctrl1 = ADAU17X1_CONVERTER1_ADC_PAIR(3); + adau->tdm_adc_slot = 2; + break; + case 0xc0: + conv_ctrl1 = ADAU17X1_CONVERTER1_ADC_PAIR(4); + adau->tdm_adc_slot = 3; + break; + default: + return -EINVAL; + } + + switch (tx_mask) { + case 0x03: + conv_ctrl0 = ADAU17X1_CONVERTER0_DAC_PAIR(1); + adau->tdm_dac_slot = 0; + break; + case 0x0c: + conv_ctrl0 = ADAU17X1_CONVERTER0_DAC_PAIR(2); + adau->tdm_dac_slot = 1; + break; + case 0x30: + conv_ctrl0 = ADAU17X1_CONVERTER0_DAC_PAIR(3); + adau->tdm_dac_slot = 2; + break; + case 0xc0: + conv_ctrl0 = ADAU17X1_CONVERTER0_DAC_PAIR(4); + adau->tdm_dac_slot = 3; + break; + default: + return -EINVAL; + } + + regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER0, + ADAU17X1_CONVERTER0_DAC_PAIR_MASK, conv_ctrl0); + regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER1, + ADAU17X1_CONVERTER1_ADC_PAIR_MASK, conv_ctrl1); + regmap_update_bits(adau->regmap, ADAU17X1_SERIAL_PORT0, + ADAU17X1_SERIAL_PORT0_TDM_MASK, ser_ctrl0); + regmap_update_bits(adau->regmap, ADAU17X1_SERIAL_PORT1, + ADAU17X1_SERIAL_PORT1_BCLK_MASK, ser_ctrl1); + + if (adau17x1_has_dsp(adau)) { + if (adau->dsp_playback_bypass) { + regmap_write(adau->regmap, ADAU17X1_SERIAL_INPUT_ROUTE, + (adau->tdm_dac_slot * 2) + 1); + } + if (adau->dsp_capture_bypass) { + regmap_write(adau->regmap, ADAU17X1_SERIAL_OUTPUT_ROUTE, + (adau->tdm_adc_slot * 2) + 1); + } + } + + return 0; +} + +const struct snd_soc_dai_ops adau17x1_dai_ops = { + .hw_params = adau17x1_hw_params, + .set_sysclk = adau17x1_set_dai_sysclk, + .set_fmt = adau17x1_set_dai_fmt, + .set_pll = adau17x1_set_dai_pll, + .set_clkdiv = adau17x1_set_dai_clkdiv, + .set_tdm_slot = adau17x1_set_dai_tdm_slot, + .startup = adau17x1_dai_startup, + .shutdown = adau17x1_dai_shutdown, +}; +EXPORT_SYMBOL_GPL(adau17x1_dai_ops); + +int adau17x1_set_micbias_voltage(struct snd_soc_codec *codec, + enum adau17x1_micbias_voltage micbias) +{ + struct adau *adau = snd_soc_codec_get_drvdata(codec); + + switch (micbias) { + case ADAU17X1_MICBIAS_0_90_AVDD: + case ADAU17X1_MICBIAS_0_65_AVDD: + break; + default: + return -EINVAL; + } + + regmap_write(adau->regmap, ADAU17X1_MICBIAS, micbias << 2); + + return 0; +} +EXPORT_SYMBOL_GPL(adau17x1_set_micbias_voltage); + +bool adau17x1_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case ADAU17X1_CLOCK_CONTROL: + case ADAU17X1_PLL_CONTROL: + case ADAU17X1_REC_POWER_MGMT: + case ADAU17X1_MICBIAS: + case ADAU17X1_SERIAL_PORT0: + case ADAU17X1_SERIAL_PORT1: + case ADAU17X1_CONVERTER0: + case ADAU17X1_CONVERTER1: + case ADAU17X1_LEFT_INPUT_DIGITAL_VOL: + case ADAU17X1_RIGHT_INPUT_DIGITAL_VOL: + case ADAU17X1_ADC_CONTROL: + case ADAU17X1_PLAY_POWER_MGMT: + case ADAU17X1_DAC_CONTROL0: + case ADAU17X1_DAC_CONTROL1: + case ADAU17X1_DAC_CONTROL2: + case ADAU17X1_SERIAL_PORT_PAD: + case ADAU17X1_CONTROL_PORT_PAD0: + case ADAU17X1_CONTROL_PORT_PAD1: + case ADAU17X1_DSP_SAMPLING_RATE: + case ADAU17X1_SERIAL_INPUT_ROUTE: + case ADAU17X1_SERIAL_OUTPUT_ROUTE: + case ADAU17X1_DSP_ENABLE: + case ADAU17X1_DSP_RUN: + case ADAU17X1_SERIAL_SAMPLING_RATE: + return true; + default: + break; + } + return false; +} +EXPORT_SYMBOL_GPL(adau17x1_readable_register); + +bool adau17x1_volatile_register(struct device *dev, unsigned int reg) +{ + /* SigmaDSP parameter and program memory */ + if (reg < 0x4000) + return true; + + switch (reg) { + /* The PLL register is 6 bytes long */ + case ADAU17X1_PLL_CONTROL: + case ADAU17X1_PLL_CONTROL + 1: + case ADAU17X1_PLL_CONTROL + 2: + case ADAU17X1_PLL_CONTROL + 3: + case ADAU17X1_PLL_CONTROL + 4: + case ADAU17X1_PLL_CONTROL + 5: + return true; + default: + break; + } + + return false; +} +EXPORT_SYMBOL_GPL(adau17x1_volatile_register); + +int adau17x1_load_firmware(struct adau *adau, struct device *dev, + const char *firmware) +{ + int ret; + int dspsr; + + ret = regmap_read(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, &dspsr); + if (ret) + return ret; + + regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 1); + regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, 0xf); + + ret = process_sigma_firmware_regmap(dev, adau->regmap, + firmware); + if (ret) { + regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 0); + return ret; + } + regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, dspsr); + + return 0; +} +EXPORT_SYMBOL_GPL(adau17x1_load_firmware); + +int adau17x1_probe(struct snd_soc_codec *codec) +{ + struct adau *adau = snd_soc_codec_get_drvdata(codec); + int ret; + + /* TODO: Remove next line */ + codec->control_data = adau->regmap; + ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); + if (ret < 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + return ret; + } + + codec->driver->set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + ret = snd_soc_add_controls(codec, adau17x1_controls, + ARRAY_SIZE(adau17x1_controls)); + if (ret) + return ret; + ret = snd_soc_dapm_new_controls(&codec->dapm, adau17x1_dapm_widgets, + ARRAY_SIZE(adau17x1_dapm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(&codec->dapm, adau17x1_dapm_routes, + ARRAY_SIZE(adau17x1_dapm_routes)); + if (ret) + return ret; + + if (!adau17x1_has_dsp(adau)) + return 0; + + ret = snd_soc_add_controls(codec, adau17x1_dsp_controls, + ARRAY_SIZE(adau17x1_dsp_controls)); + if (ret) + return ret; + ret = snd_soc_dapm_new_controls(&codec->dapm, adau17x1_dsp_dapm_widgets, + ARRAY_SIZE(adau17x1_dsp_dapm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(&codec->dapm, adau17x1_dsp_dapm_routes, + ARRAY_SIZE(adau17x1_dsp_dapm_routes)); + return ret; +} +EXPORT_SYMBOL_GPL(adau17x1_probe); + +#if IS_ENABLED(CONFIG_SPI_MASTER) +static void adau17x1_spi_mode(struct device *dev) +{ + /* To get the device into SPI mode CLATCH has to be pulled low three + * times. Do this by issuing three dummy reads. */ + spi_w8r8(to_spi_device(dev), 0x00); + spi_w8r8(to_spi_device(dev), 0x00); + spi_w8r8(to_spi_device(dev), 0x00); +} +#else +static inline void adau17x1_spi_mode(struct device *dev) {} +#endif + +int adau17x1_suspend(struct snd_soc_codec *codec) +{ + codec->driver->set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} +EXPORT_SYMBOL_GPL(adau17x1_suspend); + +int adau17x1_resume(struct snd_soc_codec *codec) +{ + struct adau *adau = snd_soc_codec_get_drvdata(codec); + + if (adau->control_type == SND_SOC_SPI) + adau17x1_spi_mode(codec->dev); + + codec->driver->set_bias_level(codec, SND_SOC_BIAS_OFF); + regcache_sync(adau->regmap); + + return 0; +} +EXPORT_SYMBOL_GPL(adau17x1_resume); + +int __devinit adau17x1_bus_probe(struct device *dev, struct regmap *regmap, + enum adau17x1_type type, enum snd_soc_control_type control_type) +{ + struct adau *adau; + + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + adau = devm_kzalloc(dev, sizeof(*adau), GFP_KERNEL); + if (!adau) + return -ENOMEM; + + adau->regmap = regmap; + adau->control_type = control_type; + adau->type = type; + adau->sysclk_div = 1; + + dev_set_drvdata(dev, adau); + + if (control_type == SND_SOC_SPI) + adau17x1_spi_mode(dev); + + return 0; +} +EXPORT_SYMBOL_GPL(adau17x1_bus_probe); + +MODULE_DESCRIPTION("ASoC ADAU1X61/ADAU1X81 common code"); +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/adau17x1.h b/sound/soc/codecs/adau17x1.h new file mode 100644 index 0000000000000..920b5b865544f --- /dev/null +++ b/sound/soc/codecs/adau17x1.h @@ -0,0 +1,124 @@ +#ifndef __ADAU17X1_H__ +#define __ADAU17X1_H__ + +#include +#include + +enum adau17x1_type { + ADAU1361, + ADAU1761, + ADAU1381, + ADAU1781, +}; + +enum adau17x1_pll { + ADAU17X1_PLL, +}; + +enum adau17x1_pll_src { + ADAU17X1_PLL_SRC_MCLK, +}; + +enum adau17x1_clk_src { + ADAU17X1_CLK_SRC_MCLK, + ADAU17X1_CLK_SRC_PLL, +}; + +struct adau { + unsigned int sysclk; + unsigned int sysclk_div; + unsigned int pll_freq; + + enum adau17x1_clk_src clk_src; + enum adau17x1_type type; + enum snd_soc_control_type control_type; + + unsigned int dai_fmt; + + uint8_t pll_regs[6]; + + bool master; + + unsigned int tdm_dac_slot; + unsigned int tdm_adc_slot; + + bool dsp_playback_bypass; + bool dsp_capture_bypass; + + struct regmap *regmap; +}; + +int adau17x1_probe(struct snd_soc_codec *codec); +int adau17x1_bus_probe(struct device *dev, + struct regmap *regmap, enum adau17x1_type type, + enum snd_soc_control_type control_type); +int adau17x1_set_micbias_voltage(struct snd_soc_codec *codec, + enum adau17x1_micbias_voltage micbias); +bool adau17x1_readable_register(struct device *dev, unsigned int reg); +bool adau17x1_volatile_register(struct device *dev, unsigned int reg); +int adau17x1_suspend(struct snd_soc_codec *codec); +int adau17x1_resume(struct snd_soc_codec *codec); + +extern const struct snd_soc_dai_ops adau17x1_dai_ops; + +int adau17x1_load_firmware(struct adau *adau, struct device *dev, + const char *firmware); + +#define ADAU17X1_CLOCK_CONTROL 0x4000 +#define ADAU17X1_PLL_CONTROL 0x4002 +#define ADAU17X1_REC_POWER_MGMT 0x4009 +#define ADAU17X1_MICBIAS 0x4010 +#define ADAU17X1_SERIAL_PORT0 0x4015 +#define ADAU17X1_SERIAL_PORT1 0x4016 +#define ADAU17X1_CONVERTER0 0x4017 +#define ADAU17X1_CONVERTER1 0x4018 +#define ADAU17X1_LEFT_INPUT_DIGITAL_VOL 0x401a +#define ADAU17X1_RIGHT_INPUT_DIGITAL_VOL 0x401b +#define ADAU17X1_ADC_CONTROL 0x4019 +#define ADAU17X1_PLAY_POWER_MGMT 0x4029 +#define ADAU17X1_DAC_CONTROL0 0x402a +#define ADAU17X1_DAC_CONTROL1 0x402b +#define ADAU17X1_DAC_CONTROL2 0x402c +#define ADAU17X1_SERIAL_PORT_PAD 0x402d +#define ADAU17X1_CONTROL_PORT_PAD0 0x402f +#define ADAU17X1_CONTROL_PORT_PAD1 0x4030 +#define ADAU17X1_DSP_SAMPLING_RATE 0x40eb +#define ADAU17X1_SERIAL_INPUT_ROUTE 0x40f2 +#define ADAU17X1_SERIAL_OUTPUT_ROUTE 0x40f3 +#define ADAU17X1_DSP_ENABLE 0x40f5 +#define ADAU17X1_DSP_RUN 0x40f6 +#define ADAU17X1_SERIAL_SAMPLING_RATE 0x40f8 + +#define ADAU17X1_SERIAL_PORT0_BCLK_POL BIT(4) +#define ADAU17X1_SERIAL_PORT0_LRCLK_POL BIT(3) +#define ADAU17X1_SERIAL_PORT0_MASTER BIT(0) + +#define ADAU17X1_SERIAL_PORT1_DELAY1 0x00 +#define ADAU17X1_SERIAL_PORT1_DELAY0 0x01 +#define ADAU17X1_SERIAL_PORT1_DELAY8 0x02 +#define ADAU17X1_SERIAL_PORT1_DELAY16 0x03 +#define ADAU17X1_SERIAL_PORT1_DELAY_MASK 0x03 + +#define ADAU17X1_CLOCK_CONTROL_INFREQ_MASK 0x6 +#define ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL BIT(3) +#define ADAU17X1_CLOCK_CONTROL_SYSCLK_EN BIT(0) + +#define ADUA_SERIAL_PORT1_BCLK32 (0x0 << 5) +#define ADUA_SERIAL_PORT1_BCLK48 (0x1 << 5) +#define ADUA_SERIAL_PORT1_BCLK64 (0x2 << 5) +#define ADUA_SERIAL_PORT1_BCLK128 (0x3 << 5) +#define ADUA_SERIAL_PORT1_BCLK256 (0x4 << 5) +#define ADAU17X1_SERIAL_PORT1_BCLK_MASK (0x7 << 5) + +#define ADUA_SERIAL_PORT0_STEREO (0x0 << 1) +#define ADUA_SERIAL_PORT0_TDM4 (0x1 << 1) +#define ADUA_SERIAL_PORT0_TDM8 (0x2 << 1) +#define ADAU17X1_SERIAL_PORT0_TDM_MASK (0x3 << 1) +#define ADAU17X1_SERIAL_PORT0_PULSE_MODE BIT(5) + +#define ADAU17X1_CONVERTER0_DAC_PAIR(x) (((x) - 1) << 5) +#define ADAU17X1_CONVERTER0_DAC_PAIR_MASK (0x3 << 5) +#define ADAU17X1_CONVERTER1_ADC_PAIR(x) ((x) - 1) +#define ADAU17X1_CONVERTER1_ADC_PAIR_MASK 0x3 + +#endif diff --git a/sound/soc/xlnx/Kconfig b/sound/soc/xlnx/Kconfig new file mode 100644 index 0000000000000..ec6cc7cd6a045 --- /dev/null +++ b/sound/soc/xlnx/Kconfig @@ -0,0 +1,18 @@ +config SND_SOC_XILINX + tristate "SoC Audio for Xilinx based boards" + depends on SND_SOC && (MICROBLAZE || ARCH_ZYNQ) + select SND_SOC_DMAENGINE_PCM + +config SND_SOC_AXI_SPDIF + tristate + +config SND_SOC_ADV7511_HDMI + tristate "ADV7511 HDMI transmitter sound support" + depends on SND_SOC_XILINX + select SND_SOC_AXI_SPDIF + +config SND_SOC_ZED_ADAU1761 + tristate "ZED board sound support" + depends on SND_SOC_XILINX + select SND_SOC_AXI_I2S + select SND_SOC_ADAU1761 diff --git a/sound/soc/xlnx/Makefile b/sound/soc/xlnx/Makefile new file mode 100644 index 0000000000000..2f352f18fd05a --- /dev/null +++ b/sound/soc/xlnx/Makefile @@ -0,0 +1,12 @@ +snd-soc-xilinx-pcm-objs := xilinx-pcm.o +snd-soc-axi-spdif-objs := axi-spdif.o +snd-soc-axi-i2s-objs := axi-i2s.o +snd-soc-adv7511-hdmi-objs := adv7511_hdmi.o +snd-soc-zed-adau1761-objs := zed_adau1761.o + +obj-$(CONFIG_SND_SOC_XILINX) += snd-soc-xilinx-pcm.o +obj-$(CONFIG_SND_SOC_AXI_SPDIF) += snd-soc-axi-spdif.o +obj-$(CONFIG_SND_SOC_AXI_I2S) += snd-soc-axi-i2s.o + +obj-$(CONFIG_SND_SOC_ADV7511_HDMI) += snd-soc-adv7511-hdmi.o +obj-$(CONFIG_SND_SOC_ZED_ADAU1761) += snd-soc-zed-adau1761.o diff --git a/sound/soc/xlnx/adv7511_hdmi.c b/sound/soc/xlnx/adv7511_hdmi.c new file mode 100644 index 0000000000000..654ad1b5ad405 --- /dev/null +++ b/sound/soc/xlnx/adv7511_hdmi.c @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2012, Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * 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. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +static char adv7511_codec_name[] = "adv7511.2-0039"; + +static struct snd_soc_dai_link hdmi_dai_link = { + .name = "HDMI", + .stream_name = "HDMI", +/* .cpu_dai_name = "75c00000.axi-spdif-tx", + .platform_name = "xilinx_pcm_audio.2",*/ + .codec_name = adv7511_codec_name, + .codec_dai_name = "adv7511", + .dai_fmt = SND_SOC_DAIFMT_SPDIF | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, +}; + +static struct snd_soc_card hdmi_card = { + .name = "HDMI monitor", + .owner = THIS_MODULE, + .dai_link = &hdmi_dai_link, + .num_links = 1, +}; + + +static int __devinit adv7511_hdmi_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card = &hdmi_card; + struct device_node *of_node = pdev->dev.of_node; + struct device_node *adapter_node; + struct i2c_adapter *adapter; + + if (!of_node) + return -ENXIO; + + card->dev = &pdev->dev; + + hdmi_dai_link.cpu_of_node = of_parse_phandle(of_node, "cpu-dai", 0); + hdmi_dai_link.platform_of_node = of_parse_phandle(of_node, "pcm", 0); + + adapter_node = of_parse_phandle(of_node, "audio-codec-adapter", 0); + adapter = of_find_i2c_adapter_by_node(adapter_node); + if (adapter) { + snprintf(adv7511_codec_name, sizeof(adv7511_codec_name), + "adv7511.%d-0039", i2c_adapter_id(adapter)); + } + + if (/*!hdmi_dai_link.codec_of_node || */!hdmi_dai_link.cpu_of_node || + !hdmi_dai_link.platform_of_node) + return -ENXIO; + + return snd_soc_register_card(card); +} + +static int __devexit adv7511_hdmi_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); + + return 0; +} + +static const struct of_device_id adv7511_hdmi_of_match[] __devinitconst = { + { .compatible = "adv7511-hdmi-snd", }, + {}, +}; +MODULE_DEVICE_TABLE(of, adv7511_hdmi_of_match); + +static struct platform_driver hdmi_card_driver = { + .driver = { + .name = "adv7511-hdmi-snd", + .owner = THIS_MODULE, + .of_match_table = adv7511_hdmi_of_match, + .pm = &snd_soc_pm_ops, + }, + .probe = adv7511_hdmi_probe, + .remove = __devexit_p(adv7511_hdmi_remove), +}; +module_platform_driver(hdmi_card_driver); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("ADV7511 HDMI sound driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/xlnx/axi-i2s.c b/sound/soc/xlnx/axi-i2s.c new file mode 100644 index 0000000000000..0f9d359cbe6dc --- /dev/null +++ b/sound/soc/xlnx/axi-i2s.c @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2012, Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * 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. + * + * 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 +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +struct axi_i2s { + void __iomem *base; + + unsigned int clock; + + struct debugfs_regset32 regset; + spinlock_t lock; +}; + + +#define AXI_I2S_REG_RESET 0x00 +#define AXI_I2S_REG_CTRL 0x04 +#define AXI_I2S_REG_CLK_CTRL 0x08 +#define AXI_I2S_REG_STATUS 0x10 +#define AXI_I2S_REG_PERIOD_SIZE 0x18 + +#define AXI_I2S_RESET_GLOBAL BIT(0) +#define AXI_I2S_RESET_TX_FIFO BIT(1) +#define AXI_I2S_RESET_RX_FIFO BIT(2) + +#define AXI_I2S_CTRL_TX_EN BIT(0) +#define AXI_I2S_CTRL_RX_EN BIT(1) + +static const struct debugfs_reg32 axi_i2s_debugfs_regs[] = { + { "Reset", AXI_I2S_REG_RESET }, + { "Control", AXI_I2S_REG_CTRL }, + { "Status", AXI_I2S_REG_STATUS }, + { "Clock control", AXI_I2S_REG_CLK_CTRL }, + { "Period size", AXI_I2S_REG_PERIOD_SIZE }, +}; + +static inline uint32_t axi_i2s_read(const struct axi_i2s *i2s, + unsigned int reg) +{ + return readl(i2s->base + reg); +} + +static inline void axi_i2s_write(const struct axi_i2s *i2s, + unsigned int reg, uint32_t value) +{ + writel(value, i2s->base + reg); +} + +static int axi_i2s_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct axi_i2s *i2s = snd_soc_dai_get_drvdata(dai); + uint32_t mask, ctrl; + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + mask = AXI_I2S_CTRL_RX_EN; + else + mask = AXI_I2S_CTRL_TX_EN; + + spin_lock(&i2s->lock); + ctrl = axi_i2s_read(i2s, AXI_I2S_REG_CTRL); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + ctrl |= mask; + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + ctrl &= ~mask; + break; + default: + return -EINVAL; + } + + axi_i2s_write(i2s, AXI_I2S_REG_CTRL, ctrl); + spin_unlock(&i2s->lock); + + return 0; +} + +static int axi_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + struct axi_i2s *i2s = snd_soc_dai_get_drvdata(dai); + unsigned int bclk_div, frame_size; + + frame_size = snd_soc_params_to_frame_size(params) / 2; + bclk_div = DIV_ROUND_UP(i2s->clock, snd_soc_params_to_bclk(params)) / 2 - 1; + axi_i2s_write(i2s, AXI_I2S_REG_CLK_CTRL, (frame_size << 16) | bclk_div); + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + unsigned int period_size = params_period_bytes(params) / 4 - 1; + axi_i2s_write(i2s, AXI_I2S_REG_PERIOD_SIZE, period_size); + } + + return 0; +} + +static int axi_i2s_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct axi_i2s *i2s = snd_soc_dai_get_drvdata(dai); + uint32_t mask; + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + mask = AXI_I2S_RESET_RX_FIFO; + else + mask = AXI_I2S_RESET_TX_FIFO; + + axi_i2s_write(i2s, AXI_I2S_REG_RESET, mask); + + return 0; +} + +static const struct snd_soc_dai_ops axi_i2s_dai_ops = { + .startup = axi_i2s_startup, + .trigger = axi_i2s_trigger, + .hw_params = axi_i2s_hw_params, +}; + +static struct snd_soc_dai_driver axi_i2s_dai = { + .playback = { + .channels_min = 2, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S32_LE, + }, + .capture = { + .channels_min = 2, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &axi_i2s_dai_ops, + .symmetric_rates = 1, +}; + +static int __devinit axi_i2s_probe(struct platform_device *pdev) +{ + struct axi_i2s *i2s; + struct resource *res; + int ret; + + i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); + + if (!i2s) + return -ENOMEM; + + spin_lock_init(&i2s->lock); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + i2s->base = devm_request_and_ioremap(&pdev->dev, res); + if (!i2s->base) + return -EBUSY; + + platform_set_drvdata(pdev, i2s); + + of_property_read_u32(pdev->dev.of_node, "clock-frequency", &i2s->clock); + ret = snd_soc_register_dai(&pdev->dev, &axi_i2s_dai); + + if (ret) { + dev_err(&pdev->dev, "Failed to register DAI\n"); + return ret; + } + + axi_i2s_write(i2s, AXI_I2S_REG_RESET, AXI_I2S_RESET_GLOBAL); + + i2s->regset.base = i2s->base; + i2s->regset.regs = axi_i2s_debugfs_regs; + i2s->regset.nregs = ARRAY_SIZE(axi_i2s_debugfs_regs); + + debugfs_create_regset32(dev_name(&pdev->dev), 0444, NULL, &i2s->regset); + + return 0; +} + +static int __devexit axi_i2s_dev_remove(struct platform_device *pdev) +{ + snd_soc_unregister_dai(&pdev->dev); + + return 0; +} + +static const struct of_device_id axi_i2s_of_match[] __devinitconst = { + { .compatible = "adi,axi-i2s-1.00.a", }, + {}, +}; +MODULE_DEVICE_TABLE(of, axi_i2s_of_match); + +static struct platform_driver axi_i2s_driver = { + .driver = { + .name = "axi-i2s", + .owner = THIS_MODULE, + .of_match_table = axi_i2s_of_match, + }, + .probe = axi_i2s_probe, + .remove = __devexit_p(axi_i2s_dev_remove), +}; +module_platform_driver(axi_i2s_driver); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("AXI I2S driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/xlnx/axi-spdif.c b/sound/soc/xlnx/axi-spdif.c new file mode 100644 index 0000000000000..02e41c1682979 --- /dev/null +++ b/sound/soc/xlnx/axi-spdif.c @@ -0,0 +1,240 @@ +/* + * Copyright (C) 2012, Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * 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. + * + * 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 +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +struct axi_spdif { + void __iomem *base; + + unsigned int clock; + + struct debugfs_regset32 regset; +}; + +#define AXI_SPDIF_REG_CTRL 0x0 +#define AXI_SPDIF_REG_STAT 0x4 + +#define AXI_SPDIF_CTRL_TXDATA BIT(1) +#define AXI_SPDIF_CTRL_TXEN BIT(0) +#define AXI_SPDIF_CTRL_RATIO_OFFSET 8 +#define AXI_SPDIF_CTRL_RATIO_MASK (0xff << 8) + +#define AXI_SPDIF_FREQ_44100 (0x0 << 6) +#define AXI_SPDIF_FREQ_48000 (0x1 << 6) +#define AXI_SPDIF_FREQ_32000 (0x2 << 6) +#define AXI_SPDIF_FREQ_NA (0x3 << 6) + +static struct debugfs_reg32 axi_spdif_debugfs_regs[] = { + { "Control", AXI_SPDIF_REG_CTRL }, + { "Status", AXI_SPDIF_REG_STAT }, +}; + +static inline uint32_t axi_spdif_read(const struct axi_spdif *spdif, + unsigned int reg) +{ + return readl(spdif->base + reg); +} + +static inline void axi_spdif_write(const struct axi_spdif *spdif, + unsigned int reg, uint32_t value) +{ + writel(value, spdif->base + reg); +} + +static int axi_spdif_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct axi_spdif *spdif = snd_soc_dai_get_drvdata(dai); + uint32_t ctrl = axi_spdif_read(spdif, AXI_SPDIF_REG_CTRL); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + ctrl |= AXI_SPDIF_CTRL_TXDATA; + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + ctrl &= ~AXI_SPDIF_CTRL_TXDATA; + break; + default: + return -EINVAL; + } + + axi_spdif_write(spdif, AXI_SPDIF_REG_CTRL, ctrl); + + return 0; +} + +static int axi_spdif_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + struct axi_spdif *spdif = snd_soc_dai_get_drvdata(dai); + uint32_t ctrl = axi_spdif_read(spdif, AXI_SPDIF_REG_CTRL); + unsigned int ratio, stat; + + switch (params_rate(params)) { + case 32000: + stat = AXI_SPDIF_FREQ_32000; + break; + case 44100: + stat = AXI_SPDIF_FREQ_44100; + break; + case 48000: + stat = AXI_SPDIF_FREQ_48000; + break; + default: + stat = AXI_SPDIF_FREQ_NA; + break; + } + + ratio = DIV_ROUND_CLOSEST(spdif->clock, (params_rate(params) * 64 * 2)) - 1; + + ctrl &= ~AXI_SPDIF_CTRL_RATIO_MASK; + ctrl |= ratio << AXI_SPDIF_CTRL_RATIO_OFFSET; + + axi_spdif_write(spdif, AXI_SPDIF_REG_STAT, stat); + axi_spdif_write(spdif, AXI_SPDIF_REG_CTRL, ctrl); + + return 0; +} +/* +static int axi_spdif_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct axi_spdif *spdif = snd_soc_dai_get_drvdata(dai); + uint32_t ctrl; + + if (dai->active) + return 0; + + ctrl = axi_spdif_read(spdif, AXI_SPDIF_REG_CTRL); + ctrl |= AXI_SPDIF_CTRL_TXEN; + axi_spdif_write(spdif, AXI_SPDIF_REG_CTRL, ctrl); + + return 0; +} + +static void axi_spdif_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct axi_spdif *spdif = snd_soc_dai_get_drvdata(dai); + uint32_t ctrl; + + if (dai->active) + return; + + ctrl = axi_spdif_read(spdif, AXI_SPDIF_REG_CTRL); + ctrl &= ~AXI_SPDIF_CTRL_TXEN; + axi_spdif_write(spdif, AXI_SPDIF_REG_CTRL, ctrl); +} +*/ +static const struct snd_soc_dai_ops axi_spdif_dai_ops = { + .trigger = axi_spdif_trigger, + .hw_params = axi_spdif_hw_params, +}; + +static struct snd_soc_dai_driver axi_spdif_dai = { + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .ops = &axi_spdif_dai_ops, +}; + +static int __devinit axi_spdif_probe(struct platform_device *pdev) +{ + struct axi_spdif *spdif; + struct resource *res; + int ret; + + spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL); + + if (!spdif) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + spdif->base = devm_request_and_ioremap(&pdev->dev, res); + if (!spdif->base) + return -EBUSY; + + platform_set_drvdata(pdev, spdif); + + of_property_read_u32(pdev->dev.of_node, "clock-frequency", &spdif->clock); + + ret = snd_soc_register_dai(&pdev->dev, &axi_spdif_dai); + + if (ret) { + dev_err(&pdev->dev, "Failed to register DAI\n"); + return ret; + } + + spdif->regset.base = spdif->base; + spdif->regset.regs = axi_spdif_debugfs_regs; + spdif->regset.nregs = ARRAY_SIZE(axi_spdif_debugfs_regs); + + debugfs_create_regset32(dev_name(&pdev->dev), 0777, NULL, &spdif->regset); + + axi_spdif_write(spdif, AXI_SPDIF_REG_CTRL, AXI_SPDIF_CTRL_TXEN); + + return 0; +} + +static int __devexit axi_spdif_dev_remove(struct platform_device *pdev) +{ + snd_soc_unregister_dai(&pdev->dev); + + return 0; +} + +static const struct of_device_id axi_spdif_of_match[] __devinitconst = { + { .compatible = "adi,axi-spdif-tx-1.00.a", }, + {}, +}; +MODULE_DEVICE_TABLE(of, axi_spdif_of_match); + +static struct platform_driver axi_spdif_driver = { + .driver = { + .name = "axi-spdif", + .owner = THIS_MODULE, + .of_match_table = axi_spdif_of_match, + }, + .probe = axi_spdif_probe, + .remove = __devexit_p(axi_spdif_dev_remove), +}; +module_platform_driver(axi_spdif_driver); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("AXI SPDIF driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/xlnx/xilinx-pcm.c b/sound/soc/xlnx/xilinx-pcm.c new file mode 100644 index 0000000000000..f304924da128b --- /dev/null +++ b/sound/soc/xlnx/xilinx-pcm.c @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2012, Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * 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. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static const struct snd_pcm_hardware xlnx_pcm_hardware = { + .info = SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER, + .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S8, + .channels_min = 1, + .channels_max = UINT_MAX, + .period_bytes_min = 1024, + .period_bytes_max = (1 << 20) - 1, + .periods_min = 2, + .periods_max = UINT_MAX, + .buffer_bytes_max = ULONG_MAX, +}; + +static int xlnx_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); +} + +struct xlnx_pcm_dma_params { + struct device_node *of_node; + int chan_id; +}; + +static bool xlnx_pcm_filter(struct dma_chan *chan, void *param) +{ + struct xlnx_pcm_dma_params *p = param; + + return chan->device->dev->of_node == p->of_node && + chan->chan_id == p->chan_id; +} + +static int xlnx_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct device *dev = rtd->platform->dev; + struct xlnx_pcm_dma_params *params = dev_get_drvdata(dev); + int ret; + + ret = snd_soc_set_runtime_hwparams(substream, &xlnx_pcm_hardware); + if (ret) + return ret; + + return snd_dmaengine_pcm_open(substream, xlnx_pcm_filter, params); +} + +static int xlnx_pcm_new(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_card *card = rtd->card->snd_card; + + return snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, + SNDRV_DMA_TYPE_DEV, + card->dev, 1 * 1024 * 1024, + xlnx_pcm_hardware.buffer_bytes_max); +} + +static int xlnx_pcm_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + return dma_mmap_coherent(substream->pcm->card->dev, vma, + runtime->dma_area, + runtime->dma_addr, + runtime->dma_bytes); + return remap_pfn_range(vma, vma->vm_start, + substream->dma_buffer.addr >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot); +} + +static struct snd_pcm_ops xlnx_pcm_ops = { + .open = xlnx_pcm_open, + .close = snd_dmaengine_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = xlnx_pcm_hw_params, + .hw_free = snd_pcm_lib_free_pages, + .trigger = snd_dmaengine_pcm_trigger, + .pointer = snd_dmaengine_pcm_pointer, + .mmap = xlnx_pcm_mmap, +}; + +static struct snd_soc_platform_driver xlnx_pcm_soc_platform = { + .pcm_new = xlnx_pcm_new, +/* .pcm_free = snd_pcm_lib_preallocate_free_for_all,*/ + .ops = &xlnx_pcm_ops, +}; + +static int __devinit xlnx_pcm_soc_platform_probe(struct platform_device *pdev) +{ + struct xlnx_pcm_dma_params *params; + struct of_phandle_args dma_spec; + int ret; + + params = devm_kzalloc(&pdev->dev, sizeof(*params), GFP_KERNEL); + if (!params) + return -ENOMEM; + + ret = of_parse_phandle_with_args(pdev->dev.of_node, "dma-request", + "#dma-cells", 0, &dma_spec); + if (ret) + return ret; + + params->of_node = dma_spec.np; + params->chan_id = dma_spec.args[0]; + + dev_set_drvdata(&pdev->dev, params); + + return snd_soc_register_platform(&pdev->dev, &xlnx_pcm_soc_platform); +} + +static int __devexit xlnx_pcm_soc_platform_remove(struct platform_device *pdev) +{ + snd_soc_unregister_platform(&pdev->dev); + return 0; +} + +static const struct of_device_id xilinx_pcm_of_match[] __devinitconst = { + { .compatible = "xilinx-pcm-audio", }, + {}, +}; +MODULE_DEVICE_TABLE(of, xilinx_pcm_of_match); + +static struct platform_driver xlnx_pcm_driver = { + .driver = { + .name = "xilinx-pcm-audio", + .owner = THIS_MODULE, + .of_match_table = xilinx_pcm_of_match, + }, + .probe = xlnx_pcm_soc_platform_probe, + .remove = __devexit_p(xlnx_pcm_soc_platform_remove), +}; +module_platform_driver(xlnx_pcm_driver); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("Xilinx DMA engine based audio DMA driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/xlnx/zed_adau1761.c b/sound/soc/xlnx/zed_adau1761.c new file mode 100644 index 0000000000000..a2ed4c2c9a996 --- /dev/null +++ b/sound/soc/xlnx/zed_adau1761.c @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2012, Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * 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. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include "../codecs/adau17x1.h" + +static const struct snd_soc_dapm_widget zed_adau1761_widgets[] = { + SND_SOC_DAPM_SPK("Line Out", NULL), + SND_SOC_DAPM_HP("Headphone Out", NULL), + SND_SOC_DAPM_MIC("Mic In", NULL), + SND_SOC_DAPM_MIC("Line In", NULL), +}; + +static const struct snd_soc_dapm_route zed_adau1761_routes[] = { + { "Line Out", NULL, "LOUT" }, + { "Line Out", NULL, "ROUT" }, + { "Headphone Out", NULL, "LHP" }, + { "Headphone Out", NULL, "RHP" }, + { "Mic In", NULL, "MICBIAS" }, + { "LINN", NULL, "Mic In" }, + { "RINN", NULL, "Mic In" }, + { "LAUX", NULL, "Line In" }, + { "RAUX", NULL, "Line In" }, +}; + +static int zed_adau1761_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + int pll_rate; + int ret; + + switch (params_rate(params)) { + case 48000: + case 8000: + case 12000: + case 16000: + case 24000: + case 32000: + case 96000: + pll_rate = 48000 * 1024; + break; + case 44100: + case 7350: + case 11025: + case 14700: + case 22050: + case 29400: + case 88200: + pll_rate = 44100 * 1024; + break; + default: + return -EINVAL; + } + + ret = snd_soc_dai_set_pll(codec_dai, ADAU17X1_PLL, + ADAU17X1_PLL_SRC_MCLK, 12288000, pll_rate); + if (ret) + return ret; + + ret = snd_soc_dai_set_sysclk(codec_dai, ADAU17X1_CLK_SRC_PLL, pll_rate, + SND_SOC_CLOCK_IN); + + return ret; +} + +static struct snd_soc_ops zed_adau1761_ops = { + .hw_params = zed_adau1761_hw_params, +}; + +static struct snd_soc_dai_link zed_adau1761_dai_link = { + .name = "adau1761", + .stream_name = "adau1761", + .codec_dai_name = "adau-hifi", + .dai_fmt = SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + .ops = &zed_adau1761_ops, +}; + +static struct snd_soc_card zed_adau1761_card = { + .name = "ZED ADAU161", + .owner = THIS_MODULE, + .dai_link = &zed_adau1761_dai_link, + .num_links = 1, + .dapm_widgets = zed_adau1761_widgets, + .num_dapm_widgets = ARRAY_SIZE(zed_adau1761_widgets), + .dapm_routes = zed_adau1761_routes, + .num_dapm_routes = ARRAY_SIZE(zed_adau1761_routes), + .fully_routed = true, +}; + +static int __devinit zed_adau1761_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card = &zed_adau1761_card; + struct device_node *of_node = pdev->dev.of_node; + + if (!of_node) + return -ENXIO; + + card->dev = &pdev->dev; + + zed_adau1761_dai_link.codec_of_node = of_parse_phandle(of_node, "audio-codec", 0); + zed_adau1761_dai_link.cpu_dai_of_node = of_parse_phandle(of_node, "cpu-dai", 0); + zed_adau1761_dai_link.platform_of_node = of_parse_phandle(of_node, "pcm", 0); + + if (!zed_adau1761_dai_link.codec_of_node || !zed_adau1761_dai_link.cpu_dai_of_node || + !zed_adau1761_dai_link.platform_of_node) + return -ENXIO; + + return snd_soc_register_card(card); +} + +static int __devexit zed_adau1761_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); + + return 0; +} + +static const struct of_device_id zed_adau1761_of_match[] __devinitconst = { + { .compatible = "zed-adau1761-snd", }, + {}, +}; +MODULE_DEVICE_TABLE(of, zed_adau1761_of_match); + +static struct platform_driver zed_adau1761_card_driver = { + .driver = { + .name = "zed-adau1761-snd", + .owner = THIS_MODULE, + .of_match_table = zed_adau1761_of_match, + .pm = &snd_soc_pm_ops, + }, + .probe = zed_adau1761_probe, + .remove = __devexit_p(zed_adau1761_remove), +}; +module_platform_driver(zed_adau1761_card_driver);